66 lines · 3.4 KB · TypeScript
RawDownload
import type { DpopFailureReason } from "@t3tools/contracts";import type { RelayProtectedError } from "@t3tools/contracts/relay"; export const DPOP_CLOCK_HINT =  "Hint: Check that automatic date and time is enabled on both devices, then try again."; /** Older servers omit the DPoP category, but newer servers can also omit it for * a credential failure that happens after proof verification. */export const DPOP_UNKNOWN_HINT =  "Hint: Try again. If it still fails, clock skew may be the cause; check that automatic date and time is enabled on both devices."; export const DPOP_RETRY_HINT = "Hint: Try again. If the problem continues, copy the trace ID."; function dpopFailureHint(reason: DpopFailureReason | undefined): string {  if (reason === "time_window") return DPOP_CLOCK_HINT;  if (reason === undefined) return DPOP_UNKNOWN_HINT;  return DPOP_RETRY_HINT;} export function dpopFailureMessage(message: string, reason: DpopFailureReason | undefined): string {  return `${message} ${dpopFailureHint(reason)}`;} export function relayProtectedErrorMessage(error: RelayProtectedError): string {  switch (error._tag) {    case "RelayAuthInvalidError":      switch (error.reason) {        case "missing_bearer":        case "invalid_bearer":          return "Relay rejected the cloud session token.";        case "invalid_dpop":          return dpopFailureMessage("Relay rejected the DPoP proof.", error.dpopFailureReason);        case "not_authorized":          return "Relay rejected the authenticated request.";      }    case "RelayEnvironmentLinkProofExpiredError":      return "Relay rejected an expired environment link proof.";    case "RelayEnvironmentLinkProofInvalidError":      return `Relay rejected the environment link proof (${error.reason}).`;    case "RelayEnvironmentConnectNotAuthorizedError":      // "Not authorized" covers non-auth causes too; surface the reason so a      // missing link does not read as a credential problem.      if (error.reason === "environment_link_not_found") {        return "Relay has no active link for this environment. The environment server may not have re-established its link yet.";      }      return error.reason        ? `Relay rejected the environment connection request (${error.reason}).`        : "Relay rejected the environment connection request.";    case "RelayEnvironmentEndpointUnavailableError":      return `Relay could not reach the environment endpoint (${error.reason}).`;    case "RelayEnvironmentEndpointTimedOutError":      return "Relay timed out while contacting the environment endpoint.";    case "RelayEnvironmentLinkFailedError":      return `Relay could not link the environment (${error.reason}).`;    case "RelayEnvironmentLinkUnavailableError":      return `Relay cannot provision the managed endpoint (${error.reason}).`;    case "RelayEnvironmentLinkLimitExceededError":      return `Relay refused the link: this account already has its maximum of ${error.maxTunnels} managed tunnels. Unlink an environment to free one up.`;    case "RelayAgentActivityPublishProofExpiredError":      return "Relay rejected an expired agent activity publish proof.";    case "RelayAgentActivityPublishProofInvalidError":      return `Relay rejected the agent activity publish proof (${error.reason}).`;    case "RelayInternalError":      return `Relay encountered an internal error (${error.reason}).`;  }}