996 lines · 34.8 KB · TypeScript
RawDownload
import {  AuthAccessTokenType,  AuthAccessWriteScope,  AuthAdministrativeScopes,  AuthStandardClientScopes,  type AuthAccessTokenResult,  type AuthBrowserSessionResult,  type AuthClientMetadata,  type AuthClientSession,  type AuthCreatePairingCredentialInput,  type AuthEnvironmentScope,  type AuthPairingLink,  type AuthPairingCredentialResult,  type AuthSessionId,  type AuthSessionState,  type ServerAuthDescriptor,  type ServerAuthSessionMethod,  type AuthWebSocketTicketResult,} from "@t3tools/contracts";import { encodeOAuthScope } from "@t3tools/shared/oauthScope";import * as Context from "effect/Context";import * as Crypto from "effect/Crypto";import * as DateTime from "effect/DateTime";import * as Duration from "effect/Duration";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as Schema from "effect/Schema";import * as HttpServerRequest from "effect/unstable/http/HttpServerRequest"; import * as EnvironmentAuthPolicy from "./EnvironmentAuthPolicy.ts";import * as PairingGrantStore from "./PairingGrantStore.ts";import * as ServerSecretStore from "./ServerSecretStore.ts";import * as SessionStore from "./SessionStore.ts";import { verifyRequestDpopProof } from "./dpop.ts";import { layerConfig as SqlitePersistenceLayer } from "../persistence/Layers/Sqlite.ts"; export const DEFAULT_SESSION_SUBJECT = "cli-issued-session";export const INTERNAL_ADMINISTRATIVE_BOOTSTRAP_SUBJECT = "administrative-bootstrap"; export interface IssuedPairingLink {  readonly id: string;  readonly credential: string;  readonly scopes: ReadonlyArray<AuthEnvironmentScope>;  readonly subject: string;  readonly label?: string;  readonly createdAt: DateTime.Utc;  readonly expiresAt: DateTime.Utc;} export interface IssuedBearerSession {  readonly sessionId: AuthSessionId;  readonly token: string;  readonly method: "bearer-access-token";  readonly scopes: ReadonlyArray<AuthEnvironmentScope>;  readonly subject: string;  readonly client: AuthClientMetadata;  readonly expiresAt: DateTime.Utc;} export interface AuthenticatedSession {  readonly sessionId: AuthSessionId;  readonly subject: string;  readonly method: ServerAuthSessionMethod;  readonly scopes: ReadonlyArray<AuthEnvironmentScope>;  readonly proofKeyThumbprint?: string;  readonly expiresAt?: DateTime.DateTime;} const serverAuthInternalErrorContext = {  cause: Schema.Defect(),}; export class ServerAuthBootstrapCredentialValidationError extends Schema.TaggedErrorClass<ServerAuthBootstrapCredentialValidationError>()(  "ServerAuthBootstrapCredentialValidationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to validate bootstrap credential.";  }} export class ServerAuthSessionCredentialValidationError extends Schema.TaggedErrorClass<ServerAuthSessionCredentialValidationError>()(  "ServerAuthSessionCredentialValidationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to validate session credential.";  }} export class ServerAuthAuthenticatedSessionIssueError extends Schema.TaggedErrorClass<ServerAuthAuthenticatedSessionIssueError>()(  "ServerAuthAuthenticatedSessionIssueError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to issue authenticated session.";  }} export class ServerAuthAuthenticatedAccessTokenIssueError extends Schema.TaggedErrorClass<ServerAuthAuthenticatedAccessTokenIssueError>()(  "ServerAuthAuthenticatedAccessTokenIssueError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to issue authenticated access token.";  }} export class ServerAuthPairingLinkCreationError extends Schema.TaggedErrorClass<ServerAuthPairingLinkCreationError>()(  "ServerAuthPairingLinkCreationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to create pairing link.";  }} export class ServerAuthPairingLinksListError extends Schema.TaggedErrorClass<ServerAuthPairingLinksListError>()(  "ServerAuthPairingLinksListError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to list pairing links.";  }} export class ServerAuthPairingLinkRevocationError extends Schema.TaggedErrorClass<ServerAuthPairingLinkRevocationError>()(  "ServerAuthPairingLinkRevocationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to revoke pairing link.";  }} export class ServerAuthSessionTokenIssueError extends Schema.TaggedErrorClass<ServerAuthSessionTokenIssueError>()(  "ServerAuthSessionTokenIssueError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to issue session token.";  }} export class ServerAuthSessionsListError extends Schema.TaggedErrorClass<ServerAuthSessionsListError>()(  "ServerAuthSessionsListError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to list sessions.";  }} export class ServerAuthSessionRevocationError extends Schema.TaggedErrorClass<ServerAuthSessionRevocationError>()(  "ServerAuthSessionRevocationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to revoke session.";  }} export class ServerAuthOtherSessionsRevocationError extends Schema.TaggedErrorClass<ServerAuthOtherSessionsRevocationError>()(  "ServerAuthOtherSessionsRevocationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to revoke other sessions.";  }} export class ServerAuthWebSocketTokenIssueError extends Schema.TaggedErrorClass<ServerAuthWebSocketTokenIssueError>()(  "ServerAuthWebSocketTokenIssueError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to issue websocket token.";  }} export class ServerAuthDpopReplayStateRecordError extends Schema.TaggedErrorClass<ServerAuthDpopReplayStateRecordError>()(  "ServerAuthDpopReplayStateRecordError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to record DPoP proof replay state.";  }} export class ServerAuthDpopReplayKeyCalculationError extends Schema.TaggedErrorClass<ServerAuthDpopReplayKeyCalculationError>()(  "ServerAuthDpopReplayKeyCalculationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to calculate DPoP replay key.";  }} export class ServerAuthLinkedCloudAccountVerificationError extends Schema.TaggedErrorClass<ServerAuthLinkedCloudAccountVerificationError>()(  "ServerAuthLinkedCloudAccountVerificationError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Could not verify the linked cloud account.";  }} export class ServerAuthLinkedCloudAccountReadError extends Schema.TaggedErrorClass<ServerAuthLinkedCloudAccountReadError>()(  "ServerAuthLinkedCloudAccountReadError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Could not read the linked cloud account.";  }} export class ServerAuthLinkedCloudAccountMissingError extends Schema.TaggedErrorClass<ServerAuthLinkedCloudAccountMissingError>()(  "ServerAuthLinkedCloudAccountMissingError",  {},) {  override get message(): string {    return "Cloud linked user is not installed for this environment.";  }} export class ServerAuthCloudLinkJwtSigningError extends Schema.TaggedErrorClass<ServerAuthCloudLinkJwtSigningError>()(  "ServerAuthCloudLinkJwtSigningError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to sign cloud link JWT.";  }} export class ServerAuthCloudMintPublicKeyMissingError extends Schema.TaggedErrorClass<ServerAuthCloudMintPublicKeyMissingError>()(  "ServerAuthCloudMintPublicKeyMissingError",  {},) {  override get message(): string {    return "Cloud mint public key is not installed for this environment.";  }} export class ServerAuthCloudRelayIssuerMissingError extends Schema.TaggedErrorClass<ServerAuthCloudRelayIssuerMissingError>()(  "ServerAuthCloudRelayIssuerMissingError",  {},) {  override get message(): string {    return "Cloud relay issuer is not installed for this environment.";  }} export class ServerAuthCloudHealthJwtSigningError extends Schema.TaggedErrorClass<ServerAuthCloudHealthJwtSigningError>()(  "ServerAuthCloudHealthJwtSigningError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to sign cloud health JWT.";  }} export class ServerAuthCloudMintJwtSigningError extends Schema.TaggedErrorClass<ServerAuthCloudMintJwtSigningError>()(  "ServerAuthCloudMintJwtSigningError",  {    ...serverAuthInternalErrorContext,  },) {  override get message(): string {    return "Failed to sign cloud mint JWT.";  }} export const ServerAuthInternalError = Schema.Union([  ServerAuthBootstrapCredentialValidationError,  ServerAuthSessionCredentialValidationError,  ServerAuthAuthenticatedSessionIssueError,  ServerAuthAuthenticatedAccessTokenIssueError,  ServerAuthPairingLinkCreationError,  ServerAuthPairingLinksListError,  ServerAuthPairingLinkRevocationError,  ServerAuthSessionTokenIssueError,  ServerAuthSessionsListError,  ServerAuthSessionRevocationError,  ServerAuthOtherSessionsRevocationError,  ServerAuthWebSocketTokenIssueError,  ServerAuthDpopReplayStateRecordError,  ServerAuthDpopReplayKeyCalculationError,  ServerAuthLinkedCloudAccountVerificationError,  ServerAuthLinkedCloudAccountReadError,  ServerAuthLinkedCloudAccountMissingError,  ServerAuthCloudLinkJwtSigningError,  ServerAuthCloudMintPublicKeyMissingError,  ServerAuthCloudRelayIssuerMissingError,  ServerAuthCloudHealthJwtSigningError,  ServerAuthCloudMintJwtSigningError,]);export type ServerAuthInternalError = typeof ServerAuthInternalError.Type;export const isServerAuthInternalError = Schema.is(ServerAuthInternalError); export class ServerAuthMissingCredentialError extends Schema.TaggedErrorClass<ServerAuthMissingCredentialError>()(  "ServerAuthMissingCredentialError",  {},) {  override get message(): string {    return "Server authentication credential is missing.";  }} export class ServerAuthInvalidCredentialError extends Schema.TaggedErrorClass<ServerAuthInvalidCredentialError>()(  "ServerAuthInvalidCredentialError",  {    diagnostic: Schema.optional(Schema.String),    cause: Schema.optional(Schema.Defect()),  },) {  override get message(): string {    return "Server authentication credential is invalid.";  }} export const ServerAuthCredentialError = Schema.Union([  ServerAuthMissingCredentialError,  ServerAuthInvalidCredentialError,]);export type ServerAuthCredentialError = typeof ServerAuthCredentialError.Type;export const isServerAuthCredentialError = Schema.is(ServerAuthCredentialError);export const serverAuthCredentialReason = (  error: ServerAuthCredentialError,): "missing_credential" | "invalid_credential" =>  error._tag === "ServerAuthMissingCredentialError" ? "missing_credential" : "invalid_credential"; export class ServerAuthInvalidScopeError extends Schema.TaggedErrorClass<ServerAuthInvalidScopeError>()(  "ServerAuthInvalidScopeError",  {},) {  override get message(): string {    return "The requested authentication scope is invalid.";  }} export class ServerAuthScopeNotGrantedError extends Schema.TaggedErrorClass<ServerAuthScopeNotGrantedError>()(  "ServerAuthScopeNotGrantedError",  {},) {  override get message(): string {    return "The requested authentication scope was not granted.";  }} export const ServerAuthInvalidRequestError = Schema.Union([  ServerAuthInvalidScopeError,  ServerAuthScopeNotGrantedError,]);export type ServerAuthInvalidRequestError = typeof ServerAuthInvalidRequestError.Type;export const isServerAuthInvalidRequestError = Schema.is(ServerAuthInvalidRequestError);export const serverAuthInvalidRequestReason = (  error: ServerAuthInvalidRequestError,): "invalid_scope" | "scope_not_granted" =>  error._tag === "ServerAuthInvalidScopeError" ? "invalid_scope" : "scope_not_granted"; export class ServerAuthForbiddenOperationError extends Schema.TaggedErrorClass<ServerAuthForbiddenOperationError>()(  "ServerAuthForbiddenOperationError",  {},) {  override get message(): string {    return "The current authentication session cannot revoke itself.";  }} export class EnvironmentAuth extends Context.Service<  EnvironmentAuth,  {    readonly getDescriptor: () => Effect.Effect<ServerAuthDescriptor>;    readonly getSessionState: (      request: HttpServerRequest.HttpServerRequest,    ) => Effect.Effect<AuthSessionState, ServerAuthInternalError>;    readonly createBrowserSession: (      credential: string,      requestMetadata: AuthClientMetadata,    ) => Effect.Effect<      {        readonly response: AuthBrowserSessionResult;        readonly sessionToken: string;      },      ServerAuthInvalidCredentialError | ServerAuthInternalError    >;    readonly exchangeBootstrapCredentialForAccessToken: (      credential: string,      requestedScopes: ReadonlyArray<AuthEnvironmentScope> | undefined,      requestMetadata: AuthClientMetadata,      input?: {        readonly proofKeyThumbprint?: string;      },    ) => Effect.Effect<      AuthAccessTokenResult,      ServerAuthInvalidCredentialError | ServerAuthInvalidRequestError | ServerAuthInternalError    >;    readonly createPairingLink: (input?: {      readonly ttl?: Duration.Duration;      readonly label?: string;      readonly scopes?: ReadonlyArray<AuthEnvironmentScope>;      readonly subject?: string;      readonly proofKeyThumbprint?: string;      readonly purpose?: "startup";    }) => Effect.Effect<IssuedPairingLink, ServerAuthInternalError>;    readonly issuePairingCredential: (      input?: AuthCreatePairingCredentialInput,    ) => Effect.Effect<AuthPairingCredentialResult, ServerAuthInternalError>;    readonly issueStartupPairingCredential: () => Effect.Effect<      AuthPairingCredentialResult,      ServerAuthInternalError    >;    readonly listPairingLinks: (input?: {      readonly excludeSubjects?: ReadonlyArray<string>;    }) => Effect.Effect<ReadonlyArray<AuthPairingLink>, ServerAuthInternalError>;    readonly revokePairingLink: (id: string) => Effect.Effect<boolean, ServerAuthInternalError>;    readonly issueSession: (input?: {      readonly ttl?: Duration.Duration;      readonly subject?: string;      readonly scopes?: ReadonlyArray<AuthEnvironmentScope>;      readonly label?: string;    }) => Effect.Effect<IssuedBearerSession, ServerAuthInternalError>;    readonly listSessions: () => Effect.Effect<      ReadonlyArray<AuthClientSession>,      ServerAuthInternalError    >;    readonly revokeSession: (      sessionId: AuthSessionId,    ) => Effect.Effect<boolean, ServerAuthInternalError>;    readonly revokeOtherSessionsExcept: (      sessionId: AuthSessionId,    ) => Effect.Effect<number, ServerAuthInternalError>;    readonly listClientSessions: (      currentSessionId: AuthSessionId,    ) => Effect.Effect<ReadonlyArray<AuthClientSession>, ServerAuthInternalError>;    readonly revokeClientSession: (      currentSessionId: AuthSessionId,      targetSessionId: AuthSessionId,    ) => Effect.Effect<boolean, ServerAuthForbiddenOperationError | ServerAuthInternalError>;    readonly revokeOtherClientSessions: (      currentSessionId: AuthSessionId,    ) => Effect.Effect<number, ServerAuthInternalError>;    readonly authenticateHttpRequest: (      request: HttpServerRequest.HttpServerRequest,    ) => Effect.Effect<AuthenticatedSession, ServerAuthCredentialError | ServerAuthInternalError>;    readonly authenticateWebSocketUpgrade: (      request: HttpServerRequest.HttpServerRequest,    ) => Effect.Effect<AuthenticatedSession, ServerAuthCredentialError | ServerAuthInternalError>;    readonly issueWebSocketTicket: (      session: Pick<AuthenticatedSession, "sessionId">,    ) => Effect.Effect<AuthWebSocketTicketResult, ServerAuthInternalError>;    readonly issueStartupPairingUrl: (      baseUrl: string,    ) => Effect.Effect<string, ServerAuthInternalError>;  }>()("t3/auth/EnvironmentAuth") {} type BootstrapExchangeResult = {  readonly response: AuthBrowserSessionResult;  readonly sessionToken: string;}; const AUTHORIZATION_PREFIX = "Bearer ";

Lines 1–500 of 996.