fastmcp
Version:
A TypeScript framework for building MCP servers.
1 lines • 90.7 kB
Source Map (JSON)
{"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/auth/index.cjs","../../src/auth/OAuthProxy.ts","../../src/auth/utils/claimsExtractor.ts","../../src/auth/utils/consent.ts","../../src/auth/utils/jwtIssuer.ts","../../src/auth/utils/pkce.ts","../../src/auth/utils/tokenStore.ts","../../src/auth/providers/AzureProvider.ts","../../src/auth/providers/GitHubProvider.ts","../../src/auth/providers/GoogleProvider.ts","../../src/auth/utils/diskStore.ts","../../src/auth/utils/jwks.ts"],"names":["randomBytes"],"mappings":"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","file":"/home/runner/work/fastmcp/fastmcp/dist/auth/index.cjs","sourcesContent":[null,"/**\n * OAuth 2.1 Proxy Implementation\n * Provides DCR-compatible interface for non-DCR OAuth providers\n */\n\nimport { randomBytes } from \"crypto\";\nimport { z } from \"zod\";\n\nimport type {\n AuthorizationParams,\n ClientCode,\n DCRRequest,\n DCRResponse,\n OAuthError,\n OAuthProxyConfig,\n OAuthTransaction,\n ProxyDCRClient,\n RefreshRequest,\n TokenRequest,\n TokenResponse,\n TokenStorage,\n UpstreamTokenSet,\n} from \"./types.js\";\n\nimport { ClaimsExtractor } from \"./utils/claimsExtractor.js\";\nimport { ConsentManager } from \"./utils/consent.js\";\nimport { JWTIssuer } from \"./utils/jwtIssuer.js\";\nimport { PKCEUtils } from \"./utils/pkce.js\";\nimport {\n EncryptedTokenStorage,\n MemoryTokenStorage,\n} from \"./utils/tokenStore.js\";\n\n/**\n * OAuth 2.1 Proxy\n * Acts as transparent intermediary between MCP clients and upstream OAuth providers\n */\nexport class OAuthProxy {\n private claimsExtractor: ClaimsExtractor | null = null;\n private cleanupInterval: NodeJS.Timeout | null = null;\n private clientCodes: Map<string, ClientCode> = new Map();\n private config: OAuthProxyConfig;\n private consentManager: ConsentManager;\n private jwtIssuer?: JWTIssuer;\n private registeredClients: Map<string, ProxyDCRClient> = new Map();\n private tokenStorage: TokenStorage;\n private transactions: Map<string, OAuthTransaction> = new Map();\n\n constructor(config: OAuthProxyConfig) {\n this.config = {\n allowedRedirectUriPatterns: [\"https://*\", \"http://localhost:*\"],\n authorizationCodeTtl: 300, // 5 minutes\n consentRequired: true,\n enableTokenSwap: true, // Enabled by default for security\n redirectPath: \"/oauth/callback\",\n transactionTtl: 600, // 10 minutes\n ...config,\n };\n\n // Set up token storage with encryption by default (matches Python's secure defaults)\n let storage = config.tokenStorage || new MemoryTokenStorage();\n\n // Wrap storage with encryption if not already encrypted\n // Check if it's already an EncryptedTokenStorage instance\n const isAlreadyEncrypted =\n storage.constructor.name === \"EncryptedTokenStorage\";\n\n if (!isAlreadyEncrypted && config.encryptionKey !== false) {\n // Auto-generate encryption key if not provided\n const encryptionKey =\n typeof config.encryptionKey === \"string\"\n ? config.encryptionKey\n : this.generateSigningKey();\n\n storage = new EncryptedTokenStorage(storage, encryptionKey);\n }\n\n this.tokenStorage = storage;\n this.consentManager = new ConsentManager(\n config.consentSigningKey || this.generateSigningKey(),\n );\n\n // Initialize JWT issuer if token swap is enabled\n if (this.config.enableTokenSwap) {\n // Auto-generate signing key if not provided\n const signingKey = this.config.jwtSigningKey || this.generateSigningKey();\n\n this.jwtIssuer = new JWTIssuer({\n audience: this.config.baseUrl,\n issuer: this.config.baseUrl,\n signingKey: signingKey,\n });\n }\n\n // Initialize claims extractor (enabled by default)\n const claimsConfig =\n config.customClaimsPassthrough !== undefined\n ? config.customClaimsPassthrough\n : true; // Default: enabled\n\n if (claimsConfig !== false) {\n this.claimsExtractor = new ClaimsExtractor(claimsConfig);\n }\n\n // Start periodic cleanup\n this.startCleanup();\n }\n\n /**\n * OAuth authorization endpoint\n */\n async authorize(params: AuthorizationParams): Promise<Response> {\n // Validate parameters\n if (!params.client_id || !params.redirect_uri || !params.response_type) {\n throw new OAuthProxyError(\n \"invalid_request\",\n \"Missing required parameters\",\n );\n }\n\n if (params.response_type !== \"code\") {\n throw new OAuthProxyError(\n \"unsupported_response_type\",\n \"Only 'code' response type is supported\",\n );\n }\n\n // Validate PKCE if provided\n if (params.code_challenge && !params.code_challenge_method) {\n throw new OAuthProxyError(\n \"invalid_request\",\n \"code_challenge_method required when code_challenge is present\",\n );\n }\n\n // Create transaction\n const transaction = await this.createTransaction(params);\n\n // If consent required, show consent screen\n if (this.config.consentRequired && !transaction.consentGiven) {\n return this.consentManager.createConsentResponse(\n transaction,\n this.getProviderName(),\n );\n }\n\n // Redirect to upstream provider\n return this.redirectToUpstream(transaction);\n }\n\n /**\n * Stop cleanup interval and destroy resources\n */\n destroy(): void {\n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = null;\n }\n\n this.transactions.clear();\n this.clientCodes.clear();\n this.registeredClients.clear();\n }\n\n /**\n * Token endpoint - exchange authorization code for tokens\n */\n async exchangeAuthorizationCode(\n request: TokenRequest,\n ): Promise<TokenResponse> {\n if (request.grant_type !== \"authorization_code\") {\n throw new OAuthProxyError(\n \"unsupported_grant_type\",\n \"Only authorization_code grant type is supported\",\n );\n }\n\n const clientCode = this.clientCodes.get(request.code);\n if (!clientCode) {\n throw new OAuthProxyError(\n \"invalid_grant\",\n \"Invalid or expired authorization code\",\n );\n }\n\n // Validate client\n if (clientCode.clientId !== request.client_id) {\n throw new OAuthProxyError(\"invalid_client\", \"Client ID mismatch\");\n }\n\n // Validate PKCE if used\n if (clientCode.codeChallenge) {\n if (!request.code_verifier) {\n throw new OAuthProxyError(\n \"invalid_request\",\n \"code_verifier required for PKCE\",\n );\n }\n\n const valid = PKCEUtils.validateChallenge(\n request.code_verifier,\n clientCode.codeChallenge,\n clientCode.codeChallengeMethod,\n );\n\n if (!valid) {\n throw new OAuthProxyError(\"invalid_grant\", \"Invalid PKCE verifier\");\n }\n }\n\n // Check if code was already used\n if (clientCode.used) {\n throw new OAuthProxyError(\n \"invalid_grant\",\n \"Authorization code already used\",\n );\n }\n\n // Mark code as used\n clientCode.used = true;\n this.clientCodes.set(request.code, clientCode);\n\n // Return tokens based on token swap setting\n if (this.config.enableTokenSwap && this.jwtIssuer) {\n // Token swap pattern: issue short-lived JWTs and store upstream tokens\n return await this.issueSwappedTokens(\n clientCode.clientId,\n clientCode.upstreamTokens,\n );\n } else {\n // Pass-through pattern: return upstream tokens directly\n const response: TokenResponse = {\n access_token: clientCode.upstreamTokens.accessToken,\n expires_in: clientCode.upstreamTokens.expiresIn,\n token_type: clientCode.upstreamTokens.tokenType,\n };\n\n if (clientCode.upstreamTokens.refreshToken) {\n response.refresh_token = clientCode.upstreamTokens.refreshToken;\n }\n\n if (clientCode.upstreamTokens.idToken) {\n response.id_token = clientCode.upstreamTokens.idToken;\n }\n\n if (clientCode.upstreamTokens.scope.length > 0) {\n response.scope = clientCode.upstreamTokens.scope.join(\" \");\n }\n\n return response;\n }\n }\n\n /**\n * Token endpoint - refresh access token\n */\n async exchangeRefreshToken(request: RefreshRequest): Promise<TokenResponse> {\n if (request.grant_type !== \"refresh_token\") {\n throw new OAuthProxyError(\n \"unsupported_grant_type\",\n \"Only refresh_token grant type is supported\",\n );\n }\n\n // Exchange refresh token with upstream provider\n const tokenResponse = await fetch(this.config.upstreamTokenEndpoint, {\n body: new URLSearchParams({\n client_id: this.config.upstreamClientId,\n client_secret: this.config.upstreamClientSecret,\n grant_type: \"refresh_token\",\n refresh_token: request.refresh_token,\n ...(request.scope && { scope: request.scope }),\n }),\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n method: \"POST\",\n });\n\n if (!tokenResponse.ok) {\n const error = (await tokenResponse.json()) as {\n error?: string;\n error_description?: string;\n };\n throw new OAuthProxyError(\n error.error || \"invalid_grant\",\n error.error_description,\n );\n }\n\n const tokens = await this.parseTokenResponse(tokenResponse);\n\n return {\n access_token: tokens.access_token,\n expires_in: tokens.expires_in || 3600,\n id_token: tokens.id_token,\n refresh_token: tokens.refresh_token,\n scope: tokens.scope,\n token_type: tokens.token_type || \"Bearer\",\n };\n }\n\n /**\n * Get OAuth discovery metadata\n */\n getAuthorizationServerMetadata(): {\n authorizationEndpoint: string;\n codeChallengeMethodsSupported?: string[];\n dpopSigningAlgValuesSupported?: string[];\n grantTypesSupported?: string[];\n introspectionEndpoint?: string;\n issuer: string;\n jwksUri?: string;\n opPolicyUri?: string;\n opTosUri?: string;\n registrationEndpoint?: string;\n responseModesSupported?: string[];\n responseTypesSupported: string[];\n revocationEndpoint?: string;\n scopesSupported?: string[];\n serviceDocumentation?: string;\n tokenEndpoint: string;\n tokenEndpointAuthMethodsSupported?: string[];\n tokenEndpointAuthSigningAlgValuesSupported?: string[];\n uiLocalesSupported?: string[];\n } {\n return {\n authorizationEndpoint: `${this.config.baseUrl}/oauth/authorize`,\n codeChallengeMethodsSupported: [\"S256\", \"plain\"],\n grantTypesSupported: [\"authorization_code\", \"refresh_token\"],\n issuer: this.config.baseUrl,\n registrationEndpoint: `${this.config.baseUrl}/oauth/register`,\n responseTypesSupported: [\"code\"],\n scopesSupported: this.config.scopes || [],\n tokenEndpoint: `${this.config.baseUrl}/oauth/token`,\n tokenEndpointAuthMethodsSupported: [\n \"client_secret_basic\",\n \"client_secret_post\",\n ],\n };\n }\n\n /**\n * Handle OAuth callback from upstream provider\n */\n async handleCallback(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const error = url.searchParams.get(\"error\");\n\n // Check for errors from upstream\n if (error) {\n const errorDescription = url.searchParams.get(\"error_description\");\n throw new OAuthProxyError(error, errorDescription || undefined);\n }\n\n if (!code || !state) {\n throw new OAuthProxyError(\n \"invalid_request\",\n \"Missing code or state parameter\",\n );\n }\n\n // Retrieve transaction\n const transaction = this.transactions.get(state);\n if (!transaction) {\n throw new OAuthProxyError(\"invalid_request\", \"Invalid or expired state\");\n }\n\n // Exchange code with upstream provider\n const upstreamTokens = await this.exchangeUpstreamCode(code, transaction);\n\n // Generate authorization code for client\n const clientCode = this.generateAuthorizationCode(\n transaction,\n upstreamTokens,\n );\n\n // Clean up transaction\n this.transactions.delete(state);\n\n // Redirect to client callback with code\n const redirectUrl = new URL(transaction.clientCallbackUrl);\n redirectUrl.searchParams.set(\"code\", clientCode);\n redirectUrl.searchParams.set(\"state\", transaction.state);\n\n return new Response(null, {\n headers: {\n Location: redirectUrl.toString(),\n },\n status: 302,\n });\n }\n\n /**\n * Handle consent form submission\n */\n async handleConsent(request: Request): Promise<Response> {\n const formData = await request.formData();\n const transactionId = formData.get(\"transaction_id\") as string;\n const action = formData.get(\"action\") as string;\n\n if (!transactionId) {\n throw new OAuthProxyError(\"invalid_request\", \"Missing transaction_id\");\n }\n\n const transaction = this.transactions.get(transactionId);\n if (!transaction) {\n throw new OAuthProxyError(\n \"invalid_request\",\n \"Invalid or expired transaction\",\n );\n }\n\n if (action === \"deny\") {\n // User denied consent\n this.transactions.delete(transactionId);\n const redirectUrl = new URL(transaction.clientCallbackUrl);\n redirectUrl.searchParams.set(\"error\", \"access_denied\");\n redirectUrl.searchParams.set(\n \"error_description\",\n \"User denied authorization\",\n );\n redirectUrl.searchParams.set(\"state\", transaction.state);\n\n return new Response(null, {\n headers: {\n Location: redirectUrl.toString(),\n },\n status: 302,\n });\n }\n\n // User approved, mark consent and redirect to upstream\n transaction.consentGiven = true;\n this.transactions.set(transactionId, transaction);\n\n return this.redirectToUpstream(transaction);\n }\n\n /**\n * Load upstream tokens from a FastMCP JWT\n */\n async loadUpstreamTokens(\n fastmcpToken: string,\n ): Promise<null | UpstreamTokenSet> {\n if (!this.jwtIssuer) {\n return null;\n }\n\n // Verify FastMCP JWT\n const result = await this.jwtIssuer.verify(fastmcpToken);\n if (!result.valid || !result.claims?.jti) {\n return null;\n }\n\n // Look up token mapping\n const mapping = (await this.tokenStorage.get(\n `mapping:${result.claims.jti}`,\n )) as {\n upstreamTokenKey: string;\n } | null;\n\n if (!mapping) {\n return null;\n }\n\n // Retrieve upstream tokens\n const upstreamTokens = (await this.tokenStorage.get(\n `upstream:${mapping.upstreamTokenKey}`,\n )) as null | UpstreamTokenSet;\n\n return upstreamTokens;\n }\n\n /**\n * RFC 7591 Dynamic Client Registration\n */\n async registerClient(request: DCRRequest): Promise<DCRResponse> {\n // Validate required fields\n if (!request.redirect_uris || request.redirect_uris.length === 0) {\n throw new OAuthProxyError(\n \"invalid_client_metadata\",\n \"redirect_uris is required\",\n );\n }\n\n // Validate redirect URIs\n for (const uri of request.redirect_uris) {\n if (!this.validateRedirectUri(uri)) {\n throw new OAuthProxyError(\n \"invalid_redirect_uri\",\n `Invalid redirect URI: ${uri}`,\n );\n }\n }\n\n // Store client registration (indexed by primary redirect URI)\n const clientId = this.config.upstreamClientId;\n const client: ProxyDCRClient = {\n callbackUrl: request.redirect_uris[0],\n clientId,\n clientSecret: this.config.upstreamClientSecret,\n metadata: {\n client_name: request.client_name,\n client_uri: request.client_uri,\n contacts: request.contacts,\n jwks: request.jwks,\n jwks_uri: request.jwks_uri,\n logo_uri: request.logo_uri,\n policy_uri: request.policy_uri,\n scope: request.scope,\n software_id: request.software_id,\n software_version: request.software_version,\n tos_uri: request.tos_uri,\n },\n registeredAt: new Date(),\n };\n\n this.registeredClients.set(request.redirect_uris[0], client);\n\n // Return RFC 7591 compliant response\n const response: DCRResponse = {\n client_id: clientId,\n client_id_issued_at: Math.floor(Date.now() / 1000),\n // Echo back optional metadata\n client_name: request.client_name,\n client_secret: this.config.upstreamClientSecret,\n client_secret_expires_at: 0, // Never expires\n client_uri: request.client_uri,\n contacts: request.contacts,\n grant_types: request.grant_types || [\n \"authorization_code\",\n \"refresh_token\",\n ],\n jwks: request.jwks,\n jwks_uri: request.jwks_uri,\n logo_uri: request.logo_uri,\n policy_uri: request.policy_uri,\n redirect_uris: request.redirect_uris,\n response_types: request.response_types || [\"code\"],\n scope: request.scope,\n software_id: request.software_id,\n software_version: request.software_version,\n token_endpoint_auth_method:\n request.token_endpoint_auth_method || \"client_secret_basic\",\n tos_uri: request.tos_uri,\n };\n\n return response;\n }\n\n /**\n * Clean up expired transactions and codes\n */\n private cleanup(): void {\n const now = Date.now();\n\n // Clean up expired transactions\n for (const [id, transaction] of this.transactions.entries()) {\n if (transaction.expiresAt.getTime() < now) {\n this.transactions.delete(id);\n }\n }\n\n // Clean up expired codes\n for (const [code, clientCode] of this.clientCodes.entries()) {\n if (clientCode.expiresAt.getTime() < now) {\n this.clientCodes.delete(code);\n }\n }\n\n // Clean up token storage\n void this.tokenStorage.cleanup();\n }\n\n /**\n * Create a new OAuth transaction\n */\n private async createTransaction(\n params: AuthorizationParams,\n ): Promise<OAuthTransaction> {\n const transactionId = this.generateId();\n const proxyPkce = PKCEUtils.generatePair(\"S256\");\n\n const transaction: OAuthTransaction = {\n clientCallbackUrl: params.redirect_uri,\n clientCodeChallenge: params.code_challenge || \"\",\n clientCodeChallengeMethod: params.code_challenge_method || \"plain\",\n clientId: params.client_id,\n createdAt: new Date(),\n expiresAt: new Date(\n Date.now() + (this.config.transactionTtl || 600) * 1000,\n ),\n id: transactionId,\n proxyCodeChallenge: proxyPkce.challenge,\n proxyCodeVerifier: proxyPkce.verifier,\n scope: params.scope ? params.scope.split(\" \") : this.config.scopes || [],\n state: params.state || this.generateId(),\n };\n\n this.transactions.set(transactionId, transaction);\n\n return transaction;\n }\n\n /**\n * Exchange authorization code with upstream provider\n */\n private async exchangeUpstreamCode(\n code: string,\n transaction: OAuthTransaction,\n ): Promise<UpstreamTokenSet> {\n const tokenResponse = await fetch(this.config.upstreamTokenEndpoint, {\n body: new URLSearchParams({\n client_id: this.config.upstreamClientId,\n client_secret: this.config.upstreamClientSecret,\n code,\n code_verifier: transaction.proxyCodeVerifier,\n grant_type: \"authorization_code\",\n redirect_uri: `${this.config.baseUrl}${this.config.redirectPath}`,\n }),\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n method: \"POST\",\n });\n\n if (!tokenResponse.ok) {\n const error = (await tokenResponse.json()) as {\n error?: string;\n error_description?: string;\n };\n throw new OAuthProxyError(\n error.error || \"server_error\",\n error.error_description,\n );\n }\n\n const tokens = await this.parseTokenResponse(tokenResponse);\n\n return {\n accessToken: tokens.access_token,\n expiresIn: tokens.expires_in || 3600,\n idToken: tokens.id_token,\n issuedAt: new Date(),\n refreshToken: tokens.refresh_token,\n scope: tokens.scope ? tokens.scope.split(\" \") : transaction.scope,\n tokenType: tokens.token_type || \"Bearer\",\n };\n }\n\n /**\n * Extract JTI from a JWT token\n */\n private async extractJti(token: string): Promise<string> {\n if (!this.jwtIssuer) {\n throw new Error(\"JWT issuer not initialized\");\n }\n\n const result = await this.jwtIssuer.verify(token);\n if (!result.valid || !result.claims?.jti) {\n throw new Error(\"Failed to extract JTI from token\");\n }\n\n return result.claims.jti;\n }\n\n /**\n * Extract custom claims from upstream tokens\n * Combines claims from access token and ID token (if present)\n */\n private async extractUpstreamClaims(\n upstreamTokens: UpstreamTokenSet,\n ): Promise<null | Record<string, unknown>> {\n if (!this.claimsExtractor) {\n return null;\n }\n\n const allClaims: Record<string, unknown> = {};\n\n // Extract from access token (if JWT format)\n const accessClaims = await this.claimsExtractor.extract(\n upstreamTokens.accessToken,\n \"access\",\n );\n if (accessClaims) {\n Object.assign(allClaims, accessClaims);\n }\n\n // Extract from ID token (if present and JWT format)\n if (upstreamTokens.idToken) {\n const idClaims = await this.claimsExtractor.extract(\n upstreamTokens.idToken,\n \"id\",\n );\n if (idClaims) {\n // Access token claims take precedence over ID token claims\n for (const [key, value] of Object.entries(idClaims)) {\n if (!(key in allClaims)) {\n allClaims[key] = value;\n }\n }\n }\n }\n\n return Object.keys(allClaims).length > 0 ? allClaims : null;\n }\n\n /**\n * Generate authorization code for client\n */\n private generateAuthorizationCode(\n transaction: OAuthTransaction,\n upstreamTokens: UpstreamTokenSet,\n ): string {\n const code = this.generateId();\n\n const clientCode: ClientCode = {\n clientId: transaction.clientId,\n code,\n codeChallenge: transaction.clientCodeChallenge,\n codeChallengeMethod: transaction.clientCodeChallengeMethod,\n createdAt: new Date(),\n expiresAt: new Date(\n Date.now() + (this.config.authorizationCodeTtl || 300) * 1000,\n ),\n transactionId: transaction.id,\n upstreamTokens,\n };\n\n this.clientCodes.set(code, clientCode);\n\n return code;\n }\n\n /**\n * Generate secure random ID\n */\n private generateId(): string {\n return randomBytes(32).toString(\"base64url\");\n }\n\n /**\n * Generate signing key for consent cookies\n */\n private generateSigningKey(): string {\n return randomBytes(32).toString(\"hex\");\n }\n\n /**\n * Get provider name for display\n */\n private getProviderName(): string {\n const url = new URL(this.config.upstreamAuthorizationEndpoint);\n return url.hostname;\n }\n\n /**\n * Issue swapped tokens (JWT pattern)\n * Issues short-lived FastMCP JWTs and stores upstream tokens securely\n */\n private async issueSwappedTokens(\n clientId: string,\n upstreamTokens: UpstreamTokenSet,\n ): Promise<TokenResponse> {\n if (!this.jwtIssuer) {\n throw new Error(\"JWT issuer not initialized\");\n }\n\n // Extract custom claims from upstream tokens\n const customClaims = await this.extractUpstreamClaims(upstreamTokens);\n\n // Store upstream tokens\n const upstreamTokenKey = this.generateId();\n await this.tokenStorage.save(\n `upstream:${upstreamTokenKey}`,\n upstreamTokens,\n upstreamTokens.expiresIn,\n );\n\n // Issue FastMCP access token with custom claims\n const accessToken = this.jwtIssuer.issueAccessToken(\n clientId,\n upstreamTokens.scope,\n customClaims || undefined,\n );\n\n // Decode JWT to get JTI\n const accessJti = await this.extractJti(accessToken);\n\n // Store token mapping\n await this.tokenStorage.save(\n `mapping:${accessJti}`,\n {\n clientId,\n createdAt: new Date(),\n expiresAt: new Date(Date.now() + upstreamTokens.expiresIn * 1000),\n jti: accessJti,\n scope: upstreamTokens.scope,\n upstreamTokenKey,\n },\n upstreamTokens.expiresIn,\n );\n\n const response: TokenResponse = {\n access_token: accessToken,\n expires_in: 3600, // FastMCP JWT expiration (1 hour)\n scope: upstreamTokens.scope.join(\" \"),\n token_type: \"Bearer\",\n };\n\n // Issue refresh token if upstream provided one\n if (upstreamTokens.refreshToken) {\n const refreshToken = this.jwtIssuer.issueRefreshToken(\n clientId,\n upstreamTokens.scope,\n customClaims || undefined,\n );\n const refreshJti = await this.extractJti(refreshToken);\n\n // Store refresh token mapping\n await this.tokenStorage.save(\n `mapping:${refreshJti}`,\n {\n clientId,\n createdAt: new Date(),\n expiresAt: new Date(Date.now() + 2592000 * 1000), // 30 days\n jti: refreshJti,\n scope: upstreamTokens.scope,\n upstreamTokenKey,\n },\n 2592000, // 30 days\n );\n\n response.refresh_token = refreshToken;\n }\n\n return response;\n }\n\n /**\n * Match URI against pattern (supports wildcards)\n */\n private matchesPattern(uri: string, pattern: string): boolean {\n const regex = new RegExp(\n \"^\" + pattern.replace(/\\*/g, \".*\").replace(/\\?/g, \".\") + \"$\",\n );\n return regex.test(uri);\n }\n\n /**\n * Parse token response that can be either JSON or URL-encoded\n * GitHub Apps return URL-encoded format, most providers return JSON\n */\n private async parseTokenResponse(response: Response): Promise<{\n access_token: string;\n expires_in?: number;\n id_token?: string;\n refresh_token?: string;\n scope?: string;\n token_type?: string;\n }> {\n const contentType = (\n response.headers.get(\"content-type\") || \"\"\n ).toLowerCase();\n\n // Define Zod schema for token response validation\n const tokenResponseSchema = z.object({\n access_token: z.string().min(1, \"access_token cannot be empty\"),\n expires_in: z.number().int().positive().optional(),\n id_token: z.string().optional(),\n refresh_token: z.string().optional(),\n scope: z.string().optional(),\n token_type: z.string().optional(),\n });\n\n // Check if response is URL-encoded (e.g., GitHub Apps)\n if (contentType.includes(\"application/x-www-form-urlencoded\")) {\n const text = await response.text();\n const params = new URLSearchParams(text);\n\n const rawData = {\n access_token: params.get(\"access_token\") || \"\",\n expires_in: params.get(\"expires_in\")\n ? parseInt(params.get(\"expires_in\")!)\n : undefined,\n id_token: params.get(\"id_token\") || undefined,\n refresh_token: params.get(\"refresh_token\") || undefined,\n scope: params.get(\"scope\") || undefined,\n token_type: params.get(\"token_type\") || undefined,\n };\n\n return tokenResponseSchema.parse(rawData);\n }\n\n // Default to JSON parsing\n const rawJson = await response.json();\n return tokenResponseSchema.parse(rawJson);\n }\n\n /**\n * Redirect to upstream OAuth provider\n */\n private redirectToUpstream(transaction: OAuthTransaction): Response {\n const authUrl = new URL(this.config.upstreamAuthorizationEndpoint);\n\n authUrl.searchParams.set(\"client_id\", this.config.upstreamClientId);\n authUrl.searchParams.set(\n \"redirect_uri\",\n `${this.config.baseUrl}${this.config.redirectPath}`,\n );\n authUrl.searchParams.set(\"response_type\", \"code\");\n authUrl.searchParams.set(\"state\", transaction.id);\n\n if (transaction.scope.length > 0) {\n authUrl.searchParams.set(\"scope\", transaction.scope.join(\" \"));\n }\n\n // Add PKCE if not forwarding client PKCE\n if (!this.config.forwardPkce) {\n authUrl.searchParams.set(\n \"code_challenge\",\n transaction.proxyCodeChallenge,\n );\n authUrl.searchParams.set(\"code_challenge_method\", \"S256\");\n }\n\n return new Response(null, {\n headers: {\n Location: authUrl.toString(),\n },\n status: 302,\n });\n }\n\n /**\n * Start periodic cleanup of expired transactions and codes\n */\n private startCleanup(): void {\n this.cleanupInterval = setInterval(() => {\n this.cleanup();\n }, 60000); // Run every minute\n }\n\n /**\n * Validate redirect URI against allowed patterns\n */\n private validateRedirectUri(uri: string): boolean {\n try {\n const url = new URL(uri);\n const patterns = this.config.allowedRedirectUriPatterns || [];\n\n for (const pattern of patterns) {\n if (this.matchesPattern(uri, pattern)) {\n return true;\n }\n }\n\n // Default: allow https and localhost\n return (\n url.protocol === \"https:\" ||\n url.hostname === \"localhost\" ||\n url.hostname === \"127.0.0.1\"\n );\n } catch {\n return false;\n }\n }\n}\n\n/**\n * OAuth Proxy Error\n */\nexport class OAuthProxyError extends Error {\n constructor(\n public code: string,\n public description?: string,\n public statusCode: number = 400,\n ) {\n super(code);\n this.name = \"OAuthProxyError\";\n }\n\n toJSON(): OAuthError {\n return {\n error: this.code,\n error_description: this.description,\n };\n }\n\n toResponse(): Response {\n return new Response(JSON.stringify(this.toJSON()), {\n headers: { \"Content-Type\": \"application/json\" },\n status: this.statusCode,\n });\n }\n}\n","/**\n * ClaimsExtractor\n * Securely extracts and filters custom claims from upstream OAuth tokens\n */\n\nimport type { CustomClaimsPassthroughConfig } from \"../types.js\";\n\nexport class ClaimsExtractor {\n private config: CustomClaimsPassthroughConfig;\n\n // Claims that MUST NOT be copied from upstream (protect proxy's JWT integrity)\n private readonly PROTECTED_CLAIMS = new Set([\n \"aud\",\n \"client_id\",\n \"exp\",\n \"iat\",\n \"iss\",\n \"jti\",\n \"nbf\",\n ]);\n\n constructor(config: boolean | CustomClaimsPassthroughConfig) {\n // Handle boolean shorthand: true = default config, false = disabled\n if (typeof config === \"boolean\") {\n config = config ? {} : { fromAccessToken: false, fromIdToken: false };\n }\n\n // Apply defaults\n this.config = {\n allowComplexClaims: config.allowComplexClaims || false,\n allowedClaims: config.allowedClaims,\n blockedClaims: config.blockedClaims || [],\n claimPrefix:\n config.claimPrefix !== undefined ? config.claimPrefix : false, // Default: no prefix\n fromAccessToken: config.fromAccessToken !== false, // Default: true\n fromIdToken: config.fromIdToken !== false, // Default: true\n maxClaimValueSize: config.maxClaimValueSize || 2000,\n };\n }\n\n /**\n * Extract claims from a token (access token or ID token)\n */\n async extract(\n token: string,\n tokenType: \"access\" | \"id\",\n ): Promise<null | Record<string, unknown>> {\n // Check if this token type is enabled\n if (tokenType === \"access\" && !this.config.fromAccessToken) {\n return null;\n }\n if (tokenType === \"id\" && !this.config.fromIdToken) {\n return null;\n }\n\n // Detect if token is JWT format (3 parts separated by dots)\n if (!this.isJWT(token)) {\n // Opaque token - no claims to extract\n return null;\n }\n\n // Decode JWT payload (base64url decode only, no signature verification)\n // We trust the token because it came from ups