better-auth 1.4.9 → 1.5.0-beta.1

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 (228) hide show
  1. package/dist/api/index.d.mts +396 -395
  2. package/dist/api/index.mjs +6 -4
  3. package/dist/api/index.mjs.map +1 -1
  4. package/dist/api/middlewares/origin-check.d.mts +3 -3
  5. package/dist/api/middlewares/origin-check.mjs +14 -4
  6. package/dist/api/middlewares/origin-check.mjs.map +1 -1
  7. package/dist/api/routes/account.d.mts +11 -11
  8. package/dist/api/routes/account.mjs +59 -30
  9. package/dist/api/routes/account.mjs.map +1 -1
  10. package/dist/api/routes/callback.d.mts +2 -2
  11. package/dist/api/routes/email-verification.d.mts +4 -4
  12. package/dist/api/routes/email-verification.mjs +14 -14
  13. package/dist/api/routes/email-verification.mjs.map +1 -1
  14. package/dist/api/routes/error.d.mts +2 -2
  15. package/dist/api/routes/ok.d.mts +2 -2
  16. package/dist/api/routes/reset-password.d.mts +5 -5
  17. package/dist/api/routes/reset-password.mjs +9 -7
  18. package/dist/api/routes/reset-password.mjs.map +1 -1
  19. package/dist/api/routes/session.d.mts +14 -14
  20. package/dist/api/routes/session.mjs +31 -11
  21. package/dist/api/routes/session.mjs.map +1 -1
  22. package/dist/api/routes/sign-in.d.mts +3 -3
  23. package/dist/api/routes/sign-in.mjs +22 -17
  24. package/dist/api/routes/sign-in.mjs.map +1 -1
  25. package/dist/api/routes/sign-out.d.mts +2 -2
  26. package/dist/api/routes/sign-up.d.mts +2 -2
  27. package/dist/api/routes/sign-up.mjs +15 -12
  28. package/dist/api/routes/sign-up.mjs.map +1 -1
  29. package/dist/api/routes/update-user.d.mts +13 -13
  30. package/dist/api/routes/update-user.mjs +29 -24
  31. package/dist/api/routes/update-user.mjs.map +1 -1
  32. package/dist/api/to-auth-endpoints.mjs +7 -6
  33. package/dist/api/to-auth-endpoints.mjs.map +1 -1
  34. package/dist/client/lynx/index.d.mts +15 -15
  35. package/dist/client/plugins/index.d.mts +12 -2
  36. package/dist/client/plugins/index.mjs +11 -1
  37. package/dist/client/react/index.d.mts +13 -13
  38. package/dist/client/solid/index.d.mts +13 -13
  39. package/dist/client/svelte/index.d.mts +15 -15
  40. package/dist/client/types.d.mts +4 -1
  41. package/dist/client/vue/index.d.mts +13 -13
  42. package/dist/context/create-context.mjs +2 -2
  43. package/dist/context/create-context.mjs.map +1 -1
  44. package/dist/context/helpers.mjs +2 -2
  45. package/dist/context/helpers.mjs.map +1 -1
  46. package/dist/db/field.d.mts +6 -6
  47. package/dist/db/schema.mjs +14 -5
  48. package/dist/db/schema.mjs.map +1 -1
  49. package/dist/index.d.mts +1 -1
  50. package/dist/integrations/next-js.d.mts +4 -4
  51. package/dist/integrations/svelte-kit.d.mts +2 -2
  52. package/dist/integrations/tanstack-start.d.mts +4 -4
  53. package/dist/oauth2/link-account.mjs +3 -2
  54. package/dist/oauth2/link-account.mjs.map +1 -1
  55. package/dist/oauth2/state.mjs +3 -3
  56. package/dist/oauth2/state.mjs.map +1 -1
  57. package/dist/plugins/admin/admin.d.mts +200 -137
  58. package/dist/plugins/admin/admin.mjs +3 -4
  59. package/dist/plugins/admin/admin.mjs.map +1 -1
  60. package/dist/plugins/admin/client.d.mts +87 -0
  61. package/dist/plugins/admin/client.mjs +3 -1
  62. package/dist/plugins/admin/client.mjs.map +1 -1
  63. package/dist/plugins/admin/error-codes.d.mts +90 -0
  64. package/dist/plugins/admin/error-codes.mjs.map +1 -1
  65. package/dist/plugins/admin/routes.mjs +40 -46
  66. package/dist/plugins/admin/routes.mjs.map +1 -1
  67. package/dist/plugins/anonymous/client.d.mts +19 -0
  68. package/dist/plugins/anonymous/client.mjs +4 -1
  69. package/dist/plugins/anonymous/client.mjs.map +1 -1
  70. package/dist/plugins/anonymous/error-codes.d.mts +22 -0
  71. package/dist/plugins/anonymous/index.d.mts +21 -9
  72. package/dist/plugins/anonymous/index.mjs +5 -5
  73. package/dist/plugins/anonymous/index.mjs.map +1 -1
  74. package/dist/plugins/api-key/client.d.mts +103 -0
  75. package/dist/plugins/api-key/client.mjs +4 -1
  76. package/dist/plugins/api-key/client.mjs.map +1 -1
  77. package/dist/plugins/api-key/error-codes.d.mts +106 -0
  78. package/dist/plugins/api-key/error-codes.mjs +34 -0
  79. package/dist/plugins/api-key/error-codes.mjs.map +1 -0
  80. package/dist/plugins/api-key/index.d.mts +181 -112
  81. package/dist/plugins/api-key/index.mjs +7 -34
  82. package/dist/plugins/api-key/index.mjs.map +1 -1
  83. package/dist/plugins/api-key/rate-limit.mjs +3 -2
  84. package/dist/plugins/api-key/rate-limit.mjs.map +1 -1
  85. package/dist/plugins/api-key/routes/create-api-key.mjs +19 -17
  86. package/dist/plugins/api-key/routes/create-api-key.mjs.map +1 -1
  87. package/dist/plugins/api-key/routes/delete-api-key.mjs +7 -5
  88. package/dist/plugins/api-key/routes/delete-api-key.mjs.map +1 -1
  89. package/dist/plugins/api-key/routes/get-api-key.mjs +5 -3
  90. package/dist/plugins/api-key/routes/get-api-key.mjs.map +1 -1
  91. package/dist/plugins/api-key/routes/update-api-key.mjs +18 -16
  92. package/dist/plugins/api-key/routes/update-api-key.mjs.map +1 -1
  93. package/dist/plugins/api-key/routes/verify-api-key.mjs +16 -35
  94. package/dist/plugins/api-key/routes/verify-api-key.mjs.map +1 -1
  95. package/dist/plugins/bearer/index.d.mts +3 -3
  96. package/dist/plugins/captcha/index.d.mts +2 -2
  97. package/dist/plugins/captcha/index.mjs +3 -3
  98. package/dist/plugins/captcha/index.mjs.map +1 -1
  99. package/dist/plugins/captcha/verify-handlers/captchafox.mjs +2 -2
  100. package/dist/plugins/captcha/verify-handlers/captchafox.mjs.map +1 -1
  101. package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +2 -2
  102. package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs.map +1 -1
  103. package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +2 -2
  104. package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs.map +1 -1
  105. package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +2 -2
  106. package/dist/plugins/captcha/verify-handlers/h-captcha.mjs.map +1 -1
  107. package/dist/plugins/custom-session/index.d.mts +5 -5
  108. package/dist/plugins/device-authorization/index.d.mts +54 -18
  109. package/dist/plugins/device-authorization/routes.mjs +18 -18
  110. package/dist/plugins/device-authorization/routes.mjs.map +1 -1
  111. package/dist/plugins/email-otp/client.d.mts +15 -0
  112. package/dist/plugins/email-otp/client.mjs +4 -1
  113. package/dist/plugins/email-otp/client.mjs.map +1 -1
  114. package/dist/plugins/email-otp/error-codes.d.mts +18 -0
  115. package/dist/plugins/email-otp/error-codes.mjs +12 -0
  116. package/dist/plugins/email-otp/error-codes.mjs.map +1 -0
  117. package/dist/plugins/email-otp/index.d.mts +64 -55
  118. package/dist/plugins/email-otp/index.mjs +4 -3
  119. package/dist/plugins/email-otp/index.mjs.map +1 -1
  120. package/dist/plugins/email-otp/routes.mjs +30 -35
  121. package/dist/plugins/email-otp/routes.mjs.map +1 -1
  122. package/dist/plugins/generic-oauth/client.d.mts +27 -0
  123. package/dist/plugins/generic-oauth/client.mjs +4 -1
  124. package/dist/plugins/generic-oauth/client.mjs.map +1 -1
  125. package/dist/plugins/generic-oauth/error-codes.d.mts +30 -0
  126. package/dist/plugins/generic-oauth/index.d.mts +55 -37
  127. package/dist/plugins/generic-oauth/index.mjs +4 -4
  128. package/dist/plugins/generic-oauth/index.mjs.map +1 -1
  129. package/dist/plugins/generic-oauth/routes.mjs +11 -12
  130. package/dist/plugins/generic-oauth/routes.mjs.map +1 -1
  131. package/dist/plugins/haveibeenpwned/index.d.mts +7 -4
  132. package/dist/plugins/haveibeenpwned/index.mjs +5 -4
  133. package/dist/plugins/haveibeenpwned/index.mjs.map +1 -1
  134. package/dist/plugins/index.d.mts +4 -2
  135. package/dist/plugins/index.mjs +6 -4
  136. package/dist/plugins/jwt/index.d.mts +9 -9
  137. package/dist/plugins/jwt/index.mjs +2 -2
  138. package/dist/plugins/jwt/index.mjs.map +1 -1
  139. package/dist/plugins/last-login-method/index.d.mts +4 -4
  140. package/dist/plugins/magic-link/index.d.mts +4 -4
  141. package/dist/plugins/mcp/authorize.mjs +1 -1
  142. package/dist/plugins/mcp/authorize.mjs.map +1 -1
  143. package/dist/plugins/mcp/index.d.mts +10 -10
  144. package/dist/plugins/multi-session/client.d.mts +10 -14
  145. package/dist/plugins/multi-session/client.mjs +5 -2
  146. package/dist/plugins/multi-session/client.mjs.map +1 -1
  147. package/dist/plugins/multi-session/error-codes.d.mts +10 -0
  148. package/dist/plugins/multi-session/error-codes.mjs +8 -0
  149. package/dist/plugins/multi-session/error-codes.mjs.map +1 -0
  150. package/dist/plugins/multi-session/index.d.mts +18 -14
  151. package/dist/plugins/multi-session/index.mjs +6 -7
  152. package/dist/plugins/multi-session/index.mjs.map +1 -1
  153. package/dist/plugins/oauth-proxy/index.d.mts +8 -8
  154. package/dist/plugins/oidc-provider/authorize.mjs +1 -1
  155. package/dist/plugins/oidc-provider/authorize.mjs.map +1 -1
  156. package/dist/plugins/oidc-provider/error.mjs +1 -1
  157. package/dist/plugins/oidc-provider/error.mjs.map +1 -1
  158. package/dist/plugins/oidc-provider/index.d.mts +15 -15
  159. package/dist/plugins/one-tap/client.d.mts +2 -2
  160. package/dist/plugins/one-tap/index.d.mts +2 -2
  161. package/dist/plugins/one-time-token/index.d.mts +5 -5
  162. package/dist/plugins/open-api/index.d.mts +3 -3
  163. package/dist/plugins/organization/client.d.mts +229 -2
  164. package/dist/plugins/organization/client.mjs +3 -1
  165. package/dist/plugins/organization/client.mjs.map +1 -1
  166. package/dist/plugins/organization/error-codes.d.mts +224 -56
  167. package/dist/plugins/organization/organization.d.mts +7 -7
  168. package/dist/plugins/organization/organization.mjs +4 -4
  169. package/dist/plugins/organization/organization.mjs.map +1 -1
  170. package/dist/plugins/organization/routes/crud-access-control.d.mts +22 -22
  171. package/dist/plugins/organization/routes/crud-access-control.mjs +40 -39
  172. package/dist/plugins/organization/routes/crud-access-control.mjs.map +1 -1
  173. package/dist/plugins/organization/routes/crud-invites.d.mts +58 -58
  174. package/dist/plugins/organization/routes/crud-invites.mjs +42 -40
  175. package/dist/plugins/organization/routes/crud-invites.mjs.map +1 -1
  176. package/dist/plugins/organization/routes/crud-members.d.mts +67 -67
  177. package/dist/plugins/organization/routes/crud-members.mjs +41 -54
  178. package/dist/plugins/organization/routes/crud-members.mjs.map +1 -1
  179. package/dist/plugins/organization/routes/crud-org.d.mts +51 -51
  180. package/dist/plugins/organization/routes/crud-org.mjs +28 -25
  181. package/dist/plugins/organization/routes/crud-org.mjs.map +1 -1
  182. package/dist/plugins/organization/routes/crud-team.d.mts +77 -77
  183. package/dist/plugins/organization/routes/crud-team.mjs +41 -47
  184. package/dist/plugins/organization/routes/crud-team.mjs.map +1 -1
  185. package/dist/plugins/phone-number/client.d.mts +51 -0
  186. package/dist/plugins/phone-number/client.mjs +4 -1
  187. package/dist/plugins/phone-number/client.mjs.map +1 -1
  188. package/dist/plugins/phone-number/error-codes.d.mts +54 -0
  189. package/dist/plugins/phone-number/index.d.mts +81 -45
  190. package/dist/plugins/phone-number/index.mjs +2 -2
  191. package/dist/plugins/phone-number/index.mjs.map +1 -1
  192. package/dist/plugins/phone-number/routes.mjs +27 -28
  193. package/dist/plugins/phone-number/routes.mjs.map +1 -1
  194. package/dist/plugins/siwe/index.d.mts +3 -3
  195. package/dist/plugins/siwe/index.mjs +7 -6
  196. package/dist/plugins/siwe/index.mjs.map +1 -1
  197. package/dist/plugins/two-factor/backup-codes/index.mjs +7 -7
  198. package/dist/plugins/two-factor/backup-codes/index.mjs.map +1 -1
  199. package/dist/plugins/two-factor/client.d.mts +39 -0
  200. package/dist/plugins/two-factor/client.mjs +4 -1
  201. package/dist/plugins/two-factor/client.mjs.map +1 -1
  202. package/dist/plugins/two-factor/error-code.d.mts +36 -9
  203. package/dist/plugins/two-factor/index.d.mts +54 -27
  204. package/dist/plugins/two-factor/index.mjs +4 -5
  205. package/dist/plugins/two-factor/index.mjs.map +1 -1
  206. package/dist/plugins/two-factor/otp/index.mjs +8 -6
  207. package/dist/plugins/two-factor/otp/index.mjs.map +1 -1
  208. package/dist/plugins/two-factor/totp/index.mjs +16 -8
  209. package/dist/plugins/two-factor/totp/index.mjs.map +1 -1
  210. package/dist/plugins/two-factor/verify-two-factor.mjs +9 -6
  211. package/dist/plugins/two-factor/verify-two-factor.mjs.map +1 -1
  212. package/dist/plugins/username/client.d.mts +35 -0
  213. package/dist/plugins/username/client.mjs +4 -1
  214. package/dist/plugins/username/client.mjs.map +1 -1
  215. package/dist/plugins/username/error-codes.d.mts +32 -8
  216. package/dist/plugins/username/index.d.mts +41 -17
  217. package/dist/plugins/username/index.mjs +21 -31
  218. package/dist/plugins/username/index.mjs.map +1 -1
  219. package/dist/plugins/username/schema.d.mts +3 -3
  220. package/dist/test-utils/test-instance.d.mts +1349 -1198
  221. package/dist/utils/is-api-error.d.mts +7 -0
  222. package/dist/utils/is-api-error.mjs +11 -0
  223. package/dist/utils/is-api-error.mjs.map +1 -0
  224. package/dist/utils/password.mjs +3 -3
  225. package/dist/utils/password.mjs.map +1 -1
  226. package/dist/utils/plugin-helper.mjs +2 -2
  227. package/dist/utils/plugin-helper.mjs.map +1 -1
  228. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"link-account.mjs","names":["e: any"],"sources":["../../src/oauth2/link-account.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { isDevelopment, logger } from \"@better-auth/core/env\";\nimport { APIError, createEmailVerificationToken } from \"../api\";\nimport { setAccountCookie } from \"../cookies/session-store\";\nimport type { Account, User } from \"../types\";\nimport { setTokenUtil } from \"./utils\";\n\nexport async function handleOAuthUserInfo(\n\tc: GenericEndpointContext,\n\topts: {\n\t\tuserInfo: Omit<User, \"createdAt\" | \"updatedAt\">;\n\t\taccount: Omit<Account, \"id\" | \"userId\" | \"createdAt\" | \"updatedAt\">;\n\t\tcallbackURL?: string | undefined;\n\t\tdisableSignUp?: boolean | undefined;\n\t\toverrideUserInfo?: boolean | undefined;\n\t\tisTrustedProvider?: boolean | undefined;\n\t},\n) {\n\tconst { userInfo, account, callbackURL, disableSignUp, overrideUserInfo } =\n\t\topts;\n\tconst dbUser = await c.context.internalAdapter\n\t\t.findOAuthUser(\n\t\t\tuserInfo.email.toLowerCase(),\n\t\t\taccount.accountId,\n\t\t\taccount.providerId,\n\t\t)\n\t\t.catch((e) => {\n\t\t\tlogger.error(\n\t\t\t\t\"Better auth was unable to query your database.\\nError: \",\n\t\t\t\te,\n\t\t\t);\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=internal_server_error`);\n\t\t});\n\tlet user = dbUser?.user;\n\tlet isRegister = !user;\n\n\tif (dbUser) {\n\t\tconst hasBeenLinked = dbUser.accounts.find(\n\t\t\t(a) =>\n\t\t\t\ta.providerId === account.providerId &&\n\t\t\t\ta.accountId === account.accountId,\n\t\t);\n\t\tif (!hasBeenLinked) {\n\t\t\tconst trustedProviders =\n\t\t\t\tc.context.options.account?.accountLinking?.trustedProviders;\n\t\t\tconst isTrustedProvider =\n\t\t\t\topts.isTrustedProvider ||\n\t\t\t\ttrustedProviders?.includes(account.providerId as \"apple\");\n\t\t\tif (\n\t\t\t\t(!isTrustedProvider && !userInfo.emailVerified) ||\n\t\t\t\tc.context.options.account?.accountLinking?.enabled === false\n\t\t\t) {\n\t\t\t\tif (isDevelopment()) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`User already exist but account isn't linked to ${account.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\terror: \"account not linked\",\n\t\t\t\t\tdata: null,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait c.context.internalAdapter.linkAccount({\n\t\t\t\t\tproviderId: account.providerId,\n\t\t\t\t\taccountId: userInfo.id.toString(),\n\t\t\t\t\tuserId: dbUser.user.id,\n\t\t\t\t\taccessToken: await setTokenUtil(account.accessToken, c.context),\n\t\t\t\t\trefreshToken: await setTokenUtil(account.refreshToken, c.context),\n\t\t\t\t\tidToken: account.idToken,\n\t\t\t\t\taccessTokenExpiresAt: account.accessTokenExpiresAt,\n\t\t\t\t\trefreshTokenExpiresAt: account.refreshTokenExpiresAt,\n\t\t\t\t\tscope: account.scope,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(\"Unable to link account\", e);\n\t\t\t\treturn {\n\t\t\t\t\terror: \"unable to link account\",\n\t\t\t\t\tdata: null,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tuserInfo.emailVerified &&\n\t\t\t\t!dbUser.user.emailVerified &&\n\t\t\t\tuserInfo.email.toLowerCase() === dbUser.user.email\n\t\t\t) {\n\t\t\t\tawait c.context.internalAdapter.updateUser(dbUser.user.id, {\n\t\t\t\t\temailVerified: true,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tif (c.context.options.account?.updateAccountOnSignIn !== false) {\n\t\t\t\tconst updateData = Object.fromEntries(\n\t\t\t\t\tObject.entries({\n\t\t\t\t\t\tidToken: account.idToken,\n\t\t\t\t\t\taccessToken: await setTokenUtil(account.accessToken, c.context),\n\t\t\t\t\t\trefreshToken: await setTokenUtil(account.refreshToken, c.context),\n\t\t\t\t\t\taccessTokenExpiresAt: account.accessTokenExpiresAt,\n\t\t\t\t\t\trefreshTokenExpiresAt: account.refreshTokenExpiresAt,\n\t\t\t\t\t\tscope: account.scope,\n\t\t\t\t\t}).filter(([_, value]) => value !== undefined),\n\t\t\t\t);\n\t\t\t\tif (c.context.options.account?.storeAccountCookie) {\n\t\t\t\t\tawait setAccountCookie(c, {\n\t\t\t\t\t\t...account,\n\t\t\t\t\t\t...updateData,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (Object.keys(updateData).length > 0) {\n\t\t\t\t\tawait c.context.internalAdapter.updateAccount(\n\t\t\t\t\t\thasBeenLinked.id,\n\t\t\t\t\t\tupdateData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tuserInfo.emailVerified &&\n\t\t\t\t!dbUser.user.emailVerified &&\n\t\t\t\tuserInfo.email.toLowerCase() === dbUser.user.email\n\t\t\t) {\n\t\t\t\tawait c.context.internalAdapter.updateUser(dbUser.user.id, {\n\t\t\t\t\temailVerified: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (overrideUserInfo) {\n\t\t\tconst { id: _, ...restUserInfo } = userInfo;\n\t\t\t// update user info from the provider if overrideUserInfo is true\n\t\t\tuser = await c.context.internalAdapter.updateUser(dbUser.user.id, {\n\t\t\t\t...restUserInfo,\n\t\t\t\temail: userInfo.email.toLowerCase(),\n\t\t\t\temailVerified:\n\t\t\t\t\tuserInfo.email.toLowerCase() === dbUser.user.email\n\t\t\t\t\t\t? dbUser.user.emailVerified || userInfo.emailVerified\n\t\t\t\t\t\t: userInfo.emailVerified,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (disableSignUp) {\n\t\t\treturn {\n\t\t\t\terror: \"signup disabled\",\n\t\t\t\tdata: null,\n\t\t\t\tisRegister: false,\n\t\t\t};\n\t\t}\n\t\ttry {\n\t\t\tconst { id: _, ...restUserInfo } = userInfo;\n\t\t\tconst accountData = {\n\t\t\t\taccessToken: await setTokenUtil(account.accessToken, c.context),\n\t\t\t\trefreshToken: await setTokenUtil(account.refreshToken, c.context),\n\t\t\t\tidToken: account.idToken,\n\t\t\t\taccessTokenExpiresAt: account.accessTokenExpiresAt,\n\t\t\t\trefreshTokenExpiresAt: account.refreshTokenExpiresAt,\n\t\t\t\tscope: account.scope,\n\t\t\t\tproviderId: account.providerId,\n\t\t\t\taccountId: userInfo.id.toString(),\n\t\t\t};\n\t\t\tconst { user: createdUser, account: createdAccount } =\n\t\t\t\tawait c.context.internalAdapter.createOAuthUser(\n\t\t\t\t\t{\n\t\t\t\t\t\t...restUserInfo,\n\t\t\t\t\t\temail: userInfo.email.toLowerCase(),\n\t\t\t\t\t},\n\t\t\t\t\taccountData,\n\t\t\t\t);\n\t\t\tuser = createdUser;\n\t\t\tif (c.context.options.account?.storeAccountCookie) {\n\t\t\t\tawait setAccountCookie(c, createdAccount);\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!userInfo.emailVerified &&\n\t\t\t\tuser &&\n\t\t\t\tc.context.options.emailVerification?.sendOnSignUp &&\n\t\t\t\tc.context.options.emailVerification?.sendVerificationEmail\n\t\t\t) {\n\t\t\t\tconst token = await createEmailVerificationToken(\n\t\t\t\t\tc.context.secret,\n\t\t\t\t\tuser.email,\n\t\t\t\t\tundefined,\n\t\t\t\t\tc.context.options.emailVerification?.expiresIn,\n\t\t\t\t);\n\t\t\t\tconst url = `${c.context.baseURL}/verify-email?token=${token}&callbackURL=${callbackURL}`;\n\t\t\t\tawait c.context.runInBackgroundOrAwait(\n\t\t\t\t\tc.context.options.emailVerification.sendVerificationEmail(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuser,\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tc.request,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (e: any) {\n\t\t\tlogger.error(e);\n\t\t\tif (e instanceof APIError) {\n\t\t\t\treturn {\n\t\t\t\t\terror: e.message,\n\t\t\t\t\tdata: null,\n\t\t\t\t\tisRegister: false,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\terror: \"unable to create user\",\n\t\t\t\tdata: null,\n\t\t\t\tisRegister: false,\n\t\t\t};\n\t\t}\n\t}\n\tif (!user) {\n\t\treturn {\n\t\t\terror: \"unable to create user\",\n\t\t\tdata: null,\n\t\t\tisRegister: false,\n\t\t};\n\t}\n\n\tconst session = await c.context.internalAdapter.createSession(user.id);\n\tif (!session) {\n\t\treturn {\n\t\t\terror: \"unable to create session\",\n\t\t\tdata: null,\n\t\t\tisRegister: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tdata: {\n\t\t\tsession,\n\t\t\tuser,\n\t\t},\n\t\terror: null,\n\t\tisRegister,\n\t};\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"link-account.mjs","names":["e: any"],"sources":["../../src/oauth2/link-account.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { isDevelopment, logger } from \"@better-auth/core/env\";\nimport { createEmailVerificationToken } from \"../api\";\nimport { setAccountCookie } from \"../cookies/session-store\";\nimport type { Account, User } from \"../types\";\nimport { isAPIError } from \"../utils/is-api-error\";\nimport { setTokenUtil } from \"./utils\";\n\nexport async function handleOAuthUserInfo(\n\tc: GenericEndpointContext,\n\topts: {\n\t\tuserInfo: Omit<User, \"createdAt\" | \"updatedAt\">;\n\t\taccount: Omit<Account, \"id\" | \"userId\" | \"createdAt\" | \"updatedAt\">;\n\t\tcallbackURL?: string | undefined;\n\t\tdisableSignUp?: boolean | undefined;\n\t\toverrideUserInfo?: boolean | undefined;\n\t\tisTrustedProvider?: boolean | undefined;\n\t},\n) {\n\tconst { userInfo, account, callbackURL, disableSignUp, overrideUserInfo } =\n\t\topts;\n\tconst dbUser = await c.context.internalAdapter\n\t\t.findOAuthUser(\n\t\t\tuserInfo.email.toLowerCase(),\n\t\t\taccount.accountId,\n\t\t\taccount.providerId,\n\t\t)\n\t\t.catch((e) => {\n\t\t\tlogger.error(\n\t\t\t\t\"Better auth was unable to query your database.\\nError: \",\n\t\t\t\te,\n\t\t\t);\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=internal_server_error`);\n\t\t});\n\tlet user = dbUser?.user;\n\tlet isRegister = !user;\n\n\tif (dbUser) {\n\t\tconst hasBeenLinked = dbUser.accounts.find(\n\t\t\t(a) =>\n\t\t\t\ta.providerId === account.providerId &&\n\t\t\t\ta.accountId === account.accountId,\n\t\t);\n\t\tif (!hasBeenLinked) {\n\t\t\tconst trustedProviders =\n\t\t\t\tc.context.options.account?.accountLinking?.trustedProviders;\n\t\t\tconst isTrustedProvider =\n\t\t\t\topts.isTrustedProvider ||\n\t\t\t\ttrustedProviders?.includes(account.providerId as \"apple\");\n\t\t\tif (\n\t\t\t\t(!isTrustedProvider && !userInfo.emailVerified) ||\n\t\t\t\tc.context.options.account?.accountLinking?.enabled === false\n\t\t\t) {\n\t\t\t\tif (isDevelopment()) {\n\t\t\t\t\tlogger.warn(\n\t\t\t\t\t\t`User already exist but account isn't linked to ${account.providerId}. To read more about how account linking works in Better Auth see https://www.better-auth.com/docs/concepts/users-accounts#account-linking.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\terror: \"account not linked\",\n\t\t\t\t\tdata: null,\n\t\t\t\t};\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait c.context.internalAdapter.linkAccount({\n\t\t\t\t\tproviderId: account.providerId,\n\t\t\t\t\taccountId: userInfo.id.toString(),\n\t\t\t\t\tuserId: dbUser.user.id,\n\t\t\t\t\taccessToken: await setTokenUtil(account.accessToken, c.context),\n\t\t\t\t\trefreshToken: await setTokenUtil(account.refreshToken, c.context),\n\t\t\t\t\tidToken: account.idToken,\n\t\t\t\t\taccessTokenExpiresAt: account.accessTokenExpiresAt,\n\t\t\t\t\trefreshTokenExpiresAt: account.refreshTokenExpiresAt,\n\t\t\t\t\tscope: account.scope,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error(\"Unable to link account\", e);\n\t\t\t\treturn {\n\t\t\t\t\terror: \"unable to link account\",\n\t\t\t\t\tdata: null,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tuserInfo.emailVerified &&\n\t\t\t\t!dbUser.user.emailVerified &&\n\t\t\t\tuserInfo.email.toLowerCase() === dbUser.user.email\n\t\t\t) {\n\t\t\t\tawait c.context.internalAdapter.updateUser(dbUser.user.id, {\n\t\t\t\t\temailVerified: true,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tif (c.context.options.account?.updateAccountOnSignIn !== false) {\n\t\t\t\tconst updateData = Object.fromEntries(\n\t\t\t\t\tObject.entries({\n\t\t\t\t\t\tidToken: account.idToken,\n\t\t\t\t\t\taccessToken: await setTokenUtil(account.accessToken, c.context),\n\t\t\t\t\t\trefreshToken: await setTokenUtil(account.refreshToken, c.context),\n\t\t\t\t\t\taccessTokenExpiresAt: account.accessTokenExpiresAt,\n\t\t\t\t\t\trefreshTokenExpiresAt: account.refreshTokenExpiresAt,\n\t\t\t\t\t\tscope: account.scope,\n\t\t\t\t\t}).filter(([_, value]) => value !== undefined),\n\t\t\t\t);\n\t\t\t\tif (c.context.options.account?.storeAccountCookie) {\n\t\t\t\t\tawait setAccountCookie(c, {\n\t\t\t\t\t\t...account,\n\t\t\t\t\t\t...updateData,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif (Object.keys(updateData).length > 0) {\n\t\t\t\t\tawait c.context.internalAdapter.updateAccount(\n\t\t\t\t\t\thasBeenLinked.id,\n\t\t\t\t\t\tupdateData,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tuserInfo.emailVerified &&\n\t\t\t\t!dbUser.user.emailVerified &&\n\t\t\t\tuserInfo.email.toLowerCase() === dbUser.user.email\n\t\t\t) {\n\t\t\t\tawait c.context.internalAdapter.updateUser(dbUser.user.id, {\n\t\t\t\t\temailVerified: true,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tif (overrideUserInfo) {\n\t\t\tconst { id: _, ...restUserInfo } = userInfo;\n\t\t\t// update user info from the provider if overrideUserInfo is true\n\t\t\tuser = await c.context.internalAdapter.updateUser(dbUser.user.id, {\n\t\t\t\t...restUserInfo,\n\t\t\t\temail: userInfo.email.toLowerCase(),\n\t\t\t\temailVerified:\n\t\t\t\t\tuserInfo.email.toLowerCase() === dbUser.user.email\n\t\t\t\t\t\t? dbUser.user.emailVerified || userInfo.emailVerified\n\t\t\t\t\t\t: userInfo.emailVerified,\n\t\t\t});\n\t\t}\n\t} else {\n\t\tif (disableSignUp) {\n\t\t\treturn {\n\t\t\t\terror: \"signup disabled\",\n\t\t\t\tdata: null,\n\t\t\t\tisRegister: false,\n\t\t\t};\n\t\t}\n\t\ttry {\n\t\t\tconst { id: _, ...restUserInfo } = userInfo;\n\t\t\tconst accountData = {\n\t\t\t\taccessToken: await setTokenUtil(account.accessToken, c.context),\n\t\t\t\trefreshToken: await setTokenUtil(account.refreshToken, c.context),\n\t\t\t\tidToken: account.idToken,\n\t\t\t\taccessTokenExpiresAt: account.accessTokenExpiresAt,\n\t\t\t\trefreshTokenExpiresAt: account.refreshTokenExpiresAt,\n\t\t\t\tscope: account.scope,\n\t\t\t\tproviderId: account.providerId,\n\t\t\t\taccountId: userInfo.id.toString(),\n\t\t\t};\n\t\t\tconst { user: createdUser, account: createdAccount } =\n\t\t\t\tawait c.context.internalAdapter.createOAuthUser(\n\t\t\t\t\t{\n\t\t\t\t\t\t...restUserInfo,\n\t\t\t\t\t\temail: userInfo.email.toLowerCase(),\n\t\t\t\t\t},\n\t\t\t\t\taccountData,\n\t\t\t\t);\n\t\t\tuser = createdUser;\n\t\t\tif (c.context.options.account?.storeAccountCookie) {\n\t\t\t\tawait setAccountCookie(c, createdAccount);\n\t\t\t}\n\t\t\tif (\n\t\t\t\t!userInfo.emailVerified &&\n\t\t\t\tuser &&\n\t\t\t\tc.context.options.emailVerification?.sendOnSignUp &&\n\t\t\t\tc.context.options.emailVerification?.sendVerificationEmail\n\t\t\t) {\n\t\t\t\tconst token = await createEmailVerificationToken(\n\t\t\t\t\tc.context.secret,\n\t\t\t\t\tuser.email,\n\t\t\t\t\tundefined,\n\t\t\t\t\tc.context.options.emailVerification?.expiresIn,\n\t\t\t\t);\n\t\t\t\tconst url = `${c.context.baseURL}/verify-email?token=${token}&callbackURL=${callbackURL}`;\n\t\t\t\tawait c.context.runInBackgroundOrAwait(\n\t\t\t\t\tc.context.options.emailVerification.sendVerificationEmail(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tuser,\n\t\t\t\t\t\t\turl,\n\t\t\t\t\t\t\ttoken,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tc.request,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (e: any) {\n\t\t\tlogger.error(e);\n\t\t\tif (isAPIError(e)) {\n\t\t\t\treturn {\n\t\t\t\t\terror: e.message,\n\t\t\t\t\tdata: null,\n\t\t\t\t\tisRegister: false,\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn {\n\t\t\t\terror: \"unable to create user\",\n\t\t\t\tdata: null,\n\t\t\t\tisRegister: false,\n\t\t\t};\n\t\t}\n\t}\n\tif (!user) {\n\t\treturn {\n\t\t\terror: \"unable to create user\",\n\t\t\tdata: null,\n\t\t\tisRegister: false,\n\t\t};\n\t}\n\n\tconst session = await c.context.internalAdapter.createSession(user.id);\n\tif (!session) {\n\t\treturn {\n\t\t\terror: \"unable to create session\",\n\t\t\tdata: null,\n\t\t\tisRegister: false,\n\t\t};\n\t}\n\n\treturn {\n\t\tdata: {\n\t\t\tsession,\n\t\t\tuser,\n\t\t},\n\t\terror: null,\n\t\tisRegister,\n\t};\n}\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import { setOAuthState } from "../api/middlewares/oauth.mjs";
2
2
  import { generateRandomString } from "../crypto/random.mjs";
3
3
  import { symmetricDecrypt, symmetricEncrypt } from "../crypto/index.mjs";
4
+ import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
4
5
  import * as z from "zod";
5
- import { APIError } from "better-call";
6
6
 
7
7
  //#region src/oauth2/state.ts
8
8
  async function generateState(c, link, additionalData) {
9
9
  const callbackURL = c.body?.callbackURL || c.context.options.baseURL;
10
- if (!callbackURL) throw new APIError("BAD_REQUEST", { message: "callbackURL is required" });
10
+ if (!callbackURL) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.CALLBACK_URL_REQUIRED);
11
11
  const codeVerifier = generateRandomString(128);
12
12
  const state = generateRandomString(32);
13
13
  const storeStateStrategy = c.context.oauthConfig.storeStateStrategy;
@@ -46,7 +46,7 @@ async function generateState(c, link, additionalData) {
46
46
  });
