better-auth 1.4.18 → 1.4.19

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 (118) hide show
  1. package/dist/adapters/drizzle-adapter/drizzle-adapter.mjs +37 -5
  2. package/dist/adapters/drizzle-adapter/drizzle-adapter.mjs.map +1 -1
  3. package/dist/adapters/kysely-adapter/kysely-adapter.mjs +13 -3
  4. package/dist/adapters/kysely-adapter/kysely-adapter.mjs.map +1 -1
  5. package/dist/adapters/memory-adapter/memory-adapter.mjs +21 -17
  6. package/dist/adapters/memory-adapter/memory-adapter.mjs.map +1 -1
  7. package/dist/adapters/mongodb-adapter/mongodb-adapter.mjs +12 -1
  8. package/dist/adapters/mongodb-adapter/mongodb-adapter.mjs.map +1 -1
  9. package/dist/adapters/prisma-adapter/prisma-adapter.mjs +2 -2
  10. package/dist/adapters/prisma-adapter/prisma-adapter.mjs.map +1 -1
  11. package/dist/api/index.d.mts +407 -407
  12. package/dist/api/routes/account.d.mts +11 -11
  13. package/dist/api/routes/account.mjs +1 -1
  14. package/dist/api/routes/account.mjs.map +1 -1
  15. package/dist/api/routes/callback.d.mts +2 -2
  16. package/dist/api/routes/callback.mjs +1 -1
  17. package/dist/api/routes/callback.mjs.map +1 -1
  18. package/dist/api/routes/email-verification.d.mts +4 -4
  19. package/dist/api/routes/email-verification.mjs +1 -1
  20. package/dist/api/routes/email-verification.mjs.map +1 -1
  21. package/dist/api/routes/error.d.mts +2 -2
  22. package/dist/api/routes/ok.d.mts +2 -2
  23. package/dist/api/routes/password.d.mts +7 -7
  24. package/dist/api/routes/session.d.mts +14 -14
  25. package/dist/api/routes/sign-in.d.mts +4 -4
  26. package/dist/api/routes/sign-out.d.mts +2 -2
  27. package/dist/api/routes/sign-up.d.mts +3 -3
  28. package/dist/api/routes/update-user.d.mts +13 -13
  29. package/dist/api/routes/update-user.mjs +1 -1
  30. package/dist/api/routes/update-user.mjs.map +1 -1
  31. package/dist/client/react/index.d.mts +13 -13
  32. package/dist/client/svelte/index.d.mts +15 -15
  33. package/dist/client/vanilla.d.mts +15 -15
  34. package/dist/client/vue/index.d.mts +15 -15
  35. package/dist/context/create-context.mjs +1 -1
  36. package/dist/context/create-context.mjs.map +1 -1
  37. package/dist/cookies/index.d.mts +6 -6
  38. package/dist/cookies/index.mjs +5 -8
  39. package/dist/cookies/index.mjs.map +1 -1
  40. package/dist/db/field.d.mts +10 -10
  41. package/dist/db/field.mjs.map +1 -1
  42. package/dist/db/internal-adapter.mjs +1 -1
  43. package/dist/db/internal-adapter.mjs.map +1 -1
  44. package/dist/integrations/next-js.d.mts +4 -4
  45. package/dist/integrations/svelte-kit.d.mts +2 -2
  46. package/dist/integrations/tanstack-start-solid.d.mts +4 -4
  47. package/dist/integrations/tanstack-start.d.mts +4 -4
  48. package/dist/plugins/access/types.d.mts +1 -1
  49. package/dist/plugins/admin/admin.d.mts +114 -119
  50. package/dist/plugins/admin/admin.mjs +1 -1
  51. package/dist/plugins/admin/admin.mjs.map +1 -1
  52. package/dist/plugins/admin/routes.mjs +1 -1
  53. package/dist/plugins/admin/routes.mjs.map +1 -1
  54. package/dist/plugins/anonymous/index.d.mts +7 -7
  55. package/dist/plugins/api-key/index.d.mts +95 -80
  56. package/dist/plugins/api-key/routes/verify-api-key.mjs +1 -0
  57. package/dist/plugins/api-key/routes/verify-api-key.mjs.map +1 -1
  58. package/dist/plugins/bearer/index.d.mts +6 -6
  59. package/dist/plugins/captcha/index.d.mts +2 -2
  60. package/dist/plugins/custom-session/index.d.mts +5 -5
  61. package/dist/plugins/custom-session/index.mjs +13 -5
  62. package/dist/plugins/custom-session/index.mjs.map +1 -1
  63. package/dist/plugins/device-authorization/index.d.mts +6 -6
  64. package/dist/plugins/email-otp/index.d.mts +16 -16
  65. package/dist/plugins/email-otp/routes.mjs +1 -1
  66. package/dist/plugins/email-otp/routes.mjs.map +1 -1
  67. package/dist/plugins/generic-oauth/error-codes.mjs +3 -1
  68. package/dist/plugins/generic-oauth/error-codes.mjs.map +1 -1
  69. package/dist/plugins/generic-oauth/index.d.mts +32 -29
  70. package/dist/plugins/generic-oauth/index.mjs +8 -0
  71. package/dist/plugins/generic-oauth/index.mjs.map +1 -1
  72. package/dist/plugins/generic-oauth/routes.mjs +19 -2
  73. package/dist/plugins/generic-oauth/routes.mjs.map +1 -1
  74. package/dist/plugins/generic-oauth/types.d.mts +14 -0
  75. package/dist/plugins/haveibeenpwned/index.d.mts +3 -3
  76. package/dist/plugins/jwt/client.d.mts +2 -2
  77. package/dist/plugins/jwt/index.d.mts +9 -9
  78. package/dist/plugins/last-login-method/index.d.mts +4 -4
  79. package/dist/plugins/magic-link/index.d.mts +4 -4
  80. package/dist/plugins/mcp/authorize.mjs +1 -1
  81. package/dist/plugins/mcp/authorize.mjs.map +1 -1
  82. package/dist/plugins/mcp/index.d.mts +10 -10
  83. package/dist/plugins/multi-session/index.d.mts +9 -9
  84. package/dist/plugins/oauth-proxy/index.d.mts +8 -8
  85. package/dist/plugins/oidc-provider/authorize.mjs +1 -1
  86. package/dist/plugins/oidc-provider/authorize.mjs.map +1 -1
  87. package/dist/plugins/oidc-provider/index.d.mts +15 -15
  88. package/dist/plugins/one-tap/client.d.mts +5 -5
  89. package/dist/plugins/one-tap/index.d.mts +2 -2
  90. package/dist/plugins/one-time-token/index.d.mts +5 -5
  91. package/dist/plugins/open-api/index.d.mts +3 -3
  92. package/dist/plugins/organization/client.d.mts +9 -9
  93. package/dist/plugins/organization/error-codes.d.mts +1 -0
  94. package/dist/plugins/organization/error-codes.mjs +2 -1
  95. package/dist/plugins/organization/error-codes.mjs.map +1 -1
  96. package/dist/plugins/organization/organization.d.mts +4 -4
  97. package/dist/plugins/organization/routes/crud-access-control.d.mts +22 -22
  98. package/dist/plugins/organization/routes/crud-access-control.mjs +22 -0
  99. package/dist/plugins/organization/routes/crud-access-control.mjs.map +1 -1
  100. package/dist/plugins/organization/routes/crud-invites.d.mts +70 -70
  101. package/dist/plugins/organization/routes/crud-invites.mjs +0 -4
  102. package/dist/plugins/organization/routes/crud-invites.mjs.map +1 -1
  103. package/dist/plugins/organization/routes/crud-members.d.mts +67 -67
  104. package/dist/plugins/organization/routes/crud-org.d.mts +59 -59
  105. package/dist/plugins/organization/routes/crud-team.d.mts +79 -79
  106. package/dist/plugins/phone-number/index.d.mts +33 -33
  107. package/dist/plugins/phone-number/routes.mjs +6 -2
  108. package/dist/plugins/phone-number/routes.mjs.map +1 -1
  109. package/dist/plugins/siwe/index.d.mts +3 -3
  110. package/dist/plugins/two-factor/backup-codes/index.d.mts +5 -5
  111. package/dist/plugins/two-factor/client.d.mts +2 -2
  112. package/dist/plugins/two-factor/index.d.mts +18 -18
  113. package/dist/plugins/two-factor/otp/index.d.mts +3 -3
  114. package/dist/plugins/two-factor/totp/index.d.mts +5 -5
  115. package/dist/plugins/username/index.d.mts +12 -12
  116. package/dist/plugins/username/schema.d.mts +3 -3
  117. package/dist/test-utils/test-instance.d.mts +1242 -1242
  118. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"routes.mjs","names":["tokens: OAuth2Tokens | undefined","defaultErrorURL","userInfo: Omit<User, \"createdAt\" | \"updatedAt\">","userInfo","toRedirectTo: string","toRedirectTo"],"sources":["../../../src/plugins/generic-oauth/routes.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { createAuthEndpoint } from \"@better-auth/core/api\";\nimport { BASE_ERROR_CODES } from \"@better-auth/core/error\";\nimport type { OAuth2Tokens, OAuth2UserInfo } from \"@better-auth/core/oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tvalidateAuthorizationCode,\n} from \"@better-auth/core/oauth2\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport { APIError } from \"better-call\";\nimport { decodeJwt } from \"jose\";\nimport * as z from \"zod\";\nimport { sessionMiddleware } from \"../../api\";\nimport { setSessionCookie } from \"../../cookies\";\nimport { handleOAuthUserInfo } from \"../../oauth2/link-account\";\nimport { generateState, parseState } from \"../../oauth2/state\";\nimport { setTokenUtil } from \"../../oauth2/utils\";\nimport type { User } from \"../../types\";\nimport { HIDE_METADATA } from \"../../utils\";\nimport { GENERIC_OAUTH_ERROR_CODES } from \"./error-codes\";\nimport type { GenericOAuthOptions } from \"./types\";\n\nconst signInWithOAuth2BodySchema = z.object({\n\tproviderId: z.string().meta({\n\t\tdescription: \"The provider ID for the OAuth provider\",\n\t}),\n\tcallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The URL to redirect to after sign in\",\n\t\t})\n\t\t.optional(),\n\terrorCallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The URL to redirect to if an error occurs\",\n\t\t})\n\t\t.optional(),\n\tnewUserCallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription:\n\t\t\t\t'The URL to redirect to after login if the user is new. Eg: \"/welcome\"',\n\t\t})\n\t\t.optional(),\n\tdisableRedirect: z\n\t\t.boolean()\n\t\t.meta({\n\t\t\tdescription: \"Disable redirect\",\n\t\t})\n\t\t.optional(),\n\tscopes: z\n\t\t.array(z.string())\n\t\t.meta({\n\t\t\tdescription: \"Scopes to be passed to the provider authorization request.\",\n\t\t})\n\t\t.optional(),\n\trequestSignUp: z\n\t\t.boolean()\n\t\t.meta({\n\t\t\tdescription:\n\t\t\t\t\"Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider. Eg: false\",\n\t\t})\n\t\t.optional(),\n\t/**\n\t * Any additional data to pass through the oauth flow.\n\t */\n\tadditionalData: z.record(z.string(), z.any()).optional(),\n});\n\n/**\n * ### Endpoint\n *\n * POST `/sign-in/oauth2`\n *\n * ### API Methods\n *\n * **server:**\n * `auth.api.signInWithOAuth2`\n *\n * **client:**\n * `authClient.signIn.oauth2`\n *\n * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/sign-in#api-method-sign-in-oauth2)\n */\nexport const signInWithOAuth2 = (options: GenericOAuthOptions) =>\n\tcreateAuthEndpoint(\n\t\t\"/sign-in/oauth2\",\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\tbody: signInWithOAuth2BodySchema,\n\t\t\tmetadata: {\n\t\t\t\topenapi: {\n\t\t\t\t\tdescription: \"Sign in with OAuth2\",\n\t\t\t\t\tresponses: {\n\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\tdescription: \"Sign in with OAuth2\",\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\turl: {\n\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},\n\t\t\t\t\t\t\t\t\t\t\tredirect: {\n\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},\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},\n\t\t},\n\t\tasync (ctx: GenericEndpointContext) => {\n\t\t\tconst { providerId } = ctx.body;\n\t\t\tconst config = options.config.find((c) => c.providerId === providerId);\n\t\t\tif (!config) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: `${GENERIC_OAUTH_ERROR_CODES.PROVIDER_CONFIG_NOT_FOUND} ${providerId}`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst {\n\t\t\t\tdiscoveryUrl,\n\t\t\t\tauthorizationUrl,\n\t\t\t\ttokenUrl,\n\t\t\t\tclientId,\n\t\t\t\tclientSecret,\n\t\t\t\tscopes,\n\t\t\t\tredirectURI,\n\t\t\t\tresponseType,\n\t\t\t\tpkce,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tauthorizationUrlParams,\n\t\t\t\tresponseMode,\n\t\t\t} = config;\n\t\t\tlet finalAuthUrl = authorizationUrl;\n\t\t\tlet finalTokenUrl = tokenUrl;\n\t\t\tif (discoveryUrl) {\n\t\t\t\tconst discovery = await betterFetch<{\n\t\t\t\t\tauthorization_endpoint: string;\n\t\t\t\t\ttoken_endpoint: string;\n\t\t\t\t}>(discoveryUrl, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: config.discoveryHeaders,\n\t\t\t\t\tonError(context) {\n\t\t\t\t\t\tctx.context.logger.error(context.error.message, context.error, {\n\t\t\t\t\t\t\tdiscoveryUrl,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (discovery.data) {\n\t\t\t\t\tfinalAuthUrl = discovery.data.authorization_endpoint;\n\t\t\t\t\tfinalTokenUrl = discovery.data.token_endpoint;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!finalAuthUrl || !finalTokenUrl) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIGURATION,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (authorizationUrlParams) {\n\t\t\t\tconst withAdditionalParams = new URL(finalAuthUrl);\n\t\t\t\tfor (const [paramName, paramValue] of Object.entries(\n\t\t\t\t\tauthorizationUrlParams,\n\t\t\t\t)) {\n\t\t\t\t\twithAdditionalParams.searchParams.set(paramName, paramValue);\n\t\t\t\t}\n\t\t\t\tfinalAuthUrl = withAdditionalParams.toString();\n\t\t\t}\n\t\t\tconst additionalParams =\n\t\t\t\ttypeof authorizationUrlParams === \"function\"\n\t\t\t\t\t? authorizationUrlParams(ctx)\n\t\t\t\t\t: authorizationUrlParams;\n\n\t\t\tconst { state, codeVerifier } = await generateState(\n\t\t\t\tctx,\n\t\t\t\tundefined,\n\t\t\t\tctx.body.additionalData,\n\t\t\t);\n\t\t\tconst authUrl = await createAuthorizationURL({\n\t\t\t\tid: providerId,\n\t\t\t\toptions: {\n\t\t\t\t\tclientId,\n\t\t\t\t\tclientSecret,\n\t\t\t\t\tredirectURI,\n\t\t\t\t},\n\t\t\t\tauthorizationEndpoint: finalAuthUrl,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier: pkce ? codeVerifier : undefined,\n\t\t\t\tscopes: ctx.body.scopes\n\t\t\t\t\t? [...ctx.body.scopes, ...(scopes || [])]\n\t\t\t\t\t: scopes || [],\n\t\t\t\tredirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerId}`,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tresponseType,\n\t\t\t\tresponseMode,\n\t\t\t\tadditionalParams,\n\t\t\t});\n\t\t\treturn ctx.json({\n\t\t\t\turl: authUrl.toString(),\n\t\t\t\tredirect: !ctx.body.disableRedirect,\n\t\t\t});\n\t\t},\n\t);\n\nconst OAuth2CallbackQuerySchema = z.object({\n\tcode: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The OAuth2 code\",\n\t\t})\n\t\t.optional(),\n\terror: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The error message, if any\",\n\t\t})\n\t\t.optional(),\n\terror_description: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The error description, if any\",\n\t\t})\n\t\t.optional(),\n\tstate: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The state parameter from the OAuth2 request\",\n\t\t})\n\t\t.optional(),\n});\n\nexport const oAuth2Callback = (options: GenericOAuthOptions) =>\n\tcreateAuthEndpoint(\n\t\t\"/oauth2/callback/:providerId\",\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t\tquery: OAuth2CallbackQuerySchema,\n\t\t\tmetadata: {\n\t\t\t\t...HIDE_METADATA,\n\t\t\t\tallowedMediaTypes: [\n\t\t\t\t\t\"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"application/json\",\n\t\t\t\t],\n\t\t\t\topenapi: {\n\t\t\t\t\tdescription: \"OAuth2 callback\",\n\t\t\t\t\tresponses: {\n\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\tdescription: \"OAuth2 callback\",\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\turl: {\n\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},\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},\n\t\t},\n\t\tasync (ctx: GenericEndpointContext) => {\n\t\t\tconst defaultErrorURL =\n\t\t\t\tctx.context.options.onAPIError?.errorURL ||\n\t\t\t\t`${ctx.context.baseURL}/error`;\n\t\t\tif (ctx.query.error || !ctx.query.code) {\n\t\t\t\tthrow ctx.redirect(\n\t\t\t\t\t`${defaultErrorURL}?error=${\n\t\t\t\t\t\tctx.query.error || \"oAuth_code_missing\"\n\t\t\t\t\t}&error_description=${ctx.query.error_description}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst providerId = ctx.params?.providerId;\n\t\t\tif (!providerId) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.PROVIDER_ID_REQUIRED,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst providerConfig = options.config.find(\n\t\t\t\t(p) => p.providerId === providerId,\n\t\t\t);\n\n\t\t\tif (!providerConfig) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: `${GENERIC_OAUTH_ERROR_CODES.PROVIDER_CONFIG_NOT_FOUND} ${providerId}`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlet tokens: OAuth2Tokens | undefined = undefined;\n\t\t\tconst parsedState = await parseState(ctx);\n\t\t\tconst {\n\t\t\t\tcallbackURL,\n\t\t\t\tcodeVerifier,\n\t\t\t\terrorURL,\n\t\t\t\trequestSignUp,\n\t\t\t\tnewUserURL,\n\t\t\t\tlink,\n\t\t\t} = parsedState;\n\t\t\tconst code = ctx.query.code;\n\n\t\t\tfunction redirectOnError(error: string) {\n\t\t\t\tconst defaultErrorURL =\n\t\t\t\t\tctx.context.options.onAPIError?.errorURL ||\n\t\t\t\t\t`${ctx.context.baseURL}/error`;\n\t\t\t\tlet url = errorURL || defaultErrorURL;\n\t\t\t\tif (url.includes(\"?\")) {\n\t\t\t\t\turl = `${url}&error=${error}`;\n\t\t\t\t} else {\n\t\t\t\t\turl = `${url}?error=${error}`;\n\t\t\t\t}\n\t\t\t\tthrow ctx.redirect(url);\n\t\t\t}\n\n\t\t\tlet finalTokenUrl = providerConfig.tokenUrl;\n\t\t\tlet finalUserInfoUrl = providerConfig.userInfoUrl;\n\t\t\tif (providerConfig.discoveryUrl) {\n\t\t\t\tconst discovery = await betterFetch<{\n\t\t\t\t\ttoken_endpoint: string;\n\t\t\t\t\tuserinfo_endpoint: string;\n\t\t\t\t}>(providerConfig.discoveryUrl, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: providerConfig.discoveryHeaders,\n\t\t\t\t});\n\t\t\t\tif (discovery.data) {\n\t\t\t\t\tfinalTokenUrl = discovery.data.token_endpoint;\n\t\t\t\t\tfinalUserInfoUrl = discovery.data.userinfo_endpoint;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttry {\n\t\t\t\t// Use custom getToken if provided\n\t\t\t\tif (providerConfig.getToken) {\n\t\t\t\t\ttokens = await providerConfig.getToken({\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tredirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerConfig.providerId}`,\n\t\t\t\t\t\tcodeVerifier: providerConfig.pkce ? codeVerifier : undefined,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Standard token exchange with tokenUrlParams support\n\t\t\t\t\tif (!finalTokenUrl) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIG,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst additionalParams =\n\t\t\t\t\t\ttypeof providerConfig.tokenUrlParams === \"function\"\n\t\t\t\t\t\t\t? providerConfig.tokenUrlParams(ctx)\n\t\t\t\t\t\t\t: providerConfig.tokenUrlParams;\n\t\t\t\t\ttokens = await validateAuthorizationCode({\n\t\t\t\t\t\theaders: providerConfig.authorizationHeaders,\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tcodeVerifier: providerConfig.pkce ? codeVerifier : undefined,\n\t\t\t\t\t\tredirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerConfig.providerId}`,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: providerConfig.clientId,\n\t\t\t\t\t\t\tclientSecret: providerConfig.clientSecret,\n\t\t\t\t\t\t\tredirectURI: providerConfig.redirectURI,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: finalTokenUrl,\n\t\t\t\t\t\tauthentication: providerConfig.authentication,\n\t\t\t\t\t\tadditionalParams,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tctx.context.logger.error(\n\t\t\t\t\te && typeof e === \"object\" && \"name\" in e ? (e.name as string) : \"\",\n\t\t\t\t\te,\n\t\t\t\t);\n\t\t\t\tthrow redirectOnError(\"oauth_code_verification_failed\");\n\t\t\t}\n\t\t\tif (!tokens) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIG,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst userInfo: Omit<User, \"createdAt\" | \"updatedAt\"> =\n\t\t\t\tawait (async function handleUserInfo() {\n\t\t\t\t\tconst userInfo = (\n\t\t\t\t\t\tproviderConfig.getUserInfo\n\t\t\t\t\t\t\t? await providerConfig.getUserInfo(tokens)\n\t\t\t\t\t\t\t: await getUserInfo(tokens, finalUserInfoUrl)\n\t\t\t\t\t) as OAuth2UserInfo | null;\n\t\t\t\t\tif (!userInfo) {\n\t\t\t\t\t\tthrow redirectOnError(\"user_info_is_missing\");\n\t\t\t\t\t}\n\t\t\t\t\tconst mapUser = providerConfig.mapProfileToUser\n\t\t\t\t\t\t? await providerConfig.mapProfileToUser(userInfo)\n\t\t\t\t\t\t: userInfo;\n\t\t\t\t\tconst email = mapUser.email\n\t\t\t\t\t\t? mapUser.email.toLowerCase()\n\t\t\t\t\t\t: userInfo.email?.toLowerCase();\n\t\t\t\t\tif (!email) {\n\t\t\t\t\t\tctx.context.logger.error(\"Unable to get user info\", userInfo);\n\t\t\t\t\t\tthrow redirectOnError(\"email_is_missing\");\n\t\t\t\t\t}\n\t\t\t\t\tconst id = mapUser.id ? String(mapUser.id) : String(userInfo.id);\n\t\t\t\t\tconst name = mapUser.name ? mapUser.name : userInfo.name;\n\t\t\t\t\tif (!name) {\n\t\t\t\t\t\tctx.context.logger.error(\"Unable to get user info\", userInfo);\n\t\t\t\t\t\tthrow redirectOnError(\"name_is_missing\");\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...userInfo,\n\t\t\t\t\t\t...mapUser,\n\t\t\t\t\t\temail,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname,\n\t\t\t\t\t};\n\t\t\t\t})();\n\t\t\tif (link) {\n\t\t\t\tif (\n\t\t\t\t\tctx.context.options.account?.accountLinking?.allowDifferentEmails !==\n\t\t\t\t\t\ttrue &&\n\t\t\t\t\tlink.email !== userInfo.email\n\t\t\t\t) {\n\t\t\t\t\treturn redirectOnError(\"email_doesn't_match\");\n\t\t\t\t}\n\t\t\t\tconst existingAccount =\n\t\t\t\t\tawait ctx.context.internalAdapter.findAccountByProviderId(\n\t\t\t\t\t\tString(userInfo.id),\n\t\t\t\t\t\tproviderConfig.providerId,\n\t\t\t\t\t);\n\t\t\t\tif (existingAccount) {\n\t\t\t\t\tif (existingAccount.userId !== link.userId) {\n\t\t\t\t\t\treturn redirectOnError(\"account_already_linked_to_different_user\");\n\t\t\t\t\t}\n\t\t\t\t\tconst updateData = Object.fromEntries(\n\t\t\t\t\t\tObject.entries({\n\t\t\t\t\t\t\taccessToken: await setTokenUtil(tokens.accessToken, ctx.context),\n\t\t\t\t\t\t\tidToken: tokens.idToken,\n\t\t\t\t\t\t\trefreshToken: await setTokenUtil(\n\t\t\t\t\t\t\t\ttokens.refreshToken,\n\t\t\t\t\t\t\t\tctx.context,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t\t\t}).filter(([_, value]) => value !== undefined),\n\t\t\t\t\t);\n\t\t\t\t\tawait ctx.context.internalAdapter.updateAccount(\n\t\t\t\t\t\texistingAccount.id,\n\t\t\t\t\t\tupdateData,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst newAccount = await ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\tuserId: link.userId,\n\t\t\t\t\t\tproviderId: providerConfig.providerId,\n\t\t\t\t\t\taccountId: userInfo.id,\n\t\t\t\t\t\taccessToken: await setTokenUtil(tokens.accessToken, ctx.context),\n\t\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t\t\trefreshToken: await setTokenUtil(tokens.refreshToken, ctx.context),\n\t\t\t\t\t\tidToken: tokens.idToken,\n\t\t\t\t\t});\n\t\t\t\t\tif (!newAccount) {\n\t\t\t\t\t\treturn redirectOnError(\"unable_to_link_account\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlet toRedirectTo: string;\n\t\t\t\ttry {\n\t\t\t\t\tconst url = callbackURL;\n\t\t\t\t\ttoRedirectTo = url.toString();\n\t\t\t\t} catch {\n\t\t\t\t\ttoRedirectTo = callbackURL;\n\t\t\t\t}\n\t\t\t\tthrow ctx.redirect(toRedirectTo);\n\t\t\t}\n\n\t\t\tconst result = await handleOAuthUserInfo(ctx, {\n\t\t\t\tuserInfo,\n\t\t\t\taccount: {\n\t\t\t\t\tproviderId: providerConfig.providerId,\n\t\t\t\t\taccountId: userInfo.id,\n\t\t\t\t\t...tokens,\n\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t},\n\t\t\t\tcallbackURL: callbackURL,\n\t\t\t\tdisableSignUp:\n\t\t\t\t\t(providerConfig.disableImplicitSignUp && !requestSignUp) ||\n\t\t\t\t\tproviderConfig.disableSignUp,\n\t\t\t\toverrideUserInfo: providerConfig.overrideUserInfo,\n\t\t\t});\n\n\t\t\tif (result.error) {\n\t\t\t\treturn redirectOnError(result.error.split(\" \").join(\"_\"));\n\t\t\t}\n\t\t\tconst { session, user } = result.data!;\n\t\t\tawait setSessionCookie(ctx, {\n\t\t\t\tsession,\n\t\t\t\tuser,\n\t\t\t});\n\t\t\tlet toRedirectTo: string;\n\t\t\ttry {\n\t\t\t\tconst url = result.isRegister ? newUserURL || callbackURL : callbackURL;\n\t\t\t\ttoRedirectTo = url.toString();\n\t\t\t} catch {\n\t\t\t\ttoRedirectTo = result.isRegister\n\t\t\t\t\t? newUserURL || callbackURL\n\t\t\t\t\t: callbackURL;\n\t\t\t}\n\t\t\tthrow ctx.redirect(toRedirectTo);\n\t\t},\n\t);\n\nconst OAuth2LinkAccountBodySchema = z.object({\n\tproviderId: z.string(),\n\t/**\n\t * Callback URL to redirect to after the user has signed in.\n\t */\n\tcallbackURL: z.string(),\n\t/**\n\t * Additional scopes to request when linking the account.\n\t * This is useful for requesting additional permissions when\n\t * linking a social account compared to the initial authentication.\n\t */\n\tscopes: z\n\t\t.array(z.string())\n\t\t.meta({\n\t\t\tdescription: \"Additional scopes to request when linking the account\",\n\t\t})\n\t\t.optional(),\n\t/**\n\t * The URL to redirect to if there is an error during the link process.\n\t */\n\terrorCallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription:\n\t\t\t\t\"The URL to redirect to if there is an error during the link process\",\n\t\t})\n\t\t.optional(),\n});\n/**\n * ### Endpoint\n *\n * POST `/oauth2/link`\n *\n * ### API Methods\n *\n * **server:**\n * `auth.api.oAuth2LinkAccount`\n *\n * **client:**\n * `authClient.oauth2.link`\n *\n * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/generic-oauth#api-method-oauth2-link)\n */\nexport const oAuth2LinkAccount = (options: GenericOAuthOptions) =>\n\tcreateAuthEndpoint(\n\t\t\"/oauth2/link\",\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\tbody: OAuth2LinkAccountBodySchema,\n\t\t\tuse: [sessionMiddleware],\n\t\t\tmetadata: {\n\t\t\t\topenapi: {\n\t\t\t\t\tdescription: \"Link an OAuth2 account to the current user session\",\n\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Authorization URL generated successfully for linking an OAuth2 account\",\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\turl: {\n\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\tformat: \"uri\",\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\"The authorization URL to redirect the user to for linking the OAuth2 account\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tredirect: {\n\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\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Indicates that the client should redirect to the provided URL\",\n\t\t\t\t\t\t\t\t\t\t\t\tenum: [true],\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\trequired: [\"url\", \"redirect\"],\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},\n\t\t},\n\t\tasync (c: GenericEndpointContext) => {\n\t\t\tconst session = c.context.session;\n\t\t\tif (!session) {\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.SESSION_REQUIRED,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst provider = options.config.find(\n\t\t\t\t(p) => p.providerId === c.body.providerId,\n\t\t\t);\n\t\t\tif (!provider) {\n\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\tmessage: BASE_ERROR_CODES.PROVIDER_NOT_FOUND,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst {\n\t\t\t\tproviderId,\n\t\t\t\tclientId,\n\t\t\t\tclientSecret,\n\t\t\t\tredirectURI,\n\t\t\t\tauthorizationUrl,\n\t\t\t\tdiscoveryUrl,\n\t\t\t\tpkce,\n\t\t\t\tscopes,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tauthorizationUrlParams,\n\t\t\t} = provider;\n\n\t\t\tlet finalAuthUrl = authorizationUrl;\n\t\t\tif (!finalAuthUrl) {\n\t\t\t\tif (!discoveryUrl) {\n\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIGURATION,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst discovery = await betterFetch<{\n\t\t\t\t\tauthorization_endpoint: string;\n\t\t\t\t\ttoken_endpoint: string;\n\t\t\t\t}>(discoveryUrl, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: provider.discoveryHeaders,\n\t\t\t\t\tonError(context) {\n\t\t\t\t\t\tc.context.logger.error(context.error.message, context.error, {\n\t\t\t\t\t\t\tdiscoveryUrl,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (discovery.data) {\n\t\t\t\t\tfinalAuthUrl = discovery.data.authorization_endpoint;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!finalAuthUrl) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIGURATION,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst state = await generateState(\n\t\t\t\tc,\n\t\t\t\t{\n\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\temail: session.user.email,\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t);\n\n\t\t\tconst additionalParams =\n\t\t\t\ttypeof authorizationUrlParams === \"function\"\n\t\t\t\t\t? authorizationUrlParams(c)\n\t\t\t\t\t: authorizationUrlParams;\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: providerId,\n\t\t\t\toptions: {\n\t\t\t\t\tclientId,\n\t\t\t\t\tclientSecret,\n\t\t\t\t\tredirectURI:\n\t\t\t\t\t\tredirectURI || `${c.context.baseURL}/oauth2/callback/${providerId}`,\n\t\t\t\t},\n\t\t\t\tauthorizationEndpoint: finalAuthUrl,\n\t\t\t\tstate: state.state,\n\t\t\t\tcodeVerifier: pkce ? state.codeVerifier : undefined,\n\t\t\t\tscopes: c.body.scopes || scopes || [],\n\t\t\t\tredirectURI:\n\t\t\t\t\tredirectURI || `${c.context.baseURL}/oauth2/callback/${providerId}`,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tadditionalParams,\n\t\t\t});\n\n\t\t\treturn c.json({\n\t\t\t\turl: url.toString(),\n\t\t\t\tredirect: true,\n\t\t\t});\n\t\t},\n\t);\n\nexport async function getUserInfo(\n\ttokens: OAuth2Tokens,\n\tfinalUserInfoUrl: string | undefined,\n): Promise<OAuth2UserInfo | null> {\n\tif (tokens.idToken) {\n\t\tconst decoded = decodeJwt(tokens.idToken) as {\n\t\t\tsub: string;\n\t\t\temail_verified: boolean;\n\t\t\temail: string;\n\t\t\tname: string;\n\t\t\tpicture: string;\n\t\t};\n\t\tif (decoded) {\n\t\t\tif (decoded.sub && decoded.email) {\n\t\t\t\treturn {\n\t\t\t\t\tid: decoded.sub,\n\t\t\t\t\temailVerified: decoded.email_verified,\n\t\t\t\t\timage: decoded.picture,\n\t\t\t\t\t...decoded,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!finalUserInfoUrl) {\n\t\treturn null;\n\t}\n\n\tconst userInfo = await betterFetch<{\n\t\temail: string;\n\t\tsub?: string | undefined;\n\t\tname: string;\n\t\temail_verified: boolean;\n\t\tpicture: string;\n\t}>(finalUserInfoUrl, {\n\t\tmethod: \"GET\",\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${tokens.accessToken}`,\n\t\t},\n\t});\n\treturn {\n\t\tid: userInfo.data?.sub ?? \"\",\n\t\temailVerified: userInfo.data?.email_verified ?? false,\n\t\temail: userInfo.data?.email,\n\t\timage: userInfo.data?.picture,\n\t\tname: userInfo.data?.name,\n\t\t...userInfo.data,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"routes.mjs","names":["tokens: OAuth2Tokens | undefined","defaultErrorURL","userInfo: Omit<User, \"createdAt\" | \"updatedAt\">","userInfo","toRedirectTo: string","toRedirectTo"],"sources":["../../../src/plugins/generic-oauth/routes.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { createAuthEndpoint } from \"@better-auth/core/api\";\nimport { BASE_ERROR_CODES } from \"@better-auth/core/error\";\nimport type { OAuth2Tokens, OAuth2UserInfo } from \"@better-auth/core/oauth2\";\nimport {\n\tcreateAuthorizationURL,\n\tvalidateAuthorizationCode,\n} from \"@better-auth/core/oauth2\";\nimport { betterFetch } from \"@better-fetch/fetch\";\nimport { APIError } from \"better-call\";\nimport { decodeJwt } from \"jose\";\nimport * as z from \"zod\";\nimport { sessionMiddleware } from \"../../api\";\nimport { setSessionCookie } from \"../../cookies\";\nimport { handleOAuthUserInfo } from \"../../oauth2/link-account\";\nimport { generateState, parseState } from \"../../oauth2/state\";\nimport { setTokenUtil } from \"../../oauth2/utils\";\nimport type { User } from \"../../types\";\nimport { HIDE_METADATA } from \"../../utils\";\nimport { GENERIC_OAUTH_ERROR_CODES } from \"./error-codes\";\nimport type { GenericOAuthOptions } from \"./types\";\n\nconst signInWithOAuth2BodySchema = z.object({\n\tproviderId: z.string().meta({\n\t\tdescription: \"The provider ID for the OAuth provider\",\n\t}),\n\tcallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The URL to redirect to after sign in\",\n\t\t})\n\t\t.optional(),\n\terrorCallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The URL to redirect to if an error occurs\",\n\t\t})\n\t\t.optional(),\n\tnewUserCallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription:\n\t\t\t\t'The URL to redirect to after login if the user is new. Eg: \"/welcome\"',\n\t\t})\n\t\t.optional(),\n\tdisableRedirect: z\n\t\t.boolean()\n\t\t.meta({\n\t\t\tdescription: \"Disable redirect\",\n\t\t})\n\t\t.optional(),\n\tscopes: z\n\t\t.array(z.string())\n\t\t.meta({\n\t\t\tdescription: \"Scopes to be passed to the provider authorization request.\",\n\t\t})\n\t\t.optional(),\n\trequestSignUp: z\n\t\t.boolean()\n\t\t.meta({\n\t\t\tdescription:\n\t\t\t\t\"Explicitly request sign-up. Useful when disableImplicitSignUp is true for this provider. Eg: false\",\n\t\t})\n\t\t.optional(),\n\t/**\n\t * Any additional data to pass through the oauth flow.\n\t */\n\tadditionalData: z.record(z.string(), z.any()).optional(),\n});\n\n/**\n * ### Endpoint\n *\n * POST `/sign-in/oauth2`\n *\n * ### API Methods\n *\n * **server:**\n * `auth.api.signInWithOAuth2`\n *\n * **client:**\n * `authClient.signIn.oauth2`\n *\n * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/sign-in#api-method-sign-in-oauth2)\n */\nexport const signInWithOAuth2 = (options: GenericOAuthOptions) =>\n\tcreateAuthEndpoint(\n\t\t\"/sign-in/oauth2\",\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\tbody: signInWithOAuth2BodySchema,\n\t\t\tmetadata: {\n\t\t\t\topenapi: {\n\t\t\t\t\tdescription: \"Sign in with OAuth2\",\n\t\t\t\t\tresponses: {\n\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\tdescription: \"Sign in with OAuth2\",\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\turl: {\n\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},\n\t\t\t\t\t\t\t\t\t\t\tredirect: {\n\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},\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},\n\t\t},\n\t\tasync (ctx: GenericEndpointContext) => {\n\t\t\tconst { providerId } = ctx.body;\n\t\t\tconst config = options.config.find((c) => c.providerId === providerId);\n\t\t\tif (!config) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: `${GENERIC_OAUTH_ERROR_CODES.PROVIDER_CONFIG_NOT_FOUND} ${providerId}`,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst {\n\t\t\t\tdiscoveryUrl,\n\t\t\t\tauthorizationUrl,\n\t\t\t\ttokenUrl,\n\t\t\t\tclientId,\n\t\t\t\tclientSecret,\n\t\t\t\tscopes,\n\t\t\t\tredirectURI,\n\t\t\t\tresponseType,\n\t\t\t\tpkce,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tauthorizationUrlParams,\n\t\t\t\tresponseMode,\n\t\t\t} = config;\n\t\t\tlet finalAuthUrl = authorizationUrl;\n\t\t\tlet finalTokenUrl = tokenUrl;\n\t\t\tif (discoveryUrl) {\n\t\t\t\tconst discovery = await betterFetch<{\n\t\t\t\t\tauthorization_endpoint: string;\n\t\t\t\t\ttoken_endpoint: string;\n\t\t\t\t}>(discoveryUrl, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: config.discoveryHeaders,\n\t\t\t\t\tonError(context) {\n\t\t\t\t\t\tctx.context.logger.error(context.error.message, context.error, {\n\t\t\t\t\t\t\tdiscoveryUrl,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (discovery.data) {\n\t\t\t\t\tfinalAuthUrl = discovery.data.authorization_endpoint;\n\t\t\t\t\tfinalTokenUrl = discovery.data.token_endpoint;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!finalAuthUrl || !finalTokenUrl) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIGURATION,\n\t\t\t\t});\n\t\t\t}\n\t\t\tif (authorizationUrlParams) {\n\t\t\t\tconst withAdditionalParams = new URL(finalAuthUrl);\n\t\t\t\tfor (const [paramName, paramValue] of Object.entries(\n\t\t\t\t\tauthorizationUrlParams,\n\t\t\t\t)) {\n\t\t\t\t\twithAdditionalParams.searchParams.set(paramName, paramValue);\n\t\t\t\t}\n\t\t\t\tfinalAuthUrl = withAdditionalParams.toString();\n\t\t\t}\n\t\t\tconst additionalParams =\n\t\t\t\ttypeof authorizationUrlParams === \"function\"\n\t\t\t\t\t? authorizationUrlParams(ctx)\n\t\t\t\t\t: authorizationUrlParams;\n\n\t\t\tconst { state, codeVerifier } = await generateState(\n\t\t\t\tctx,\n\t\t\t\tundefined,\n\t\t\t\tctx.body.additionalData,\n\t\t\t);\n\t\t\tconst authUrl = await createAuthorizationURL({\n\t\t\t\tid: providerId,\n\t\t\t\toptions: {\n\t\t\t\t\tclientId,\n\t\t\t\t\tclientSecret,\n\t\t\t\t\tredirectURI,\n\t\t\t\t},\n\t\t\t\tauthorizationEndpoint: finalAuthUrl,\n\t\t\t\tstate,\n\t\t\t\tcodeVerifier: pkce ? codeVerifier : undefined,\n\t\t\t\tscopes: ctx.body.scopes\n\t\t\t\t\t? [...ctx.body.scopes, ...(scopes || [])]\n\t\t\t\t\t: scopes || [],\n\t\t\t\tredirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerId}`,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tresponseType,\n\t\t\t\tresponseMode,\n\t\t\t\tadditionalParams,\n\t\t\t});\n\t\t\treturn ctx.json({\n\t\t\t\turl: authUrl.toString(),\n\t\t\t\tredirect: !ctx.body.disableRedirect,\n\t\t\t});\n\t\t},\n\t);\n\nconst OAuth2CallbackQuerySchema = z.object({\n\tcode: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The OAuth2 code\",\n\t\t})\n\t\t.optional(),\n\terror: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The error message, if any\",\n\t\t})\n\t\t.optional(),\n\terror_description: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The error description, if any\",\n\t\t})\n\t\t.optional(),\n\tstate: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The state parameter from the OAuth2 request\",\n\t\t})\n\t\t.optional(),\n\tiss: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription: \"The issuer identifier\",\n\t\t})\n\t\t.optional(),\n});\n\nexport const oAuth2Callback = (options: GenericOAuthOptions) =>\n\tcreateAuthEndpoint(\n\t\t\"/oauth2/callback/:providerId\",\n\t\t{\n\t\t\tmethod: \"GET\",\n\t\t\tquery: OAuth2CallbackQuerySchema,\n\t\t\tmetadata: {\n\t\t\t\t...HIDE_METADATA,\n\t\t\t\tallowedMediaTypes: [\n\t\t\t\t\t\"application/x-www-form-urlencoded\",\n\t\t\t\t\t\"application/json\",\n\t\t\t\t],\n\t\t\t\topenapi: {\n\t\t\t\t\tdescription: \"OAuth2 callback\",\n\t\t\t\t\tresponses: {\n\t\t\t\t\t\t200: {\n\t\t\t\t\t\t\tdescription: \"OAuth2 callback\",\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\turl: {\n\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},\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},\n\t\t},\n\t\tasync (ctx: GenericEndpointContext) => {\n\t\t\tconst defaultErrorURL =\n\t\t\t\tctx.context.options.onAPIError?.errorURL ||\n\t\t\t\t`${ctx.context.baseURL}/error`;\n\t\t\tif (ctx.query.error || !ctx.query.code) {\n\t\t\t\tthrow ctx.redirect(\n\t\t\t\t\t`${defaultErrorURL}?error=${\n\t\t\t\t\t\tctx.query.error || \"oAuth_code_missing\"\n\t\t\t\t\t}&error_description=${ctx.query.error_description}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst providerId = ctx.params?.providerId;\n\t\t\tif (!providerId) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.PROVIDER_ID_REQUIRED,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst providerConfig = options.config.find(\n\t\t\t\t(p) => p.providerId === providerId,\n\t\t\t);\n\n\t\t\tif (!providerConfig) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: `${GENERIC_OAUTH_ERROR_CODES.PROVIDER_CONFIG_NOT_FOUND} ${providerId}`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tlet tokens: OAuth2Tokens | undefined = undefined;\n\t\t\tconst parsedState = await parseState(ctx);\n\t\t\tconst {\n\t\t\t\tcallbackURL,\n\t\t\t\tcodeVerifier,\n\t\t\t\terrorURL,\n\t\t\t\trequestSignUp,\n\t\t\t\tnewUserURL,\n\t\t\t\tlink,\n\t\t\t} = parsedState;\n\t\t\tconst code = ctx.query.code;\n\n\t\t\tfunction redirectOnError(error: string) {\n\t\t\t\tconst defaultErrorURL =\n\t\t\t\t\tctx.context.options.onAPIError?.errorURL ||\n\t\t\t\t\t`${ctx.context.baseURL}/error`;\n\t\t\t\tlet url = errorURL || defaultErrorURL;\n\t\t\t\tif (url.includes(\"?\")) {\n\t\t\t\t\turl = `${url}&error=${error}`;\n\t\t\t\t} else {\n\t\t\t\t\turl = `${url}?error=${error}`;\n\t\t\t\t}\n\t\t\t\tthrow ctx.redirect(url);\n\t\t\t}\n\n\t\t\tlet finalTokenUrl = providerConfig.tokenUrl;\n\t\t\tlet finalUserInfoUrl = providerConfig.userInfoUrl;\n\t\t\tlet expectedIssuer = providerConfig.issuer;\n\n\t\t\tif (providerConfig.discoveryUrl) {\n\t\t\t\tconst discovery = await betterFetch<{\n\t\t\t\t\ttoken_endpoint: string;\n\t\t\t\t\tuserinfo_endpoint: string;\n\t\t\t\t\tissuer: string;\n\t\t\t\t}>(providerConfig.discoveryUrl, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: providerConfig.discoveryHeaders,\n\t\t\t\t});\n\t\t\t\tif (discovery.data) {\n\t\t\t\t\tfinalTokenUrl = discovery.data.token_endpoint;\n\t\t\t\t\tfinalUserInfoUrl = discovery.data.userinfo_endpoint;\n\t\t\t\t\tif (!expectedIssuer && discovery.data.issuer) {\n\t\t\t\t\t\texpectedIssuer = discovery.data.issuer;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (expectedIssuer) {\n\t\t\t\tif (ctx.query.iss) {\n\t\t\t\t\tif (ctx.query.iss !== expectedIssuer) {\n\t\t\t\t\t\tctx.context.logger.error(\"OAuth issuer mismatch\", {\n\t\t\t\t\t\t\texpected: expectedIssuer,\n\t\t\t\t\t\t\treceived: ctx.query.iss,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn redirectOnError(\"issuer_mismatch\");\n\t\t\t\t\t}\n\t\t\t\t} else if (providerConfig.requireIssuerValidation) {\n\t\t\t\t\tctx.context.logger.error(\"OAuth issuer parameter missing\", {\n\t\t\t\t\t\texpected: expectedIssuer,\n\t\t\t\t\t});\n\t\t\t\t\treturn redirectOnError(\"issuer_missing\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\t// Use custom getToken if provided\n\t\t\t\tif (providerConfig.getToken) {\n\t\t\t\t\ttokens = await providerConfig.getToken({\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tredirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerConfig.providerId}`,\n\t\t\t\t\t\tcodeVerifier: providerConfig.pkce ? codeVerifier : undefined,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t// Standard token exchange with tokenUrlParams support\n\t\t\t\t\tif (!finalTokenUrl) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIG,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tconst additionalParams =\n\t\t\t\t\t\ttypeof providerConfig.tokenUrlParams === \"function\"\n\t\t\t\t\t\t\t? providerConfig.tokenUrlParams(ctx)\n\t\t\t\t\t\t\t: providerConfig.tokenUrlParams;\n\t\t\t\t\ttokens = await validateAuthorizationCode({\n\t\t\t\t\t\theaders: providerConfig.authorizationHeaders,\n\t\t\t\t\t\tcode,\n\t\t\t\t\t\tcodeVerifier: providerConfig.pkce ? codeVerifier : undefined,\n\t\t\t\t\t\tredirectURI: `${ctx.context.baseURL}/oauth2/callback/${providerConfig.providerId}`,\n\t\t\t\t\t\toptions: {\n\t\t\t\t\t\t\tclientId: providerConfig.clientId,\n\t\t\t\t\t\t\tclientSecret: providerConfig.clientSecret,\n\t\t\t\t\t\t\tredirectURI: providerConfig.redirectURI,\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttokenEndpoint: finalTokenUrl,\n\t\t\t\t\t\tauthentication: providerConfig.authentication,\n\t\t\t\t\t\tadditionalParams,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} catch (e) {\n\t\t\t\tctx.context.logger.error(\n\t\t\t\t\te && typeof e === \"object\" && \"name\" in e ? (e.name as string) : \"\",\n\t\t\t\t\te,\n\t\t\t\t);\n\t\t\t\tthrow redirectOnError(\"oauth_code_verification_failed\");\n\t\t\t}\n\t\t\tif (!tokens) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIG,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst userInfo: Omit<User, \"createdAt\" | \"updatedAt\"> =\n\t\t\t\tawait (async function handleUserInfo() {\n\t\t\t\t\tconst userInfo = (\n\t\t\t\t\t\tproviderConfig.getUserInfo\n\t\t\t\t\t\t\t? await providerConfig.getUserInfo(tokens)\n\t\t\t\t\t\t\t: await getUserInfo(tokens, finalUserInfoUrl)\n\t\t\t\t\t) as OAuth2UserInfo | null;\n\t\t\t\t\tif (!userInfo) {\n\t\t\t\t\t\tthrow redirectOnError(\"user_info_is_missing\");\n\t\t\t\t\t}\n\t\t\t\t\tconst mapUser = providerConfig.mapProfileToUser\n\t\t\t\t\t\t? await providerConfig.mapProfileToUser(userInfo)\n\t\t\t\t\t\t: userInfo;\n\t\t\t\t\tconst email = mapUser.email\n\t\t\t\t\t\t? mapUser.email.toLowerCase()\n\t\t\t\t\t\t: userInfo.email?.toLowerCase();\n\t\t\t\t\tif (!email) {\n\t\t\t\t\t\tctx.context.logger.error(\"Unable to get user info\", userInfo);\n\t\t\t\t\t\tthrow redirectOnError(\"email_is_missing\");\n\t\t\t\t\t}\n\t\t\t\t\tconst id = mapUser.id ? String(mapUser.id) : String(userInfo.id);\n\t\t\t\t\tconst name = mapUser.name ? mapUser.name : userInfo.name;\n\t\t\t\t\tif (!name) {\n\t\t\t\t\t\tctx.context.logger.error(\"Unable to get user info\", userInfo);\n\t\t\t\t\t\tthrow redirectOnError(\"name_is_missing\");\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...userInfo,\n\t\t\t\t\t\t...mapUser,\n\t\t\t\t\t\temail,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname,\n\t\t\t\t\t};\n\t\t\t\t})();\n\t\t\tif (link) {\n\t\t\t\tif (\n\t\t\t\t\tctx.context.options.account?.accountLinking?.allowDifferentEmails !==\n\t\t\t\t\t\ttrue &&\n\t\t\t\t\tlink.email.toLowerCase() !== userInfo.email.toLowerCase()\n\t\t\t\t) {\n\t\t\t\t\treturn redirectOnError(\"email_doesn't_match\");\n\t\t\t\t}\n\t\t\t\tconst existingAccount =\n\t\t\t\t\tawait ctx.context.internalAdapter.findAccountByProviderId(\n\t\t\t\t\t\tString(userInfo.id),\n\t\t\t\t\t\tproviderConfig.providerId,\n\t\t\t\t\t);\n\t\t\t\tif (existingAccount) {\n\t\t\t\t\tif (existingAccount.userId !== link.userId) {\n\t\t\t\t\t\treturn redirectOnError(\"account_already_linked_to_different_user\");\n\t\t\t\t\t}\n\t\t\t\t\tconst updateData = Object.fromEntries(\n\t\t\t\t\t\tObject.entries({\n\t\t\t\t\t\t\taccessToken: await setTokenUtil(tokens.accessToken, ctx.context),\n\t\t\t\t\t\t\tidToken: tokens.idToken,\n\t\t\t\t\t\t\trefreshToken: await setTokenUtil(\n\t\t\t\t\t\t\t\ttokens.refreshToken,\n\t\t\t\t\t\t\t\tctx.context,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t\t\t}).filter(([_, value]) => value !== undefined),\n\t\t\t\t\t);\n\t\t\t\t\tawait ctx.context.internalAdapter.updateAccount(\n\t\t\t\t\t\texistingAccount.id,\n\t\t\t\t\t\tupdateData,\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tconst newAccount = await ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\tuserId: link.userId,\n\t\t\t\t\t\tproviderId: providerConfig.providerId,\n\t\t\t\t\t\taccountId: userInfo.id,\n\t\t\t\t\t\taccessToken: await setTokenUtil(tokens.accessToken, ctx.context),\n\t\t\t\t\t\taccessTokenExpiresAt: tokens.accessTokenExpiresAt,\n\t\t\t\t\t\trefreshTokenExpiresAt: tokens.refreshTokenExpiresAt,\n\t\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t\t\trefreshToken: await setTokenUtil(tokens.refreshToken, ctx.context),\n\t\t\t\t\t\tidToken: tokens.idToken,\n\t\t\t\t\t});\n\t\t\t\t\tif (!newAccount) {\n\t\t\t\t\t\treturn redirectOnError(\"unable_to_link_account\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlet toRedirectTo: string;\n\t\t\t\ttry {\n\t\t\t\t\tconst url = callbackURL;\n\t\t\t\t\ttoRedirectTo = url.toString();\n\t\t\t\t} catch {\n\t\t\t\t\ttoRedirectTo = callbackURL;\n\t\t\t\t}\n\t\t\t\tthrow ctx.redirect(toRedirectTo);\n\t\t\t}\n\n\t\t\tconst result = await handleOAuthUserInfo(ctx, {\n\t\t\t\tuserInfo,\n\t\t\t\taccount: {\n\t\t\t\t\tproviderId: providerConfig.providerId,\n\t\t\t\t\taccountId: userInfo.id,\n\t\t\t\t\t...tokens,\n\t\t\t\t\tscope: tokens.scopes?.join(\",\"),\n\t\t\t\t},\n\t\t\t\tcallbackURL: callbackURL,\n\t\t\t\tdisableSignUp:\n\t\t\t\t\t(providerConfig.disableImplicitSignUp && !requestSignUp) ||\n\t\t\t\t\tproviderConfig.disableSignUp,\n\t\t\t\toverrideUserInfo: providerConfig.overrideUserInfo,\n\t\t\t});\n\n\t\t\tif (result.error) {\n\t\t\t\treturn redirectOnError(result.error.split(\" \").join(\"_\"));\n\t\t\t}\n\t\t\tconst { session, user } = result.data!;\n\t\t\tawait setSessionCookie(ctx, {\n\t\t\t\tsession,\n\t\t\t\tuser,\n\t\t\t});\n\t\t\tlet toRedirectTo: string;\n\t\t\ttry {\n\t\t\t\tconst url = result.isRegister ? newUserURL || callbackURL : callbackURL;\n\t\t\t\ttoRedirectTo = url.toString();\n\t\t\t} catch {\n\t\t\t\ttoRedirectTo = result.isRegister\n\t\t\t\t\t? newUserURL || callbackURL\n\t\t\t\t\t: callbackURL;\n\t\t\t}\n\t\t\tthrow ctx.redirect(toRedirectTo);\n\t\t},\n\t);\n\nconst OAuth2LinkAccountBodySchema = z.object({\n\tproviderId: z.string(),\n\t/**\n\t * Callback URL to redirect to after the user has signed in.\n\t */\n\tcallbackURL: z.string(),\n\t/**\n\t * Additional scopes to request when linking the account.\n\t * This is useful for requesting additional permissions when\n\t * linking a social account compared to the initial authentication.\n\t */\n\tscopes: z\n\t\t.array(z.string())\n\t\t.meta({\n\t\t\tdescription: \"Additional scopes to request when linking the account\",\n\t\t})\n\t\t.optional(),\n\t/**\n\t * The URL to redirect to if there is an error during the link process.\n\t */\n\terrorCallbackURL: z\n\t\t.string()\n\t\t.meta({\n\t\t\tdescription:\n\t\t\t\t\"The URL to redirect to if there is an error during the link process\",\n\t\t})\n\t\t.optional(),\n});\n/**\n * ### Endpoint\n *\n * POST `/oauth2/link`\n *\n * ### API Methods\n *\n * **server:**\n * `auth.api.oAuth2LinkAccount`\n *\n * **client:**\n * `authClient.oauth2.link`\n *\n * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/generic-oauth#api-method-oauth2-link)\n */\nexport const oAuth2LinkAccount = (options: GenericOAuthOptions) =>\n\tcreateAuthEndpoint(\n\t\t\"/oauth2/link\",\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\tbody: OAuth2LinkAccountBodySchema,\n\t\t\tuse: [sessionMiddleware],\n\t\t\tmetadata: {\n\t\t\t\topenapi: {\n\t\t\t\t\tdescription: \"Link an OAuth2 account to the current user session\",\n\t\t\t\t\tresponses: {\n\t\t\t\t\t\t\"200\": {\n\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\"Authorization URL generated successfully for linking an OAuth2 account\",\n\t\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\t\t\"application/json\": {\n\t\t\t\t\t\t\t\t\tschema: {\n\t\t\t\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\turl: {\n\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\tformat: \"uri\",\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\"The authorization URL to redirect the user to for linking the OAuth2 account\",\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tredirect: {\n\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\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\"Indicates that the client should redirect to the provided URL\",\n\t\t\t\t\t\t\t\t\t\t\t\tenum: [true],\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\trequired: [\"url\", \"redirect\"],\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},\n\t\t},\n\t\tasync (c: GenericEndpointContext) => {\n\t\t\tconst session = c.context.session;\n\t\t\tif (!session) {\n\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.SESSION_REQUIRED,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst provider = options.config.find(\n\t\t\t\t(p) => p.providerId === c.body.providerId,\n\t\t\t);\n\t\t\tif (!provider) {\n\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\tmessage: BASE_ERROR_CODES.PROVIDER_NOT_FOUND,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst {\n\t\t\t\tproviderId,\n\t\t\t\tclientId,\n\t\t\t\tclientSecret,\n\t\t\t\tredirectURI,\n\t\t\t\tauthorizationUrl,\n\t\t\t\tdiscoveryUrl,\n\t\t\t\tpkce,\n\t\t\t\tscopes,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tauthorizationUrlParams,\n\t\t\t} = provider;\n\n\t\t\tlet finalAuthUrl = authorizationUrl;\n\t\t\tif (!finalAuthUrl) {\n\t\t\t\tif (!discoveryUrl) {\n\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIGURATION,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tconst discovery = await betterFetch<{\n\t\t\t\t\tauthorization_endpoint: string;\n\t\t\t\t\ttoken_endpoint: string;\n\t\t\t\t}>(discoveryUrl, {\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\theaders: provider.discoveryHeaders,\n\t\t\t\t\tonError(context) {\n\t\t\t\t\t\tc.context.logger.error(context.error.message, context.error, {\n\t\t\t\t\t\t\tdiscoveryUrl,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tif (discovery.data) {\n\t\t\t\t\tfinalAuthUrl = discovery.data.authorization_endpoint;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!finalAuthUrl) {\n\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\tmessage: GENERIC_OAUTH_ERROR_CODES.INVALID_OAUTH_CONFIGURATION,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst state = await generateState(\n\t\t\t\tc,\n\t\t\t\t{\n\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\temail: session.user.email,\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t);\n\n\t\t\tconst additionalParams =\n\t\t\t\ttypeof authorizationUrlParams === \"function\"\n\t\t\t\t\t? authorizationUrlParams(c)\n\t\t\t\t\t: authorizationUrlParams;\n\n\t\t\tconst url = await createAuthorizationURL({\n\t\t\t\tid: providerId,\n\t\t\t\toptions: {\n\t\t\t\t\tclientId,\n\t\t\t\t\tclientSecret,\n\t\t\t\t\tredirectURI:\n\t\t\t\t\t\tredirectURI || `${c.context.baseURL}/oauth2/callback/${providerId}`,\n\t\t\t\t},\n\t\t\t\tauthorizationEndpoint: finalAuthUrl,\n\t\t\t\tstate: state.state,\n\t\t\t\tcodeVerifier: pkce ? state.codeVerifier : undefined,\n\t\t\t\tscopes: c.body.scopes || scopes || [],\n\t\t\t\tredirectURI:\n\t\t\t\t\tredirectURI || `${c.context.baseURL}/oauth2/callback/${providerId}`,\n\t\t\t\tprompt,\n\t\t\t\taccessType,\n\t\t\t\tadditionalParams,\n\t\t\t});\n\n\t\t\treturn c.json({\n\t\t\t\turl: url.toString(),\n\t\t\t\tredirect: true,\n\t\t\t});\n\t\t},\n\t);\n\nexport async function getUserInfo(\n\ttokens: OAuth2Tokens,\n\tfinalUserInfoUrl: string | undefined,\n): Promise<OAuth2UserInfo | null> {\n\tif (tokens.idToken) {\n\t\tconst decoded = decodeJwt(tokens.idToken) as {\n\t\t\tsub: string;\n\t\t\temail_verified: boolean;\n\t\t\temail: string;\n\t\t\tname: string;\n\t\t\tpicture: string;\n\t\t};\n\t\tif (decoded) {\n\t\t\tif (decoded.sub && decoded.email) {\n\t\t\t\treturn {\n\t\t\t\t\tid: decoded.sub,\n\t\t\t\t\temailVerified: decoded.email_verified,\n\t\t\t\t\timage: decoded.picture,\n\t\t\t\t\t...decoded,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!finalUserInfoUrl) {\n\t\treturn null;\n\t}\n\n\tconst userInfo = await betterFetch<{\n\t\temail: string;\n\t\tsub?: string | undefined;\n\t\tname: string;\n\t\temail_verified: boolean;\n\t\tpicture: string;\n\t}>(finalUserInfoUrl, {\n\t\tmethod: \"GET\",\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${tokens.accessToken}`,\n\t\t},\n\t});\n\treturn {\n\t\tid: userInfo.data?.sub ?? \"\",\n\t\temailVerified: userInfo.data?.email_verified ?? false,\n\t\temail: userInfo.data?.email,\n\t\timage: userInfo.data?.picture,\n\t\tname: userInfo.data?.name,\n\t\t...userInfo.data,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,MAAM,6BAA6B,EAAE,OAAO;CAC3C,YAAY,EAAE,QAAQ,CAAC,KAAK,EAC3B,aAAa,0CACb,CAAC;CACF,aAAa,EACX,QAAQ,CACR,KAAK,EACL,aAAa,wCACb,CAAC,CACD,UAAU;CACZ,kBAAkB,EAChB,QAAQ,CACR,KAAK,EACL,aAAa,6CACb,CAAC,CACD,UAAU;CACZ,oBAAoB,EAClB,QAAQ,CACR,KAAK,EACL,aACC,2EACD,CAAC,CACD,UAAU;CACZ,iBAAiB,EACf,SAAS,CACT,KAAK,EACL,aAAa,oBACb,CAAC,CACD,UAAU;CACZ,QAAQ,EACN,MAAM,EAAE,QAAQ,CAAC,CACjB,KAAK,EACL,aAAa,8DACb,CAAC,CACD,UAAU;CACZ,eAAe,EACb,SAAS,CACT,KAAK,EACL,aACC,sGACD,CAAC,CACD,UAAU;CAIZ,gBAAgB,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,KAAK,CAAC,CAAC,UAAU;CACxD,CAAC;;;;;;;;;;;;;;;;AAiBF,MAAa,oBAAoB,YAChC,mBACC,mBACA;CACC,QAAQ;CACR,MAAM;CACN,UAAU,EACT,SAAS;EACR,aAAa;EACb,WAAW,EACV,KAAK;GACJ,aAAa;GACb,SAAS,EACR,oBAAoB,EACnB,QAAQ;IACP,MAAM;IACN,YAAY;KACX,KAAK,EACJ,MAAM,UACN;KACD,UAAU,EACT,MAAM,WACN;KACD;IACD,EACD,EACD;GACD,EACD;EACD,EACD;CACD,EACD,OAAO,QAAgC;CACtC,MAAM,EAAE,eAAe,IAAI;CAC3B,MAAM,SAAS,QAAQ,OAAO,MAAM,MAAM,EAAE,eAAe,WAAW;AACtE,KAAI,CAAC,OACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,GAAG,0BAA0B,0BAA0B,GAAG,cACnE,CAAC;CAEH,MAAM,EACL,cACA,kBACA,UACA,UACA,cACA,QACA,aACA,cACA,MACA,QACA,YACA,wBACA,iBACG;CACJ,IAAI,eAAe;CACnB,IAAI,gBAAgB;AACpB,KAAI,cAAc;EACjB,MAAM,YAAY,MAAM,YAGrB,cAAc;GAChB,QAAQ;GACR,SAAS,OAAO;GAChB,QAAQ,SAAS;AAChB,QAAI,QAAQ,OAAO,MAAM,QAAQ,MAAM,SAAS,QAAQ,OAAO,EAC9D,cACA,CAAC;;GAEH,CAAC;AACF,MAAI,UAAU,MAAM;AACnB,kBAAe,UAAU,KAAK;AAC9B,mBAAgB,UAAU,KAAK;;;AAGjC,KAAI,CAAC,gBAAgB,CAAC,cACrB,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,0BAA0B,6BACnC,CAAC;AAEH,KAAI,wBAAwB;EAC3B,MAAM,uBAAuB,IAAI,IAAI,aAAa;AAClD,OAAK,MAAM,CAAC,WAAW,eAAe,OAAO,QAC5C,uBACA,CACA,sBAAqB,aAAa,IAAI,WAAW,WAAW;AAE7D,iBAAe,qBAAqB,UAAU;;CAE/C,MAAM,mBACL,OAAO,2BAA2B,aAC/B,uBAAuB,IAAI,GAC3B;CAEJ,MAAM,EAAE,OAAO,iBAAiB,MAAM,cACrC,KACA,QACA,IAAI,KAAK,eACT;CACD,MAAM,UAAU,MAAM,uBAAuB;EAC5C,IAAI;EACJ,SAAS;GACR;GACA;GACA;GACA;EACD,uBAAuB;EACvB;EACA,cAAc,OAAO,eAAe;EACpC,QAAQ,IAAI,KAAK,SACd,CAAC,GAAG,IAAI,KAAK,QAAQ,GAAI,UAAU,EAAE,CAAE,GACvC,UAAU,EAAE;EACf,aAAa,GAAG,IAAI,QAAQ,QAAQ,mBAAmB;EACvD;EACA;EACA;EACA;EACA;EACA,CAAC;AACF,QAAO,IAAI,KAAK;EACf,KAAK,QAAQ,UAAU;EACvB,UAAU,CAAC,IAAI,KAAK;EACpB,CAAC;EAEH;AAEF,MAAM,4BAA4B,EAAE,OAAO;CAC1C,MAAM,EACJ,QAAQ,CACR,KAAK,EACL,aAAa,mBACb,CAAC,CACD,UAAU;CACZ,OAAO,EACL,QAAQ,CACR,KAAK,EACL,aAAa,6BACb,CAAC,CACD,UAAU;CACZ,mBAAmB,EACjB,QAAQ,CACR,KAAK,EACL,aAAa,iCACb,CAAC,CACD,UAAU;CACZ,OAAO,EACL,QAAQ,CACR,KAAK,EACL,aAAa,+CACb,CAAC,CACD,UAAU;CACZ,KAAK,EACH,QAAQ,CACR,KAAK,EACL,aAAa,yBACb,CAAC,CACD,UAAU;CACZ,CAAC;AAEF,MAAa,kBAAkB,YAC9B,mBACC,gCACA;CACC,QAAQ;CACR,OAAO;CACP,UAAU;EACT,GAAG;EACH,mBAAmB,CAClB,qCACA,mBACA;EACD,SAAS;GACR,aAAa;GACb,WAAW,EACV,KAAK;IACJ,aAAa;IACb,SAAS,EACR,oBAAoB,EACnB,QAAQ;KACP,MAAM;KACN,YAAY,EACX,KAAK,EACJ,MAAM,UACN,EACD;KACD,EACD,EACD;IACD,EACD;GACD;EACD;CACD,EACD,OAAO,QAAgC;CACtC,MAAM,kBACL,IAAI,QAAQ,QAAQ,YAAY,YAChC,GAAG,IAAI,QAAQ,QAAQ;AACxB,KAAI,IAAI,MAAM,SAAS,CAAC,IAAI,MAAM,KACjC,OAAM,IAAI,SACT,GAAG,gBAAgB,SAClB,IAAI,MAAM,SAAS,qBACnB,qBAAqB,IAAI,MAAM,oBAChC;CAEF,MAAM,aAAa,IAAI,QAAQ;AAC/B,KAAI,CAAC,WACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,0BAA0B,sBACnC,CAAC;CAEH,MAAM,iBAAiB,QAAQ,OAAO,MACpC,MAAM,EAAE,eAAe,WACxB;AAED,KAAI,CAAC,eACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,GAAG,0BAA0B,0BAA0B,GAAG,cACnE,CAAC;CAGH,IAAIA,SAAmC;CAEvC,MAAM,EACL,aACA,cACA,UACA,eACA,YACA,SAPmB,MAAM,WAAW,IAAI;CASzC,MAAM,OAAO,IAAI,MAAM;CAEvB,SAAS,gBAAgB,OAAe;EACvC,MAAMC,oBACL,IAAI,QAAQ,QAAQ,YAAY,YAChC,GAAG,IAAI,QAAQ,QAAQ;EACxB,IAAI,MAAM,YAAYA;AACtB,MAAI,IAAI,SAAS,IAAI,CACpB,OAAM,GAAG,IAAI,SAAS;MAEtB,OAAM,GAAG,IAAI,SAAS;AAEvB,QAAM,IAAI,SAAS,IAAI;;CAGxB,IAAI,gBAAgB,eAAe;CACnC,IAAI,mBAAmB,eAAe;CACtC,IAAI,iBAAiB,eAAe;AAEpC,KAAI,eAAe,cAAc;EAChC,MAAM,YAAY,MAAM,YAIrB,eAAe,cAAc;GAC/B,QAAQ;GACR,SAAS,eAAe;GACxB,CAAC;AACF,MAAI,UAAU,MAAM;AACnB,mBAAgB,UAAU,KAAK;AAC/B,sBAAmB,UAAU,KAAK;AAClC,OAAI,CAAC,kBAAkB,UAAU,KAAK,OACrC,kBAAiB,UAAU,KAAK;;;AAKnC,KAAI,gBACH;MAAI,IAAI,MAAM,KACb;OAAI,IAAI,MAAM,QAAQ,gBAAgB;AACrC,QAAI,QAAQ,OAAO,MAAM,yBAAyB;KACjD,UAAU;KACV,UAAU,IAAI,MAAM;KACpB,CAAC;AACF,WAAO,gBAAgB,kBAAkB;;aAEhC,eAAe,yBAAyB;AAClD,OAAI,QAAQ,OAAO,MAAM,kCAAkC,EAC1D,UAAU,gBACV,CAAC;AACF,UAAO,gBAAgB,iBAAiB;;;AAI1C,KAAI;AAEH,MAAI,eAAe,SAClB,UAAS,MAAM,eAAe,SAAS;GACtC;GACA,aAAa,GAAG,IAAI,QAAQ,QAAQ,mBAAmB,eAAe;GACtE,cAAc,eAAe,OAAO,eAAe;GACnD,CAAC;OACI;AAEN,OAAI,CAAC,cACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,0BAA0B,sBACnC,CAAC;GAEH,MAAM,mBACL,OAAO,eAAe,mBAAmB,aACtC,eAAe,eAAe,IAAI,GAClC,eAAe;AACnB,YAAS,MAAM,0BAA0B;IACxC,SAAS,eAAe;IACxB;IACA,cAAc,eAAe,OAAO,eAAe;IACnD,aAAa,GAAG,IAAI,QAAQ,QAAQ,mBAAmB,eAAe;IACtE,SAAS;KACR,UAAU,eAAe;KACzB,cAAc,eAAe;KAC7B,aAAa,eAAe;KAC5B;IACD,eAAe;IACf,gBAAgB,eAAe;IAC/B;IACA,CAAC;;UAEK,GAAG;AACX,MAAI,QAAQ,OAAO,MAClB,KAAK,OAAO,MAAM,YAAY,UAAU,IAAK,EAAE,OAAkB,IACjE,EACA;AACD,QAAM,gBAAgB,iCAAiC;;AAExD,KAAI,CAAC,OACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,0BAA0B,sBACnC,CAAC;CAEH,MAAMC,WACL,OAAO,eAAe,iBAAiB;EACtC,MAAMC,aACL,eAAe,cACZ,MAAM,eAAe,YAAY,OAAO,GACxC,MAAM,YAAY,QAAQ,iBAAiB;AAE/C,MAAI,CAACA,WACJ,OAAM,gBAAgB,uBAAuB;EAE9C,MAAM,UAAU,eAAe,mBAC5B,MAAM,eAAe,iBAAiBA,WAAS,GAC/CA;EACH,MAAM,QAAQ,QAAQ,QACnB,QAAQ,MAAM,aAAa,GAC3BA,WAAS,OAAO,aAAa;AAChC,MAAI,CAAC,OAAO;AACX,OAAI,QAAQ,OAAO,MAAM,2BAA2BA,WAAS;AAC7D,SAAM,gBAAgB,mBAAmB;;EAE1C,MAAM,KAAK,QAAQ,KAAK,OAAO,QAAQ,GAAG,GAAG,OAAOA,WAAS,GAAG;EAChE,MAAM,OAAO,QAAQ,OAAO,QAAQ,OAAOA,WAAS;AACpD,MAAI,CAAC,MAAM;AACV,OAAI,QAAQ,OAAO,MAAM,2BAA2BA,WAAS;AAC7D,SAAM,gBAAgB,kBAAkB;;AAEzC,SAAO;GACN,GAAGA;GACH,GAAG;GACH;GACA;GACA;GACA;KACE;AACL,KAAI,MAAM;AACT,MACC,IAAI,QAAQ,QAAQ,SAAS,gBAAgB,yBAC5C,QACD,KAAK,MAAM,aAAa,KAAK,SAAS,MAAM,aAAa,CAEzD,QAAO,gBAAgB,sBAAsB;EAE9C,MAAM,kBACL,MAAM,IAAI,QAAQ,gBAAgB,wBACjC,OAAO,SAAS,GAAG,EACnB,eAAe,WACf;AACF,MAAI,iBAAiB;AACpB,OAAI,gBAAgB,WAAW,KAAK,OACnC,QAAO,gBAAgB,2CAA2C;GAEnE,MAAM,aAAa,OAAO,YACzB,OAAO,QAAQ;IACd,aAAa,MAAM,aAAa,OAAO,aAAa,IAAI,QAAQ;IAChE,SAAS,OAAO;IAChB,cAAc,MAAM,aACnB,OAAO,cACP,IAAI,QACJ;IACD,sBAAsB,OAAO;IAC7B,uBAAuB,OAAO;IAC9B,OAAO,OAAO,QAAQ,KAAK,IAAI;IAC/B,CAAC,CAAC,QAAQ,CAAC,GAAG,WAAW,UAAU,OAAU,CAC9C;AACD,SAAM,IAAI,QAAQ,gBAAgB,cACjC,gBAAgB,IAChB,WACA;aAaG,CAXe,MAAM,IAAI,QAAQ,gBAAgB,cAAc;GAClE,QAAQ,KAAK;GACb,YAAY,eAAe;GAC3B,WAAW,SAAS;GACpB,aAAa,MAAM,aAAa,OAAO,aAAa,IAAI,QAAQ;GAChE,sBAAsB,OAAO;GAC7B,uBAAuB,OAAO;GAC9B,OAAO,OAAO,QAAQ,KAAK,IAAI;GAC/B,cAAc,MAAM,aAAa,OAAO,cAAc,IAAI,QAAQ;GAClE,SAAS,OAAO;GAChB,CAAC,CAED,QAAO,gBAAgB,yBAAyB;EAGlD,IAAIC;AACJ,MAAI;AAEH,oBADY,YACO,UAAU;UACtB;AACP,oBAAe;;AAEhB,QAAM,IAAI,SAASC,eAAa;;CAGjC,MAAM,SAAS,MAAM,oBAAoB,KAAK;EAC7C;EACA,SAAS;GACR,YAAY,eAAe;GAC3B,WAAW,SAAS;GACpB,GAAG;GACH,OAAO,OAAO,QAAQ,KAAK,IAAI;GAC/B;EACY;EACb,eACE,eAAe,yBAAyB,CAAC,iBAC1C,eAAe;EAChB,kBAAkB,eAAe;EACjC,CAAC;AAEF,KAAI,OAAO,MACV,QAAO,gBAAgB,OAAO,MAAM,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC;CAE1D,MAAM,EAAE,SAAS,SAAS,OAAO;AACjC,OAAM,iBAAiB,KAAK;EAC3B;EACA;EACA,CAAC;CACF,IAAID;AACJ,KAAI;AAEH,kBADY,OAAO,aAAa,cAAc,cAAc,aACzC,UAAU;SACtB;AACP,iBAAe,OAAO,aACnB,cAAc,cACd;;AAEJ,OAAM,IAAI,SAAS,aAAa;EAEjC;AAEF,MAAM,8BAA8B,EAAE,OAAO;CAC5C,YAAY,EAAE,QAAQ;CAItB,aAAa,EAAE,QAAQ;CAMvB,QAAQ,EACN,MAAM,EAAE,QAAQ,CAAC,CACjB,KAAK,EACL,aAAa,yDACb,CAAC,CACD,UAAU;CAIZ,kBAAkB,EAChB,QAAQ,CACR,KAAK,EACL,aACC,uEACD,CAAC,CACD,UAAU;CACZ,CAAC;;;;;;;;;;;;;;;;AAgBF,MAAa,qBAAqB,YACjC,mBACC,gBACA;CACC,QAAQ;CACR,MAAM;CACN,KAAK,CAAC,kBAAkB;CACxB,UAAU,EACT,SAAS;EACR,aAAa;EACb,WAAW,EACV,OAAO;GACN,aACC;GACD,SAAS,EACR,oBAAoB,EACnB,QAAQ;IACP,MAAM;IACN,YAAY;KACX,KAAK;MACJ,MAAM;MACN,QAAQ;MACR,aACC;MACD;KACD,UAAU;MACT,MAAM;MACN,aACC;MACD,MAAM,CAAC,KAAK;MACZ;KACD;IACD,UAAU,CAAC,OAAO,WAAW;IAC7B,EACD,EACD;GACD,EACD;EACD,EACD;CACD,EACD,OAAO,MAA8B;CACpC,MAAM,UAAU,EAAE,QAAQ;AAC1B,KAAI,CAAC,QACJ,OAAM,IAAI,SAAS,gBAAgB,EAClC,SAAS,0BAA0B,kBACnC,CAAC;CAEH,MAAM,WAAW,QAAQ,OAAO,MAC9B,MAAM,EAAE,eAAe,EAAE,KAAK,WAC/B;AACD,KAAI,CAAC,SACJ,OAAM,IAAI,SAAS,aAAa,EAC/B,SAAS,iBAAiB,oBAC1B,CAAC;CAEH,MAAM,EACL,YACA,UACA,cACA,aACA,kBACA,cACA,MACA,QACA,QACA,YACA,2BACG;CAEJ,IAAI,eAAe;AACnB,KAAI,CAAC,cAAc;AAClB,MAAI,CAAC,aACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,0BAA0B,6BACnC,CAAC;EAEH,MAAM,YAAY,MAAM,YAGrB,cAAc;GAChB,QAAQ;GACR,SAAS,SAAS;GAClB,QAAQ,SAAS;AAChB,MAAE,QAAQ,OAAO,MAAM,QAAQ,MAAM,SAAS,QAAQ,OAAO,EAC5D,cACA,CAAC;;GAEH,CAAC;AACF,MAAI,UAAU,KACb,gBAAe,UAAU,KAAK;;AAIhC,KAAI,CAAC,aACJ,OAAM,IAAI,SAAS,eAAe,EACjC,SAAS,0BAA0B,6BACnC,CAAC;CAGH,MAAM,QAAQ,MAAM,cACnB,GACA;EACC,QAAQ,QAAQ,KAAK;EACrB,OAAO,QAAQ,KAAK;EACpB,EACD,OACA;CAED,MAAM,mBACL,OAAO,2BAA2B,aAC/B,uBAAuB,EAAE,GACzB;CAEJ,MAAM,MAAM,MAAM,uBAAuB;EACxC,IAAI;EACJ,SAAS;GACR;GACA;GACA,aACC,eAAe,GAAG,EAAE,QAAQ,QAAQ,mBAAmB;GACxD;EACD,uBAAuB;EACvB,OAAO,MAAM;EACb,cAAc,OAAO,MAAM,eAAe;EAC1C,QAAQ,EAAE,KAAK,UAAU,UAAU,EAAE;EACrC,aACC,eAAe,GAAG,EAAE,QAAQ,QAAQ,mBAAmB;EACxD;EACA;EACA;EACA,CAAC;AAEF,QAAO,EAAE,KAAK;EACb,KAAK,IAAI,UAAU;EACnB,UAAU;EACV,CAAC;EAEH;AAEF,eAAsB,YACrB,QACA,kBACiC;AACjC,KAAI,OAAO,SAAS;EACnB,MAAM,UAAU,UAAU,OAAO,QAAQ;AAOzC,MAAI,SACH;OAAI,QAAQ,OAAO,QAAQ,MAC1B,QAAO;IACN,IAAI,QAAQ;IACZ,eAAe,QAAQ;IACvB,OAAO,QAAQ;IACf,GAAG;IACH;;;AAKJ,KAAI,CAAC,iBACJ,QAAO;CAGR,MAAM,WAAW,MAAM,YAMpB,kBAAkB;EACpB,QAAQ;EACR,SAAS,EACR,eAAe,UAAU,OAAO,eAChC;EACD,CAAC;AACF,QAAO;EACN,IAAI,SAAS,MAAM,OAAO;EAC1B,eAAe,SAAS,MAAM,kBAAkB;EAChD,OAAO,SAAS,MAAM;EACtB,OAAO,SAAS,MAAM;EACtB,MAAM,SAAS,MAAM;EACrB,GAAG,SAAS;EACZ"}
