better-auth 1.4.8-beta.1 → 1.4.8-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/api/index.d.mts +393 -393
  2. package/dist/api/middlewares/origin-check.d.mts +3 -3
  3. package/dist/api/routes/account.d.mts +11 -11
  4. package/dist/api/routes/callback.d.mts +2 -2
  5. package/dist/api/routes/email-verification.d.mts +4 -4
  6. package/dist/api/routes/error.d.mts +2 -2
  7. package/dist/api/routes/ok.d.mts +2 -2
  8. package/dist/api/routes/reset-password.d.mts +5 -5
  9. package/dist/api/routes/session.d.mts +14 -14
  10. package/dist/api/routes/sign-in.d.mts +3 -3
  11. package/dist/api/routes/sign-out.d.mts +2 -2
  12. package/dist/api/routes/sign-up.d.mts +2 -2
  13. package/dist/api/routes/update-user.d.mts +13 -13
  14. package/dist/client/lynx/index.d.mts +15 -15
  15. package/dist/client/react/index.d.mts +13 -13
  16. package/dist/client/solid/index.d.mts +13 -13
  17. package/dist/client/svelte/index.d.mts +13 -13
  18. package/dist/client/vue/index.d.mts +15 -15
  19. package/dist/db/field.d.mts +6 -6
  20. package/dist/integrations/next-js.d.mts +4 -4
  21. package/dist/integrations/svelte-kit.d.mts +2 -2
  22. package/dist/integrations/tanstack-start.d.mts +4 -4
  23. package/dist/plugins/anonymous/index.d.mts +6 -5
  24. package/dist/plugins/anonymous/index.mjs +1 -0
  25. package/dist/plugins/anonymous/index.mjs.map +1 -1
  26. package/dist/plugins/api-key/index.d.mts +18 -18
  27. package/dist/plugins/bearer/index.d.mts +8 -7
  28. package/dist/plugins/bearer/index.mjs +2 -1
  29. package/dist/plugins/bearer/index.mjs.map +1 -1
  30. package/dist/plugins/captcha/index.d.mts +3 -2
  31. package/dist/plugins/captcha/index.mjs +2 -1
  32. package/dist/plugins/captcha/index.mjs.map +1 -1
  33. package/dist/plugins/custom-session/index.d.mts +6 -5
  34. package/dist/plugins/custom-session/index.mjs +2 -1
  35. package/dist/plugins/custom-session/index.mjs.map +1 -1
  36. package/dist/plugins/device-authorization/index.d.mts +35 -8
  37. package/dist/plugins/device-authorization/index.mjs +2 -1
  38. package/dist/plugins/device-authorization/index.mjs.map +1 -1
  39. package/dist/plugins/email-otp/index.d.mts +49 -48
  40. package/dist/plugins/email-otp/index.mjs +2 -1
  41. package/dist/plugins/email-otp/index.mjs.map +1 -1
  42. package/dist/plugins/generic-oauth/index.d.mts +1 -0
  43. package/dist/plugins/generic-oauth/index.mjs +1 -0
  44. package/dist/plugins/generic-oauth/index.mjs.map +1 -1
  45. package/dist/plugins/haveibeenpwned/index.d.mts +4 -3
  46. package/dist/plugins/haveibeenpwned/index.mjs +1 -0
  47. package/dist/plugins/haveibeenpwned/index.mjs.map +1 -1
  48. package/dist/plugins/index.d.mts +4 -3
  49. package/dist/plugins/jwt/index.d.mts +9 -9
  50. package/dist/plugins/last-login-method/index.d.mts +3 -2
  51. package/dist/plugins/last-login-method/index.mjs +2 -1
  52. package/dist/plugins/last-login-method/index.mjs.map +1 -1
  53. package/dist/plugins/magic-link/index.d.mts +5 -4
  54. package/dist/plugins/magic-link/index.mjs +2 -1
  55. package/dist/plugins/magic-link/index.mjs.map +1 -1
  56. package/dist/plugins/mcp/index.d.mts +11 -10
  57. package/dist/plugins/mcp/index.mjs +2 -1
  58. package/dist/plugins/mcp/index.mjs.map +1 -1
  59. package/dist/plugins/multi-session/index.d.mts +10 -9
  60. package/dist/plugins/multi-session/index.mjs +1 -0
  61. package/dist/plugins/multi-session/index.mjs.map +1 -1
  62. package/dist/plugins/oauth-proxy/index.d.mts +8 -8
  63. package/dist/plugins/oidc-provider/index.d.mts +13 -13
  64. package/dist/plugins/one-tap/index.d.mts +4 -3
  65. package/dist/plugins/one-tap/index.mjs +2 -1
  66. package/dist/plugins/one-tap/index.mjs.map +1 -1
  67. package/dist/plugins/one-time-token/index.d.mts +6 -5
  68. package/dist/plugins/one-time-token/index.mjs +2 -1
  69. package/dist/plugins/one-time-token/index.mjs.map +1 -1
  70. package/dist/plugins/open-api/index.d.mts +4 -3
  71. package/dist/plugins/open-api/index.mjs +2 -1
  72. package/dist/plugins/open-api/index.mjs.map +1 -1
  73. package/dist/plugins/organization/organization.d.mts +4 -4
  74. package/dist/plugins/organization/organization.mjs.map +1 -1
  75. package/dist/plugins/organization/routes/crud-access-control.d.mts +22 -22
  76. package/dist/plugins/organization/routes/crud-invites.d.mts +58 -58
  77. package/dist/plugins/organization/routes/crud-members.d.mts +62 -62
  78. package/dist/plugins/organization/routes/crud-org.d.mts +51 -51
  79. package/dist/plugins/organization/routes/crud-team.d.mts +76 -76
  80. package/dist/plugins/phone-number/index.d.mts +10 -9
  81. package/dist/plugins/phone-number/index.mjs +1 -0
  82. package/dist/plugins/phone-number/index.mjs.map +1 -1
  83. package/dist/plugins/siwe/index.d.mts +4 -3
  84. package/dist/plugins/siwe/index.mjs +2 -1
  85. package/dist/plugins/siwe/index.mjs.map +1 -1
  86. package/dist/plugins/two-factor/backup-codes/index.d.mts +5 -5
  87. package/dist/plugins/two-factor/index.d.mts +18 -18
  88. package/dist/plugins/two-factor/otp/index.d.mts +3 -3
  89. package/dist/plugins/two-factor/totp/index.d.mts +5 -5
  90. package/dist/plugins/username/index.d.mts +10 -9
  91. package/dist/plugins/username/index.mjs +1 -0
  92. package/dist/plugins/username/index.mjs.map +1 -1
  93. package/dist/test-utils/test-instance.d.mts +271 -271
  94. package/dist/utils/time.d.mts +29 -1
  95. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["accessToken","accessTokenExpiresAt","refreshTokenExpiresAt"],"sources":["../../../src/plugins/mcp/index.ts"],"sourcesContent":["import type {\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n\tGenericEndpointContext,\n} from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport { isProduction, logger } from \"@better-auth/core/env\";\nimport { getWebcryptoSubtle } from \"@better-auth/utils\";\nimport { base64 } from \"@better-auth/utils/base64\";\nimport { createHash } from \"@better-auth/utils/hash\";\nimport { SignJWT } from \"jose\";\nimport * as z from \"zod\";\nimport { APIError, getSessionFromCtx } from \"../../api\";\nimport { parseSetCookieHeader } from \"../../cookies\";\nimport { generateRandomString } from \"../../crypto\";\nimport { HIDE_METADATA } from \"../../utils\";\nimport { getBaseURL } from \"../../utils/url\";\nimport type {\n\tClient,\n\tCodeVerificationValue,\n\tOAuthAccessToken,\n\tOIDCMetadata,\n\tOIDCOptions,\n} from \"../oidc-provider\";\nimport { oidcProvider } from \"../oidc-provider\";\nimport { schema } from \"../oidc-provider/schema\";\nimport { parsePrompt } from \"../oidc-provider/utils/prompt\";\nimport { authorizeMCPOAuth } from \"./authorize\";\n\ninterface MCPOptions {\n\tloginPage: string;\n\tresource?: string | undefined;\n\toidcConfig?: OIDCOptions | undefined;\n}\n\nexport const getMCPProviderMetadata = (\n\tctx: GenericEndpointContext,\n\toptions?: OIDCOptions | undefined,\n): OIDCMetadata => {\n\tconst issuer = ctx.context.options.baseURL as string;\n\tconst baseURL = ctx.context.baseURL;\n\tif (!issuer || !baseURL) {\n\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\terror: \"invalid_issuer\",\n\t\t\terror_description:\n\t\t\t\t\"issuer or baseURL is not set. If you're the app developer, please make sure to set the `baseURL` in your auth config.\",\n\t\t});\n\t}\n\treturn {\n\t\tissuer,\n\t\tauthorization_endpoint: `${baseURL}/mcp/authorize`,\n\t\ttoken_endpoint: `${baseURL}/mcp/token`,\n\t\tuserinfo_endpoint: `${baseURL}/mcp/userinfo`,\n\t\tjwks_uri: `${baseURL}/mcp/jwks`,\n\t\tregistration_endpoint: `${baseURL}/mcp/register`,\n\t\tscopes_supported: [\"openid\", \"profile\", \"email\", \"offline_access\"],\n\t\tresponse_types_supported: [\"code\"],\n\t\tresponse_modes_supported: [\"query\"],\n\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\tacr_values_supported: [\n\t\t\t\"urn:mace:incommon:iap:silver\",\n\t\t\t\"urn:mace:incommon:iap:bronze\",\n\t\t],\n\t\tsubject_types_supported: [\"public\"],\n\t\tid_token_signing_alg_values_supported: [\"RS256\", \"none\"],\n\t\ttoken_endpoint_auth_methods_supported: [\n\t\t\t\"client_secret_basic\",\n\t\t\t\"client_secret_post\",\n\t\t\t\"none\",\n\t\t],\n\t\tcode_challenge_methods_supported: [\"S256\"],\n\t\tclaims_supported: [\n\t\t\t\"sub\",\n\t\t\t\"iss\",\n\t\t\t\"aud\",\n\t\t\t\"exp\",\n\t\t\t\"nbf\",\n\t\t\t\"iat\",\n\t\t\t\"jti\",\n\t\t\t\"email\",\n\t\t\t\"email_verified\",\n\t\t\t\"name\",\n\t\t],\n\t\t...options?.metadata,\n\t};\n};\n\nexport const getMCPProtectedResourceMetadata = (\n\tctx: GenericEndpointContext,\n\toptions?: MCPOptions | undefined,\n) => {\n\tconst baseURL = ctx.context.baseURL;\n\tconst origin = new URL(baseURL).origin;\n\n\treturn {\n\t\tresource: options?.resource ?? origin,\n\t\tauthorization_servers: [origin],\n\t\tjwks_uri: options?.oidcConfig?.metadata?.jwks_uri ?? `${baseURL}/mcp/jwks`,\n\t\tscopes_supported: options?.oidcConfig?.metadata?.scopes_supported ?? [\n\t\t\t\"openid\",\n\t\t\t\"profile\",\n\t\t\t\"email\",\n\t\t\t\"offline_access\",\n\t\t],\n\t\tbearer_methods_supported: [\"header\"],\n\t\tresource_signing_alg_values_supported: [\"RS256\", \"none\"],\n\t};\n};\n\nconst registerMcpClientBodySchema = z.object({\n\tredirect_uris: z.array(z.string()),\n\ttoken_endpoint_auth_method: z\n\t\t.enum([\"none\", \"client_secret_basic\", \"client_secret_post\"])\n\t\t.default(\"client_secret_basic\")\n\t\t.optional(),\n\tgrant_types: z\n\t\t.array(\n\t\t\tz.enum([\n\t\t\t\t\"authorization_code\",\n\t\t\t\t\"implicit\",\n\t\t\t\t\"password\",\n\t\t\t\t\"client_credentials\",\n\t\t\t\t\"refresh_token\",\n\t\t\t\t\"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n\t\t\t\t\"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n\t\t\t]),\n\t\t)\n\t\t.default([\"authorization_code\"])\n\t\t.optional(),\n\tresponse_types: z\n\t\t.array(z.enum([\"code\", \"token\"]))\n\t\t.default([\"code\"])\n\t\t.optional(),\n\tclient_name: z.string().optional(),\n\tclient_uri: z.string().optional(),\n\tlogo_uri: z.string().optional(),\n\tscope: z.string().optional(),\n\tcontacts: z.array(z.string()).optional(),\n\ttos_uri: z.string().optional(),\n\tpolicy_uri: z.string().optional(),\n\tjwks_uri: z.string().optional(),\n\tjwks: z.record(z.string(), z.any()).optional(),\n\tmetadata: z.record(z.any(), z.any()).optional(),\n\tsoftware_id: z.string().optional(),\n\tsoftware_version: z.string().optional(),\n\tsoftware_statement: z.string().optional(),\n});\n\nconst mcpOAuthTokenBodySchema = z.record(z.any(), z.any());\n\nexport const mcp = (options: MCPOptions) => {\n\tconst opts = {\n\t\tcodeExpiresIn: 600,\n\t\tdefaultScope: \"openid\",\n\t\taccessTokenExpiresIn: 3600,\n\t\trefreshTokenExpiresIn: 604800,\n\t\tallowPlainCodeChallengeMethod: true,\n\t\t...options.oidcConfig,\n\t\tloginPage: options.loginPage,\n\t\tscopes: [\n\t\t\t\"openid\",\n\t\t\t\"profile\",\n\t\t\t\"email\",\n\t\t\t\"offline_access\",\n\t\t\t...(options.oidcConfig?.scopes || []),\n\t\t],\n\t};\n\tconst modelName = {\n\t\toauthClient: \"oauthApplication\",\n\t\toauthAccessToken: \"oauthAccessToken\",\n\t\toauthConsent: \"oauthConsent\",\n\t};\n\tconst provider = oidcProvider(opts);\n\treturn {\n\t\tid: \"mcp\",\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher() {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookie = await ctx.getSignedCookie(\n\t\t\t\t\t\t\t\"oidc_login_prompt\",\n\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst cookieName = ctx.context.authCookies.sessionToken.name;\n\t\t\t\t\t\tconst parsedSetCookieHeader = parseSetCookieHeader(\n\t\t\t\t\t\t\tctx.context.responseHeaders?.get(\"set-cookie\") || \"\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst hasSessionToken = parsedSetCookieHeader.has(cookieName);\n\t\t\t\t\t\tif (!cookie || !hasSessionToken) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.setCookie(\"oidc_login_prompt\", \"\", {\n\t\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst sessionCookie = parsedSetCookieHeader.get(cookieName)?.value;\n\t\t\t\t\t\tconst sessionToken = sessionCookie?.split(\".\")[0]!;\n\t\t\t\t\t\tif (!sessionToken) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst session =\n\t\t\t\t\t\t\t(await ctx.context.internalAdapter.findSession(sessionToken)) ||\n\t\t\t\t\t\t\tctx.context.newSession;\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Remove \"login\" from prompt since user just logged in\n\t\t\t\t\t\tconst promptSet = parsePrompt(String(ctx.query?.prompt));\n\t\t\t\t\t\tif (promptSet.has(\"login\")) {\n\t\t\t\t\t\t\tconst newPromptSet = new Set(promptSet);\n\t\t\t\t\t\t\tnewPromptSet.delete(\"login\");\n\t\t\t\t\t\t\tctx.query = {\n\t\t\t\t\t\t\t\t...ctx.query,\n\t\t\t\t\t\t\t\tprompt: Array.from(newPromptSet).join(\" \"),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.context.session = session;\n\t\t\t\t\t\tconst response = await authorizeMCPOAuth(ctx, opts);\n\t\t\t\t\t\treturn response;\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tendpoints: {\n\t\t\toAuthConsent: provider.endpoints.oAuthConsent,\n\t\t\tgetMcpOAuthConfig: createAuthEndpoint(\n\t\t\t\t\"/.well-known/oauth-authorization-server\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: HIDE_METADATA,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst metadata = getMCPProviderMetadata(c, options);\n\t\t\t\t\t\treturn c.json(metadata);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.log(e);\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetMCPProtectedResource: createAuthEndpoint(\n\t\t\t\t\"/.well-known/oauth-protected-resource\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: HIDE_METADATA,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst metadata = getMCPProtectedResourceMetadata(c, options);\n\t\t\t\t\treturn c.json(metadata);\n\t\t\t\t},\n\t\t\t),\n\t\t\tmcpOAuthAuthorize: createAuthEndpoint(\n\t\t\t\t\"/mcp/authorize\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tquery: z.record(z.string(), z.any()),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Authorize an OAuth2 request using MCP\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\t\t\tdescription: \"Authorization response generated successfully\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Authorization response, contents depend on the authorize function implementation\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\treturn authorizeMCPOAuth(ctx, opts);\n\t\t\t\t},\n\t\t\t),\n\t\t\tmcpOAuthToken: createAuthEndpoint(\n\t\t\t\t\"/mcp/token\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: mcpOAuthTokenBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t...HIDE_METADATA,\n\t\t\t\t\t\tallowedMediaTypes: [\n\t\t\t\t\t\t\t\"application/x-www-form-urlencoded\",\n\t\t\t\t\t\t\t\"application/json\",\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\t//cors\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t\t\t\"Content-Type, Authorization\",\n\t\t\t\t\t);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\n\t\t\t\t\tlet { body } = ctx;\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tthrow ctx.error(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"request body not found\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (body instanceof FormData) {\n\t\t\t\t\t\tbody = Object.fromEntries(body.entries());\n\t\t\t\t\t}\n\t\t\t\t\tif (!(body instanceof Object)) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"request body is not an object\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tlet { client_id, client_secret } = body;\n\t\t\t\t\tconst authorization =\n\t\t\t\t\t\tctx.request?.headers.get(\"authorization\") || null;\n\t\t\t\t\tif (\n\t\t\t\t\t\tauthorization &&\n\t\t\t\t\t\t!client_id &&\n\t\t\t\t\t\t!client_secret &&\n\t\t\t\t\t\tauthorization.startsWith(\"Basic \")\n\t\t\t\t\t) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst encoded = authorization.replace(\"Basic \", \"\");\n\t\t\t\t\t\t\tconst decoded = new TextDecoder().decode(base64.decode(encoded));\n\t\t\t\t\t\t\tif (!decoded.includes(\":\")) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst [id, secret] = decoded.split(\":\");\n\t\t\t\t\t\t\tif (!id || !secret) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tclient_id = id;\n\t\t\t\t\t\t\tclient_secret = secret;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst {\n\t\t\t\t\t\tgrant_type,\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tredirect_uri,\n\t\t\t\t\t\trefresh_token,\n\t\t\t\t\t\tcode_verifier,\n\t\t\t\t\t} = body;\n\t\t\t\t\tif (grant_type === \"refresh_token\") {\n\t\t\t\t\t\tif (!refresh_token) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror_description: \"refresh_token is required\",\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst token = await ctx.context.adapter.findOne<OAuthAccessToken>({\n\t\t\t\t\t\t\tmodel: \"oauthAccessToken\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfield: \"refreshToken\",\n\t\t\t\t\t\t\t\t\tvalue: refresh_token.toString(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid refresh token\",\n\t\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (token.clientId !== client_id?.toString()) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (token.refreshTokenExpiresAt < new Date()) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"refresh token expired\",\n\t\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst accessToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\t\tconst newRefreshToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\t\tconst accessTokenExpiresAt = new Date(\n\t\t\t\t\t\t\tDate.now() + opts.accessTokenExpiresIn * 1000,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst refreshTokenExpiresAt = new Date(\n\t\t\t\t\t\t\tDate.now() + opts.refreshTokenExpiresIn * 1000,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\taccessToken,\n\t\t\t\t\t\t\t\trefreshToken: newRefreshToken,\n\t\t\t\t\t\t\t\taccessTokenExpiresAt,\n\t\t\t\t\t\t\t\trefreshTokenExpiresAt,\n\t\t\t\t\t\t\t\tclientId: client_id.toString(),\n\t\t\t\t\t\t\t\tuserId: token.userId,\n\t\t\t\t\t\t\t\tscopes: token.scopes,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\t\taccess_token: accessToken,\n\t\t\t\t\t\t\ttoken_type: \"bearer\",\n\t\t\t\t\t\t\texpires_in: opts.accessTokenExpiresIn,\n\t\t\t\t\t\t\trefresh_token: newRefreshToken,\n\t\t\t\t\t\t\tscope: token.scopes,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.requirePKCE && !code_verifier) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code verifier is missing\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * We need to check if the code is valid before we can proceed\n\t\t\t\t\t * with the rest of the request.\n\t\t\t\t\t */\n\t\t\t\t\tconst verificationValue =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findVerificationValue(\n\t\t\t\t\t\t\tcode.toString(),\n\t\t\t\t\t\t);\n\t\t\t\t\tif (!verificationValue) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid code\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (verificationValue.expiresAt < new Date()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"code expired\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteVerificationValue(\n\t\t\t\t\t\tverificationValue.id,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!client_id) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"client_id is required\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (!grant_type) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"grant_type is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (grant_type !== \"authorization_code\") {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"grant_type must be 'authorization_code'\",\n\t\t\t\t\t\t\terror: \"unsupported_grant_type\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!redirect_uri) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"redirect_uri is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst client = await ctx.context.adapter\n\t\t\t\t\t\t.findOne<Record<string, any>>({\n\t\t\t\t\t\t\tmodel: modelName.oauthClient,\n\t\t\t\t\t\t\twhere: [{ field: \"clientId\", value: client_id.toString() }],\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tif (!res) {\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...res,\n\t\t\t\t\t\t\t\tredirectUrls: res.redirectUrls.split(\",\"),\n\t\t\t\t\t\t\t\tmetadata: res.metadata ? JSON.parse(res.metadata) : {},\n\t\t\t\t\t\t\t} as Client;\n\t\t\t\t\t\t});\n\t\t\t\t\tif (!client) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (client.disabled) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"client is disabled\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// For public clients (type: 'public'), validate PKCE instead of client_secret\n\t\t\t\t\tif (client.type === \"public\") {\n\t\t\t\t\t\t// Public clients must use PKCE\n\t\t\t\t\t\tif (!code_verifier) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"code verifier is required for public clients\",\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// PKCE validation happens later in the flow, so we skip client_secret validation\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// For confidential clients, validate client_secret\n\t\t\t\t\t\tif (!client_secret) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"client_secret is required for confidential clients\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst isValidSecret =\n\t\t\t\t\t\t\tclient.clientSecret === client_secret.toString();\n\t\t\t\t\t\tif (!isValidSecret) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid client_secret\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst value = JSON.parse(\n\t\t\t\t\t\tverificationValue.value,\n\t\t\t\t\t) as CodeVerificationValue;\n\t\t\t\t\tif (value.clientId !== client_id.toString()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (value.redirectURI !== redirect_uri.toString()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid redirect_uri\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (value.codeChallenge && !code_verifier) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code verifier is missing\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst challenge =\n\t\t\t\t\t\tvalue.codeChallengeMethod === \"plain\"\n\t\t\t\t\t\t\t? code_verifier\n\t\t\t\t\t\t\t: await createHash(\"SHA-256\", \"base64urlnopad\").digest(\n\t\t\t\t\t\t\t\t\tcode_verifier,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\tif (challenge !== value.codeChallenge) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"code verification failed\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst requestedScopes = value.scope;\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteVerificationValue(\n\t\t\t\t\t\tverificationValue.id,\n\t\t\t\t\t);\n\t\t\t\t\tconst accessToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\tconst refreshToken = generateRandomString(32, \"A-Z\", \"a-z\");\n\t\t\t\t\tconst accessTokenExpiresAt = new Date(\n\t\t\t\t\t\tDate.now() + opts.accessTokenExpiresIn * 1000,\n\t\t\t\t\t);\n\t\t\t\t\tconst refreshTokenExpiresAt = new Date(\n\t\t\t\t\t\tDate.now() + opts.refreshTokenExpiresIn * 1000,\n\t\t\t\t\t);\n\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\taccessToken,\n\t\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\t\taccessTokenExpiresAt,\n\t\t\t\t\t\t\trefreshTokenExpiresAt,\n\t\t\t\t\t\t\tclientId: client_id.toString(),\n\t\t\t\t\t\t\tuserId: value.userId,\n\t\t\t\t\t\t\tscopes: requestedScopes.join(\" \"),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tconst user = await ctx.context.internalAdapter.findUserById(\n\t\t\t\t\t\tvalue.userId,\n\t\t\t\t\t);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"user not found\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tlet secretKey = {\n\t\t\t\t\t\talg: \"HS256\",\n\t\t\t\t\t\tkey: await getWebcryptoSubtle().generateKey(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: \"HMAC\",\n\t\t\t\t\t\t\t\thash: \"SHA-256\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t[\"sign\", \"verify\"],\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\tgiven_name: user.name.split(\" \")[0]!,\n\t\t\t\t\t\tfamily_name: user.name.split(\" \")[1]!,\n\t\t\t\t\t\tname: user.name,\n\t\t\t\t\t\tprofile: user.image,\n\t\t\t\t\t\tupdated_at: Math.floor(new Date(user.updatedAt).getTime() / 1000),\n\t\t\t\t\t};\n\t\t\t\t\tconst email = {\n\t\t\t\t\t\temail: user.email,\n\t\t\t\t\t\temail_verified: user.emailVerified,\n\t\t\t\t\t};\n\t\t\t\t\tconst userClaims = {\n\t\t\t\t\t\t...(requestedScopes.includes(\"profile\") ? profile : {}),\n\t\t\t\t\t\t...(requestedScopes.includes(\"email\") ? email : {}),\n\t\t\t\t\t};\n\n\t\t\t\t\tconst additionalUserClaims = opts.getAdditionalUserInfoClaim\n\t\t\t\t\t\t? await opts.getAdditionalUserInfoClaim(\n\t\t\t\t\t\t\t\tuser,\n\t\t\t\t\t\t\t\trequestedScopes,\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: {};\n\n\t\t\t\t\tconst idToken = await new SignJWT({\n\t\t\t\t\t\tsub: user.id,\n\t\t\t\t\t\taud: client_id.toString(),\n\t\t\t\t\t\tiat: Date.now(),\n\t\t\t\t\t\tauth_time: ctx.context.session\n\t\t\t\t\t\t\t? new Date(ctx.context.session.session.createdAt).getTime()\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tnonce: value.nonce,\n\t\t\t\t\t\tacr: \"urn:mace:incommon:iap:silver\", // default to silver - ⚠︎ this should be configurable and should be validated against the client's metadata\n\t\t\t\t\t\t...userClaims,\n\t\t\t\t\t\t...additionalUserClaims,\n\t\t\t\t\t})\n\t\t\t\t\t\t.setProtectedHeader({ alg: secretKey.alg })\n\t\t\t\t\t\t.setIssuedAt()\n\t\t\t\t\t\t.setExpirationTime(\n\t\t\t\t\t\t\tMath.floor(Date.now() / 1000) + opts.accessTokenExpiresIn,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.sign(secretKey.key);\n\t\t\t\t\treturn ctx.json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taccess_token: accessToken,\n\t\t\t\t\t\t\ttoken_type: \"Bearer\",\n\t\t\t\t\t\t\texpires_in: opts.accessTokenExpiresIn,\n\t\t\t\t\t\t\trefresh_token: requestedScopes.includes(\"offline_access\")\n\t\t\t\t\t\t\t\t? refreshToken\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tscope: requestedScopes.join(\" \"),\n\t\t\t\t\t\t\tid_token: requestedScopes.includes(\"openid\")\n\t\t\t\t\t\t\t\t? idToken\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\t\t\tPragma: \"no-cache\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t),\n\t\t\tregisterMcpClient: createAuthEndpoint(\n\t\t\t\t\"/mcp/register\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: registerMcpClientBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Register an OAuth2 application\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\t\t\tdescription: \"OAuth2 application registered successfully\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Name of the OAuth2 application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\ticon: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Icon URL for the application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Additional metadata for the application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tclientId: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Unique identifier for the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tclientSecret: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Secret key for the client. Not included for public clients.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tredirectUrls: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\titems: { type: \"string\", format: \"uri\" },\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"List of allowed redirect URLs\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Type of the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"web\", \"public\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tauthenticationScheme: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Authentication scheme used by the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"client_secret\", \"none\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Whether the client is disabled\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [false],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tuserId: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"ID of the user who registered the client, null if registered anonymously\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tcreatedAt: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Creation timestamp\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tupdatedAt: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Last update timestamp\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\trequired: [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"clientId\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"redirectUrls\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"authenticationScheme\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"disabled\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"createdAt\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"updatedAt\",\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst body = ctx.body;\n\t\t\t\t\tconst session = await getSessionFromCtx(ctx);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t\t\t\"Content-Type, Authorization\",\n\t\t\t\t\t);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\t\t\t\t\tctx.headers?.set(\"Access-Control-Max-Age\", \"86400\");\n\t\t\t\t\tif (\n\t\t\t\t\t\t(!body.grant_types ||\n\t\t\t\t\t\t\tbody.grant_types.includes(\"authorization_code\") ||\n\t\t\t\t\t\t\tbody.grant_types.includes(\"implicit\")) &&\n\t\t\t\t\t\t(!body.redirect_uris || body.redirect_uris.length === 0)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror: \"invalid_redirect_uri\",\n\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\"Redirect URIs are required for authorization_code and implicit grant types\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (body.grant_types && body.response_types) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbody.grant_types.includes(\"authorization_code\") &&\n\t\t\t\t\t\t\t!body.response_types.includes(\"code\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror: \"invalid_client_metadata\",\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"When 'authorization_code' grant type is used, 'code' response type must be included\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbody.grant_types.includes(\"implicit\") &&\n\t\t\t\t\t\t\t!body.response_types.includes(\"token\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror: \"invalid_client_metadata\",\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"When 'implicit' grant type is used, 'token' response type must be included\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst clientId =\n\t\t\t\t\t\topts.generateClientId?.() || generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\tconst clientSecret =\n\t\t\t\t\t\topts.generateClientSecret?.() ||\n\t\t\t\t\t\tgenerateRandomString(32, \"a-z\", \"A-Z\");\n\n\t\t\t\t\t// Determine client type based on auth method\n\t\t\t\t\tconst clientType =\n\t\t\t\t\t\tbody.token_endpoint_auth_method === \"none\" ? \"public\" : \"web\";\n\t\t\t\t\tconst finalClientSecret = clientType === \"public\" ? \"\" : clientSecret;\n\n\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: modelName.oauthClient,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tname: body.client_name,\n\t\t\t\t\t\t\ticon: body.logo_uri,\n\t\t\t\t\t\t\tmetadata: body.metadata ? JSON.stringify(body.metadata) : null,\n\t\t\t\t\t\t\tclientId: clientId,\n\t\t\t\t\t\t\tclientSecret: finalClientSecret,\n\t\t\t\t\t\t\tredirectUrls: body.redirect_uris.join(\",\"),\n\t\t\t\t\t\t\ttype: clientType,\n\t\t\t\t\t\t\tauthenticationScheme:\n\t\t\t\t\t\t\t\tbody.token_endpoint_auth_method || \"client_secret_basic\",\n\t\t\t\t\t\t\tdisabled: false,\n\t\t\t\t\t\t\tuserId: session?.session.userId,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst responseData = {\n\t\t\t\t\t\tclient_id: clientId,\n\t\t\t\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t\t\t\t\tredirect_uris: body.redirect_uris,\n\t\t\t\t\t\ttoken_endpoint_auth_method:\n\t\t\t\t\t\t\tbody.token_endpoint_auth_method || \"client_secret_basic\",\n\t\t\t\t\t\tgrant_types: body.grant_types || [\"authorization_code\"],\n\t\t\t\t\t\tresponse_types: body.response_types || [\"code\"],\n\t\t\t\t\t\tclient_name: body.client_name,\n\t\t\t\t\t\tclient_uri: body.client_uri,\n\t\t\t\t\t\tlogo_uri: body.logo_uri,\n\t\t\t\t\t\tscope: body.scope,\n\t\t\t\t\t\tcontacts: body.contacts,\n\t\t\t\t\t\ttos_uri: body.tos_uri,\n\t\t\t\t\t\tpolicy_uri: body.policy_uri,\n\t\t\t\t\t\tjwks_uri: body.jwks_uri,\n\t\t\t\t\t\tjwks: body.jwks,\n\t\t\t\t\t\tsoftware_id: body.software_id,\n\t\t\t\t\t\tsoftware_version: body.software_version,\n\t\t\t\t\t\tsoftware_statement: body.software_statement,\n\t\t\t\t\t\tmetadata: body.metadata,\n\t\t\t\t\t\t...(clientType !== \"public\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tclient_secret: finalClientSecret,\n\t\t\t\t\t\t\t\t\tclient_secret_expires_at: 0, // 0 means it doesn't expire\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t};\n\n\t\t\t\t\treturn new Response(JSON.stringify(responseData), {\n\t\t\t\t\t\tstatus: 201,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\t\tPragma: \"no-cache\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetMcpSession: createAuthEndpoint(\n\t\t\t\t\"/mcp/get-session\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst accessToken = c.headers\n\t\t\t\t\t\t?.get(\"Authorization\")\n\t\t\t\t\t\t?.replace(\"Bearer \", \"\");\n\t\t\t\t\tif (!accessToken) {\n\t\t\t\t\t\tc.headers?.set(\"WWW-Authenticate\", \"Bearer\");\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t\tconst accessTokenData =\n\t\t\t\t\t\tawait c.context.adapter.findOne<OAuthAccessToken>({\n\t\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfield: \"accessToken\",\n\t\t\t\t\t\t\t\t\tvalue: accessToken,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\tif (!accessTokenData) {\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t\treturn c.json(accessTokenData);\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\tschema,\n\t} satisfies BetterAuthPlugin;\n};\n\nexport const withMcpAuth = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMcpSession: (...args: any) => Promise<OAuthAccessToken | null>;\n\t\t};\n\t\toptions: BetterAuthOptions;\n\t},\n>(\n\tauth: Auth,\n\thandler: (\n\t\treq: Request,\n\t\tsession: OAuthAccessToken,\n\t) => Response | Promise<Response>,\n) => {\n\treturn async (req: Request) => {\n\t\tconst baseURL = getBaseURL(auth.options.baseURL, auth.options.basePath);\n\t\tif (!baseURL && !isProduction) {\n\t\t\tlogger.warn(\"Unable to get the baseURL, please check your config!\");\n\t\t}\n\t\tconst session = await auth.api.getMcpSession({\n\t\t\theaders: req.headers,\n\t\t});\n\t\tconst wwwAuthenticateValue = `Bearer resource_metadata=\"${baseURL}/.well-known/oauth-protected-resource\"`;\n\t\tif (!session) {\n\t\t\treturn Response.json(\n\t\t\t\t{\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: -32000,\n\t\t\t\t\t\tmessage: \"Unauthorized: Authentication required\",\n\t\t\t\t\t\t\"www-authenticate\": wwwAuthenticateValue,\n\t\t\t\t\t},\n\t\t\t\t\tid: null,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tstatus: 401,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"WWW-Authenticate\": wwwAuthenticateValue,\n\t\t\t\t\t\t// we also add this headers otherwise browser based clients will not be able to read the `www-authenticate` header\n\t\t\t\t\t\t\"Access-Control-Expose-Headers\": \"WWW-Authenticate\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\treturn handler(req, session);\n\t};\n};\n\nexport const oAuthDiscoveryMetadata = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMcpOAuthConfig: (...args: any) => any;\n\t\t};\n\t},\n>(\n\tauth: Auth,\n) => {\n\treturn async (request: Request) => {\n\t\tconst res = await auth.api.getMcpOAuthConfig();\n\t\treturn new Response(JSON.stringify(res), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Max-Age\": \"86400\",\n\t\t\t},\n\t\t});\n\t};\n};\n\nexport const oAuthProtectedResourceMetadata = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMCPProtectedResource: (...args: any) => any;\n\t\t};\n\t},\n>(\n\tauth: Auth,\n) => {\n\treturn async (request: Request) => {\n\t\tconst res = await auth.api.getMCPProtectedResource();\n\t\treturn new Response(JSON.stringify(res), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Max-Age\": \"86400\",\n\t\t\t},\n\t\t});\n\t};\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["accessToken","accessTokenExpiresAt","refreshTokenExpiresAt"],"sources":["../../../src/plugins/mcp/index.ts"],"sourcesContent":["import type {\n\tBetterAuthOptions,\n\tBetterAuthPlugin,\n\tGenericEndpointContext,\n} from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport { isProduction, logger } from \"@better-auth/core/env\";\nimport { getWebcryptoSubtle } from \"@better-auth/utils\";\nimport { base64 } from \"@better-auth/utils/base64\";\nimport { createHash } from \"@better-auth/utils/hash\";\nimport { SignJWT } from \"jose\";\nimport * as z from \"zod\";\nimport { APIError, getSessionFromCtx } from \"../../api\";\nimport { parseSetCookieHeader } from \"../../cookies\";\nimport { generateRandomString } from \"../../crypto\";\nimport { HIDE_METADATA } from \"../../utils\";\nimport { getBaseURL } from \"../../utils/url\";\nimport type {\n\tClient,\n\tCodeVerificationValue,\n\tOAuthAccessToken,\n\tOIDCMetadata,\n\tOIDCOptions,\n} from \"../oidc-provider\";\nimport { oidcProvider } from \"../oidc-provider\";\nimport { schema } from \"../oidc-provider/schema\";\nimport { parsePrompt } from \"../oidc-provider/utils/prompt\";\nimport { authorizeMCPOAuth } from \"./authorize\";\n\ninterface MCPOptions {\n\tloginPage: string;\n\tresource?: string | undefined;\n\toidcConfig?: OIDCOptions | undefined;\n}\n\nexport const getMCPProviderMetadata = (\n\tctx: GenericEndpointContext,\n\toptions?: OIDCOptions | undefined,\n): OIDCMetadata => {\n\tconst issuer = ctx.context.options.baseURL as string;\n\tconst baseURL = ctx.context.baseURL;\n\tif (!issuer || !baseURL) {\n\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\terror: \"invalid_issuer\",\n\t\t\terror_description:\n\t\t\t\t\"issuer or baseURL is not set. If you're the app developer, please make sure to set the `baseURL` in your auth config.\",\n\t\t});\n\t}\n\treturn {\n\t\tissuer,\n\t\tauthorization_endpoint: `${baseURL}/mcp/authorize`,\n\t\ttoken_endpoint: `${baseURL}/mcp/token`,\n\t\tuserinfo_endpoint: `${baseURL}/mcp/userinfo`,\n\t\tjwks_uri: `${baseURL}/mcp/jwks`,\n\t\tregistration_endpoint: `${baseURL}/mcp/register`,\n\t\tscopes_supported: [\"openid\", \"profile\", \"email\", \"offline_access\"],\n\t\tresponse_types_supported: [\"code\"],\n\t\tresponse_modes_supported: [\"query\"],\n\t\tgrant_types_supported: [\"authorization_code\", \"refresh_token\"],\n\t\tacr_values_supported: [\n\t\t\t\"urn:mace:incommon:iap:silver\",\n\t\t\t\"urn:mace:incommon:iap:bronze\",\n\t\t],\n\t\tsubject_types_supported: [\"public\"],\n\t\tid_token_signing_alg_values_supported: [\"RS256\", \"none\"],\n\t\ttoken_endpoint_auth_methods_supported: [\n\t\t\t\"client_secret_basic\",\n\t\t\t\"client_secret_post\",\n\t\t\t\"none\",\n\t\t],\n\t\tcode_challenge_methods_supported: [\"S256\"],\n\t\tclaims_supported: [\n\t\t\t\"sub\",\n\t\t\t\"iss\",\n\t\t\t\"aud\",\n\t\t\t\"exp\",\n\t\t\t\"nbf\",\n\t\t\t\"iat\",\n\t\t\t\"jti\",\n\t\t\t\"email\",\n\t\t\t\"email_verified\",\n\t\t\t\"name\",\n\t\t],\n\t\t...options?.metadata,\n\t};\n};\n\nexport const getMCPProtectedResourceMetadata = (\n\tctx: GenericEndpointContext,\n\toptions?: MCPOptions | undefined,\n) => {\n\tconst baseURL = ctx.context.baseURL;\n\tconst origin = new URL(baseURL).origin;\n\n\treturn {\n\t\tresource: options?.resource ?? origin,\n\t\tauthorization_servers: [origin],\n\t\tjwks_uri: options?.oidcConfig?.metadata?.jwks_uri ?? `${baseURL}/mcp/jwks`,\n\t\tscopes_supported: options?.oidcConfig?.metadata?.scopes_supported ?? [\n\t\t\t\"openid\",\n\t\t\t\"profile\",\n\t\t\t\"email\",\n\t\t\t\"offline_access\",\n\t\t],\n\t\tbearer_methods_supported: [\"header\"],\n\t\tresource_signing_alg_values_supported: [\"RS256\", \"none\"],\n\t};\n};\n\nconst registerMcpClientBodySchema = z.object({\n\tredirect_uris: z.array(z.string()),\n\ttoken_endpoint_auth_method: z\n\t\t.enum([\"none\", \"client_secret_basic\", \"client_secret_post\"])\n\t\t.default(\"client_secret_basic\")\n\t\t.optional(),\n\tgrant_types: z\n\t\t.array(\n\t\t\tz.enum([\n\t\t\t\t\"authorization_code\",\n\t\t\t\t\"implicit\",\n\t\t\t\t\"password\",\n\t\t\t\t\"client_credentials\",\n\t\t\t\t\"refresh_token\",\n\t\t\t\t\"urn:ietf:params:oauth:grant-type:jwt-bearer\",\n\t\t\t\t\"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n\t\t\t]),\n\t\t)\n\t\t.default([\"authorization_code\"])\n\t\t.optional(),\n\tresponse_types: z\n\t\t.array(z.enum([\"code\", \"token\"]))\n\t\t.default([\"code\"])\n\t\t.optional(),\n\tclient_name: z.string().optional(),\n\tclient_uri: z.string().optional(),\n\tlogo_uri: z.string().optional(),\n\tscope: z.string().optional(),\n\tcontacts: z.array(z.string()).optional(),\n\ttos_uri: z.string().optional(),\n\tpolicy_uri: z.string().optional(),\n\tjwks_uri: z.string().optional(),\n\tjwks: z.record(z.string(), z.any()).optional(),\n\tmetadata: z.record(z.any(), z.any()).optional(),\n\tsoftware_id: z.string().optional(),\n\tsoftware_version: z.string().optional(),\n\tsoftware_statement: z.string().optional(),\n});\n\nconst mcpOAuthTokenBodySchema = z.record(z.any(), z.any());\n\nexport const mcp = (options: MCPOptions) => {\n\tconst opts = {\n\t\tcodeExpiresIn: 600,\n\t\tdefaultScope: \"openid\",\n\t\taccessTokenExpiresIn: 3600,\n\t\trefreshTokenExpiresIn: 604800,\n\t\tallowPlainCodeChallengeMethod: true,\n\t\t...options.oidcConfig,\n\t\tloginPage: options.loginPage,\n\t\tscopes: [\n\t\t\t\"openid\",\n\t\t\t\"profile\",\n\t\t\t\"email\",\n\t\t\t\"offline_access\",\n\t\t\t...(options.oidcConfig?.scopes || []),\n\t\t],\n\t};\n\tconst modelName = {\n\t\toauthClient: \"oauthApplication\",\n\t\toauthAccessToken: \"oauthAccessToken\",\n\t\toauthConsent: \"oauthConsent\",\n\t};\n\tconst provider = oidcProvider(opts);\n\treturn {\n\t\tid: \"mcp\",\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher() {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookie = await ctx.getSignedCookie(\n\t\t\t\t\t\t\t\"oidc_login_prompt\",\n\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst cookieName = ctx.context.authCookies.sessionToken.name;\n\t\t\t\t\t\tconst parsedSetCookieHeader = parseSetCookieHeader(\n\t\t\t\t\t\t\tctx.context.responseHeaders?.get(\"set-cookie\") || \"\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst hasSessionToken = parsedSetCookieHeader.has(cookieName);\n\t\t\t\t\t\tif (!cookie || !hasSessionToken) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tctx.setCookie(\"oidc_login_prompt\", \"\", {\n\t\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst sessionCookie = parsedSetCookieHeader.get(cookieName)?.value;\n\t\t\t\t\t\tconst sessionToken = sessionCookie?.split(\".\")[0]!;\n\t\t\t\t\t\tif (!sessionToken) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst session =\n\t\t\t\t\t\t\t(await ctx.context.internalAdapter.findSession(sessionToken)) ||\n\t\t\t\t\t\t\tctx.context.newSession;\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Remove \"login\" from prompt since user just logged in\n\t\t\t\t\t\tconst promptSet = parsePrompt(String(ctx.query?.prompt));\n\t\t\t\t\t\tif (promptSet.has(\"login\")) {\n\t\t\t\t\t\t\tconst newPromptSet = new Set(promptSet);\n\t\t\t\t\t\t\tnewPromptSet.delete(\"login\");\n\t\t\t\t\t\t\tctx.query = {\n\t\t\t\t\t\t\t\t...ctx.query,\n\t\t\t\t\t\t\t\tprompt: Array.from(newPromptSet).join(\" \"),\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.context.session = session;\n\t\t\t\t\t\tconst response = await authorizeMCPOAuth(ctx, opts);\n\t\t\t\t\t\treturn response;\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tendpoints: {\n\t\t\toAuthConsent: provider.endpoints.oAuthConsent,\n\t\t\tgetMcpOAuthConfig: createAuthEndpoint(\n\t\t\t\t\"/.well-known/oauth-authorization-server\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: HIDE_METADATA,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst metadata = getMCPProviderMetadata(c, options);\n\t\t\t\t\t\treturn c.json(metadata);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tconsole.log(e);\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetMCPProtectedResource: createAuthEndpoint(\n\t\t\t\t\"/.well-known/oauth-protected-resource\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tmetadata: HIDE_METADATA,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst metadata = getMCPProtectedResourceMetadata(c, options);\n\t\t\t\t\treturn c.json(metadata);\n\t\t\t\t},\n\t\t\t),\n\t\t\tmcpOAuthAuthorize: createAuthEndpoint(\n\t\t\t\t\"/mcp/authorize\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tquery: z.record(z.string(), z.any()),\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Authorize an OAuth2 request using MCP\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\t\t\tdescription: \"Authorization response generated successfully\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Authorization response, contents depend on the authorize function implementation\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\treturn authorizeMCPOAuth(ctx, opts);\n\t\t\t\t},\n\t\t\t),\n\t\t\tmcpOAuthToken: createAuthEndpoint(\n\t\t\t\t\"/mcp/token\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: mcpOAuthTokenBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t...HIDE_METADATA,\n\t\t\t\t\t\tallowedMediaTypes: [\n\t\t\t\t\t\t\t\"application/x-www-form-urlencoded\",\n\t\t\t\t\t\t\t\"application/json\",\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\t//cors\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t\t\t\"Content-Type, Authorization\",\n\t\t\t\t\t);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\n\t\t\t\t\tlet { body } = ctx;\n\t\t\t\t\tif (!body) {\n\t\t\t\t\t\tthrow ctx.error(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"request body not found\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (body instanceof FormData) {\n\t\t\t\t\t\tbody = Object.fromEntries(body.entries());\n\t\t\t\t\t}\n\t\t\t\t\tif (!(body instanceof Object)) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"request body is not an object\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tlet { client_id, client_secret } = body;\n\t\t\t\t\tconst authorization =\n\t\t\t\t\t\tctx.request?.headers.get(\"authorization\") || null;\n\t\t\t\t\tif (\n\t\t\t\t\t\tauthorization &&\n\t\t\t\t\t\t!client_id &&\n\t\t\t\t\t\t!client_secret &&\n\t\t\t\t\t\tauthorization.startsWith(\"Basic \")\n\t\t\t\t\t) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst encoded = authorization.replace(\"Basic \", \"\");\n\t\t\t\t\t\t\tconst decoded = new TextDecoder().decode(base64.decode(encoded));\n\t\t\t\t\t\t\tif (!decoded.includes(\":\")) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconst [id, secret] = decoded.split(\":\");\n\t\t\t\t\t\t\tif (!id || !secret) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tclient_id = id;\n\t\t\t\t\t\t\tclient_secret = secret;\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid authorization header format\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst {\n\t\t\t\t\t\tgrant_type,\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tredirect_uri,\n\t\t\t\t\t\trefresh_token,\n\t\t\t\t\t\tcode_verifier,\n\t\t\t\t\t} = body;\n\t\t\t\t\tif (grant_type === \"refresh_token\") {\n\t\t\t\t\t\tif (!refresh_token) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror_description: \"refresh_token is required\",\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst token = await ctx.context.adapter.findOne<OAuthAccessToken>({\n\t\t\t\t\t\t\tmodel: \"oauthAccessToken\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfield: \"refreshToken\",\n\t\t\t\t\t\t\t\t\tvalue: refresh_token.toString(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (!token) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid refresh token\",\n\t\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (token.clientId !== client_id?.toString()) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (token.refreshTokenExpiresAt < new Date()) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"refresh token expired\",\n\t\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst accessToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\t\tconst newRefreshToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\t\tconst accessTokenExpiresAt = new Date(\n\t\t\t\t\t\t\tDate.now() + opts.accessTokenExpiresIn * 1000,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst refreshTokenExpiresAt = new Date(\n\t\t\t\t\t\t\tDate.now() + opts.refreshTokenExpiresIn * 1000,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\taccessToken,\n\t\t\t\t\t\t\t\trefreshToken: newRefreshToken,\n\t\t\t\t\t\t\t\taccessTokenExpiresAt,\n\t\t\t\t\t\t\t\trefreshTokenExpiresAt,\n\t\t\t\t\t\t\t\tclientId: client_id.toString(),\n\t\t\t\t\t\t\t\tuserId: token.userId,\n\t\t\t\t\t\t\t\tscopes: token.scopes,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\t\taccess_token: accessToken,\n\t\t\t\t\t\t\ttoken_type: \"bearer\",\n\t\t\t\t\t\t\texpires_in: opts.accessTokenExpiresIn,\n\t\t\t\t\t\t\trefresh_token: newRefreshToken,\n\t\t\t\t\t\t\tscope: token.scopes,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!code) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (opts.requirePKCE && !code_verifier) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code verifier is missing\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * We need to check if the code is valid before we can proceed\n\t\t\t\t\t * with the rest of the request.\n\t\t\t\t\t */\n\t\t\t\t\tconst verificationValue =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findVerificationValue(\n\t\t\t\t\t\t\tcode.toString(),\n\t\t\t\t\t\t);\n\t\t\t\t\tif (!verificationValue) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid code\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (verificationValue.expiresAt < new Date()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"code expired\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteVerificationValue(\n\t\t\t\t\t\tverificationValue.id,\n\t\t\t\t\t);\n\n\t\t\t\t\tif (!client_id) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"client_id is required\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (!grant_type) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"grant_type is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (grant_type !== \"authorization_code\") {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"grant_type must be 'authorization_code'\",\n\t\t\t\t\t\t\terror: \"unsupported_grant_type\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!redirect_uri) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"redirect_uri is required\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst client = await ctx.context.adapter\n\t\t\t\t\t\t.findOne<Record<string, any>>({\n\t\t\t\t\t\t\tmodel: modelName.oauthClient,\n\t\t\t\t\t\t\twhere: [{ field: \"clientId\", value: client_id.toString() }],\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.then((res) => {\n\t\t\t\t\t\t\tif (!res) {\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...res,\n\t\t\t\t\t\t\t\tredirectUrls: res.redirectUrls.split(\",\"),\n\t\t\t\t\t\t\t\tmetadata: res.metadata ? JSON.parse(res.metadata) : {},\n\t\t\t\t\t\t\t} as Client;\n\t\t\t\t\t\t});\n\t\t\t\t\tif (!client) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (client.disabled) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"client is disabled\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// For public clients (type: 'public'), validate PKCE instead of client_secret\n\t\t\t\t\tif (client.type === \"public\") {\n\t\t\t\t\t\t// Public clients must use PKCE\n\t\t\t\t\t\tif (!code_verifier) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"code verifier is required for public clients\",\n\t\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// PKCE validation happens later in the flow, so we skip client_secret validation\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// For confidential clients, validate client_secret\n\t\t\t\t\t\tif (!client_secret) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"client_secret is required for confidential clients\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst isValidSecret =\n\t\t\t\t\t\t\tclient.clientSecret === client_secret.toString();\n\t\t\t\t\t\tif (!isValidSecret) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\terror_description: \"invalid client_secret\",\n\t\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst value = JSON.parse(\n\t\t\t\t\t\tverificationValue.value,\n\t\t\t\t\t) as CodeVerificationValue;\n\t\t\t\t\tif (value.clientId !== client_id.toString()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid client_id\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (value.redirectURI !== redirect_uri.toString()) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"invalid redirect_uri\",\n\t\t\t\t\t\t\terror: \"invalid_client\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tif (value.codeChallenge && !code_verifier) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror_description: \"code verifier is missing\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst challenge =\n\t\t\t\t\t\tvalue.codeChallengeMethod === \"plain\"\n\t\t\t\t\t\t\t? code_verifier\n\t\t\t\t\t\t\t: await createHash(\"SHA-256\", \"base64urlnopad\").digest(\n\t\t\t\t\t\t\t\t\tcode_verifier,\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\tif (challenge !== value.codeChallenge) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"code verification failed\",\n\t\t\t\t\t\t\terror: \"invalid_request\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst requestedScopes = value.scope;\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteVerificationValue(\n\t\t\t\t\t\tverificationValue.id,\n\t\t\t\t\t);\n\t\t\t\t\tconst accessToken = generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\tconst refreshToken = generateRandomString(32, \"A-Z\", \"a-z\");\n\t\t\t\t\tconst accessTokenExpiresAt = new Date(\n\t\t\t\t\t\tDate.now() + opts.accessTokenExpiresIn * 1000,\n\t\t\t\t\t);\n\t\t\t\t\tconst refreshTokenExpiresAt = new Date(\n\t\t\t\t\t\tDate.now() + opts.refreshTokenExpiresIn * 1000,\n\t\t\t\t\t);\n\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\taccessToken,\n\t\t\t\t\t\t\trefreshToken,\n\t\t\t\t\t\t\taccessTokenExpiresAt,\n\t\t\t\t\t\t\trefreshTokenExpiresAt,\n\t\t\t\t\t\t\tclientId: client_id.toString(),\n\t\t\t\t\t\t\tuserId: value.userId,\n\t\t\t\t\t\t\tscopes: requestedScopes.join(\" \"),\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tconst user = await ctx.context.internalAdapter.findUserById(\n\t\t\t\t\t\tvalue.userId,\n\t\t\t\t\t);\n\t\t\t\t\tif (!user) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\terror_description: \"user not found\",\n\t\t\t\t\t\t\terror: \"invalid_grant\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tlet secretKey = {\n\t\t\t\t\t\talg: \"HS256\",\n\t\t\t\t\t\tkey: await getWebcryptoSubtle().generateKey(\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: \"HMAC\",\n\t\t\t\t\t\t\t\thash: \"SHA-256\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\ttrue,\n\t\t\t\t\t\t\t[\"sign\", \"verify\"],\n\t\t\t\t\t\t),\n\t\t\t\t\t};\n\t\t\t\t\tconst profile = {\n\t\t\t\t\t\tgiven_name: user.name.split(\" \")[0]!,\n\t\t\t\t\t\tfamily_name: user.name.split(\" \")[1]!,\n\t\t\t\t\t\tname: user.name,\n\t\t\t\t\t\tprofile: user.image,\n\t\t\t\t\t\tupdated_at: Math.floor(new Date(user.updatedAt).getTime() / 1000),\n\t\t\t\t\t};\n\t\t\t\t\tconst email = {\n\t\t\t\t\t\temail: user.email,\n\t\t\t\t\t\temail_verified: user.emailVerified,\n\t\t\t\t\t};\n\t\t\t\t\tconst userClaims = {\n\t\t\t\t\t\t...(requestedScopes.includes(\"profile\") ? profile : {}),\n\t\t\t\t\t\t...(requestedScopes.includes(\"email\") ? email : {}),\n\t\t\t\t\t};\n\n\t\t\t\t\tconst additionalUserClaims = opts.getAdditionalUserInfoClaim\n\t\t\t\t\t\t? await opts.getAdditionalUserInfoClaim(\n\t\t\t\t\t\t\t\tuser,\n\t\t\t\t\t\t\t\trequestedScopes,\n\t\t\t\t\t\t\t\tclient,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: {};\n\n\t\t\t\t\tconst idToken = await new SignJWT({\n\t\t\t\t\t\tsub: user.id,\n\t\t\t\t\t\taud: client_id.toString(),\n\t\t\t\t\t\tiat: Date.now(),\n\t\t\t\t\t\tauth_time: ctx.context.session\n\t\t\t\t\t\t\t? new Date(ctx.context.session.session.createdAt).getTime()\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\tnonce: value.nonce,\n\t\t\t\t\t\tacr: \"urn:mace:incommon:iap:silver\", // default to silver - ⚠︎ this should be configurable and should be validated against the client's metadata\n\t\t\t\t\t\t...userClaims,\n\t\t\t\t\t\t...additionalUserClaims,\n\t\t\t\t\t})\n\t\t\t\t\t\t.setProtectedHeader({ alg: secretKey.alg })\n\t\t\t\t\t\t.setIssuedAt()\n\t\t\t\t\t\t.setExpirationTime(\n\t\t\t\t\t\t\tMath.floor(Date.now() / 1000) + opts.accessTokenExpiresIn,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.sign(secretKey.key);\n\t\t\t\t\treturn ctx.json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taccess_token: accessToken,\n\t\t\t\t\t\t\ttoken_type: \"Bearer\",\n\t\t\t\t\t\t\texpires_in: opts.accessTokenExpiresIn,\n\t\t\t\t\t\t\trefresh_token: requestedScopes.includes(\"offline_access\")\n\t\t\t\t\t\t\t\t? refreshToken\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t\tscope: requestedScopes.join(\" \"),\n\t\t\t\t\t\t\tid_token: requestedScopes.includes(\"openid\")\n\t\t\t\t\t\t\t\t? idToken\n\t\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\t\t\tPragma: \"no-cache\",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t),\n\t\t\tregisterMcpClient: createAuthEndpoint(\n\t\t\t\t\"/mcp/register\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: registerMcpClientBodySchema,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Register an OAuth2 application\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\t\t\tdescription: \"OAuth2 application registered successfully\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tname: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Name of the OAuth2 application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\ticon: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Icon URL for the application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tmetadata: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tadditionalProperties: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Additional metadata for the application\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tclientId: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Unique identifier for the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tclientSecret: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Secret key for the client. Not included for public clients.\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tredirectUrls: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"array\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\titems: { type: \"string\", format: \"uri\" },\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"List of allowed redirect URLs\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\ttype: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Type of the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"web\", \"public\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tauthenticationScheme: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Authentication scheme used by the client\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [\"client_secret\", \"none\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tdisabled: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Whether the client is disabled\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tenum: [false],\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tuserId: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tnullable: true,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"ID of the user who registered the client, null if registered anonymously\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tcreatedAt: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Creation timestamp\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\tupdatedAt: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tformat: \"date-time\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tdescription: \"Last update timestamp\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\trequired: [\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"name\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"clientId\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"redirectUrls\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"type\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"authenticationScheme\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"disabled\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"createdAt\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"updatedAt\",\n\t\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst body = ctx.body;\n\t\t\t\t\tconst session = await getSessionFromCtx(ctx);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\t\t\t\t\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\t\t\t\t\tctx.setHeader(\n\t\t\t\t\t\t\"Access-Control-Allow-Headers\",\n\t\t\t\t\t\t\"Content-Type, Authorization\",\n\t\t\t\t\t);\n\t\t\t\t\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\t\t\t\t\tctx.headers?.set(\"Access-Control-Max-Age\", \"86400\");\n\t\t\t\t\tif (\n\t\t\t\t\t\t(!body.grant_types ||\n\t\t\t\t\t\t\tbody.grant_types.includes(\"authorization_code\") ||\n\t\t\t\t\t\t\tbody.grant_types.includes(\"implicit\")) &&\n\t\t\t\t\t\t(!body.redirect_uris || body.redirect_uris.length === 0)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\terror: \"invalid_redirect_uri\",\n\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\"Redirect URIs are required for authorization_code and implicit grant types\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (body.grant_types && body.response_types) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbody.grant_types.includes(\"authorization_code\") &&\n\t\t\t\t\t\t\t!body.response_types.includes(\"code\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror: \"invalid_client_metadata\",\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"When 'authorization_code' grant type is used, 'code' response type must be included\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tbody.grant_types.includes(\"implicit\") &&\n\t\t\t\t\t\t\t!body.response_types.includes(\"token\")\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\terror: \"invalid_client_metadata\",\n\t\t\t\t\t\t\t\terror_description:\n\t\t\t\t\t\t\t\t\t\"When 'implicit' grant type is used, 'token' response type must be included\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst clientId =\n\t\t\t\t\t\topts.generateClientId?.() || generateRandomString(32, \"a-z\", \"A-Z\");\n\t\t\t\t\tconst clientSecret =\n\t\t\t\t\t\topts.generateClientSecret?.() ||\n\t\t\t\t\t\tgenerateRandomString(32, \"a-z\", \"A-Z\");\n\n\t\t\t\t\t// Determine client type based on auth method\n\t\t\t\t\tconst clientType =\n\t\t\t\t\t\tbody.token_endpoint_auth_method === \"none\" ? \"public\" : \"web\";\n\t\t\t\t\tconst finalClientSecret = clientType === \"public\" ? \"\" : clientSecret;\n\n\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\tmodel: modelName.oauthClient,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tname: body.client_name,\n\t\t\t\t\t\t\ticon: body.logo_uri,\n\t\t\t\t\t\t\tmetadata: body.metadata ? JSON.stringify(body.metadata) : null,\n\t\t\t\t\t\t\tclientId: clientId,\n\t\t\t\t\t\t\tclientSecret: finalClientSecret,\n\t\t\t\t\t\t\tredirectUrls: body.redirect_uris.join(\",\"),\n\t\t\t\t\t\t\ttype: clientType,\n\t\t\t\t\t\t\tauthenticationScheme:\n\t\t\t\t\t\t\t\tbody.token_endpoint_auth_method || \"client_secret_basic\",\n\t\t\t\t\t\t\tdisabled: false,\n\t\t\t\t\t\t\tuserId: session?.session.userId,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst responseData = {\n\t\t\t\t\t\tclient_id: clientId,\n\t\t\t\t\t\tclient_id_issued_at: Math.floor(Date.now() / 1000),\n\t\t\t\t\t\tredirect_uris: body.redirect_uris,\n\t\t\t\t\t\ttoken_endpoint_auth_method:\n\t\t\t\t\t\t\tbody.token_endpoint_auth_method || \"client_secret_basic\",\n\t\t\t\t\t\tgrant_types: body.grant_types || [\"authorization_code\"],\n\t\t\t\t\t\tresponse_types: body.response_types || [\"code\"],\n\t\t\t\t\t\tclient_name: body.client_name,\n\t\t\t\t\t\tclient_uri: body.client_uri,\n\t\t\t\t\t\tlogo_uri: body.logo_uri,\n\t\t\t\t\t\tscope: body.scope,\n\t\t\t\t\t\tcontacts: body.contacts,\n\t\t\t\t\t\ttos_uri: body.tos_uri,\n\t\t\t\t\t\tpolicy_uri: body.policy_uri,\n\t\t\t\t\t\tjwks_uri: body.jwks_uri,\n\t\t\t\t\t\tjwks: body.jwks,\n\t\t\t\t\t\tsoftware_id: body.software_id,\n\t\t\t\t\t\tsoftware_version: body.software_version,\n\t\t\t\t\t\tsoftware_statement: body.software_statement,\n\t\t\t\t\t\tmetadata: body.metadata,\n\t\t\t\t\t\t...(clientType !== \"public\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\tclient_secret: finalClientSecret,\n\t\t\t\t\t\t\t\t\tclient_secret_expires_at: 0, // 0 means it doesn't expire\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t};\n\n\t\t\t\t\treturn new Response(JSON.stringify(responseData), {\n\t\t\t\t\t\tstatus: 201,\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\t\t\t\t\tPragma: \"no-cache\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetMcpSession: createAuthEndpoint(\n\t\t\t\t\"/mcp/get-session\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (c) => {\n\t\t\t\t\tconst accessToken = c.headers\n\t\t\t\t\t\t?.get(\"Authorization\")\n\t\t\t\t\t\t?.replace(\"Bearer \", \"\");\n\t\t\t\t\tif (!accessToken) {\n\t\t\t\t\t\tc.headers?.set(\"WWW-Authenticate\", \"Bearer\");\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t\tconst accessTokenData =\n\t\t\t\t\t\tawait c.context.adapter.findOne<OAuthAccessToken>({\n\t\t\t\t\t\t\tmodel: modelName.oauthAccessToken,\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfield: \"accessToken\",\n\t\t\t\t\t\t\t\t\tvalue: accessToken,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\tif (!accessTokenData) {\n\t\t\t\t\t\treturn c.json(null);\n\t\t\t\t\t}\n\t\t\t\t\treturn c.json(accessTokenData);\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\tschema,\n\t\toptions,\n\t} satisfies BetterAuthPlugin;\n};\n\nexport const withMcpAuth = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMcpSession: (...args: any) => Promise<OAuthAccessToken | null>;\n\t\t};\n\t\toptions: BetterAuthOptions;\n\t},\n>(\n\tauth: Auth,\n\thandler: (\n\t\treq: Request,\n\t\tsession: OAuthAccessToken,\n\t) => Response | Promise<Response>,\n) => {\n\treturn async (req: Request) => {\n\t\tconst baseURL = getBaseURL(auth.options.baseURL, auth.options.basePath);\n\t\tif (!baseURL && !isProduction) {\n\t\t\tlogger.warn(\"Unable to get the baseURL, please check your config!\");\n\t\t}\n\t\tconst session = await auth.api.getMcpSession({\n\t\t\theaders: req.headers,\n\t\t});\n\t\tconst wwwAuthenticateValue = `Bearer resource_metadata=\"${baseURL}/.well-known/oauth-protected-resource\"`;\n\t\tif (!session) {\n\t\t\treturn Response.json(\n\t\t\t\t{\n\t\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcode: -32000,\n\t\t\t\t\t\tmessage: \"Unauthorized: Authentication required\",\n\t\t\t\t\t\t\"www-authenticate\": wwwAuthenticateValue,\n\t\t\t\t\t},\n\t\t\t\t\tid: null,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tstatus: 401,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t\"WWW-Authenticate\": wwwAuthenticateValue,\n\t\t\t\t\t\t// we also add this headers otherwise browser based clients will not be able to read the `www-authenticate` header\n\t\t\t\t\t\t\"Access-Control-Expose-Headers\": \"WWW-Authenticate\",\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\treturn handler(req, session);\n\t};\n};\n\nexport const oAuthDiscoveryMetadata = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMcpOAuthConfig: (...args: any) => any;\n\t\t};\n\t},\n>(\n\tauth: Auth,\n) => {\n\treturn async (request: Request) => {\n\t\tconst res = await auth.api.getMcpOAuthConfig();\n\t\treturn new Response(JSON.stringify(res), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Max-Age\": \"86400\",\n\t\t\t},\n\t\t});\n\t};\n};\n\nexport const oAuthProtectedResourceMetadata = <\n\tAuth extends {\n\t\tapi: {\n\t\t\tgetMCPProtectedResource: (...args: any) => any;\n\t\t};\n\t},\n>(\n\tauth: Auth,\n) => {\n\treturn async (request: Request) => {\n\t\tconst res = await auth.api.getMCPProtectedResource();\n\t\treturn new Response(JSON.stringify(res), {\n\t\t\tstatus: 200,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\t\"Access-Control-Allow-Origin\": \"*\",\n\t\t\t\t\"Access-Control-Allow-Methods\": \"POST, OPTIONS\",\n\t\t\t\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\t\t\t\"Access-Control-Max-Age\": \"86400\",\n\t\t\t},\n\t\t});\n\t};\n};\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
- import * as _better_auth_core9 from "@better-auth/core";
1
+ import * as _better_auth_core8 from "@better-auth/core";
2
2
  import * as _better_auth_core_db0 from "@better-auth/core/db";
3
3
  import * as z from "zod";
4
- import * as better_call167 from "better-call";
4
+ import * as better_call157 from "better-call";
5
5
 
6
6
  //#region src/plugins/multi-session/index.d.ts
7
7
  interface MultiSessionConfig {
@@ -30,7 +30,7 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
30
30
  *
31
31
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-list-device-sessions)
32
32
  */
33
- listDeviceSessions: better_call167.StrictEndpoint<"/multi-session/list-device-sessions", {
33
+ listDeviceSessions: better_call157.StrictEndpoint<"/multi-session/list-device-sessions", {
34
34
  method: "GET";
35
35
  requireHeaders: true;
36
36
  }, {
@@ -52,13 +52,13 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
52
52
  *
53
53
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-set-active)
54
54
  */
55
- setActiveSession: better_call167.StrictEndpoint<"/multi-session/set-active", {
55
+ setActiveSession: better_call157.StrictEndpoint<"/multi-session/set-active", {
56
56
  method: "POST";
57
57
  body: z.ZodObject<{
58
58
  sessionToken: z.ZodString;
59
59
  }, z.core.$strip>;
60
60
  requireHeaders: true;
61
- use: ((inputContext: better_call167.MiddlewareInputContext<better_call167.MiddlewareOptions>) => Promise<{
61
+ use: ((inputContext: better_call157.MiddlewareInputContext<better_call157.MiddlewareOptions>) => Promise<{
62
62
  session: {
63
63
  session: Record<string, any> & {
64
64
  id: string;
@@ -122,13 +122,13 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
122
122
  *
123
123
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-revoke)
124
124
  */
125
- revokeDeviceSession: better_call167.StrictEndpoint<"/multi-session/revoke", {
125
+ revokeDeviceSession: better_call157.StrictEndpoint<"/multi-session/revoke", {
126
126
  method: "POST";
127
127
  body: z.ZodObject<{
128
128
  sessionToken: z.ZodString;
129
129
  }, z.core.$strip>;
130
130
  requireHeaders: true;
131
- use: ((inputContext: better_call167.MiddlewareInputContext<better_call167.MiddlewareOptions>) => Promise<{
131
+ use: ((inputContext: better_call157.MiddlewareInputContext<better_call157.MiddlewareOptions>) => Promise<{
132
132
  session: {
133
133
  session: Record<string, any> & {
134
134
  id: string;
@@ -179,10 +179,11 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
179
179
  };
180
180
  hooks: {
181
181
  after: {
182
- matcher: (context: _better_auth_core9.HookEndpointContext) => boolean;
183
- handler: (inputContext: better_call167.MiddlewareInputContext<better_call167.MiddlewareOptions>) => Promise<void>;
182
+ matcher: (context: _better_auth_core8.HookEndpointContext) => boolean;
183
+ handler: (inputContext: better_call157.MiddlewareInputContext<better_call157.MiddlewareOptions>) => Promise<void>;
184
184
  }[];
185
185
  };
186
+ options: MultiSessionConfig | undefined;
186
187
  $ERROR_CODES: {
187
188
  readonly INVALID_SESSION_TOKEN: "Invalid session token";
188
189
  };
@@ -141,6 +141,7 @@ const multiSession = (options) => {
141
141
  if (verifiedTokens.length > 0) await ctx.context.internalAdapter.deleteSessions(verifiedTokens);
142
142
  })
143
143
  }] },
144
+ options,
144
145
  $ERROR_CODES: ERROR_CODES
145
146
  };
146
147
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/multi-session/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport { defineErrorCodes } from \"@better-auth/core/utils\";\nimport * as z from \"zod\";\nimport { APIError, sessionMiddleware } from \"../../api\";\nimport {\n\tdeleteSessionCookie,\n\tparseCookies,\n\tparseSetCookieHeader,\n\tsetSessionCookie,\n} from \"../../cookies\";\n\nexport interface MultiSessionConfig {\n\t/**\n\t * The maximum number of sessions a user can have\n\t * at a time\n\t * @default 5\n\t */\n\tmaximumSessions?: number | undefined;\n}\n\nconst ERROR_CODES = defineErrorCodes({\n\tINVALID_SESSION_TOKEN: \"Invalid session token\",\n});\n\nconst setActiveSessionBodySchema = z.object({\n\tsessionToken: z.string().meta({\n\t\tdescription: \"The session token to set as active\",\n\t}),\n});\n\nconst revokeDeviceSessionBodySchema = z.object({\n\tsessionToken: z.string().meta({\n\t\tdescription: \"The session token to revoke\",\n\t}),\n});\n\nexport const multiSession = (options?: MultiSessionConfig | undefined) => {\n\tconst opts = {\n\t\tmaximumSessions: 5,\n\t\t...options,\n\t};\n\n\tconst isMultiSessionCookie = (key: string) => key.includes(\"_multi-\");\n\n\treturn {\n\t\tid: \"multi-session\",\n\t\tendpoints: {\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * GET `/multi-session/list-device-sessions`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.listDeviceSessions`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.listDeviceSessions`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-list-device-sessions)\n\t\t\t */\n\t\t\tlistDeviceSessions: createAuthEndpoint(\n\t\t\t\t\"/multi-session/list-device-sessions\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\tif (!cookieHeader) return ctx.json([]);\n\n\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\t\t\t\t\tconst sessionTokens = (\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tObject.entries(cookies)\n\t\t\t\t\t\t\t\t.filter(([key]) => isMultiSessionCookie(key))\n\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\tasync ([key]) =>\n\t\t\t\t\t\t\t\t\t\tawait ctx.getSignedCookie(key, ctx.context.secret),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\n\t\t\t\t\tif (!sessionTokens.length) return ctx.json([]);\n\t\t\t\t\tconst sessions =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findSessions(sessionTokens);\n\t\t\t\t\tconst validSessions = sessions.filter(\n\t\t\t\t\t\t(session) => session && session.session.expiresAt > new Date(),\n\t\t\t\t\t);\n\t\t\t\t\tconst uniqueUserSessions = validSessions.reduce(\n\t\t\t\t\t\t(acc, session) => {\n\t\t\t\t\t\t\tif (!acc.find((s) => s.user.id === session.user.id)) {\n\t\t\t\t\t\t\t\tacc.push(session);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn acc;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[] as typeof validSessions,\n\t\t\t\t\t);\n\t\t\t\t\treturn ctx.json(uniqueUserSessions);\n\t\t\t\t},\n\t\t\t),\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * POST `/multi-session/set-active`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.setActiveSession`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.setActive`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-set-active)\n\t\t\t */\n\t\t\tsetActiveSession: createAuthEndpoint(\n\t\t\t\t\"/multi-session/set-active\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: setActiveSessionBodySchema,\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Set the active session\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsession: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$ref: \"#/components/schemas/Session\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst sessionToken = ctx.body.sessionToken;\n\t\t\t\t\tconst multiSessionCookieName = `${\n\t\t\t\t\t\tctx.context.authCookies.sessionToken.name\n\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\t\t\t\t\tconst sessionCookie = await ctx.getSignedCookie(\n\t\t\t\t\t\tmultiSessionCookieName,\n\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t);\n\t\t\t\t\tif (!sessionCookie) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: ERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst session =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findSession(sessionToken);\n\t\t\t\t\tif (!session || session.session.expiresAt < new Date()) {\n\t\t\t\t\t\tctx.setCookie(multiSessionCookieName, \"\", {\n\t\t\t\t\t\t\t...ctx.context.authCookies.sessionToken.options,\n\t\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: ERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tawait setSessionCookie(ctx, session);\n\t\t\t\t\treturn ctx.json(session);\n\t\t\t\t},\n\t\t\t),\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * POST `/multi-session/revoke`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.revokeDeviceSession`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.revoke`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-revoke)\n\t\t\t */\n\t\t\trevokeDeviceSession: createAuthEndpoint(\n\t\t\t\t\"/multi-session/revoke\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: revokeDeviceSessionBodySchema,\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Revoke a device session\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst sessionToken = ctx.body.sessionToken;\n\t\t\t\t\tconst multiSessionCookieName = `${\n\t\t\t\t\t\tctx.context.authCookies.sessionToken.name\n\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\t\t\t\t\tconst sessionCookie = await ctx.getSignedCookie(\n\t\t\t\t\t\tmultiSessionCookieName,\n\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t);\n\t\t\t\t\tif (!sessionCookie) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: ERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteSession(sessionToken);\n\t\t\t\t\tctx.setCookie(multiSessionCookieName, \"\", {\n\t\t\t\t\t\t...ctx.context.authCookies.sessionToken.options,\n\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t});\n\t\t\t\t\tconst isActive = ctx.context.session?.session.token === sessionToken;\n\t\t\t\t\tif (!isActive) return ctx.json({ status: true });\n\n\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\tif (cookieHeader) {\n\t\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\n\t\t\t\t\t\tconst sessionTokens = (\n\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\tObject.entries(cookies)\n\t\t\t\t\t\t\t\t\t.filter(([key]) => isMultiSessionCookie(key))\n\t\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t\tasync ([key]) =>\n\t\t\t\t\t\t\t\t\t\t\tawait ctx.getSignedCookie(key, ctx.context.secret),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\t\t\t\t\t\tconst internalAdapter = ctx.context.internalAdapter;\n\n\t\t\t\t\t\tif (sessionTokens.length > 0) {\n\t\t\t\t\t\t\tconst sessions =\n\t\t\t\t\t\t\t\tawait internalAdapter.findSessions(sessionTokens);\n\t\t\t\t\t\t\tconst validSessions = sessions.filter(\n\t\t\t\t\t\t\t\t(session) => session && session.session.expiresAt > new Date(),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (validSessions.length > 0) {\n\t\t\t\t\t\t\t\tconst nextSession = validSessions[0]!;\n\t\t\t\t\t\t\t\tawait setSessionCookie(ctx, nextSession);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t}\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tstatus: true,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher: () => true,\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookieString = ctx.context.responseHeaders?.get(\"set-cookie\");\n\t\t\t\t\t\tif (!cookieString) return;\n\t\t\t\t\t\tconst setCookies = parseSetCookieHeader(cookieString);\n\t\t\t\t\t\tconst sessionCookieConfig = ctx.context.authCookies.sessionToken;\n\t\t\t\t\t\tconst sessionToken = ctx.context.newSession?.session.token;\n\t\t\t\t\t\tif (!sessionToken) return;\n\t\t\t\t\t\tconst cookies = parseCookies(ctx.headers?.get(\"cookie\") || \"\");\n\n\t\t\t\t\t\tconst cookieName = `${\n\t\t\t\t\t\t\tsessionCookieConfig.name\n\t\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\n\t\t\t\t\t\tif (setCookies.get(cookieName) || cookies.get(cookieName)) return;\n\n\t\t\t\t\t\tconst currentMultiSessions =\n\t\t\t\t\t\t\tObject.keys(Object.fromEntries(cookies)).filter(\n\t\t\t\t\t\t\t\tisMultiSessionCookie,\n\t\t\t\t\t\t\t).length + (cookieString.includes(\"session_token\") ? 1 : 0);\n\n\t\t\t\t\t\tif (currentMultiSessions >= opts.maximumSessions) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait ctx.setSignedCookie(\n\t\t\t\t\t\t\tcookieName,\n\t\t\t\t\t\t\tsessionToken,\n\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t\tsessionCookieConfig.options,\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmatcher: (context) => context.path === \"/sign-out\",\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\t\tif (!cookieHeader) return;\n\t\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\t\t\t\t\t\tconst multiSessionKeys = Object.keys(cookies).filter((key) =>\n\t\t\t\t\t\t\tisMultiSessionCookie(key),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst verifiedTokens = (\n\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\tmultiSessionKeys.map(async (key) => {\n\t\t\t\t\t\t\t\t\tconst verifiedToken = await ctx.getSignedCookie(\n\t\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tif (verifiedToken) {\n\t\t\t\t\t\t\t\t\t\tctx.setCookie(\n\t\t\t\t\t\t\t\t\t\t\tkey.toLowerCase().replace(\"__secure-\", \"__Secure-\"),\n\t\t\t\t\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t...ctx.context.authCookies.sessionToken.options,\n\t\t\t\t\t\t\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\treturn verifiedToken;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\t\t\t\t\t\tif (verifiedTokens.length > 0) {\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.deleteSessions(verifiedTokens);\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t$ERROR_CODES: ERROR_CODES,\n\t} satisfies BetterAuthPlugin;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/multi-session/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport {\n\tcreateAuthEndpoint,\n\tcreateAuthMiddleware,\n} from \"@better-auth/core/api\";\nimport { defineErrorCodes } from \"@better-auth/core/utils\";\nimport * as z from \"zod\";\nimport { APIError, sessionMiddleware } from \"../../api\";\nimport {\n\tdeleteSessionCookie,\n\tparseCookies,\n\tparseSetCookieHeader,\n\tsetSessionCookie,\n} from \"../../cookies\";\n\nexport interface MultiSessionConfig {\n\t/**\n\t * The maximum number of sessions a user can have\n\t * at a time\n\t * @default 5\n\t */\n\tmaximumSessions?: number | undefined;\n}\n\nconst ERROR_CODES = defineErrorCodes({\n\tINVALID_SESSION_TOKEN: \"Invalid session token\",\n});\n\nconst setActiveSessionBodySchema = z.object({\n\tsessionToken: z.string().meta({\n\t\tdescription: \"The session token to set as active\",\n\t}),\n});\n\nconst revokeDeviceSessionBodySchema = z.object({\n\tsessionToken: z.string().meta({\n\t\tdescription: \"The session token to revoke\",\n\t}),\n});\n\nexport const multiSession = (options?: MultiSessionConfig | undefined) => {\n\tconst opts = {\n\t\tmaximumSessions: 5,\n\t\t...options,\n\t};\n\n\tconst isMultiSessionCookie = (key: string) => key.includes(\"_multi-\");\n\n\treturn {\n\t\tid: \"multi-session\",\n\t\tendpoints: {\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * GET `/multi-session/list-device-sessions`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.listDeviceSessions`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.listDeviceSessions`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-list-device-sessions)\n\t\t\t */\n\t\t\tlistDeviceSessions: createAuthEndpoint(\n\t\t\t\t\"/multi-session/list-device-sessions\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\tif (!cookieHeader) return ctx.json([]);\n\n\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\t\t\t\t\tconst sessionTokens = (\n\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\tObject.entries(cookies)\n\t\t\t\t\t\t\t\t.filter(([key]) => isMultiSessionCookie(key))\n\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\tasync ([key]) =>\n\t\t\t\t\t\t\t\t\t\tawait ctx.getSignedCookie(key, ctx.context.secret),\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\n\t\t\t\t\tif (!sessionTokens.length) return ctx.json([]);\n\t\t\t\t\tconst sessions =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findSessions(sessionTokens);\n\t\t\t\t\tconst validSessions = sessions.filter(\n\t\t\t\t\t\t(session) => session && session.session.expiresAt > new Date(),\n\t\t\t\t\t);\n\t\t\t\t\tconst uniqueUserSessions = validSessions.reduce(\n\t\t\t\t\t\t(acc, session) => {\n\t\t\t\t\t\t\tif (!acc.find((s) => s.user.id === session.user.id)) {\n\t\t\t\t\t\t\t\tacc.push(session);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn acc;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t[] as typeof validSessions,\n\t\t\t\t\t);\n\t\t\t\t\treturn ctx.json(uniqueUserSessions);\n\t\t\t\t},\n\t\t\t),\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * POST `/multi-session/set-active`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.setActiveSession`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.setActive`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-set-active)\n\t\t\t */\n\t\t\tsetActiveSession: createAuthEndpoint(\n\t\t\t\t\"/multi-session/set-active\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: setActiveSessionBodySchema,\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Set the active session\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tsession: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$ref: \"#/components/schemas/Session\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst sessionToken = ctx.body.sessionToken;\n\t\t\t\t\tconst multiSessionCookieName = `${\n\t\t\t\t\t\tctx.context.authCookies.sessionToken.name\n\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\t\t\t\t\tconst sessionCookie = await ctx.getSignedCookie(\n\t\t\t\t\t\tmultiSessionCookieName,\n\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t);\n\t\t\t\t\tif (!sessionCookie) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: ERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst session =\n\t\t\t\t\t\tawait ctx.context.internalAdapter.findSession(sessionToken);\n\t\t\t\t\tif (!session || session.session.expiresAt < new Date()) {\n\t\t\t\t\t\tctx.setCookie(multiSessionCookieName, \"\", {\n\t\t\t\t\t\t\t...ctx.context.authCookies.sessionToken.options,\n\t\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: ERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tawait setSessionCookie(ctx, session);\n\t\t\t\t\treturn ctx.json(session);\n\t\t\t\t},\n\t\t\t),\n\t\t\t/**\n\t\t\t * ### Endpoint\n\t\t\t *\n\t\t\t * POST `/multi-session/revoke`\n\t\t\t *\n\t\t\t * ### API Methods\n\t\t\t *\n\t\t\t * **server:**\n\t\t\t * `auth.api.revokeDeviceSession`\n\t\t\t *\n\t\t\t * **client:**\n\t\t\t * `authClient.multiSession.revoke`\n\t\t\t *\n\t\t\t * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-revoke)\n\t\t\t */\n\t\t\trevokeDeviceSession: createAuthEndpoint(\n\t\t\t\t\"/multi-session/revoke\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: revokeDeviceSessionBodySchema,\n\t\t\t\t\trequireHeaders: true,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\topenapi: {\n\t\t\t\t\t\t\tdescription: \"Revoke a device session\",\n\t\t\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\t\t\tdescription: \"Success\",\n\t\t\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype: \"boolean\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst sessionToken = ctx.body.sessionToken;\n\t\t\t\t\tconst multiSessionCookieName = `${\n\t\t\t\t\t\tctx.context.authCookies.sessionToken.name\n\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\t\t\t\t\tconst sessionCookie = await ctx.getSignedCookie(\n\t\t\t\t\t\tmultiSessionCookieName,\n\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t);\n\t\t\t\t\tif (!sessionCookie) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: ERROR_CODES.INVALID_SESSION_TOKEN,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.internalAdapter.deleteSession(sessionToken);\n\t\t\t\t\tctx.setCookie(multiSessionCookieName, \"\", {\n\t\t\t\t\t\t...ctx.context.authCookies.sessionToken.options,\n\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t});\n\t\t\t\t\tconst isActive = ctx.context.session?.session.token === sessionToken;\n\t\t\t\t\tif (!isActive) return ctx.json({ status: true });\n\n\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\tif (cookieHeader) {\n\t\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\n\t\t\t\t\t\tconst sessionTokens = (\n\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\tObject.entries(cookies)\n\t\t\t\t\t\t\t\t\t.filter(([key]) => isMultiSessionCookie(key))\n\t\t\t\t\t\t\t\t\t.map(\n\t\t\t\t\t\t\t\t\t\tasync ([key]) =>\n\t\t\t\t\t\t\t\t\t\t\tawait ctx.getSignedCookie(key, ctx.context.secret),\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\t\t\t\t\t\tconst internalAdapter = ctx.context.internalAdapter;\n\n\t\t\t\t\t\tif (sessionTokens.length > 0) {\n\t\t\t\t\t\t\tconst sessions =\n\t\t\t\t\t\t\t\tawait internalAdapter.findSessions(sessionTokens);\n\t\t\t\t\t\t\tconst validSessions = sessions.filter(\n\t\t\t\t\t\t\t\t(session) => session && session.session.expiresAt > new Date(),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (validSessions.length > 0) {\n\t\t\t\t\t\t\t\tconst nextSession = validSessions[0]!;\n\t\t\t\t\t\t\t\tawait setSessionCookie(ctx, nextSession);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdeleteSessionCookie(ctx);\n\t\t\t\t\t}\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tstatus: true,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher: () => true,\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookieString = ctx.context.responseHeaders?.get(\"set-cookie\");\n\t\t\t\t\t\tif (!cookieString) return;\n\t\t\t\t\t\tconst setCookies = parseSetCookieHeader(cookieString);\n\t\t\t\t\t\tconst sessionCookieConfig = ctx.context.authCookies.sessionToken;\n\t\t\t\t\t\tconst sessionToken = ctx.context.newSession?.session.token;\n\t\t\t\t\t\tif (!sessionToken) return;\n\t\t\t\t\t\tconst cookies = parseCookies(ctx.headers?.get(\"cookie\") || \"\");\n\n\t\t\t\t\t\tconst cookieName = `${\n\t\t\t\t\t\t\tsessionCookieConfig.name\n\t\t\t\t\t\t}_multi-${sessionToken.toLowerCase()}`;\n\n\t\t\t\t\t\tif (setCookies.get(cookieName) || cookies.get(cookieName)) return;\n\n\t\t\t\t\t\tconst currentMultiSessions =\n\t\t\t\t\t\t\tObject.keys(Object.fromEntries(cookies)).filter(\n\t\t\t\t\t\t\t\tisMultiSessionCookie,\n\t\t\t\t\t\t\t).length + (cookieString.includes(\"session_token\") ? 1 : 0);\n\n\t\t\t\t\t\tif (currentMultiSessions >= opts.maximumSessions) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait ctx.setSignedCookie(\n\t\t\t\t\t\t\tcookieName,\n\t\t\t\t\t\t\tsessionToken,\n\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t\tsessionCookieConfig.options,\n\t\t\t\t\t\t);\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmatcher: (context) => context.path === \"/sign-out\",\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst cookieHeader = ctx.headers?.get(\"cookie\");\n\t\t\t\t\t\tif (!cookieHeader) return;\n\t\t\t\t\t\tconst cookies = Object.fromEntries(parseCookies(cookieHeader));\n\t\t\t\t\t\tconst multiSessionKeys = Object.keys(cookies).filter((key) =>\n\t\t\t\t\t\t\tisMultiSessionCookie(key),\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst verifiedTokens = (\n\t\t\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\t\t\tmultiSessionKeys.map(async (key) => {\n\t\t\t\t\t\t\t\t\tconst verifiedToken = await ctx.getSignedCookie(\n\t\t\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\t\t\tctx.context.secret,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\tif (verifiedToken) {\n\t\t\t\t\t\t\t\t\t\tctx.setCookie(\n\t\t\t\t\t\t\t\t\t\t\tkey.toLowerCase().replace(\"__secure-\", \"__Secure-\"),\n\t\t\t\t\t\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t...ctx.context.authCookies.sessionToken.options,\n\t\t\t\t\t\t\t\t\t\t\t\tmaxAge: 0,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\treturn verifiedToken;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).filter((v) => typeof v === \"string\");\n\t\t\t\t\t\tif (verifiedTokens.length > 0) {\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.deleteSessions(verifiedTokens);\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\toptions,\n\t\t$ERROR_CODES: ERROR_CODES,\n\t} satisfies BetterAuthPlugin;\n};\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import * as _better_auth_core10 from "@better-auth/core";
1
+ import * as _better_auth_core9 from "@better-auth/core";
2
2
  import * as z from "zod";
3
- import * as better_call196 from "better-call";
3
+ import * as better_call166 from "better-call";
4
4
 
5
5
  //#region src/plugins/oauth-proxy/index.d.ts
6
6
  interface OAuthProxyOptions {
@@ -34,14 +34,14 @@ declare const oAuthProxy: <O extends OAuthProxyOptions>(opts?: O) => {
34
34
  id: "oauth-proxy";
35
35
  options: NoInfer<O>;
36
36
  endpoints: {
37
- oAuthProxy: better_call196.StrictEndpoint<"/oauth-proxy-callback", {
37
+ oAuthProxy: better_call166.StrictEndpoint<"/oauth-proxy-callback", {
38
38
  method: "GET";
39
39
  operationId: string;
40
40
  query: z.ZodObject<{
41
41
  callbackURL: z.ZodString;
42
42
  cookies: z.ZodString;
43
43
  }, z.core.$strip>;
44
- use: ((inputContext: better_call196.MiddlewareInputContext<better_call196.MiddlewareOptions>) => Promise<void>)[];
44
+ use: ((inputContext: better_call166.MiddlewareInputContext<better_call166.MiddlewareOptions>) => Promise<void>)[];
45
45
  metadata: {
46
46
  openapi: {
47
47
  operationId: string;
@@ -71,12 +71,12 @@ declare const oAuthProxy: <O extends OAuthProxyOptions>(opts?: O) => {
71
71
  };
72
72
  hooks: {
73
73
  before: {
74
- matcher(context: _better_auth_core10.HookEndpointContext): boolean;
75
- handler: (inputContext: better_call196.MiddlewareInputContext<better_call196.MiddlewareOptions>) => Promise<void>;
74
+ matcher(context: _better_auth_core9.HookEndpointContext): boolean;
75
+ handler: (inputContext: better_call166.MiddlewareInputContext<better_call166.MiddlewareOptions>) => Promise<void>;
76
76
  }[];
77
77
  after: {
78
- matcher(context: _better_auth_core10.HookEndpointContext): boolean;
79
- handler: (inputContext: better_call196.MiddlewareInputContext<better_call196.MiddlewareOptions>) => Promise<void>;
78
+ matcher(context: _better_auth_core9.HookEndpointContext): boolean;
79
+ handler: (inputContext: better_call166.MiddlewareInputContext<better_call166.MiddlewareOptions>) => Promise<void>;
80
80
  }[];
81
81
  };
82
82
  };
@@ -5,7 +5,7 @@ import "../index.mjs";
5
5
  import { GenericEndpointContext } from "@better-auth/core";
6
6
  import * as _better_auth_core_db4 from "@better-auth/core/db";
7
7
  import * as z from "zod";
8
- import * as better_call181 from "better-call";
8
+ import * as better_call196 from "better-call";
9
9
  import { OpenAPIParameter } from "better-call";
10
10
 
11
11
  //#region src/plugins/oidc-provider/index.d.ts
@@ -31,21 +31,21 @@ declare const oidcProvider: (options: OIDCOptions) => {
31
31
  hooks: {
32
32
  after: {
33
33
  matcher(): true;
34
- handler: (inputContext: better_call181.MiddlewareInputContext<better_call181.MiddlewareOptions>) => Promise<Response | {
34
+ handler: (inputContext: better_call196.MiddlewareInputContext<better_call196.MiddlewareOptions>) => Promise<Response | {
35
35
  redirect: boolean;
36
36
  url: string;
37
37
  } | undefined>;
38
38
  }[];
39
39
  };
40
40
  endpoints: {
41
- getOpenIdConfig: better_call181.StrictEndpoint<"/.well-known/openid-configuration", {
41
+ getOpenIdConfig: better_call196.StrictEndpoint<"/.well-known/openid-configuration", {
42
42
  method: "GET";
43
43
  operationId: string;
44
44
  metadata: {
45
45
  readonly scope: "server";
46
46
  };
47
47
  }, OIDCMetadata>;
48
- oAuth2authorize: better_call181.StrictEndpoint<"/oauth2/authorize", {
48
+ oAuth2authorize: better_call196.StrictEndpoint<"/oauth2/authorize", {
49
49
  method: "GET";
50
50
  operationId: string;
51
51
  query: z.ZodRecord<z.ZodString, z.ZodAny>;
@@ -72,14 +72,14 @@ declare const oidcProvider: (options: OIDCOptions) => {
72
72
  redirect: boolean;
73
73
  url: string;
74
74
  }>;
75
- oAuthConsent: better_call181.StrictEndpoint<"/oauth2/consent", {
75
+ oAuthConsent: better_call196.StrictEndpoint<"/oauth2/consent", {
76
76
  method: "POST";
77
77
  operationId: string;
78
78
  body: z.ZodObject<{
79
79
  accept: z.ZodBoolean;
80
80
  consent_code: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodString>>>;
81
81
  }, z.core.$strip>;
82
- use: ((inputContext: better_call181.MiddlewareInputContext<better_call181.MiddlewareOptions>) => Promise<{
82
+ use: ((inputContext: better_call196.MiddlewareInputContext<better_call196.MiddlewareOptions>) => Promise<{
83
83
  session: {
84
84
  session: Record<string, any> & {
85
85
  id: string;
@@ -151,7 +151,7 @@ declare const oidcProvider: (options: OIDCOptions) => {
151
151
  }, {
152
152
  redirectURI: string;
153
153
  }>;
154
- oAuth2token: better_call181.StrictEndpoint<"/oauth2/token", {
154
+ oAuth2token: better_call196.StrictEndpoint<"/oauth2/token", {
155
155
  method: "POST";
156
156
  operationId: string;
157
157
  body: z.ZodRecord<z.ZodAny, z.ZodAny>;
@@ -173,7 +173,7 @@ declare const oidcProvider: (options: OIDCOptions) => {
173
173
  scope: string;
174
174
  id_token: string | undefined;
175
175
  }>;
176
- oAuth2userInfo: better_call181.StrictEndpoint<"/oauth2/userinfo", {
176
+ oAuth2userInfo: better_call196.StrictEndpoint<"/oauth2/userinfo", {
177
177
  method: "GET";
178
178
  operationId: string;
179
179
  metadata: {
@@ -265,7 +265,7 @@ declare const oidcProvider: (options: OIDCOptions) => {
265
265
  *
266
266
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/oidc-provider#api-method-oauth2-register)
267
267
  */
268
- registerOAuthApplication: better_call181.StrictEndpoint<"/oauth2/register", {
268
+ registerOAuthApplication: better_call196.StrictEndpoint<"/oauth2/register", {
269
269
  method: "POST";
270
270
  body: z.ZodObject<{
271
271
  redirect_uris: z.ZodArray<z.ZodString>;
@@ -405,9 +405,9 @@ declare const oidcProvider: (options: OIDCOptions) => {
405
405
  client_secret?: string | undefined;
406
406
  client_id: string;
407
407
  }>;
408
- getOAuthClient: better_call181.StrictEndpoint<"/oauth2/client/:id", {
408
+ getOAuthClient: better_call196.StrictEndpoint<"/oauth2/client/:id", {
409
409
  method: "GET";
410
- use: ((inputContext: better_call181.MiddlewareInputContext<better_call181.MiddlewareOptions>) => Promise<{
410
+ use: ((inputContext: better_call196.MiddlewareInputContext<better_call196.MiddlewareOptions>) => Promise<{
411
411
  session: {
412
412
  session: Record<string, any> & {
413
413
  id: string;
@@ -478,7 +478,7 @@ declare const oidcProvider: (options: OIDCOptions) => {
478
478
  *
479
479
  * @see [OpenID Connect RP-Initiated Logout Spec](https://openid.net/specs/openid-connect-rpinitiated-1_0.html)
480
480
  */
481
- endSession: better_call181.StrictEndpoint<"/oauth2/endsession", {
481
+ endSession: better_call196.StrictEndpoint<"/oauth2/endsession", {
482
482
  method: ("GET" | "POST")[];
483
483
  query: z.ZodOptional<z.ZodObject<{
484
484
  id_token_hint: z.ZodOptional<z.ZodString>;
@@ -504,7 +504,7 @@ declare const oidcProvider: (options: OIDCOptions) => {
504
504
  scope: "server";
505
505
  };
506
506
  }, {
507
- status: ("OK" | "CREATED" | "ACCEPTED" | "NO_CONTENT" | "MULTIPLE_CHOICES" | "MOVED_PERMANENTLY" | "FOUND" | "SEE_OTHER" | "NOT_MODIFIED" | "TEMPORARY_REDIRECT" | "BAD_REQUEST" | "UNAUTHORIZED" | "PAYMENT_REQUIRED" | "FORBIDDEN" | "NOT_FOUND" | "METHOD_NOT_ALLOWED" | "NOT_ACCEPTABLE" | "PROXY_AUTHENTICATION_REQUIRED" | "REQUEST_TIMEOUT" | "CONFLICT" | "GONE" | "LENGTH_REQUIRED" | "PRECONDITION_FAILED" | "PAYLOAD_TOO_LARGE" | "URI_TOO_LONG" | "UNSUPPORTED_MEDIA_TYPE" | "RANGE_NOT_SATISFIABLE" | "EXPECTATION_FAILED" | "I'M_A_TEAPOT" | "MISDIRECTED_REQUEST" | "UNPROCESSABLE_ENTITY" | "LOCKED" | "FAILED_DEPENDENCY" | "TOO_EARLY" | "UPGRADE_REQUIRED" | "PRECONDITION_REQUIRED" | "TOO_MANY_REQUESTS" | "REQUEST_HEADER_FIELDS_TOO_LARGE" | "UNAVAILABLE_FOR_LEGAL_REASONS" | "INTERNAL_SERVER_ERROR" | "NOT_IMPLEMENTED" | "BAD_GATEWAY" | "SERVICE_UNAVAILABLE" | "GATEWAY_TIMEOUT" | "HTTP_VERSION_NOT_SUPPORTED" | "VARIANT_ALSO_NEGOTIATES" | "INSUFFICIENT_STORAGE" | "LOOP_DETECTED" | "NOT_EXTENDED" | "NETWORK_AUTHENTICATION_REQUIRED") | better_call181.Status;
507
+ status: ("OK" | "CREATED" | "ACCEPTED" | "NO_CONTENT" | "MULTIPLE_CHOICES" | "MOVED_PERMANENTLY" | "FOUND" | "SEE_OTHER" | "NOT_MODIFIED" | "TEMPORARY_REDIRECT" | "BAD_REQUEST" | "UNAUTHORIZED" | "PAYMENT_REQUIRED" | "FORBIDDEN" | "NOT_FOUND" | "METHOD_NOT_ALLOWED" | "NOT_ACCEPTABLE" | "PROXY_AUTHENTICATION_REQUIRED" | "REQUEST_TIMEOUT" | "CONFLICT" | "GONE" | "LENGTH_REQUIRED" | "PRECONDITION_FAILED" | "PAYLOAD_TOO_LARGE" | "URI_TOO_LONG" | "UNSUPPORTED_MEDIA_TYPE" | "RANGE_NOT_SATISFIABLE" | "EXPECTATION_FAILED" | "I'M_A_TEAPOT" | "MISDIRECTED_REQUEST" | "UNPROCESSABLE_ENTITY" | "LOCKED" | "FAILED_DEPENDENCY" | "TOO_EARLY" | "UPGRADE_REQUIRED" | "PRECONDITION_REQUIRED" | "TOO_MANY_REQUESTS" | "REQUEST_HEADER_FIELDS_TOO_LARGE" | "UNAVAILABLE_FOR_LEGAL_REASONS" | "INTERNAL_SERVER_ERROR" | "NOT_IMPLEMENTED" | "BAD_GATEWAY" | "SERVICE_UNAVAILABLE" | "GATEWAY_TIMEOUT" | "HTTP_VERSION_NOT_SUPPORTED" | "VARIANT_ALSO_NEGOTIATES" | "INSUFFICIENT_STORAGE" | "LOOP_DETECTED" | "NOT_EXTENDED" | "NETWORK_AUTHENTICATION_REQUIRED") | better_call196.Status;
508
508
  body: ({
509
509
  message?: string;
510
510
  code?: string;
@@ -1,5 +1,5 @@
1
1
  import * as z from "zod";
2
- import * as better_call176 from "better-call";
2
+ import * as better_call173 from "better-call";
3
3
 
4
4
  //#region src/plugins/one-tap/index.d.ts
5
5
  interface OneTapOptions {
@@ -20,7 +20,7 @@ interface OneTapOptions {
20
20
  declare const oneTap: (options?: OneTapOptions | undefined) => {
21
21
  id: "one-tap";
22
22
  endpoints: {
23
- oneTapCallback: better_call176.StrictEndpoint<"/one-tap/callback", {
23
+ oneTapCallback: better_call173.StrictEndpoint<"/one-tap/callback", {
24
24
  method: "POST";
25
25
  body: z.ZodObject<{
26
26
  idToken: z.ZodString;
@@ -69,7 +69,8 @@ declare const oneTap: (options?: OneTapOptions | undefined) => {
69
69
  };
70
70
  }>;
71
71
  };
72
+ options: OneTapOptions | undefined;
72
73
  };
73
74
  //#endregion
74
- export { oneTap };
75
+ export { OneTapOptions, oneTap };
75
76
  //# sourceMappingURL=index.d.mts.map
@@ -102,7 +102,8 @@ const oneTap = (options) => ({
102
102
  updatedAt: user.user.updatedAt
103
103
  }
104
104
  });
105
- }) }
105
+ }) },
106
+ options
106
107
  });
107
108
 
108
109
  //#endregion