47
47
  if (!verification) {
48
48
  c.context.logger.error("Unable to create verification. Make sure the database adapter is properly working and there is a verification table in the database");
49
- throw new APIError("INTERNAL_SERVER_ERROR", { message: "Unable to create verification" });
49
+ throw APIError.from("INTERNAL_SERVER_ERROR", BASE_ERROR_CODES.FAILED_TO_CREATE_VERIFICATION);
50
50
  }
51
51
  return {
52
52
  state: verification.identifier,
@@ -1 +1 @@
1
- {"version":3,"file":"state.mjs","names":["stateCookie","parsedData: z.infer<typeof stateDataSchema>"],"sources":["../../src/oauth2/state.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { APIError } from \"better-call\";\nimport * as z from \"zod\";\nimport { setOAuthState } from \"../api/middlewares/oauth\";\nimport {\n\tgenerateRandomString,\n\tsymmetricDecrypt,\n\tsymmetricEncrypt,\n} from \"../crypto\";\n\nexport async function generateState(\n\tc: GenericEndpointContext,\n\tlink:\n\t\t| {\n\t\t\t\temail: string;\n\t\t\t\tuserId: string;\n\t\t }\n\t\t| undefined,\n\tadditionalData: Record<string, any> | false | undefined,\n) {\n\tconst callbackURL = c.body?.callbackURL || c.context.options.baseURL;\n\tif (!callbackURL) {\n\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\tmessage: \"callbackURL is required\",\n\t\t});\n\t}\n\n\tconst codeVerifier = generateRandomString(128);\n\tconst state = generateRandomString(32);\n\tconst storeStateStrategy = c.context.oauthConfig.storeStateStrategy;\n\n\tconst stateData = {\n\t\t...(additionalData ? additionalData : {}),\n\t\tcallbackURL,\n\t\tcodeVerifier,\n\t\terrorURL: c.body?.errorCallbackURL,\n\t\tnewUserURL: c.body?.newUserCallbackURL,\n\t\tlink,\n\t\t/**\n\t\t * This is the actual expiry time of the state\n\t\t */\n\t\texpiresAt: Date.now() + 10 * 60 * 1000,\n\t\trequestSignUp: c.body?.requestSignUp,\n\t\tstate,\n\t};\n\n\tawait setOAuthState(stateData);\n\n\tif (storeStateStrategy === \"cookie\") {\n\t\t// Store state data in an encrypted cookie\n\t\tconst encryptedData = await symmetricEncrypt({\n\t\t\tkey: c.context.secret,\n\t\t\tdata: JSON.stringify(stateData),\n\t\t});\n\n\t\tconst stateCookie = c.context.createAuthCookie(\"oauth_state\", {\n\t\t\tmaxAge: 10 * 60 * 1000, // 10 minutes\n\t\t});\n\n\t\tc.setCookie(stateCookie.name, encryptedData, stateCookie.attributes);\n\n\t\treturn {\n\t\t\tstate,\n\t\t\tcodeVerifier,\n\t\t};\n\t}\n\n\t// Default: database strategy\n\tconst stateCookie = c.context.createAuthCookie(\"state\", {\n\t\tmaxAge: 5 * 60 * 1000, // 5 minutes\n\t});\n\tawait c.setSignedCookie(\n\t\tstateCookie.name,\n\t\tstate,\n\t\tc.context.secret,\n\t\tstateCookie.attributes,\n\t);\n\n\tconst expiresAt = new Date();\n\texpiresAt.setMinutes(expiresAt.getMinutes() + 10);\n\tconst verification = await c.context.internalAdapter.createVerificationValue({\n\t\tvalue: JSON.stringify(stateData),\n\t\tidentifier: state,\n\t\texpiresAt,\n\t});\n\tif (!verification) {\n\t\tc.context.logger.error(\n\t\t\t\"Unable to create verification. Make sure the database adapter is properly working and there is a verification table in the database\",\n\t\t);\n\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\tmessage: \"Unable to create verification\",\n\t\t});\n\t}\n\treturn {\n\t\tstate: verification.identifier,\n\t\tcodeVerifier,\n\t};\n}\n\nexport async function parseState(c: GenericEndpointContext) {\n\tconst state = c.query.state || c.body.state;\n\tconst storeStateStrategy = c.context.oauthConfig.storeStateStrategy;\n\n\tconst stateDataSchema = z.looseObject({\n\t\tcallbackURL: z.string(),\n\t\tcodeVerifier: z.string(),\n\t\terrorURL: z.string().optional(),\n\t\tnewUserURL: z.string().optional(),\n\t\texpiresAt: z.number(),\n\t\tlink: z\n\t\t\t.object({\n\t\t\t\temail: z.string(),\n\t\t\t\tuserId: z.coerce.string(),\n\t\t\t})\n\t\t\t.optional(),\n\t\trequestSignUp: z.boolean().optional(),\n\t\tstate: z.string().optional(),\n\t});\n\n\tlet parsedData: z.infer<typeof stateDataSchema>;\n\t/**\n\t * This is generally cause security issue and should only be used in\n\t * dev or staging environments. It's currently used by the oauth-proxy\n\t * plugin\n\t */\n\tconst skipStateCookieCheck = c.context.oauthConfig?.skipStateCookieCheck;\n\tif (storeStateStrategy === \"cookie\") {\n\t\t// Retrieve state data from encrypted cookie\n\t\tconst stateCookie = c.context.createAuthCookie(\"oauth_state\");\n\t\tconst encryptedData = c.getCookie(stateCookie.name);\n\n\t\tif (!encryptedData) {\n\t\t\tc.context.logger.error(\"State Mismatch. OAuth state cookie not found\", {\n\t\t\t\tstate,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t\t}\n\n\t\ttry {\n\t\t\tconst decryptedData = await symmetricDecrypt({\n\t\t\t\tkey: c.context.secret,\n\t\t\t\tdata: encryptedData,\n\t\t\t});\n\n\t\t\tparsedData = stateDataSchema.parse(JSON.parse(decryptedData));\n\t\t} catch (error) {\n\t\t\tc.context.logger.error(\"Failed to decrypt or parse OAuth state cookie\", {\n\t\t\t\terror,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t\t}\n\n\t\tconst skipStateCookieCheck = c.context.oauthConfig?.skipStateCookieCheck;\n\t\tif (\n\t\t\t!skipStateCookieCheck &&\n\t\t\tparsedData.state &&\n\t\t\tparsedData.state !== state\n\t\t) {\n\t\t\tc.context.logger.error(\"State Mismatch. State parameter does not match\", {\n\t\t\t\texpected: parsedData.state,\n\t\t\t\treceived: state,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=state_mismatch`);\n\t\t}\n\n\t\t// Clear the cookie after successful parsing\n\t\tc.setCookie(stateCookie.name, \"\", {\n\t\t\tmaxAge: 0,\n\t\t});\n\t} else {\n\t\t// Default: database strategy\n\t\tconst data = await c.context.internalAdapter.findVerificationValue(state);\n\t\tif (!data) {\n\t\t\tc.context.logger.error(\"State Mismatch. Verification not found\", {\n\t\t\t\tstate,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t\t}\n\n\t\tparsedData = stateDataSchema.parse(JSON.parse(data.value));\n\n\t\tconst stateCookie = c.context.createAuthCookie(\"state\");\n\t\tconst stateCookieValue = await c.getSignedCookie(\n\t\t\tstateCookie.name,\n\t\t\tc.context.secret,\n\t\t);\n\n\t\tif (\n\t\t\t!skipStateCookieCheck &&\n\t\t\t(!stateCookieValue || stateCookieValue !== state)\n\t\t) {\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=state_mismatch`);\n\t\t}\n\t\tc.setCookie(stateCookie.name, \"\", {\n\t\t\tmaxAge: 0,\n\t\t});\n\n\t\t// Delete verification value after retrieval\n\t\tawait c.context.internalAdapter.deleteVerificationValue(data.id);\n\t}\n\n\tif (!parsedData.errorURL) {\n\t\tparsedData.errorURL =\n\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t}\n\n\t// Check expiration\n\tif (parsedData.expiresAt < Date.now()) {\n\t\tconst errorURL =\n\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t}\n\n\tif (parsedData) {\n\t\tawait setOAuthState(parsedData);\n\t}\n\n\treturn parsedData;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"state.mjs","names":["stateCookie","parsedData: z.infer<typeof stateDataSchema>"],"sources":["../../src/oauth2/state.ts"],"sourcesContent":["import type { GenericEndpointContext } from \"@better-auth/core\";\nimport { APIError, BASE_ERROR_CODES } from \"@better-auth/core/error\";\nimport * as z from \"zod\";\nimport { setOAuthState } from \"../api/middlewares/oauth\";\nimport {\n\tgenerateRandomString,\n\tsymmetricDecrypt,\n\tsymmetricEncrypt,\n} from \"../crypto\";\n\nexport async function generateState(\n\tc: GenericEndpointContext,\n\tlink:\n\t\t| {\n\t\t\t\temail: string;\n\t\t\t\tuserId: string;\n\t\t }\n\t\t| undefined,\n\tadditionalData: Record<string, any> | false | undefined,\n) {\n\tconst callbackURL = c.body?.callbackURL || c.context.options.baseURL;\n\tif (!callbackURL) {\n\t\tthrow APIError.from(\"BAD_REQUEST\", BASE_ERROR_CODES.CALLBACK_URL_REQUIRED);\n\t}\n\n\tconst codeVerifier = generateRandomString(128);\n\tconst state = generateRandomString(32);\n\tconst storeStateStrategy = c.context.oauthConfig.storeStateStrategy;\n\n\tconst stateData = {\n\t\t...(additionalData ? additionalData : {}),\n\t\tcallbackURL,\n\t\tcodeVerifier,\n\t\terrorURL: c.body?.errorCallbackURL,\n\t\tnewUserURL: c.body?.newUserCallbackURL,\n\t\tlink,\n\t\t/**\n\t\t * This is the actual expiry time of the state\n\t\t */\n\t\texpiresAt: Date.now() + 10 * 60 * 1000,\n\t\trequestSignUp: c.body?.requestSignUp,\n\t\tstate,\n\t};\n\n\tawait setOAuthState(stateData);\n\n\tif (storeStateStrategy === \"cookie\") {\n\t\t// Store state data in an encrypted cookie\n\t\tconst encryptedData = await symmetricEncrypt({\n\t\t\tkey: c.context.secret,\n\t\t\tdata: JSON.stringify(stateData),\n\t\t});\n\n\t\tconst stateCookie = c.context.createAuthCookie(\"oauth_state\", {\n\t\t\tmaxAge: 10 * 60 * 1000, // 10 minutes\n\t\t});\n\n\t\tc.setCookie(stateCookie.name, encryptedData, stateCookie.attributes);\n\n\t\treturn {\n\t\t\tstate,\n\t\t\tcodeVerifier,\n\t\t};\n\t}\n\n\t// Default: database strategy\n\tconst stateCookie = c.context.createAuthCookie(\"state\", {\n\t\tmaxAge: 5 * 60 * 1000, // 5 minutes\n\t});\n\tawait c.setSignedCookie(\n\t\tstateCookie.name,\n\t\tstate,\n\t\tc.context.secret,\n\t\tstateCookie.attributes,\n\t);\n\n\tconst expiresAt = new Date();\n\texpiresAt.setMinutes(expiresAt.getMinutes() + 10);\n\tconst verification = await c.context.internalAdapter.createVerificationValue({\n\t\tvalue: JSON.stringify(stateData),\n\t\tidentifier: state,\n\t\texpiresAt,\n\t});\n\tif (!verification) {\n\t\tc.context.logger.error(\n\t\t\t\"Unable to create verification. Make sure the database adapter is properly working and there is a verification table in the database\",\n\t\t);\n\t\tthrow APIError.from(\n\t\t\t\"INTERNAL_SERVER_ERROR\",\n\t\t\tBASE_ERROR_CODES.FAILED_TO_CREATE_VERIFICATION,\n\t\t);\n\t}\n\treturn {\n\t\tstate: verification.identifier,\n\t\tcodeVerifier,\n\t};\n}\n\nexport async function parseState(c: GenericEndpointContext) {\n\tconst state = c.query.state || c.body.state;\n\tconst storeStateStrategy = c.context.oauthConfig.storeStateStrategy;\n\n\tconst stateDataSchema = z.looseObject({\n\t\tcallbackURL: z.string(),\n\t\tcodeVerifier: z.string(),\n\t\terrorURL: z.string().optional(),\n\t\tnewUserURL: z.string().optional(),\n\t\texpiresAt: z.number(),\n\t\tlink: z\n\t\t\t.object({\n\t\t\t\temail: z.string(),\n\t\t\t\tuserId: z.coerce.string(),\n\t\t\t})\n\t\t\t.optional(),\n\t\trequestSignUp: z.boolean().optional(),\n\t\tstate: z.string().optional(),\n\t});\n\n\tlet parsedData: z.infer<typeof stateDataSchema>;\n\t/**\n\t * This is generally cause security issue and should only be used in\n\t * dev or staging environments. It's currently used by the oauth-proxy\n\t * plugin\n\t */\n\tconst skipStateCookieCheck = c.context.oauthConfig?.skipStateCookieCheck;\n\tif (storeStateStrategy === \"cookie\") {\n\t\t// Retrieve state data from encrypted cookie\n\t\tconst stateCookie = c.context.createAuthCookie(\"oauth_state\");\n\t\tconst encryptedData = c.getCookie(stateCookie.name);\n\n\t\tif (!encryptedData) {\n\t\t\tc.context.logger.error(\"State Mismatch. OAuth state cookie not found\", {\n\t\t\t\tstate,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t\t}\n\n\t\ttry {\n\t\t\tconst decryptedData = await symmetricDecrypt({\n\t\t\t\tkey: c.context.secret,\n\t\t\t\tdata: encryptedData,\n\t\t\t});\n\n\t\t\tparsedData = stateDataSchema.parse(JSON.parse(decryptedData));\n\t\t} catch (error) {\n\t\t\tc.context.logger.error(\"Failed to decrypt or parse OAuth state cookie\", {\n\t\t\t\terror,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t\t}\n\n\t\tconst skipStateCookieCheck = c.context.oauthConfig?.skipStateCookieCheck;\n\t\tif (\n\t\t\t!skipStateCookieCheck &&\n\t\t\tparsedData.state &&\n\t\t\tparsedData.state !== state\n\t\t) {\n\t\t\tc.context.logger.error(\"State Mismatch. State parameter does not match\", {\n\t\t\t\texpected: parsedData.state,\n\t\t\t\treceived: state,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=state_mismatch`);\n\t\t}\n\n\t\t// Clear the cookie after successful parsing\n\t\tc.setCookie(stateCookie.name, \"\", {\n\t\t\tmaxAge: 0,\n\t\t});\n\t} else {\n\t\t// Default: database strategy\n\t\tconst data = await c.context.internalAdapter.findVerificationValue(state);\n\t\tif (!data) {\n\t\t\tc.context.logger.error(\"State Mismatch. Verification not found\", {\n\t\t\t\tstate,\n\t\t\t});\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t\t}\n\n\t\tparsedData = stateDataSchema.parse(JSON.parse(data.value));\n\n\t\tconst stateCookie = c.context.createAuthCookie(\"state\");\n\t\tconst stateCookieValue = await c.getSignedCookie(\n\t\t\tstateCookie.name,\n\t\t\tc.context.secret,\n\t\t);\n\n\t\tif (\n\t\t\t!skipStateCookieCheck &&\n\t\t\t(!stateCookieValue || stateCookieValue !== state)\n\t\t) {\n\t\t\tconst errorURL =\n\t\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\t\tthrow c.redirect(`${errorURL}?error=state_mismatch`);\n\t\t}\n\t\tc.setCookie(stateCookie.name, \"\", {\n\t\t\tmaxAge: 0,\n\t\t});\n\n\t\t// Delete verification value after retrieval\n\t\tawait c.context.internalAdapter.deleteVerificationValue(data.id);\n\t}\n\n\tif (!parsedData.errorURL) {\n\t\tparsedData.errorURL =\n\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t}\n\n\t// Check expiration\n\tif (parsedData.expiresAt < Date.now()) {\n\t\tconst errorURL =\n\t\t\tc.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;\n\t\tthrow c.redirect(`${errorURL}?error=please_restart_the_process`);\n\t}\n\n\tif (parsedData) {\n\t\tawait setOAuthState(parsedData);\n\t}\n\n\treturn parsedData;\n}\n"],"mappings":"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"}