{"version":3,"file":"auth-DSr-vVBh.mjs","names":["errorUri?: string","response: OAuthErrorResponse","customErrorCode: string","allowedMethods","req: URL","reg: URL","requestedScopes: string[]","target: URL","clientInfo: Omit<OAuthClientInformationFull, 'client_id'> & { client_id?: string }","parseResult","protectedResourceMetadata: OAuthProtectedResourceMetadata"],"sources":["../src/auth/errors.ts","../src/auth/middleware/allowedMethods.ts","../src/auth/handlers/authorize.ts","../src/auth/handlers/metadata.ts","../src/auth/handlers/register.ts","../src/auth/middleware/clientAuth.ts","../src/auth/handlers/revoke.ts","../src/auth/handlers/token.ts","../src/auth/router.ts","../src/auth/providers/proxyProvider.ts","../src/auth/middleware/bearerAuth.ts"],"sourcesContent":["import type { OAuthErrorResponse } from '@modelcontextprotocol/core-internal';\n\n/**\n * Base class for all OAuth errors\n */\nexport class OAuthError extends Error {\n    static errorCode: string;\n\n    constructor(\n        message: string,\n        public readonly errorUri?: string\n    ) {\n        super(message);\n        this.name = this.constructor.name;\n    }\n\n    /**\n     * Converts the error to a standard OAuth error response object\n     */\n    toResponseObject(): OAuthErrorResponse {\n        const response: OAuthErrorResponse = {\n            error: this.errorCode,\n            error_description: this.message\n        };\n\n        if (this.errorUri) {\n            response.error_uri = this.errorUri;\n        }\n\n        return response;\n    }\n\n    get errorCode(): string {\n        return (this.constructor as typeof OAuthError).errorCode;\n    }\n}\n\n/**\n * Invalid request error - The request is missing a required parameter,\n * includes an invalid parameter value, includes a parameter more than once,\n * or is otherwise malformed.\n */\nexport class InvalidRequestError extends OAuthError {\n    static override errorCode = 'invalid_request';\n}\n\n/**\n * Invalid client error - Client authentication failed (e.g., unknown client, no client\n * authentication included, or unsupported authentication method).\n */\nexport class InvalidClientError extends OAuthError {\n    static override errorCode = 'invalid_client';\n}\n\n/**\n * Invalid grant error - The provided authorization grant or refresh token is\n * invalid, expired, revoked, does not match the redirection URI used in the\n * authorization request, or was issued to another client.\n */\nexport class InvalidGrantError extends OAuthError {\n    static override errorCode = 'invalid_grant';\n}\n\n/**\n * Unauthorized client error - The authenticated client is not authorized to use\n * this authorization grant type.\n */\nexport class UnauthorizedClientError extends OAuthError {\n    static override errorCode = 'unauthorized_client';\n}\n\n/**\n * Unsupported grant type error - The authorization grant type is not supported\n * by the authorization server.\n */\nexport class UnsupportedGrantTypeError extends OAuthError {\n    static override errorCode = 'unsupported_grant_type';\n}\n\n/**\n * Invalid scope error - The requested scope is invalid, unknown, malformed, or\n * exceeds the scope granted by the resource owner.\n */\nexport class InvalidScopeError extends OAuthError {\n    static override errorCode = 'invalid_scope';\n}\n\n/**\n * Access denied error - The resource owner or authorization server denied the request.\n */\nexport class AccessDeniedError extends OAuthError {\n    static override errorCode = 'access_denied';\n}\n\n/**\n * Server error - The authorization server encountered an unexpected condition\n * that prevented it from fulfilling the request.\n */\nexport class ServerError extends OAuthError {\n    static override errorCode = 'server_error';\n}\n\n/**\n * Temporarily unavailable error - The authorization server is currently unable to\n * handle the request due to a temporary overloading or maintenance of the server.\n */\nexport class TemporarilyUnavailableError extends OAuthError {\n    static override errorCode = 'temporarily_unavailable';\n}\n\n/**\n * Unsupported response type error - The authorization server does not support\n * obtaining an authorization code using this method.\n */\nexport class UnsupportedResponseTypeError extends OAuthError {\n    static override errorCode = 'unsupported_response_type';\n}\n\n/**\n * Unsupported token type error - The authorization server does not support\n * the requested token type.\n */\nexport class UnsupportedTokenTypeError extends OAuthError {\n    static override errorCode = 'unsupported_token_type';\n}\n\n/**\n * Invalid token error - The access token provided is expired, revoked, malformed,\n * or invalid for other reasons.\n */\nexport class InvalidTokenError extends OAuthError {\n    static override errorCode = 'invalid_token';\n}\n\n/**\n * Method not allowed error - The HTTP method used is not allowed for this endpoint.\n * (Custom, non-standard error)\n */\nexport class MethodNotAllowedError extends OAuthError {\n    static override errorCode = 'method_not_allowed';\n}\n\n/**\n * Too many requests error - Rate limit exceeded.\n * (Custom, non-standard error based on RFC 6585)\n */\nexport class TooManyRequestsError extends OAuthError {\n    static override errorCode = 'too_many_requests';\n}\n\n/**\n * Invalid client metadata error - The client metadata is invalid.\n * (Custom error for dynamic client registration - RFC 7591)\n */\nexport class InvalidClientMetadataError extends OAuthError {\n    static override errorCode = 'invalid_client_metadata';\n}\n\n/**\n * Insufficient scope error - The request requires higher privileges than provided by the access token.\n */\nexport class InsufficientScopeError extends OAuthError {\n    static override errorCode = 'insufficient_scope';\n}\n\n/**\n * Invalid target error - The requested resource is invalid, missing, unknown, or malformed.\n * (Custom error for resource indicators - RFC 8707)\n */\nexport class InvalidTargetError extends OAuthError {\n    static override errorCode = 'invalid_target';\n}\n\n/**\n * A utility class for defining one-off error codes\n */\nexport class CustomOAuthError extends OAuthError {\n    constructor(\n        private readonly customErrorCode: string,\n        message: string,\n        errorUri?: string\n    ) {\n        super(message, errorUri);\n    }\n\n    override get errorCode(): string {\n        return this.customErrorCode;\n    }\n}\n\n/**\n * A full list of all OAuthErrors, enabling parsing from error responses\n */\nexport const OAUTH_ERRORS = {\n    [InvalidRequestError.errorCode]: InvalidRequestError,\n    [InvalidClientError.errorCode]: InvalidClientError,\n    [InvalidGrantError.errorCode]: InvalidGrantError,\n    [UnauthorizedClientError.errorCode]: UnauthorizedClientError,\n    [UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,\n    [InvalidScopeError.errorCode]: InvalidScopeError,\n    [AccessDeniedError.errorCode]: AccessDeniedError,\n    [ServerError.errorCode]: ServerError,\n    [TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,\n    [UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,\n    [UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,\n    [InvalidTokenError.errorCode]: InvalidTokenError,\n    [MethodNotAllowedError.errorCode]: MethodNotAllowedError,\n    [TooManyRequestsError.errorCode]: TooManyRequestsError,\n    [InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,\n    [InsufficientScopeError.errorCode]: InsufficientScopeError,\n    [InvalidTargetError.errorCode]: InvalidTargetError\n} as const;\n","import type { RequestHandler } from 'express';\n\nimport { MethodNotAllowedError } from '../errors';\n\n/**\n * Middleware to handle unsupported HTTP methods with a 405 Method Not Allowed response.\n *\n * @param allowedMethods Array of allowed HTTP methods for this endpoint (e.g., ['GET', 'POST'])\n * @returns Express middleware that returns a 405 error if method not in allowed list\n */\nexport function allowedMethods(allowedMethods: string[]): RequestHandler {\n    return (req, res, next) => {\n        if (allowedMethods.includes(req.method)) {\n            next();\n            return;\n        }\n\n        const error = new MethodNotAllowedError(`The method ${req.method} is not allowed for this endpoint`);\n        res.status(405).set('Allow', allowedMethods.join(', ')).json(error.toResponseObject());\n    };\n}\n","import type { RequestHandler, Response } from 'express';\nimport express from 'express';\nimport type { Options as RateLimitOptions } from 'express-rate-limit';\nimport { rateLimit } from 'express-rate-limit';\nimport * as z from 'zod/v4';\n\nimport { InvalidClientError, InvalidRequestError, OAuthError, ServerError, TooManyRequestsError } from '../errors';\nimport { allowedMethods } from '../middleware/allowedMethods';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- AuthorizationParams referenced in JSDoc {@linkcode}\nimport type { AuthorizationParams, OAuthServerProvider } from '../provider';\n\nexport type AuthorizationHandlerOptions = {\n    provider: OAuthServerProvider;\n    /**\n     * The authorization server's issuer identifier. When set, the handler appends it as the\n     * `iss` query parameter (RFC 9207) to any redirect — success or error — that targets the\n     * client's validated `redirect_uri`, and also supplies it to the provider as\n     * {@linkcode AuthorizationParams.issuer}. `mcpAuthRouter` always sets this from its\n     * `issuerUrl`.\n     */\n    issuerUrl?: URL;\n    /**\n     * Rate limiting configuration for the authorization endpoint.\n     * Set to false to disable rate limiting for this endpoint.\n     */\n    rateLimit?: Partial<RateLimitOptions> | false;\n};\n\nconst LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '[::1]']);\n\n/**\n * Validates a requested redirect_uri against a registered one.\n *\n * Per RFC 8252 §7.3 (OAuth 2.0 for Native Apps), authorization servers MUST\n * allow any port for loopback redirect URIs (localhost, 127.0.0.1, [::1]) to\n * accommodate native clients that obtain an ephemeral port from the OS. For\n * non-loopback URIs, exact match is required.\n *\n * @see https://datatracker.ietf.org/doc/html/rfc8252#section-7.3\n */\nexport function redirectUriMatches(requested: string, registered: string): boolean {\n    if (requested === registered) {\n        return true;\n    }\n    let req: URL, reg: URL;\n    try {\n        req = new URL(requested);\n        reg = new URL(registered);\n    } catch {\n        return false;\n    }\n    // Port relaxation only applies when both URIs target a loopback host.\n    if (!LOOPBACK_HOSTS.has(req.hostname) || !LOOPBACK_HOSTS.has(reg.hostname)) {\n        return false;\n    }\n    // RFC 8252 relaxes the port only — scheme, host, path, and query must\n    // still match exactly. Note: hostname must match exactly too (the RFC\n    // does not allow localhost↔127.0.0.1 cross-matching).\n    return req.protocol === reg.protocol && req.hostname === reg.hostname && req.pathname === reg.pathname && req.search === reg.search;\n}\n\n// Parameters that must be validated in order to issue redirects.\nconst ClientAuthorizationParamsSchema = z.object({\n    client_id: z.string(),\n    redirect_uri: z\n        .string()\n        .optional()\n        .refine(value => value === undefined || URL.canParse(value), { message: 'redirect_uri must be a valid URL' })\n});\n\n// Parameters that must be validated for a successful authorization request. Failure can be reported to the redirect URI.\nconst RequestAuthorizationParamsSchema = z.object({\n    response_type: z.literal('code'),\n    code_challenge: z.string(),\n    code_challenge_method: z.literal('S256'),\n    scope: z.string().optional(),\n    state: z.string().optional(),\n    resource: z.string().url().optional()\n});\n\nexport function authorizationHandler({ provider, issuerUrl, rateLimit: rateLimitConfig }: AuthorizationHandlerOptions): RequestHandler {\n    const issuer = issuerUrl?.href;\n    // Create a router to apply middleware\n    const router = express.Router();\n    router.use(allowedMethods(['GET', 'POST']));\n    router.use(express.urlencoded({ extended: false }));\n\n    // Apply rate limiting unless explicitly disabled\n    if (rateLimitConfig !== false) {\n        router.use(\n            rateLimit({\n                windowMs: 15 * 60 * 1000, // 15 minutes\n                max: 100, // 100 requests per windowMs\n                standardHeaders: true,\n                legacyHeaders: false,\n                message: new TooManyRequestsError('You have exceeded the rate limit for authorization requests').toResponseObject(),\n                ...rateLimitConfig\n            })\n        );\n    }\n\n    router.all('/', async (req, res) => {\n        res.setHeader('Cache-Control', 'no-store');\n\n        // In the authorization flow, errors are split into two categories:\n        // 1. Pre-redirect errors (direct response with 400)\n        // 2. Post-redirect errors (redirect with error parameters)\n\n        // Phase 1: Validate client_id and redirect_uri. Any errors here must be direct responses.\n        let client_id, redirect_uri, client;\n        try {\n            const result = ClientAuthorizationParamsSchema.safeParse(req.method === 'POST' ? req.body : req.query);\n            if (!result.success) {\n                throw new InvalidRequestError(result.error.message);\n            }\n\n            client_id = result.data.client_id;\n            redirect_uri = result.data.redirect_uri;\n\n            client = await provider.clientsStore.getClient(client_id);\n            if (!client) {\n                throw new InvalidClientError('Invalid client_id');\n            }\n\n            if (redirect_uri !== undefined) {\n                const requested = redirect_uri;\n                if (!client.redirect_uris.some(registered => redirectUriMatches(requested, registered))) {\n                    throw new InvalidRequestError('Unregistered redirect_uri');\n                }\n            } else if (client.redirect_uris.length === 1) {\n                redirect_uri = client.redirect_uris[0];\n            } else {\n                throw new InvalidRequestError('redirect_uri must be specified when client has multiple registered URIs');\n            }\n        } catch (error) {\n            // Pre-redirect errors - return direct response\n            //\n            // These don't need to be JSON encoded, as they'll be displayed in a user\n            // agent, but OTOH they all represent exceptional situations (arguably,\n            // \"programmer error\"), so presenting a nice HTML page doesn't help the\n            // user anyway.\n            if (error instanceof OAuthError) {\n                const status = error instanceof ServerError ? 500 : 400;\n                res.status(status).json(error.toResponseObject());\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.status(500).json(serverError.toResponseObject());\n            }\n\n            return;\n        }\n\n        // Phase 2: Validate other parameters. Any errors here should go into redirect responses.\n        let state;\n        try {\n            // Parse and validate authorization parameters\n            const parseResult = RequestAuthorizationParamsSchema.safeParse(req.method === 'POST' ? req.body : req.query);\n            if (!parseResult.success) {\n                throw new InvalidRequestError(parseResult.error.message);\n            }\n\n            const { scope, code_challenge, resource } = parseResult.data;\n            state = parseResult.data.state;\n\n            // Validate scopes\n            let requestedScopes: string[] = [];\n            if (scope !== undefined) {\n                requestedScopes = scope.split(' ');\n            }\n\n            // All validation passed, proceed with authorization. RFC 9207: the metadata\n            // advertises `authorization_response_iss_parameter_supported`, so make that claim\n            // true from SDK code by appending `iss` to whatever redirect the provider issues\n            // back to the client's validated redirect_uri — the provider need not do anything.\n            // Redirects elsewhere (e.g. to an upstream authorize endpoint) are left untouched.\n            await provider.authorize(\n                client,\n                {\n                    state,\n                    scopes: requestedScopes,\n                    redirectUri: redirect_uri!,\n                    codeChallenge: code_challenge,\n                    resource: resource ? new URL(resource) : undefined,\n                    issuer\n                },\n                issuer ? withIssOnCallbackRedirect(res, redirect_uri!, issuer) : res\n            );\n        } catch (error) {\n            // Post-redirect errors - redirect with error parameters\n            if (error instanceof OAuthError) {\n                res.redirect(302, createErrorRedirect(redirect_uri!, error, state, issuer));\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.redirect(302, createErrorRedirect(redirect_uri!, serverError, state, issuer));\n            }\n        }\n    });\n\n    return router;\n}\n\n/**\n * Wraps `res.redirect` so that when the provider redirects to the client's validated\n * `redirect_uri` (i.e. the OAuth authorization response), `iss` is appended per RFC 9207.\n * Only redirects whose origin and path match `redirectUri` are touched; an `iss` already\n * set by the provider is preserved. This is what backs the\n * `authorization_response_iss_parameter_supported: true` metadata claim without requiring\n * `OAuthServerProvider.authorize()` implementations to change.\n */\nfunction withIssOnCallbackRedirect(res: Response, redirectUri: string, issuer: string): Response {\n    const cb = new URL(redirectUri);\n    const appendIss = (url: string): string => {\n        let target: URL;\n        try {\n            target = new URL(url);\n        } catch {\n            return url;\n        }\n        if (target.origin === cb.origin && target.pathname === cb.pathname && !target.searchParams.has('iss')) {\n            target.searchParams.set('iss', issuer);\n            return target.href;\n        }\n        return url;\n    };\n    const original = res.redirect.bind(res) as (...args: unknown[]) => void;\n    res.redirect = ((statusOrUrl: number | string, maybeUrl?: string | number): void => {\n        if (typeof statusOrUrl === 'number') original(statusOrUrl, appendIss(String(maybeUrl)));\n        // Express 4 still accepts the deprecated reversed form `res.redirect(url, status)`.\n        else if (typeof maybeUrl === 'number') original(appendIss(statusOrUrl), maybeUrl);\n        else original(appendIss(statusOrUrl));\n    }) as Response['redirect'];\n    return res;\n}\n\n/**\n * Helper function to create redirect URL with error parameters\n */\nfunction createErrorRedirect(redirectUri: string, error: OAuthError, state?: string, issuer?: string): string {\n    const errorUrl = new URL(redirectUri);\n    errorUrl.searchParams.set('error', error.errorCode);\n    errorUrl.searchParams.set('error_description', error.message);\n    if (error.errorUri) {\n        errorUrl.searchParams.set('error_uri', error.errorUri);\n    }\n    if (state) {\n        errorUrl.searchParams.set('state', state);\n    }\n    if (issuer) {\n        // RFC 9207 §2: the iss parameter is required on error responses too.\n        errorUrl.searchParams.set('iss', issuer);\n    }\n    return errorUrl.href;\n}\n","import type { OAuthMetadata, OAuthProtectedResourceMetadata } from '@modelcontextprotocol/core-internal';\nimport cors from 'cors';\nimport type { RequestHandler } from 'express';\nimport express from 'express';\n\nimport { allowedMethods } from '../middleware/allowedMethods';\n\nexport function metadataHandler(metadata: OAuthMetadata | OAuthProtectedResourceMetadata): RequestHandler {\n    // Nested router so we can configure middleware and restrict HTTP method\n    const router = express.Router();\n\n    // Configure CORS to allow any origin, to make accessible to web-based MCP clients\n    router.use(cors());\n\n    router.use(allowedMethods(['GET', 'OPTIONS']));\n    router.get('/', (req, res) => {\n        res.status(200).json(metadata);\n    });\n\n    return router;\n}\n","import crypto from 'node:crypto';\n\nimport type { OAuthClientInformationFull } from '@modelcontextprotocol/core-internal';\nimport { OAuthClientMetadataSchema } from '@modelcontextprotocol/core-internal';\nimport cors from 'cors';\nimport type { RequestHandler } from 'express';\nimport express from 'express';\nimport type { Options as RateLimitOptions } from 'express-rate-limit';\nimport { rateLimit } from 'express-rate-limit';\n\nimport type { OAuthRegisteredClientsStore } from '../clients';\nimport { InvalidClientMetadataError, OAuthError, ServerError, TooManyRequestsError } from '../errors';\nimport { allowedMethods } from '../middleware/allowedMethods';\n\nexport type ClientRegistrationHandlerOptions = {\n    /**\n     * A store used to save information about dynamically registered OAuth clients.\n     */\n    clientsStore: OAuthRegisteredClientsStore;\n\n    /**\n     * The number of seconds after which to expire issued client secrets, or 0 to prevent expiration of client secrets (not recommended).\n     *\n     * If not set, defaults to 30 days.\n     */\n    clientSecretExpirySeconds?: number;\n\n    /**\n     * Rate limiting configuration for the client registration endpoint.\n     * Set to false to disable rate limiting for this endpoint.\n     * Registration endpoints are particularly sensitive to abuse and should be rate limited.\n     */\n    rateLimit?: Partial<RateLimitOptions> | false;\n\n    /**\n     * Whether to generate a client ID before calling the client registration endpoint.\n     *\n     * If not set, defaults to true.\n     */\n    clientIdGeneration?: boolean;\n};\n\nconst DEFAULT_CLIENT_SECRET_EXPIRY_SECONDS = 30 * 24 * 60 * 60; // 30 days\n\nexport function clientRegistrationHandler({\n    clientsStore,\n    clientSecretExpirySeconds = DEFAULT_CLIENT_SECRET_EXPIRY_SECONDS,\n    rateLimit: rateLimitConfig,\n    clientIdGeneration = true\n}: ClientRegistrationHandlerOptions): RequestHandler {\n    if (!clientsStore.registerClient) {\n        throw new Error('Client registration store does not support registering clients');\n    }\n\n    // Nested router so we can configure middleware and restrict HTTP method\n    const router = express.Router();\n\n    // Configure CORS to allow any origin, to make accessible to web-based MCP clients\n    router.use(cors());\n\n    router.use(allowedMethods(['POST']));\n    router.use(express.json());\n\n    // Apply rate limiting unless explicitly disabled - stricter limits for registration\n    if (rateLimitConfig !== false) {\n        router.use(\n            rateLimit({\n                windowMs: 60 * 60 * 1000, // 1 hour\n                max: 20, // 20 requests per hour - stricter as registration is sensitive\n                standardHeaders: true,\n                legacyHeaders: false,\n                message: new TooManyRequestsError('You have exceeded the rate limit for client registration requests').toResponseObject(),\n                ...rateLimitConfig\n            })\n        );\n    }\n\n    router.post('/', async (req, res) => {\n        res.setHeader('Cache-Control', 'no-store');\n\n        try {\n            const parseResult = OAuthClientMetadataSchema.safeParse(req.body);\n            if (!parseResult.success) {\n                throw new InvalidClientMetadataError(parseResult.error.message);\n            }\n\n            const clientMetadata = parseResult.data;\n            const isPublicClient = clientMetadata.token_endpoint_auth_method === 'none';\n\n            // Generate client credentials\n            const clientSecret = isPublicClient ? undefined : crypto.randomBytes(32).toString('hex');\n            const clientIdIssuedAt = Math.floor(Date.now() / 1000);\n\n            // Calculate client secret expiry time\n            const clientsDoExpire = clientSecretExpirySeconds > 0;\n            const secretExpiryTime = clientsDoExpire ? clientIdIssuedAt + clientSecretExpirySeconds : 0;\n            const clientSecretExpiresAt = isPublicClient ? undefined : secretExpiryTime;\n\n            let clientInfo: Omit<OAuthClientInformationFull, 'client_id'> & { client_id?: string } = {\n                ...clientMetadata,\n                client_secret: clientSecret,\n                client_secret_expires_at: clientSecretExpiresAt\n            };\n\n            if (clientIdGeneration) {\n                clientInfo.client_id = crypto.randomUUID();\n                clientInfo.client_id_issued_at = clientIdIssuedAt;\n            }\n\n            clientInfo = await clientsStore.registerClient!(clientInfo);\n            res.status(201).json(clientInfo);\n        } catch (error) {\n            if (error instanceof OAuthError) {\n                const status = error instanceof ServerError ? 500 : 400;\n                res.status(status).json(error.toResponseObject());\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.status(500).json(serverError.toResponseObject());\n            }\n        }\n    });\n\n    return router;\n}\n","import type { OAuthClientInformationFull } from '@modelcontextprotocol/core-internal';\nimport type { RequestHandler } from 'express';\nimport * as z from 'zod/v4';\n\nimport type { OAuthRegisteredClientsStore } from '../clients';\nimport { InvalidClientError, InvalidRequestError, OAuthError, ServerError } from '../errors';\n\nexport type ClientAuthenticationMiddlewareOptions = {\n    /**\n     * A store used to read information about registered OAuth clients.\n     */\n    clientsStore: OAuthRegisteredClientsStore;\n};\n\nconst ClientAuthenticatedRequestSchema = z.object({\n    client_id: z.string(),\n    client_secret: z.string().optional()\n});\n\ndeclare module 'express-serve-static-core' {\n    interface Request {\n        /**\n         * The authenticated client for this request, if the `authenticateClient` middleware was used.\n         */\n        client?: OAuthClientInformationFull;\n    }\n}\n\nexport function authenticateClient({ clientsStore }: ClientAuthenticationMiddlewareOptions): RequestHandler {\n    return async (req, res, next) => {\n        try {\n            const result = ClientAuthenticatedRequestSchema.safeParse(req.body);\n            if (!result.success) {\n                throw new InvalidRequestError(String(result.error));\n            }\n            const { client_id, client_secret } = result.data;\n            const client = await clientsStore.getClient(client_id);\n            if (!client) {\n                throw new InvalidClientError('Invalid client_id');\n            }\n            if (client.client_secret) {\n                if (!client_secret) {\n                    throw new InvalidClientError('Client secret is required');\n                }\n                if (client.client_secret !== client_secret) {\n                    throw new InvalidClientError('Invalid client_secret');\n                }\n                if (client.client_secret_expires_at && client.client_secret_expires_at < Math.floor(Date.now() / 1000)) {\n                    throw new InvalidClientError('Client secret has expired');\n                }\n            }\n\n            req.client = client;\n            next();\n        } catch (error) {\n            if (error instanceof OAuthError) {\n                const status = error instanceof ServerError ? 500 : 400;\n                res.status(status).json(error.toResponseObject());\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.status(500).json(serverError.toResponseObject());\n            }\n        }\n    };\n}\n","import { OAuthTokenRevocationRequestSchema } from '@modelcontextprotocol/core-internal';\nimport cors from 'cors';\nimport type { RequestHandler } from 'express';\nimport express from 'express';\nimport type { Options as RateLimitOptions } from 'express-rate-limit';\nimport { rateLimit } from 'express-rate-limit';\n\nimport { InvalidRequestError, OAuthError, ServerError, TooManyRequestsError } from '../errors';\nimport { allowedMethods } from '../middleware/allowedMethods';\nimport { authenticateClient } from '../middleware/clientAuth';\nimport type { OAuthServerProvider } from '../provider';\n\nexport type RevocationHandlerOptions = {\n    provider: OAuthServerProvider;\n    /**\n     * Rate limiting configuration for the token revocation endpoint.\n     * Set to false to disable rate limiting for this endpoint.\n     */\n    rateLimit?: Partial<RateLimitOptions> | false;\n};\n\nexport function revocationHandler({ provider, rateLimit: rateLimitConfig }: RevocationHandlerOptions): RequestHandler {\n    if (!provider.revokeToken) {\n        throw new Error('Auth provider does not support revoking tokens');\n    }\n\n    // Nested router so we can configure middleware and restrict HTTP method\n    const router = express.Router();\n\n    // Configure CORS to allow any origin, to make accessible to web-based MCP clients\n    router.use(cors());\n\n    router.use(allowedMethods(['POST']));\n    router.use(express.urlencoded({ extended: false }));\n\n    // Apply rate limiting unless explicitly disabled\n    if (rateLimitConfig !== false) {\n        router.use(\n            rateLimit({\n                windowMs: 15 * 60 * 1000, // 15 minutes\n                max: 50, // 50 requests per windowMs\n                standardHeaders: true,\n                legacyHeaders: false,\n                message: new TooManyRequestsError('You have exceeded the rate limit for token revocation requests').toResponseObject(),\n                ...rateLimitConfig\n            })\n        );\n    }\n\n    // Authenticate and extract client details\n    router.use(authenticateClient({ clientsStore: provider.clientsStore }));\n\n    router.post('/', async (req, res) => {\n        res.setHeader('Cache-Control', 'no-store');\n\n        try {\n            const parseResult = OAuthTokenRevocationRequestSchema.safeParse(req.body);\n            if (!parseResult.success) {\n                throw new InvalidRequestError(parseResult.error.message);\n            }\n\n            const client = req.client;\n            if (!client) {\n                // This should never happen\n                throw new ServerError('Internal Server Error');\n            }\n\n            await provider.revokeToken!(client, parseResult.data);\n            res.status(200).json({});\n        } catch (error) {\n            if (error instanceof OAuthError) {\n                const status = error instanceof ServerError ? 500 : 400;\n                res.status(status).json(error.toResponseObject());\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.status(500).json(serverError.toResponseObject());\n            }\n        }\n    });\n\n    return router;\n}\n","import cors from 'cors';\nimport type { RequestHandler } from 'express';\nimport express from 'express';\nimport type { Options as RateLimitOptions } from 'express-rate-limit';\nimport { rateLimit } from 'express-rate-limit';\nimport { verifyChallenge } from 'pkce-challenge';\nimport * as z from 'zod/v4';\n\nimport {\n    InvalidGrantError,\n    InvalidRequestError,\n    OAuthError,\n    ServerError,\n    TooManyRequestsError,\n    UnsupportedGrantTypeError\n} from '../errors';\nimport { allowedMethods } from '../middleware/allowedMethods';\nimport { authenticateClient } from '../middleware/clientAuth';\nimport type { OAuthServerProvider } from '../provider';\n\nexport type TokenHandlerOptions = {\n    provider: OAuthServerProvider;\n    /**\n     * Rate limiting configuration for the token endpoint.\n     * Set to false to disable rate limiting for this endpoint.\n     */\n    rateLimit?: Partial<RateLimitOptions> | false;\n};\n\nconst TokenRequestSchema = z.object({\n    grant_type: z.string()\n});\n\nconst AuthorizationCodeGrantSchema = z.object({\n    code: z.string(),\n    code_verifier: z.string(),\n    redirect_uri: z.string().optional(),\n    resource: z.string().url().optional()\n});\n\nconst RefreshTokenGrantSchema = z.object({\n    refresh_token: z.string(),\n    scope: z.string().optional(),\n    resource: z.string().url().optional()\n});\n\nexport function tokenHandler({ provider, rateLimit: rateLimitConfig }: TokenHandlerOptions): RequestHandler {\n    // Nested router so we can configure middleware and restrict HTTP method\n    const router = express.Router();\n\n    // Configure CORS to allow any origin, to make accessible to web-based MCP clients\n    router.use(cors());\n\n    router.use(allowedMethods(['POST']));\n    router.use(express.urlencoded({ extended: false }));\n\n    // Apply rate limiting unless explicitly disabled\n    if (rateLimitConfig !== false) {\n        router.use(\n            rateLimit({\n                windowMs: 15 * 60 * 1000, // 15 minutes\n                max: 50, // 50 requests per windowMs\n                standardHeaders: true,\n                legacyHeaders: false,\n                message: new TooManyRequestsError('You have exceeded the rate limit for token requests').toResponseObject(),\n                ...rateLimitConfig\n            })\n        );\n    }\n\n    // Authenticate and extract client details\n    router.use(authenticateClient({ clientsStore: provider.clientsStore }));\n\n    router.post('/', async (req, res) => {\n        res.setHeader('Cache-Control', 'no-store');\n\n        try {\n            const parseResult = TokenRequestSchema.safeParse(req.body);\n            if (!parseResult.success) {\n                throw new InvalidRequestError(parseResult.error.message);\n            }\n\n            const { grant_type } = parseResult.data;\n\n            const client = req.client;\n            if (!client) {\n                // This should never happen\n                throw new ServerError('Internal Server Error');\n            }\n\n            switch (grant_type) {\n                case 'authorization_code': {\n                    const parseResult = AuthorizationCodeGrantSchema.safeParse(req.body);\n                    if (!parseResult.success) {\n                        throw new InvalidRequestError(parseResult.error.message);\n                    }\n\n                    const { code, code_verifier, redirect_uri, resource } = parseResult.data;\n\n                    const skipLocalPkceValidation = provider.skipLocalPkceValidation;\n\n                    // Perform local PKCE validation unless explicitly skipped\n                    // (e.g. to validate code_verifier in upstream server)\n                    if (!skipLocalPkceValidation) {\n                        const codeChallenge = await provider.challengeForAuthorizationCode(client, code);\n                        if (!(await verifyChallenge(code_verifier, codeChallenge))) {\n                            throw new InvalidGrantError('code_verifier does not match the challenge');\n                        }\n                    }\n\n                    // Passes the code_verifier to the provider if PKCE validation didn't occur locally\n                    const tokens = await provider.exchangeAuthorizationCode(\n                        client,\n                        code,\n                        skipLocalPkceValidation ? code_verifier : undefined,\n                        redirect_uri,\n                        resource ? new URL(resource) : undefined\n                    );\n                    res.status(200).json(tokens);\n                    break;\n                }\n\n                case 'refresh_token': {\n                    const parseResult = RefreshTokenGrantSchema.safeParse(req.body);\n                    if (!parseResult.success) {\n                        throw new InvalidRequestError(parseResult.error.message);\n                    }\n\n                    const { refresh_token, scope, resource } = parseResult.data;\n\n                    const scopes = scope?.split(' ');\n                    const tokens = await provider.exchangeRefreshToken(\n                        client,\n                        refresh_token,\n                        scopes,\n                        resource ? new URL(resource) : undefined\n                    );\n                    res.status(200).json(tokens);\n                    break;\n                }\n                default: {\n                    throw new UnsupportedGrantTypeError('The grant type is not supported by this authorization server.');\n                }\n            }\n        } catch (error) {\n            if (error instanceof OAuthError) {\n                const status = error instanceof ServerError ? 500 : 400;\n                res.status(status).json(error.toResponseObject());\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.status(500).json(serverError.toResponseObject());\n            }\n        }\n    });\n\n    return router;\n}\n","import type { OAuthMetadata, OAuthProtectedResourceMetadata } from '@modelcontextprotocol/core-internal';\nimport type { RequestHandler } from 'express';\nimport express from 'express';\n\nimport type { AuthorizationHandlerOptions } from './handlers/authorize';\nimport { authorizationHandler } from './handlers/authorize';\nimport { metadataHandler } from './handlers/metadata';\nimport type { ClientRegistrationHandlerOptions } from './handlers/register';\nimport { clientRegistrationHandler } from './handlers/register';\nimport type { RevocationHandlerOptions } from './handlers/revoke';\nimport { revocationHandler } from './handlers/revoke';\nimport type { TokenHandlerOptions } from './handlers/token';\nimport { tokenHandler } from './handlers/token';\nimport type { OAuthServerProvider } from './provider';\n\n// Check for dev mode flag that allows HTTP issuer URLs (for development/testing only)\nconst allowInsecureIssuerUrl =\n    process.env.MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL === 'true' || process.env.MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL === '1';\nif (allowInsecureIssuerUrl) {\n    // eslint-disable-next-line no-console\n    console.warn('MCP_DANGEROUSLY_ALLOW_INSECURE_ISSUER_URL is enabled - HTTP issuer URLs are allowed. Do not use in production.');\n}\n\nexport type AuthRouterOptions = {\n    /**\n     * A provider implementing the actual authorization logic for this router.\n     */\n    provider: OAuthServerProvider;\n\n    /**\n     * The authorization server's issuer identifier, which is a URL that uses the \"https\" scheme and has no query or fragment components.\n     */\n    issuerUrl: URL;\n\n    /**\n     * The base URL of the authorization server to use for the metadata endpoints.\n     *\n     * If not provided, the issuer URL will be used as the base URL.\n     */\n    baseUrl?: URL;\n\n    /**\n     * An optional URL of a page containing human-readable information that developers might want or need to know when using the authorization server.\n     */\n    serviceDocumentationUrl?: URL;\n\n    /**\n     * An optional list of scopes supported by this authorization server\n     */\n    scopesSupported?: string[];\n\n    /**\n     * The resource name to be displayed in protected resource metadata\n     */\n    resourceName?: string;\n\n    /**\n     * The URL of the protected resource (RS) whose metadata we advertise.\n     * If not provided, falls back to `baseUrl` and then to `issuerUrl` (AS=RS).\n     */\n    resourceServerUrl?: URL;\n\n    // Individual options per route\n    authorizationOptions?: Omit<AuthorizationHandlerOptions, 'provider' | 'issuerUrl'>;\n    clientRegistrationOptions?: Omit<ClientRegistrationHandlerOptions, 'clientsStore'>;\n    revocationOptions?: Omit<RevocationHandlerOptions, 'provider'>;\n    tokenOptions?: Omit<TokenHandlerOptions, 'provider'>;\n};\n\nconst checkIssuerUrl = (issuer: URL): void => {\n    // Technically RFC 8414 does not permit a localhost HTTPS exemption, but this will be necessary for ease of testing\n    if (issuer.protocol !== 'https:' && issuer.hostname !== 'localhost' && issuer.hostname !== '127.0.0.1' && !allowInsecureIssuerUrl) {\n        throw new Error('Issuer URL must be HTTPS');\n    }\n    if (issuer.hash) {\n        throw new Error(`Issuer URL must not have a fragment: ${issuer}`);\n    }\n    if (issuer.search) {\n        throw new Error(`Issuer URL must not have a query string: ${issuer}`);\n    }\n};\n\nexport const createOAuthMetadata = (options: {\n    provider: OAuthServerProvider;\n    issuerUrl: URL;\n    baseUrl?: URL;\n    serviceDocumentationUrl?: URL;\n    scopesSupported?: string[];\n}): OAuthMetadata => {\n    const issuer = options.issuerUrl;\n    const baseUrl = options.baseUrl;\n\n    checkIssuerUrl(issuer);\n\n    const authorization_endpoint = '/authorize';\n    const token_endpoint = '/token';\n    const registration_endpoint = options.provider.clientsStore.registerClient ? '/register' : undefined;\n    const revocation_endpoint = options.provider.revokeToken ? '/revoke' : undefined;\n\n    const metadata: OAuthMetadata = {\n        issuer: issuer.href,\n        service_documentation: options.serviceDocumentationUrl?.href,\n\n        authorization_endpoint: new URL(authorization_endpoint, baseUrl || issuer).href,\n        response_types_supported: ['code'],\n        code_challenge_methods_supported: ['S256'],\n\n        token_endpoint: new URL(token_endpoint, baseUrl || issuer).href,\n        token_endpoint_auth_methods_supported: ['client_secret_post', 'none'],\n        grant_types_supported: ['authorization_code', 'refresh_token'],\n\n        scopes_supported: options.scopesSupported,\n\n        revocation_endpoint: revocation_endpoint ? new URL(revocation_endpoint, baseUrl || issuer).href : undefined,\n        revocation_endpoint_auth_methods_supported: revocation_endpoint ? ['client_secret_post'] : undefined,\n\n        registration_endpoint: registration_endpoint ? new URL(registration_endpoint, baseUrl || issuer).href : undefined,\n\n        // RFC 9207: the bundled authorize handler appends `iss` to any redirect the provider\n        // issues via `res.redirect(...)` to the client's validated redirect_uri, so the default\n        // is `true`. Providers whose callback is issued by an upstream AS (e.g. the proxy\n        // provider) override this to `false` so we don't over-claim — SEP-2468 clients reject\n        // a callback that omits `iss` when support is advertised.\n        authorization_response_iss_parameter_supported: options.provider.authorizationResponseIssParameterSupported ?? true\n    };\n\n    return metadata;\n};\n\n/**\n * Installs standard MCP authorization server endpoints, including dynamic client registration and token revocation (if supported).\n * Also advertises standard authorization server metadata, for easier discovery of supported configurations by clients.\n * Note: if your MCP server is only a resource server and not an authorization server, use mcpAuthMetadataRouter instead.\n *\n * By default, rate limiting is applied to all endpoints to prevent abuse.\n *\n * This router MUST be installed at the application root, like so:\n *\n *  const app = express();\n *  app.use(mcpAuthRouter(...));\n */\nexport function mcpAuthRouter(options: AuthRouterOptions): RequestHandler {\n    const oauthMetadata = createOAuthMetadata(options);\n\n    const router = express.Router();\n\n    router.use(\n        new URL(oauthMetadata.authorization_endpoint).pathname,\n        authorizationHandler({ provider: options.provider, issuerUrl: options.issuerUrl, ...options.authorizationOptions })\n    );\n\n    router.use(new URL(oauthMetadata.token_endpoint).pathname, tokenHandler({ provider: options.provider, ...options.tokenOptions }));\n\n    router.use(\n        mcpAuthMetadataRouter({\n            oauthMetadata,\n            // Prefer explicit RS; otherwise fall back to AS baseUrl, then to issuer (back-compat)\n            resourceServerUrl: options.resourceServerUrl ?? options.baseUrl ?? new URL(oauthMetadata.issuer),\n            serviceDocumentationUrl: options.serviceDocumentationUrl,\n            scopesSupported: options.scopesSupported,\n            resourceName: options.resourceName\n        })\n    );\n\n    if (oauthMetadata.registration_endpoint) {\n        router.use(\n            new URL(oauthMetadata.registration_endpoint).pathname,\n            clientRegistrationHandler({\n                clientsStore: options.provider.clientsStore,\n                ...options.clientRegistrationOptions\n            })\n        );\n    }\n\n    if (oauthMetadata.revocation_endpoint) {\n        router.use(\n            new URL(oauthMetadata.revocation_endpoint).pathname,\n            revocationHandler({ provider: options.provider, ...options.revocationOptions })\n        );\n    }\n\n    return router;\n}\n\nexport type AuthMetadataOptions = {\n    /**\n     * OAuth Metadata as would be returned from the authorization server\n     * this MCP server relies on\n     */\n    oauthMetadata: OAuthMetadata;\n\n    /**\n     * The url of the MCP server, for use in protected resource metadata\n     */\n    resourceServerUrl: URL;\n\n    /**\n     * The url for documentation for the MCP server\n     */\n    serviceDocumentationUrl?: URL;\n\n    /**\n     * An optional list of scopes supported by this MCP server\n     */\n    scopesSupported?: string[];\n\n    /**\n     * An optional resource name to display in resource metadata\n     */\n    resourceName?: string;\n};\n\nexport function mcpAuthMetadataRouter(options: AuthMetadataOptions): express.Router {\n    checkIssuerUrl(new URL(options.oauthMetadata.issuer));\n\n    const router = express.Router();\n\n    const protectedResourceMetadata: OAuthProtectedResourceMetadata = {\n        resource: options.resourceServerUrl.href,\n\n        authorization_servers: [options.oauthMetadata.issuer],\n\n        scopes_supported: options.scopesSupported,\n        resource_name: options.resourceName,\n        resource_documentation: options.serviceDocumentationUrl?.href\n    };\n\n    // Serve PRM at the path-specific URL per RFC 9728\n    const rsPath = new URL(options.resourceServerUrl.href).pathname;\n    router.use(`/.well-known/oauth-protected-resource${rsPath === '/' ? '' : rsPath}`, metadataHandler(protectedResourceMetadata));\n\n    // Always add this for OAuth Authorization Server metadata per RFC 8414\n    router.use('/.well-known/oauth-authorization-server', metadataHandler(options.oauthMetadata));\n\n    return router;\n}\n\n/**\n * Helper function to construct the OAuth 2.0 Protected Resource Metadata URL\n * from a given server URL. This replaces the path with the standard metadata endpoint.\n *\n * @param serverUrl - The base URL of the protected resource server\n * @returns The URL for the OAuth protected resource metadata endpoint\n *\n * @example\n * getOAuthProtectedResourceMetadataUrl(new URL('https://api.example.com/mcp'))\n * // Returns: 'https://api.example.com/.well-known/oauth-protected-resource/mcp'\n */\nexport function getOAuthProtectedResourceMetadataUrl(serverUrl: URL): string {\n    const u = new URL(serverUrl.href);\n    const rsPath = u.pathname && u.pathname !== '/' ? u.pathname : '';\n    return new URL(`/.well-known/oauth-protected-resource${rsPath}`, u).href;\n}\n","import type { FetchLike, OAuthClientInformationFull, OAuthTokenRevocationRequest, OAuthTokens } from '@modelcontextprotocol/core-internal';\nimport { OAuthClientInformationFullSchema, OAuthTokensSchema } from '@modelcontextprotocol/core-internal';\nimport type { Response } from 'express';\n\nimport type { OAuthRegisteredClientsStore } from '../clients';\nimport { ServerError } from '../errors';\nimport type { AuthorizationParams, OAuthServerProvider } from '../provider';\nimport type { AuthInfo } from '../types';\n\nexport type ProxyEndpoints = {\n    authorizationUrl: string;\n    tokenUrl: string;\n    revocationUrl?: string;\n    registrationUrl?: string;\n};\n\nexport type ProxyOptions = {\n    /**\n     * Individual endpoint URLs for proxying specific OAuth operations\n     */\n    endpoints: ProxyEndpoints;\n\n    /**\n     * Function to verify access tokens and return auth info\n     */\n    verifyAccessToken: (token: string) => Promise<AuthInfo>;\n\n    /**\n     * Function to fetch client information from the upstream server\n     */\n    getClient: (clientId: string) => Promise<OAuthClientInformationFull | undefined>;\n\n    /**\n     * Custom fetch implementation used for all network requests.\n     */\n    fetch?: FetchLike;\n};\n\n/**\n * Implements an OAuth server that proxies requests to another OAuth server.\n */\nexport class ProxyOAuthServerProvider implements OAuthServerProvider {\n    protected readonly _endpoints: ProxyEndpoints;\n    protected readonly _verifyAccessToken: (token: string) => Promise<AuthInfo>;\n    protected readonly _getClient: (clientId: string) => Promise<OAuthClientInformationFull | undefined>;\n    protected readonly _fetch?: FetchLike;\n\n    skipLocalPkceValidation = true;\n\n    /**\n     * The proxy redirects the browser to the upstream AS's authorize endpoint with\n     * `redirect_uri = params.redirectUri`, so the upstream — not this proxy — issues the\n     * callback. The proxy cannot append its own `iss`, and any `iss` the upstream emits is the\n     * upstream's issuer, not `issuerUrl`. Advertise `false` so the metadata does not over-claim —\n     * a callback *without* `iss` then passes validation. Note: an upstream that *does* emit its\n     * own `iss` will still mismatch this proxy's issuer and be rejected by RFC 9207 clients\n     * regardless of this flag.\n     */\n    authorizationResponseIssParameterSupported = false;\n\n    revokeToken?: (client: OAuthClientInformationFull, request: OAuthTokenRevocationRequest) => Promise<void>;\n\n    constructor(options: ProxyOptions) {\n        this._endpoints = options.endpoints;\n        this._verifyAccessToken = options.verifyAccessToken;\n        this._getClient = options.getClient;\n        this._fetch = options.fetch;\n        if (options.endpoints?.revocationUrl) {\n            this.revokeToken = async (client: OAuthClientInformationFull, request: OAuthTokenRevocationRequest) => {\n                const revocationUrl = this._endpoints.revocationUrl;\n\n                if (!revocationUrl) {\n                    throw new Error('No revocation endpoint configured');\n                }\n\n                const params = new URLSearchParams();\n                params.set('token', request.token);\n                params.set('client_id', client.client_id);\n                if (client.client_secret) {\n                    params.set('client_secret', client.client_secret);\n                }\n                if (request.token_type_hint) {\n                    params.set('token_type_hint', request.token_type_hint);\n                }\n\n                const response = await (this._fetch ?? fetch)(revocationUrl, {\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application/x-www-form-urlencoded'\n                    },\n                    body: params.toString()\n                });\n                await response.body?.cancel();\n\n                if (!response.ok) {\n                    throw new ServerError(`Token revocation failed: ${response.status}`);\n                }\n            };\n        }\n    }\n\n    get clientsStore(): OAuthRegisteredClientsStore {\n        const registrationUrl = this._endpoints.registrationUrl;\n        return {\n            getClient: this._getClient,\n            ...(registrationUrl && {\n                registerClient: async (client: OAuthClientInformationFull) => {\n                    const response = await (this._fetch ?? fetch)(registrationUrl, {\n                        method: 'POST',\n                        headers: {\n                            'Content-Type': 'application/json'\n                        },\n                        body: JSON.stringify(client)\n                    });\n\n                    if (!response.ok) {\n                        await response.body?.cancel();\n                        throw new ServerError(`Client registration failed: ${response.status}`);\n                    }\n\n                    const data = await response.json();\n                    return OAuthClientInformationFullSchema.parse(data);\n                }\n            })\n        };\n    }\n\n    async authorize(client: OAuthClientInformationFull, params: AuthorizationParams, res: Response): Promise<void> {\n        // Start with required OAuth parameters\n        const targetUrl = new URL(this._endpoints.authorizationUrl);\n        const searchParams = new URLSearchParams({\n            client_id: client.client_id,\n            response_type: 'code',\n            redirect_uri: params.redirectUri,\n            code_challenge: params.codeChallenge,\n            code_challenge_method: 'S256'\n        });\n\n        // Add optional standard OAuth parameters\n        if (params.state) searchParams.set('state', params.state);\n        if (params.scopes?.length) searchParams.set('scope', params.scopes.join(' '));\n        if (params.resource) searchParams.set('resource', params.resource.href);\n\n        targetUrl.search = searchParams.toString();\n        res.redirect(targetUrl.toString());\n    }\n\n    async challengeForAuthorizationCode(_client: OAuthClientInformationFull, _authorizationCode: string): Promise<string> {\n        // In a proxy setup, we don't store the code challenge ourselves\n        // Instead, we proxy the token request and let the upstream server validate it\n        return '';\n    }\n\n    async exchangeAuthorizationCode(\n        client: OAuthClientInformationFull,\n        authorizationCode: string,\n        codeVerifier?: string,\n        redirectUri?: string,\n        resource?: URL\n    ): Promise<OAuthTokens> {\n        const params = new URLSearchParams({\n            grant_type: 'authorization_code',\n            client_id: client.client_id,\n            code: authorizationCode\n        });\n\n        if (client.client_secret) {\n            params.append('client_secret', client.client_secret);\n        }\n\n        if (codeVerifier) {\n            params.append('code_verifier', codeVerifier);\n        }\n\n        if (redirectUri) {\n            params.append('redirect_uri', redirectUri);\n        }\n\n        if (resource) {\n            params.append('resource', resource.href);\n        }\n\n        const response = await (this._fetch ?? fetch)(this._endpoints.tokenUrl, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded'\n            },\n            body: params.toString()\n        });\n\n        if (!response.ok) {\n            await response.body?.cancel();\n            throw new ServerError(`Token exchange failed: ${response.status}`);\n        }\n\n        const data = await response.json();\n        return OAuthTokensSchema.parse(data);\n    }\n\n    async exchangeRefreshToken(\n        client: OAuthClientInformationFull,\n        refreshToken: string,\n        scopes?: string[],\n        resource?: URL\n    ): Promise<OAuthTokens> {\n        const params = new URLSearchParams({\n            grant_type: 'refresh_token',\n            client_id: client.client_id,\n            refresh_token: refreshToken\n        });\n\n        if (client.client_secret) {\n            params.set('client_secret', client.client_secret);\n        }\n\n        if (scopes?.length) {\n            params.set('scope', scopes.join(' '));\n        }\n\n        if (resource) {\n            params.set('resource', resource.href);\n        }\n\n        const response = await (this._fetch ?? fetch)(this._endpoints.tokenUrl, {\n            method: 'POST',\n            headers: {\n                'Content-Type': 'application/x-www-form-urlencoded'\n            },\n            body: params.toString()\n        });\n\n        if (!response.ok) {\n            await response.body?.cancel();\n            throw new ServerError(`Token refresh failed: ${response.status}`);\n        }\n\n        const data = await response.json();\n        return OAuthTokensSchema.parse(data);\n    }\n\n    async verifyAccessToken(token: string): Promise<AuthInfo> {\n        return this._verifyAccessToken(token);\n    }\n}\n","import type { RequestHandler } from 'express';\n\nimport { InsufficientScopeError, InvalidTokenError, OAuthError, ServerError } from '../errors';\nimport type { OAuthTokenVerifier } from '../provider';\nimport type { AuthInfo } from '../types';\n\nexport type BearerAuthMiddlewareOptions = {\n    /**\n     * A provider used to verify tokens.\n     */\n    verifier: OAuthTokenVerifier;\n\n    /**\n     * Optional scopes that the token must have.\n     */\n    requiredScopes?: string[];\n\n    /**\n     * Optional resource metadata URL to include in WWW-Authenticate header.\n     */\n    resourceMetadataUrl?: string;\n};\n\ndeclare module 'express-serve-static-core' {\n    interface Request {\n        /**\n         * Information about the validated access token, if the `requireBearerAuth` middleware was used.\n         */\n        auth?: AuthInfo;\n    }\n}\n\n/**\n * Middleware that requires a valid Bearer token in the Authorization header.\n *\n * This will validate the token with the auth provider and add the resulting auth info to the request object.\n *\n * If resourceMetadataUrl is provided, it will be included in the WWW-Authenticate header\n * for 401 responses as per the OAuth 2.0 Protected Resource Metadata spec.\n */\nexport function requireBearerAuth({ verifier, requiredScopes = [], resourceMetadataUrl }: BearerAuthMiddlewareOptions): RequestHandler {\n    const buildWwwAuthHeader = (errorCode: string, message: string): string => {\n        let header = `Bearer error=\"${errorCode}\", error_description=\"${message}\"`;\n        if (requiredScopes.length > 0) {\n            header += `, scope=\"${requiredScopes.join(' ')}\"`;\n        }\n        if (resourceMetadataUrl) {\n            header += `, resource_metadata=\"${resourceMetadataUrl}\"`;\n        }\n        return header;\n    };\n\n    return async (req, res, next) => {\n        try {\n            const authHeader = req.headers.authorization;\n            if (!authHeader) {\n                throw new InvalidTokenError('Missing Authorization header');\n            }\n\n            const [type, token] = authHeader.split(' ') as [string | undefined, string | undefined];\n            if (!type || type.toLowerCase() !== 'bearer' || !token) {\n                throw new InvalidTokenError(\"Invalid Authorization header format, expected 'Bearer TOKEN'\");\n            }\n\n            const authInfo = await verifier.verifyAccessToken(token);\n\n            if (requiredScopes.length > 0) {\n                const hasAllScopes = requiredScopes.every(scope => authInfo.scopes.includes(scope));\n\n                if (!hasAllScopes) {\n                    throw new InsufficientScopeError('Insufficient scope');\n                }\n            }\n\n            if (typeof authInfo.expiresAt !== 'number' || Number.isNaN(authInfo.expiresAt)) {\n                throw new InvalidTokenError('Token has no expiration time');\n            } else if (authInfo.expiresAt < Date.now() / 1000) {\n                throw new InvalidTokenError('Token has expired');\n            }\n\n            req.auth = authInfo;\n            next();\n        } catch (error) {\n            if (error instanceof InvalidTokenError) {\n                res.set('WWW-Authenticate', buildWwwAuthHeader(error.errorCode, error.message));\n                res.status(401).json(error.toResponseObject());\n            } else if (error instanceof InsufficientScopeError) {\n                res.set('WWW-Authenticate', buildWwwAuthHeader(error.errorCode, error.message));\n                res.status(403).json(error.toResponseObject());\n            } else if (error instanceof ServerError) {\n                res.status(500).json(error.toResponseObject());\n            } else if (error instanceof OAuthError) {\n                res.status(400).json(error.toResponseObject());\n            } else {\n                const serverError = new ServerError('Internal Server Error');\n                res.status(500).json(serverError.toResponseObject());\n            }\n        }\n    };\n}\n"],"mappings":"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"}