@@ -20,6 +20,20 @@ interface GenericOAuthConfig {
20
20
  * If provided, the authorization and token endpoints will be fetched from this URL.
21
21
  */
22
22
  discoveryUrl?: string | undefined;
23
+ /**
24
+ * The expected issuer identifier for validation.
25
+ * If not provided but discoveryUrl is set, it will be fetched from the discovery document.
26
+ * When set, the callback validates that the `iss` parameter matches this value.
27
+ * @see https://datatracker.ietf.org/doc/html/rfc9207
28
+ */
29
+ issuer?: string | undefined;
30
+ /**
31
+ * When true, requires the `iss` parameter in callbacks if an issuer is configured.
32
+ * This provides stricter security but may break with older OAuth servers
33
+ * that don't support issuer identification.
34
+ * @default false
35
+ */
36
+ requireIssuerValidation?: boolean | undefined;
23
37
  /**
24
38
  * URL for the authorization endpoint.
25
39
  * Optional if using discoveryUrl.
@@ -1,4 +1,4 @@
1
- import * as _better_auth_core14 from "@better-auth/core";
1
+ import * as _better_auth_core18 from "@better-auth/core";
2
2
 
3
3
  //#region src/plugins/haveibeenpwned/index.d.ts
4
4
  interface HaveIBeenPwnedOptions {
@@ -12,7 +12,7 @@ interface HaveIBeenPwnedOptions {
12
12
  }
13
13
  declare const haveIBeenPwned: (options?: HaveIBeenPwnedOptions | undefined) => {
14
14
  id: "haveIBeenPwned";
15
- init(ctx: _better_auth_core14.AuthContext): {
15
+ init(ctx: _better_auth_core18.AuthContext): {
16
16
  context: {
17
17
  password: {
18
18
  hash(password: string): Promise<string>;
@@ -24,7 +24,7 @@ declare const haveIBeenPwned: (options?: HaveIBeenPwnedOptions | undefined) => {
24
24
  minPasswordLength: number;
25
25
  maxPasswordLength: number;
26
26
  };
27
- checkPassword: (userId: string, ctx: _better_auth_core14.GenericEndpointContext<_better_auth_core14.BetterAuthOptions>) => Promise<boolean>;
27
+ checkPassword: (userId: string, ctx: _better_auth_core18.GenericEndpointContext<_better_auth_core18.BetterAuthOptions>) => Promise<boolean>;
28
28
  };
29
29
  };
30
30
  };
@@ -1,7 +1,7 @@
1
1
  import { JWKOptions, JWSAlgorithms, Jwk, JwtOptions } from "./types.mjs";
2
2
  import { jwt } from "./index.mjs";
3
3
  import { JSONWebKeySet } from "jose";
4
- import * as _better_fetch_fetch95 from "@better-fetch/fetch";
4
+ import * as _better_fetch_fetch111 from "@better-fetch/fetch";
5
5
 
6
6
  //#region src/plugins/jwt/client.d.ts
7
7
  interface JwtClientOptions {
@@ -21,7 +21,7 @@ declare const jwtClient: (options?: JwtClientOptions) => {
21
21
  pathMethods: {
22
22
  [x: string]: "GET";
23
23
  };
24
- getActions: ($fetch: _better_fetch_fetch95.BetterFetch) => {
24
+ getActions: ($fetch: _better_fetch_fetch111.BetterFetch) => {
25
25
  jwks: (fetchOptions?: any) => Promise<{
26
26
  data: null;
27
27
  error: {
@@ -2,8 +2,8 @@ import { JWKOptions, JWSAlgorithms, Jwk, JwtOptions } from "./types.mjs";
2
2
  import { getJwtToken, signJWT } from "./sign.mjs";
3
3
  import { createJwk, generateExportedKeyPair, toExpJWT } from "./utils.mjs";
4
4
  import { verifyJWT } from "./verify.mjs";
5
- import * as _better_auth_core9 from "@better-auth/core";
6
- import * as better_call44 from "better-call";
5
+ import * as _better_auth_core7 from "@better-auth/core";
6
+ import * as better_call31 from "better-call";
7
7
  import * as z from "zod";
8
8
  import { JSONWebKeySet, JWTPayload } from "jose";
9
9
 
@@ -12,7 +12,7 @@ declare const jwt: <O extends JwtOptions>(options?: O) => {
12
12
  id: "jwt";
13
13
  options: NoInfer<O>;
14
14
  endpoints: {
15
- getJwks: better_call44.StrictEndpoint<string, {
15
+ getJwks: better_call31.StrictEndpoint<string, {
16
16
  method: "GET";
17
17
  metadata: {
18
18
  openapi: {
@@ -89,10 +89,10 @@ declare const jwt: <O extends JwtOptions>(options?: O) => {
89
89
  };
90
90
  };
91
91
  }, JSONWebKeySet>;
92
- getToken: better_call44.StrictEndpoint<"/token", {
92
+ getToken: better_call31.StrictEndpoint<"/token", {
93
93
  method: "GET";
94
94
  requireHeaders: true;
95
- use: ((inputContext: better_call44.MiddlewareInputContext<better_call44.MiddlewareOptions>) => Promise<{
95
+ use: ((inputContext: better_call31.MiddlewareInputContext<better_call31.MiddlewareOptions>) => Promise<{
96
96
  session: {
97
97
  session: Record<string, any> & {
98
98
  id: string;
@@ -141,7 +141,7 @@ declare const jwt: <O extends JwtOptions>(options?: O) => {
141
141
  }, {
142
142
  token: string;
143
143
  }>;
144
- signJWT: better_call44.StrictEndpoint<string, {
144
+ signJWT: better_call31.StrictEndpoint<string, {
145
145
  method: "POST";
146
146
  metadata: {
147
147
  $Infer: {
@@ -158,7 +158,7 @@ declare const jwt: <O extends JwtOptions>(options?: O) => {
158
158
  }, {
159
159
  token: string;
160
160
  }>;
161
- verifyJWT: better_call44.StrictEndpoint<string, {
161
+ verifyJWT: better_call31.StrictEndpoint<string, {
162
162
  method: "POST";
163
163
  metadata: {
164
164
  $Infer: {
@@ -185,8 +185,8 @@ declare const jwt: <O extends JwtOptions>(options?: O) => {
185
185
  };
186
186
  hooks: {
187
187
  after: {
188
- matcher(context: _better_auth_core9.HookEndpointContext): boolean;
189
- handler: (inputContext: better_call44.MiddlewareInputContext<better_call44.MiddlewareOptions>) => Promise<void>;
188
+ matcher(context: _better_auth_core7.HookEndpointContext): boolean;
189
+ handler: (inputContext: better_call31.MiddlewareInputContext<better_call31.MiddlewareOptions>) => Promise<void>;
190
190
  }[];
191
191
  };
192
192
  schema: {
@@ -1,6 +1,6 @@
1
- import * as _better_auth_core31 from "@better-auth/core";
1
+ import * as _better_auth_core35 from "@better-auth/core";
2
2
  import { GenericEndpointContext } from "@better-auth/core";
3
- import * as better_call727 from "better-call";
3
+ import * as better_call285 from "better-call";
4
4
 
5
5
  //#region src/plugins/last-login-method/index.d.ts
6
6
  /**
@@ -43,7 +43,7 @@ interface LastLoginMethodOptions {
43
43
  */
44
44
  declare const lastLoginMethod: <O extends LastLoginMethodOptions>(userConfig?: O | undefined) => {
45
45
  id: "last-login-method";
46
- init(ctx: _better_auth_core31.AuthContext): {
46
+ init(ctx: _better_auth_core35.AuthContext): {
47
47
  options: {
48
48
  databaseHooks: {
49
49
  user: {
@@ -90,7 +90,7 @@ declare const lastLoginMethod: <O extends LastLoginMethodOptions>(userConfig?: O
90
90
  hooks: {
91
91
  after: {
92
92
  matcher(): true;
93
- handler: (inputContext: better_call727.MiddlewareInputContext<better_call727.MiddlewareOptions>) => Promise<void>;
93
+ handler: (inputContext: better_call285.MiddlewareInputContext<better_call285.MiddlewareOptions>) => Promise<void>;
94
94
  }[];
95
95
  };
96
96
  schema: O["storeInDatabase"] extends true ? {
@@ -1,5 +1,5 @@
1
1
  import { Awaitable, GenericEndpointContext } from "@better-auth/core";
2
- import * as better_call40 from "better-call";
2
+ import * as better_call39 from "better-call";
3
3
  import * as z from "zod";
4
4
 
5
5
  //#region src/plugins/magic-link/index.d.ts
@@ -68,7 +68,7 @@ declare const magicLink: (options: MagicLinkOptions) => {
68
68
  *
69
69
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/sign-in#api-method-sign-in-magic-link)
70
70
  */
71
- signInMagicLink: better_call40.StrictEndpoint<"/sign-in/magic-link", {
71
+ signInMagicLink: better_call39.StrictEndpoint<"/sign-in/magic-link", {
72
72
  method: "POST";
73
73
  requireHeaders: true;
74
74
  body: z.ZodObject<{
@@ -119,7 +119,7 @@ declare const magicLink: (options: MagicLinkOptions) => {
119
119
  *
120
120
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/magic-link#api-method-magic-link-verify)
121
121
  */
122
- magicLinkVerify: better_call40.StrictEndpoint<"/magic-link/verify", {
122
+ magicLinkVerify: better_call39.StrictEndpoint<"/magic-link/verify", {
123
123
  method: "GET";
124
124
  query: z.ZodObject<{
125
125
  token: z.ZodString;
@@ -127,7 +127,7 @@ declare const magicLink: (options: MagicLinkOptions) => {
127
127
  errorCallbackURL: z.ZodOptional<z.ZodString>;
128
128
  newUserCallbackURL: z.ZodOptional<z.ZodString>;
129
129
  }, z.core.$strip>;
130
- use: ((inputContext: better_call40.MiddlewareInputContext<better_call40.MiddlewareOptions>) => Promise<void>)[];
130
+ use: ((inputContext: better_call39.MiddlewareInputContext<better_call39.MiddlewareOptions>) => Promise<void>)[];
131
131
  requireHeaders: true;
132
132
  metadata: {
133
133
  openapi: {
@@ -6,7 +6,7 @@ import { APIError } from "better-call";
6
6
 
7
7
  //#region src/plugins/mcp/authorize.ts
8
8
  function redirectErrorURL(url, error, description) {
9
- return `${url.includes("?") ? "&" : "?"}error=${error}&error_description=${description}`;
9
+ return `${url}${url.includes("?") ? "&" : "?"}error=${error}&error_description=${description}`;
10
10
  }
11
11
  async function authorizeMCPOAuth(ctx, options) {
12
12
  ctx.setHeader("Access-Control-Allow-Origin", "*");
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.mjs","names":["redirectURIWithCode"],"sources":["../../../src/plugins/mcp/authorize.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { APIError } from \"better-call\";\nimport { getSessionFromCtx } from \"../../api\";\nimport { generateRandomString } from \"../../crypto\";\nimport type { OAuthApplication } from \"../oidc-provider/schema\";\nimport type {\n\tAuthorizationQuery,\n\tClient,\n\tOIDCOptions,\n} from \"../oidc-provider/types\";\n\nfunction redirectErrorURL(url: string, error: string, description: string) {\n\treturn `${\n\t\turl.includes(\"?\") ? \"&\" : \"?\"\n\t}error=${error}&error_description=${description}`;\n}\n\nexport async function authorizeMCPOAuth(\n\tctx: GenericEndpointContext,\n\toptions: OIDCOptions,\n) {\n\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\tctx.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\");\n\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\tconst opts = {\n\t\tcodeExpiresIn: 600,\n\t\tdefaultScope: \"openid\",\n\t\t...options,\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?.scopes || []),\n\t\t],\n\t};\n\tif (!ctx.request) {\n\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\terror_description: \"request not found\",\n\t\t\terror: \"invalid_request\",\n\t\t});\n\t}\n\tconst session = await getSessionFromCtx(ctx);\n\tif (!session) {\n\t\t/**\n\t\t * If the user is not logged in, we need to redirect them to the\n\t\t * login page.\n\t\t */\n\t\tawait ctx.setSignedCookie(\n\t\t\t\"oidc_login_prompt\",\n\t\t\tJSON.stringify(ctx.query),\n\t\t\tctx.context.secret,\n\t\t\t{\n\t\t\t\tmaxAge: 600,\n\t\t\t\tpath: \"/\",\n\t\t\t\tsameSite: \"lax\",\n\t\t\t},\n\t\t);\n\t\tconst queryFromURL = ctx.request.url?.split(\"?\")[1]!;\n\t\tthrow ctx.redirect(`${options.loginPage}?${queryFromURL}`);\n\t}\n\n\tconst query = ctx.query as AuthorizationQuery;\n\tif (!query.client_id) {\n\t\tthrow ctx.redirect(`${ctx.context.baseURL}/error?error=invalid_client`);\n\t}\n\n\tif (!query.response_type) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\t`${ctx.context.baseURL}/error`,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"response_type is required\",\n\t\t\t),\n\t\t);\n\t}\n\n\tconst client = await ctx.context.adapter\n\t\t.findOne<OAuthApplication>({\n\t\t\tmodel: \"oauthApplication\",\n\t\t\twhere: [\n\t\t\t\t{\n\t\t\t\t\tfield: \"clientId\",\n\t\t\t\t\tvalue: ctx.query.client_id,\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t\t.then((res) => {\n\t\t\tif (!res) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...res,\n\t\t\t\tredirectUrls: res.redirectUrls.split(\",\"),\n\t\t\t\tmetadata: res.metadata ? JSON.parse(res.metadata) : {},\n\t\t\t} as Client;\n\t\t});\n\tif (!client) {\n\t\tthrow ctx.redirect(`${ctx.context.baseURL}/error?error=invalid_client`);\n\t}\n\tconst redirectURI = client.redirectUrls.find(\n\t\t(url) => url === ctx.query.redirect_uri,\n\t);\n\n\tif (!redirectURI || !query.redirect_uri) {\n\t\t/**\n\t\t * show UI error here warning the user that the redirect URI is invalid\n\t\t */\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"Invalid redirect URI\",\n\t\t});\n\t}\n\tif (client.disabled) {\n\t\tthrow ctx.redirect(`${ctx.context.baseURL}/error?error=client_disabled`);\n\t}\n\n\tif (query.response_type !== \"code\") {\n\t\tthrow ctx.redirect(\n\t\t\t`${ctx.context.baseURL}/error?error=unsupported_response_type`,\n\t\t);\n\t}\n\n\tconst requestScope =\n\t\tquery.scope?.split(\" \").filter((s) => s) || opts.defaultScope.split(\" \");\n\tconst invalidScopes = requestScope.filter((scope) => {\n\t\treturn !opts.scopes.includes(scope);\n\t});\n\tif (invalidScopes.length) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"invalid_scope\",\n\t\t\t\t`The following scopes are invalid: ${invalidScopes.join(\", \")}`,\n\t\t\t),\n\t\t);\n\t}\n\n\tif (\n\t\t(!query.code_challenge || !query.code_challenge_method) &&\n\t\toptions.requirePKCE\n\t) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"pkce is required\",\n\t\t\t),\n\t\t);\n\t}\n\n\tif (!query.code_challenge_method) {\n\t\tquery.code_challenge_method = \"plain\";\n\t}\n\n\tif (\n\t\t![\n\t\t\t\"s256\",\n\t\t\toptions.allowPlainCodeChallengeMethod ? \"plain\" : \"s256\",\n\t\t].includes(query.code_challenge_method?.toLowerCase() || \"\")\n\t) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"invalid code_challenge method\",\n\t\t\t),\n\t\t);\n\t}\n\n\tconst code = generateRandomString(32, \"a-z\", \"A-Z\", \"0-9\");\n\tconst codeExpiresInMs = opts.codeExpiresIn * 1000;\n\tconst expiresAt = new Date(Date.now() + codeExpiresInMs);\n\ttry {\n\t\t/**\n\t\t * Save the code in the database\n\t\t */\n\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\tvalue: JSON.stringify({\n\t\t\t\tclientId: client.clientId,\n\t\t\t\tredirectURI: query.redirect_uri,\n\t\t\t\tscope: requestScope,\n\t\t\t\tuserId: session.user.id,\n\t\t\t\tauthTime: new Date(session.session.createdAt).getTime(),\n\t\t\t\t/**\n\t\t\t\t * If the prompt is set to `consent`, then we need\n\t\t\t\t * to require the user to consent to the scopes.\n\t\t\t\t *\n\t\t\t\t * This means the code now needs to be treated as a\n\t\t\t\t * consent request.\n\t\t\t\t *\n\t\t\t\t * once the user consents, the code will be updated\n\t\t\t\t * with the actual code. This is to prevent the\n\t\t\t\t * client from using the code before the user\n\t\t\t\t * consents.\n\t\t\t\t */\n\t\t\t\trequireConsent: query.prompt === \"consent\",\n\t\t\t\tstate: query.prompt === \"consent\" ? query.state : null,\n\t\t\t\tcodeChallenge: query.code_challenge,\n\t\t\t\tcodeChallengeMethod: query.code_challenge_method,\n\t\t\t\tnonce: query.nonce,\n\t\t\t}),\n\t\t\tidentifier: code,\n\t\t\texpiresAt,\n\t\t});\n\t} catch {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"server_error\",\n\t\t\t\t\"An error occurred while processing the request\",\n\t\t\t),\n\t\t);\n\t}\n\n\t// Consent is NOT required - redirect with the code immediately\n\tif (query.prompt !== \"consent\") {\n\t\tconst redirectURIWithCode = new URL(redirectURI);\n\t\tredirectURIWithCode.searchParams.set(\"code\", code);\n\t\tif (ctx.query.state) {\n\t\t\tredirectURIWithCode.searchParams.set(\"state\", ctx.query.state);\n\t\t}\n\t\tthrow ctx.redirect(redirectURIWithCode.toString());\n\t}\n\n\t// Consent is REQUIRED - redirect to consent page or show consent HTML\n\tif (options?.consentPage) {\n\t\t// Set cookie to support cookie-based consent flows\n\t\tawait ctx.setSignedCookie(\"oidc_consent_prompt\", code, ctx.context.secret, {\n\t\t\tmaxAge: 600,\n\t\t\tpath: \"/\",\n\t\t\tsameSite: \"lax\",\n\t\t});\n\n\t\t// Pass the consent code as a URL parameter to support URL-BASED consent flows\n\t\tconst urlParams = new URLSearchParams();\n\t\turlParams.set(\"consent_code\", code);\n\t\turlParams.set(\"client_id\", client.clientId);\n\t\turlParams.set(\"scope\", requestScope.join(\" \"));\n\t\tconst consentURI = `${options.consentPage}?${urlParams.toString()}`;\n\n\t\tthrow ctx.redirect(consentURI);\n\t}\n\n\t// No consent page configured - fall back to direct redirect with code\n\tconst redirectURIWithCode = new URL(redirectURI);\n\tredirectURIWithCode.searchParams.set(\"code\", code);\n\tif (ctx.query.state) {\n\t\tredirectURIWithCode.searchParams.set(\"state\", ctx.query.state);\n\t}\n\tthrow ctx.redirect(redirectURIWithCode.toString());\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"authorize.mjs","names":["redirectURIWithCode"],"sources":["../../../src/plugins/mcp/authorize.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { APIError } from \"better-call\";\nimport { getSessionFromCtx } from \"../../api\";\nimport { generateRandomString } from \"../../crypto\";\nimport type { OAuthApplication } from \"../oidc-provider/schema\";\nimport type {\n\tAuthorizationQuery,\n\tClient,\n\tOIDCOptions,\n} from \"../oidc-provider/types\";\n\nfunction redirectErrorURL(url: string, error: string, description: string) {\n\treturn `${url}${\n\t\turl.includes(\"?\") ? \"&\" : \"?\"\n\t}error=${error}&error_description=${description}`;\n}\n\nexport async function authorizeMCPOAuth(\n\tctx: GenericEndpointContext,\n\toptions: OIDCOptions,\n) {\n\tctx.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n\tctx.setHeader(\"Access-Control-Allow-Methods\", \"POST, OPTIONS\");\n\tctx.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, Authorization\");\n\tctx.setHeader(\"Access-Control-Max-Age\", \"86400\");\n\tconst opts = {\n\t\tcodeExpiresIn: 600,\n\t\tdefaultScope: \"openid\",\n\t\t...options,\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?.scopes || []),\n\t\t],\n\t};\n\tif (!ctx.request) {\n\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\terror_description: \"request not found\",\n\t\t\terror: \"invalid_request\",\n\t\t});\n\t}\n\tconst session = await getSessionFromCtx(ctx);\n\tif (!session) {\n\t\t/**\n\t\t * If the user is not logged in, we need to redirect them to the\n\t\t * login page.\n\t\t */\n\t\tawait ctx.setSignedCookie(\n\t\t\t\"oidc_login_prompt\",\n\t\t\tJSON.stringify(ctx.query),\n\t\t\tctx.context.secret,\n\t\t\t{\n\t\t\t\tmaxAge: 600,\n\t\t\t\tpath: \"/\",\n\t\t\t\tsameSite: \"lax\",\n\t\t\t},\n\t\t);\n\t\tconst queryFromURL = ctx.request.url?.split(\"?\")[1]!;\n\t\tthrow ctx.redirect(`${options.loginPage}?${queryFromURL}`);\n\t}\n\n\tconst query = ctx.query as AuthorizationQuery;\n\tif (!query.client_id) {\n\t\tthrow ctx.redirect(`${ctx.context.baseURL}/error?error=invalid_client`);\n\t}\n\n\tif (!query.response_type) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\t`${ctx.context.baseURL}/error`,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"response_type is required\",\n\t\t\t),\n\t\t);\n\t}\n\n\tconst client = await ctx.context.adapter\n\t\t.findOne<OAuthApplication>({\n\t\t\tmodel: \"oauthApplication\",\n\t\t\twhere: [\n\t\t\t\t{\n\t\t\t\t\tfield: \"clientId\",\n\t\t\t\t\tvalue: ctx.query.client_id,\n\t\t\t\t},\n\t\t\t],\n\t\t})\n\t\t.then((res) => {\n\t\t\tif (!res) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...res,\n\t\t\t\tredirectUrls: res.redirectUrls.split(\",\"),\n\t\t\t\tmetadata: res.metadata ? JSON.parse(res.metadata) : {},\n\t\t\t} as Client;\n\t\t});\n\tif (!client) {\n\t\tthrow ctx.redirect(`${ctx.context.baseURL}/error?error=invalid_client`);\n\t}\n\tconst redirectURI = client.redirectUrls.find(\n\t\t(url) => url === ctx.query.redirect_uri,\n\t);\n\n\tif (!redirectURI || !query.redirect_uri) {\n\t\t/**\n\t\t * show UI error here warning the user that the redirect URI is invalid\n\t\t */\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"Invalid redirect URI\",\n\t\t});\n\t}\n\tif (client.disabled) {\n\t\tthrow ctx.redirect(`${ctx.context.baseURL}/error?error=client_disabled`);\n\t}\n\n\tif (query.response_type !== \"code\") {\n\t\tthrow ctx.redirect(\n\t\t\t`${ctx.context.baseURL}/error?error=unsupported_response_type`,\n\t\t);\n\t}\n\n\tconst requestScope =\n\t\tquery.scope?.split(\" \").filter((s) => s) || opts.defaultScope.split(\" \");\n\tconst invalidScopes = requestScope.filter((scope) => {\n\t\treturn !opts.scopes.includes(scope);\n\t});\n\tif (invalidScopes.length) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"invalid_scope\",\n\t\t\t\t`The following scopes are invalid: ${invalidScopes.join(\", \")}`,\n\t\t\t),\n\t\t);\n\t}\n\n\tif (\n\t\t(!query.code_challenge || !query.code_challenge_method) &&\n\t\toptions.requirePKCE\n\t) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"pkce is required\",\n\t\t\t),\n\t\t);\n\t}\n\n\tif (!query.code_challenge_method) {\n\t\tquery.code_challenge_method = \"plain\";\n\t}\n\n\tif (\n\t\t![\n\t\t\t\"s256\",\n\t\t\toptions.allowPlainCodeChallengeMethod ? \"plain\" : \"s256\",\n\t\t].includes(query.code_challenge_method?.toLowerCase() || \"\")\n\t) {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"invalid_request\",\n\t\t\t\t\"invalid code_challenge method\",\n\t\t\t),\n\t\t);\n\t}\n\n\tconst code = generateRandomString(32, \"a-z\", \"A-Z\", \"0-9\");\n\tconst codeExpiresInMs = opts.codeExpiresIn * 1000;\n\tconst expiresAt = new Date(Date.now() + codeExpiresInMs);\n\ttry {\n\t\t/**\n\t\t * Save the code in the database\n\t\t */\n\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\tvalue: JSON.stringify({\n\t\t\t\tclientId: client.clientId,\n\t\t\t\tredirectURI: query.redirect_uri,\n\t\t\t\tscope: requestScope,\n\t\t\t\tuserId: session.user.id,\n\t\t\t\tauthTime: new Date(session.session.createdAt).getTime(),\n\t\t\t\t/**\n\t\t\t\t * If the prompt is set to `consent`, then we need\n\t\t\t\t * to require the user to consent to the scopes.\n\t\t\t\t *\n\t\t\t\t * This means the code now needs to be treated as a\n\t\t\t\t * consent request.\n\t\t\t\t *\n\t\t\t\t * once the user consents, the code will be updated\n\t\t\t\t * with the actual code. This is to prevent the\n\t\t\t\t * client from using the code before the user\n\t\t\t\t * consents.\n\t\t\t\t */\n\t\t\t\trequireConsent: query.prompt === \"consent\",\n\t\t\t\tstate: query.prompt === \"consent\" ? query.state : null,\n\t\t\t\tcodeChallenge: query.code_challenge,\n\t\t\t\tcodeChallengeMethod: query.code_challenge_method,\n\t\t\t\tnonce: query.nonce,\n\t\t\t}),\n\t\t\tidentifier: code,\n\t\t\texpiresAt,\n\t\t});\n\t} catch {\n\t\tthrow ctx.redirect(\n\t\t\tredirectErrorURL(\n\t\t\t\tquery.redirect_uri,\n\t\t\t\t\"server_error\",\n\t\t\t\t\"An error occurred while processing the request\",\n\t\t\t),\n\t\t);\n\t}\n\n\t// Consent is NOT required - redirect with the code immediately\n\tif (query.prompt !== \"consent\") {\n\t\tconst redirectURIWithCode = new URL(redirectURI);\n\t\tredirectURIWithCode.searchParams.set(\"code\", code);\n\t\tif (ctx.query.state) {\n\t\t\tredirectURIWithCode.searchParams.set(\"state\", ctx.query.state);\n\t\t}\n\t\tthrow ctx.redirect(redirectURIWithCode.toString());\n\t}\n\n\t// Consent is REQUIRED - redirect to consent page or show consent HTML\n\tif (options?.consentPage) {\n\t\t// Set cookie to support cookie-based consent flows\n\t\tawait ctx.setSignedCookie(\"oidc_consent_prompt\", code, ctx.context.secret, {\n\t\t\tmaxAge: 600,\n\t\t\tpath: \"/\",\n\t\t\tsameSite: \"lax\",\n\t\t});\n\n\t\t// Pass the consent code as a URL parameter to support URL-BASED consent flows\n\t\tconst urlParams = new URLSearchParams();\n\t\turlParams.set(\"consent_code\", code);\n\t\turlParams.set(\"client_id\", client.clientId);\n\t\turlParams.set(\"scope\", requestScope.join(\" \"));\n\t\tconst consentURI = `${options.consentPage}?${urlParams.toString()}`;\n\n\t\tthrow ctx.redirect(consentURI);\n\t}\n\n\t// No consent page configured - fall back to direct redirect with code\n\tconst redirectURIWithCode = new URL(redirectURI);\n\tredirectURIWithCode.searchParams.set(\"code\", code);\n\tif (ctx.query.state) {\n\t\tredirectURIWithCode.searchParams.set(\"state\", ctx.query.state);\n\t}\n\tthrow ctx.redirect(redirectURIWithCode.toString());\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { OAuthAccessToken, OIDCMetadata, OIDCOptions } from "../oidc-provider/types.mjs";
2
2
  import "../oidc-provider/index.mjs";
3
3
  import { BetterAuthOptions, GenericEndpointContext } from "@better-auth/core";
4
- import * as better_call716 from "better-call";
4
+ import * as better_call287 from "better-call";
5
5
  import * as z from "zod";
6
6
 
7
7
  //#region src/plugins/mcp/index.d.ts
@@ -24,18 +24,18 @@ declare const mcp: (options: MCPOptions) => {
24
24
  hooks: {
25
25
  after: {
26
26
  matcher(): true;
27
- handler: (inputContext: better_call716.MiddlewareInputContext<better_call716.MiddlewareOptions>) => Promise<void>;
27
+ handler: (inputContext: better_call287.MiddlewareInputContext<better_call287.MiddlewareOptions>) => Promise<void>;
28
28
  }[];
29
29
  };
30
30
  endpoints: {
31
- oAuthConsent: better_call716.StrictEndpoint<"/oauth2/consent", {
31
+ oAuthConsent: better_call287.StrictEndpoint<"/oauth2/consent", {
32
32
  method: "POST";
33
33
  operationId: string;
34
34
  body: z.ZodObject<{
35
35
  accept: z.ZodBoolean;
36
36
  consent_code: z.ZodOptional<z.ZodNullable<z.ZodOptional<z.ZodString>>>;
37
37
  }, z.core.$strip>;
38
- use: ((inputContext: better_call716.MiddlewareInputContext<better_call716.MiddlewareOptions>) => Promise<{
38
+ use: ((inputContext: better_call287.MiddlewareInputContext<better_call287.MiddlewareOptions>) => Promise<{
39
39
  session: {
40
40
  session: Record<string, any> & {
41
41
  id: string;
@@ -107,13 +107,13 @@ declare const mcp: (options: MCPOptions) => {
107
107
  }, {
108
108
  redirectURI: string;
109
109
  }>;
110
- getMcpOAuthConfig: better_call716.StrictEndpoint<"/.well-known/oauth-authorization-server", {
110
+ getMcpOAuthConfig: better_call287.StrictEndpoint<"/.well-known/oauth-authorization-server", {
111
111
  method: "GET";
112
112
  metadata: {
113
113
  readonly scope: "server";
114
114
  };
115
115
  }, OIDCMetadata | null>;
116
- getMCPProtectedResource: better_call716.StrictEndpoint<"/.well-known/oauth-protected-resource", {
116
+ getMCPProtectedResource: better_call287.StrictEndpoint<"/.well-known/oauth-protected-resource", {
117
117
  method: "GET";
118
118
  metadata: {
119
119
  readonly scope: "server";
@@ -126,7 +126,7 @@ declare const mcp: (options: MCPOptions) => {
126
126
  bearer_methods_supported: string[];
127
127
  resource_signing_alg_values_supported: string[];
128
128
  }>;
129
- mcpOAuthAuthorize: better_call716.StrictEndpoint<"/mcp/authorize", {
129
+ mcpOAuthAuthorize: better_call287.StrictEndpoint<"/mcp/authorize", {
130
130
  method: "GET";
131
131
  query: z.ZodRecord<z.ZodString, z.ZodAny>;
132
132
  metadata: {
@@ -149,7 +149,7 @@ declare const mcp: (options: MCPOptions) => {
149
149
  };
150
150
  };
151
151
  }, void>;
152
- mcpOAuthToken: better_call716.StrictEndpoint<"/mcp/token", {
152
+ mcpOAuthToken: better_call287.StrictEndpoint<"/mcp/token", {
153
153
  method: "POST";
154
154
  body: z.ZodRecord<z.ZodAny, z.ZodAny>;
155
155
  metadata: {
@@ -170,7 +170,7 @@ declare const mcp: (options: MCPOptions) => {
170
170
  scope: string;
171
171
  id_token: string | undefined;
172
172
  }>;
173
- registerMcpClient: better_call716.StrictEndpoint<"/mcp/register", {
173
+ registerMcpClient: better_call287.StrictEndpoint<"/mcp/register", {
174
174
  method: "POST";
175
175
  body: z.ZodObject<{
176
176
  redirect_uris: z.ZodArray<z.ZodString>;
@@ -288,7 +288,7 @@ declare const mcp: (options: MCPOptions) => {
288
288
  };
289
289
  };
290
290
  }, Response>;
291
- getMcpSession: better_call716.StrictEndpoint<"/mcp/get-session", {
291
+ getMcpSession: better_call287.StrictEndpoint<"/mcp/get-session", {
292
292
  method: "GET";
293
293
  requireHeaders: true;
294
294
  }, OAuthAccessToken | null>;
@@ -1,5 +1,5 @@
1
- import * as _better_auth_core10 from "@better-auth/core";
2
- import * as better_call52 from "better-call";
1
+ import * as _better_auth_core8 from "@better-auth/core";
2
+ import * as better_call43 from "better-call";
3
3
  import * as z from "zod";
4
4
 
5
5
  //#region src/plugins/multi-session/index.d.ts
@@ -29,7 +29,7 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
29
29
  *
30
30
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-list-device-sessions)
31
31
  */
32
- listDeviceSessions: better_call52.StrictEndpoint<"/multi-session/list-device-sessions", {
32
+ listDeviceSessions: better_call43.StrictEndpoint<"/multi-session/list-device-sessions", {
33
33
  method: "GET";
34
34
  requireHeaders: true;
35
35
  }, {
@@ -68,13 +68,13 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
68
68
  *
69
69
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-set-active)
70
70
  */
71
- setActiveSession: better_call52.StrictEndpoint<"/multi-session/set-active", {
71
+ setActiveSession: better_call43.StrictEndpoint<"/multi-session/set-active", {
72
72
  method: "POST";
73
73
  body: z.ZodObject<{
74
74
  sessionToken: z.ZodString;
75
75
  }, z.core.$strip>;
76
76
  requireHeaders: true;
77
- use: ((inputContext: better_call52.MiddlewareInputContext<better_call52.MiddlewareOptions>) => Promise<{
77
+ use: ((inputContext: better_call43.MiddlewareInputContext<better_call43.MiddlewareOptions>) => Promise<{
78
78
  session: {
79
79
  session: Record<string, any> & {
80
80
  id: string;
@@ -155,13 +155,13 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
155
155
  *
156
156
  * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/multi-session#api-method-multi-session-revoke)
157
157
  */
158
- revokeDeviceSession: better_call52.StrictEndpoint<"/multi-session/revoke", {
158
+ revokeDeviceSession: better_call43.StrictEndpoint<"/multi-session/revoke", {
159
159
  method: "POST";
160
160
  body: z.ZodObject<{
161
161
  sessionToken: z.ZodString;
162
162
  }, z.core.$strip>;
163
163
  requireHeaders: true;
164
- use: ((inputContext: better_call52.MiddlewareInputContext<better_call52.MiddlewareOptions>) => Promise<{
164
+ use: ((inputContext: better_call43.MiddlewareInputContext<better_call43.MiddlewareOptions>) => Promise<{
165
165
  session: {
166
166
  session: Record<string, any> & {
167
167
  id: string;
@@ -212,8 +212,8 @@ declare const multiSession: (options?: MultiSessionConfig | undefined) => {
212
212
  };
213
213
  hooks: {
214
214
  after: {
215
- matcher: (context: _better_auth_core10.HookEndpointContext) => boolean;
216
- handler: (inputContext: better_call52.MiddlewareInputContext<better_call52.MiddlewareOptions>) => Promise<void>;
215
+ matcher: (context: _better_auth_core8.HookEndpointContext) => boolean;
216
+ handler: (inputContext: better_call43.MiddlewareInputContext<better_call43.MiddlewareOptions>) => Promise<void>;
217
217
  }[];
218
218
  };
219
219
  options: MultiSessionConfig | undefined;
@@ -1,5 +1,5 @@
1
- import * as _better_auth_core12 from "@better-auth/core";
2
- import * as better_call68 from "better-call";
1
+ import * as _better_auth_core10 from "@better-auth/core";
2
+ import * as better_call212 from "better-call";
3
3
  import * as z from "zod";
4
4
 
5
5
  //#region src/plugins/oauth-proxy/index.d.ts
@@ -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_call68.StrictEndpoint<"/oauth-proxy-callback", {
37
+ oAuthProxy: better_call212.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_call68.MiddlewareInputContext<better_call68.MiddlewareOptions>) => Promise<void>)[];
44
+ use: ((inputContext: better_call212.MiddlewareInputContext<better_call212.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_core12.HookEndpointContext): boolean;
75
- handler: (inputContext: better_call68.MiddlewareInputContext<better_call68.MiddlewareOptions>) => Promise<void>;
74
+ matcher(context: _better_auth_core10.HookEndpointContext): boolean;
75
+ handler: (inputContext: better_call212.MiddlewareInputContext<better_call212.MiddlewareOptions>) => Promise<void>;
76
76
  }[];
77
77
  after: {
78
- matcher(context: _better_auth_core12.HookEndpointContext): boolean;
79
- handler: (inputContext: better_call68.MiddlewareInputContext<better_call68.MiddlewareOptions>) => Promise<void>;
78
+ matcher(context: _better_auth_core10.HookEndpointContext): boolean;
79
+ handler: (inputContext: better_call212.MiddlewareInputContext<better_call212.MiddlewareOptions>) => Promise<void>;
80
80
  }[];
81
81
  };
82
82
  };
@@ -8,7 +8,7 @@ import { APIError } from "better-call";
8
8
 
9
9
  //#region src/plugins/oidc-provider/authorize.ts
10
10
  function formatErrorURL(url, error, description) {
11
- return `${url.includes("?") ? "&" : "?"}error=${error}&error_description=${description}`;
11
+ return `${url}${url.includes("?") ? "&" : "?"}error=${error}&error_description=${description}`;
12
12
  }
13
13
  function getErrorURL(ctx, error, description) {
14
14
  return formatErrorURL(ctx.context.options.onAPIError?.errorURL || `${ctx.context.baseURL}/error`, error, description);