better-auth 1.7.0-beta.2 → 1.7.0-beta.4

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 (282) hide show
  1. package/README.md +14 -15
  2. package/dist/_virtual/_rolldown/runtime.mjs +10 -1
  3. package/dist/api/index.d.mts +18 -48
  4. package/dist/api/routes/account.d.mts +4 -23
  5. package/dist/api/routes/account.mjs +102 -75
  6. package/dist/api/routes/callback.mjs +42 -20
  7. package/dist/api/routes/email-verification.d.mts +1 -0
  8. package/dist/api/routes/email-verification.mjs +6 -5
  9. package/dist/api/routes/error.mjs +1 -1
  10. package/dist/api/routes/password.mjs +1 -1
  11. package/dist/api/routes/session.mjs +15 -10
  12. package/dist/api/routes/sign-in.d.mts +3 -1
  13. package/dist/api/routes/sign-in.mjs +13 -15
  14. package/dist/api/routes/sign-up.d.mts +1 -0
  15. package/dist/api/routes/sign-up.mjs +10 -8
  16. package/dist/api/routes/update-user.mjs +8 -8
  17. package/dist/api/to-auth-endpoints.mjs +7 -1
  18. package/dist/auth/base.mjs +30 -27
  19. package/dist/client/config.mjs +8 -1
  20. package/dist/client/fetch-plugins.mjs +2 -1
  21. package/dist/client/index.d.mts +2 -2
  22. package/dist/client/lynx/index.d.mts +13 -0
  23. package/dist/client/lynx/index.mjs +2 -1
  24. package/dist/client/parser.mjs +0 -1
  25. package/dist/client/plugins/index.d.mts +4 -17
  26. package/dist/client/plugins/index.mjs +1 -4
  27. package/dist/client/proxy.mjs +2 -1
  28. package/dist/client/react/index.d.mts +13 -0
  29. package/dist/client/react/index.mjs +2 -1
  30. package/dist/client/session-atom.mjs +12 -1
  31. package/dist/client/solid/index.d.mts +13 -0
  32. package/dist/client/solid/index.mjs +3 -2
  33. package/dist/client/svelte/index.d.mts +13 -0
  34. package/dist/client/svelte/index.mjs +2 -1
  35. package/dist/client/vanilla.d.mts +13 -0
  36. package/dist/client/vanilla.mjs +2 -1
  37. package/dist/client/vue/index.d.mts +13 -0
  38. package/dist/client/vue/index.mjs +2 -1
  39. package/dist/context/create-context.mjs +10 -14
  40. package/dist/context/helpers.mjs +3 -2
  41. package/dist/cookies/cookie-utils.d.mts +33 -1
  42. package/dist/cookies/cookie-utils.mjs +95 -14
  43. package/dist/cookies/index.d.mts +2 -3
  44. package/dist/cookies/index.mjs +39 -11
  45. package/dist/cookies/session-store.mjs +4 -23
  46. package/dist/db/get-migration.mjs +4 -4
  47. package/dist/db/index.d.mts +2 -2
  48. package/dist/db/index.mjs +3 -2
  49. package/dist/db/internal-adapter.mjs +129 -27
  50. package/dist/db/schema.d.mts +14 -1
  51. package/dist/db/schema.mjs +26 -1
  52. package/dist/db/with-hooks.d.mts +1 -0
  53. package/dist/db/with-hooks.mjs +58 -1
  54. package/dist/index.d.mts +2 -2
  55. package/dist/index.mjs +2 -2
  56. package/dist/integrations/cookie-plugin-guard.mjs +18 -0
  57. package/dist/integrations/next-js.mjs +6 -0
  58. package/dist/integrations/svelte-kit.mjs +6 -0
  59. package/dist/integrations/tanstack-start-solid.mjs +6 -0
  60. package/dist/integrations/tanstack-start.mjs +6 -0
  61. package/dist/node_modules/.pnpm/clipboardy@4.0.0/node_modules/clipboardy/index.mjs +32 -0
  62. package/dist/node_modules/.pnpm/clipboardy@4.0.0/node_modules/clipboardy/lib/linux.mjs +55 -0
  63. package/dist/node_modules/.pnpm/clipboardy@4.0.0/node_modules/clipboardy/lib/macos.mjs +26 -0
  64. package/dist/node_modules/.pnpm/clipboardy@4.0.0/node_modules/clipboardy/lib/termux.mjs +39 -0
  65. package/dist/node_modules/.pnpm/clipboardy@4.0.0/node_modules/clipboardy/lib/windows.mjs +19 -0
  66. package/dist/node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/chunks/prompt.mjs +845 -0
  67. package/dist/node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/core.mjs +386 -0
  68. package/dist/node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/index.mjs +320 -0
  69. package/dist/node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/shared/consola.DRwqZj3T.mjs +62 -0
  70. package/dist/node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs +190 -0
  71. package/dist/node_modules/.pnpm/consola@3.4.2/node_modules/consola/dist/utils.mjs +2 -0
  72. package/dist/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/index.mjs +29 -0
  73. package/dist/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/enoent.mjs +42 -0
  74. package/dist/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/parse.mjs +67 -0
  75. package/dist/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/escape.mjs +23 -0
  76. package/dist/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/readShebang.mjs +22 -0
  77. package/dist/node_modules/.pnpm/cross-spawn@7.0.6/node_modules/cross-spawn/lib/util/resolveCommand.mjs +36 -0
  78. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/adapters/node.d.mts +292 -0
  79. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/adapters/node.mjs +127 -0
  80. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/index.d.mts +145 -0
  81. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/shared/crossws.BQXMA5bH.d.mts +298 -0
  82. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/shared/crossws.By9qWDAI.mjs +9 -0
  83. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/shared/crossws.CipVM6lf.mjs +3549 -0
  84. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/shared/crossws.D9ehKjSh.mjs +66 -0
  85. package/dist/node_modules/.pnpm/crossws@0.3.5/node_modules/crossws/dist/shared/crossws.DfCzGthR.mjs +227 -0
  86. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/index.mjs +224 -0
  87. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/command.mjs +52 -0
  88. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/error.mjs +54 -0
  89. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/kill.mjs +62 -0
  90. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/pipe.mjs +26 -0
  91. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/promise.mjs +32 -0
  92. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/stdio.mjs +19 -0
  93. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/stream.mjs +98 -0
  94. package/dist/node_modules/.pnpm/execa@8.0.1/node_modules/execa/lib/verbose.mjs +15 -0
  95. package/dist/node_modules/.pnpm/get-port-please@3.2.0/node_modules/get-port-please/dist/index.d.mts +15 -0
  96. package/dist/node_modules/.pnpm/get-port-please@3.2.0/node_modules/get-port-please/dist/index.mjs +220 -0
  97. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/array-buffer.mjs +54 -0
  98. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/array.mjs +2 -0
  99. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/buffer.mjs +14 -0
  100. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/contents.mjs +76 -0
  101. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/index.mjs +6 -0
  102. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/string.mjs +35 -0
  103. package/dist/node_modules/.pnpm/get-stream@8.0.1/node_modules/get-stream/source/utils.mjs +10 -0
  104. package/dist/node_modules/.pnpm/http-shutdown@1.2.2/node_modules/http-shutdown/index.mjs +76 -0
  105. package/dist/node_modules/.pnpm/human-signals@5.0.0/node_modules/human-signals/build/src/core.mjs +274 -0
  106. package/dist/node_modules/.pnpm/human-signals@5.0.0/node_modules/human-signals/build/src/main.mjs +44 -0
  107. package/dist/node_modules/.pnpm/human-signals@5.0.0/node_modules/human-signals/build/src/realtime.mjs +15 -0
  108. package/dist/node_modules/.pnpm/human-signals@5.0.0/node_modules/human-signals/build/src/signals.mjs +23 -0
  109. package/dist/node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.mjs +24 -0
  110. package/dist/node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.mjs +18 -0
  111. package/dist/node_modules/.pnpm/is-stream@3.0.0/node_modules/is-stream/index.mjs +9 -0
  112. package/dist/node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.mjs +20 -0
  113. package/dist/node_modules/.pnpm/is64bit@2.0.0/node_modules/is64bit/index.mjs +13 -0
  114. package/dist/node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/index.mjs +47 -0
  115. package/dist/node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/mode.mjs +33 -0
  116. package/dist/node_modules/.pnpm/isexe@2.0.0/node_modules/isexe/windows.mjs +33 -0
  117. package/dist/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/dist/chunks/xdg-open.mjs +1070 -0
  118. package/dist/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/dist/index.mjs +619 -0
  119. package/dist/node_modules/.pnpm/listhen@1.9.0/node_modules/listhen/dist/shared/listhen.1c46e31d.d.mts +83 -0
  120. package/dist/node_modules/.pnpm/merge-stream@2.0.0/node_modules/merge-stream/index.mjs +38 -0
  121. package/dist/node_modules/.pnpm/mimic-fn@4.0.0/node_modules/mimic-fn/index.mjs +38 -0
  122. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/aes.mjs +597 -0
  123. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/aesCipherSuites.mjs +195 -0
  124. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/asn1-validator.mjs +76 -0
  125. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/asn1.mjs +967 -0
  126. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/baseN.mjs +137 -0
  127. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/cipher.mjs +186 -0
  128. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/cipherModes.mjs +597 -0
  129. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/des.mjs +1187 -0
  130. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/ed25519.mjs +1029 -0
  131. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/forge.mjs +15 -0
  132. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/hmac.mjs +107 -0
  133. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/index.mjs +66 -0
  134. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/jsbn.mjs +1334 -0
  135. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/kem.mjs +146 -0
  136. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/log.mjs +241 -0
  137. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/md.all.mjs +24 -0
  138. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/md.mjs +18 -0
  139. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/md5.mjs +324 -0
  140. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/mgf.mjs +20 -0
  141. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/mgf1.mjs +44 -0
  142. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/oids.mjs +154 -0
  143. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pbe.mjs +815 -0
  144. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pbkdf2.mjs +125 -0
  145. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pem.mjs +175 -0
  146. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pkcs1.mjs +200 -0
  147. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pkcs12.mjs +724 -0
  148. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pkcs7.mjs +642 -0
  149. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pkcs7asn1.mjs +405 -0
  150. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pki.mjs +101 -0
  151. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/prime.mjs +193 -0
  152. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/prng.mjs +290 -0
  153. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/pss.mjs +141 -0
  154. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/random.mjs +141 -0
  155. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/rc2.mjs +538 -0
  156. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/rsa.mjs +1309 -0
  157. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/sha1.mjs +230 -0
  158. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/sha256.mjs +267 -0
  159. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/sha512.mjs +413 -0
  160. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/ssh.mjs +194 -0
  161. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/tls.mjs +3655 -0
  162. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/util.mjs +2117 -0
  163. package/dist/node_modules/.pnpm/node-forge@1.4.0/node_modules/node-forge/lib/x509.mjs +2168 -0
  164. package/dist/node_modules/.pnpm/npm-run-path@5.3.0/node_modules/npm-run-path/index.mjs +34 -0
  165. package/dist/node_modules/.pnpm/onetime@6.0.0/node_modules/onetime/index.mjs +26 -0
  166. package/dist/node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.mjs +14 -0
  167. package/dist/node_modules/.pnpm/path-key@4.0.0/node_modules/path-key/index.mjs +8 -0
  168. package/dist/node_modules/.pnpm/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.mjs +176 -0
  169. package/dist/node_modules/.pnpm/shebang-command@2.0.0/node_modules/shebang-command/index.mjs +17 -0
  170. package/dist/node_modules/.pnpm/shebang-regex@3.0.0/node_modules/shebang-regex/index.mjs +8 -0
  171. package/dist/node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/index.mjs +169 -0
  172. package/dist/node_modules/.pnpm/signal-exit@4.1.0/node_modules/signal-exit/dist/mjs/signals.mjs +33 -0
  173. package/dist/node_modules/.pnpm/std-env@3.10.0/node_modules/std-env/dist/index.mjs +171 -0
  174. package/dist/node_modules/.pnpm/strip-final-newline@3.0.0/node_modules/strip-final-newline/index.mjs +10 -0
  175. package/dist/node_modules/.pnpm/system-architecture@0.1.0/node_modules/system-architecture/index.mjs +16 -0
  176. package/dist/node_modules/.pnpm/uncrypto@0.1.3/node_modules/uncrypto/dist/crypto.node.mjs +7 -0
  177. package/dist/node_modules/.pnpm/untun@0.1.3/node_modules/untun/dist/chunks/index.mjs +154 -0
  178. package/dist/node_modules/.pnpm/untun@0.1.3/node_modules/untun/dist/index.mjs +34 -0
  179. package/dist/node_modules/.pnpm/uqr@0.1.2/node_modules/uqr/dist/index.mjs +896 -0
  180. package/dist/node_modules/.pnpm/which@2.0.2/node_modules/which/which.mjs +76 -0
  181. package/dist/oauth2/errors.mjs +27 -0
  182. package/dist/oauth2/index.d.mts +2 -2
  183. package/dist/oauth2/index.mjs +3 -3
  184. package/dist/oauth2/link-account.d.mts +27 -1
  185. package/dist/oauth2/link-account.mjs +30 -5
  186. package/dist/oauth2/state.mjs +8 -2
  187. package/dist/{package.mjs → packages/better-auth/package.mjs} +1 -1
  188. package/dist/plugins/access/access.d.mts +3 -15
  189. package/dist/plugins/access/access.mjs +11 -6
  190. package/dist/plugins/access/index.d.mts +2 -2
  191. package/dist/plugins/access/types.d.mts +11 -4
  192. package/dist/plugins/admin/access/statement.d.mts +29 -93
  193. package/dist/plugins/admin/admin.mjs +0 -4
  194. package/dist/plugins/admin/client.d.mts +6 -1
  195. package/dist/plugins/admin/client.mjs +5 -0
  196. package/dist/plugins/admin/routes.mjs +3 -2
  197. package/dist/plugins/anonymous/client.d.mts +1 -0
  198. package/dist/plugins/anonymous/error-codes.d.mts +1 -0
  199. package/dist/plugins/anonymous/error-codes.mjs +1 -0
  200. package/dist/plugins/anonymous/index.d.mts +1 -0
  201. package/dist/plugins/anonymous/index.mjs +16 -2
  202. package/dist/plugins/bearer/index.mjs +5 -12
  203. package/dist/plugins/captcha/index.mjs +14 -1
  204. package/dist/plugins/device-authorization/error-codes.mjs +1 -0
  205. package/dist/plugins/device-authorization/index.d.mts +1 -0
  206. package/dist/plugins/device-authorization/routes.mjs +34 -3
  207. package/dist/plugins/email-otp/routes.mjs +4 -4
  208. package/dist/plugins/generic-oauth/error-codes.mjs +0 -1
  209. package/dist/plugins/generic-oauth/index.d.mts +2 -4
  210. package/dist/plugins/generic-oauth/index.mjs +23 -17
  211. package/dist/plugins/generic-oauth/providers/auth0.mjs +1 -0
  212. package/dist/plugins/generic-oauth/providers/gumroad.mjs +1 -0
  213. package/dist/plugins/generic-oauth/providers/hubspot.mjs +1 -0
  214. package/dist/plugins/generic-oauth/providers/keycloak.mjs +1 -0
  215. package/dist/plugins/generic-oauth/providers/line.mjs +1 -0
  216. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +1 -0
  217. package/dist/plugins/generic-oauth/providers/okta.mjs +1 -0
  218. package/dist/plugins/generic-oauth/providers/patreon.mjs +1 -0
  219. package/dist/plugins/generic-oauth/providers/slack.mjs +1 -0
  220. package/dist/plugins/generic-oauth/types.d.mts +30 -8
  221. package/dist/plugins/index.d.mts +2 -2
  222. package/dist/plugins/jwt/utils.d.mts +1 -1
  223. package/dist/plugins/last-login-method/client.mjs +2 -2
  224. package/dist/plugins/magic-link/index.d.mts +8 -1
  225. package/dist/plugins/magic-link/index.mjs +4 -17
  226. package/dist/plugins/mcp/authorize.mjs +8 -2
  227. package/dist/plugins/mcp/index.mjs +75 -35
  228. package/dist/plugins/multi-session/index.mjs +2 -2
  229. package/dist/plugins/oauth-proxy/index.mjs +45 -32
  230. package/dist/plugins/oauth-proxy/utils.mjs +3 -10
  231. package/dist/plugins/oidc-provider/authorize.mjs +8 -2
  232. package/dist/plugins/oidc-provider/index.mjs +65 -38
  233. package/dist/plugins/one-tap/client.mjs +9 -2
  234. package/dist/plugins/one-tap/index.mjs +19 -36
  235. package/dist/plugins/open-api/generator.mjs +25 -5
  236. package/dist/plugins/organization/access/statement.d.mts +68 -201
  237. package/dist/plugins/organization/adapter.d.mts +1 -1
  238. package/dist/plugins/organization/adapter.mjs +65 -58
  239. package/dist/plugins/organization/client.d.mts +3 -1
  240. package/dist/plugins/organization/client.mjs +1 -1
  241. package/dist/plugins/organization/error-codes.d.mts +2 -0
  242. package/dist/plugins/organization/error-codes.mjs +3 -1
  243. package/dist/plugins/organization/routes/crud-access-control.d.mts +2 -2
  244. package/dist/plugins/organization/routes/crud-invites.d.mts +8 -1
  245. package/dist/plugins/organization/routes/crud-invites.mjs +8 -3
  246. package/dist/plugins/organization/routes/crud-org.d.mts +4 -4
  247. package/dist/plugins/organization/routes/crud-org.mjs +2 -2
  248. package/dist/plugins/organization/routes/crud-team.mjs +7 -2
  249. package/dist/plugins/organization/schema.d.mts +1 -1
  250. package/dist/plugins/organization/types.d.mts +15 -5
  251. package/dist/plugins/phone-number/routes.mjs +1 -1
  252. package/dist/plugins/siwe/client.d.mts +4 -0
  253. package/dist/plugins/siwe/client.mjs +5 -1
  254. package/dist/plugins/siwe/index.d.mts +13 -2
  255. package/dist/plugins/siwe/index.mjs +179 -165
  256. package/dist/plugins/two-factor/backup-codes/index.d.mts +4 -3
  257. package/dist/plugins/two-factor/client.mjs +2 -1
  258. package/dist/plugins/two-factor/index.mjs +3 -2
  259. package/dist/plugins/username/client.d.mts +1 -0
  260. package/dist/plugins/username/error-codes.d.mts +1 -0
  261. package/dist/plugins/username/error-codes.mjs +2 -1
  262. package/dist/plugins/username/index.d.mts +43 -2
  263. package/dist/plugins/username/index.mjs +73 -6
  264. package/dist/state.d.mts +2 -2
  265. package/dist/state.mjs +18 -4
  266. package/dist/test-utils/headers.mjs +2 -7
  267. package/dist/test-utils/http-test-instance.d.mts +397 -0
  268. package/dist/test-utils/http-test-instance.mjs +54 -0
  269. package/dist/test-utils/index.d.mts +2 -1
  270. package/dist/test-utils/index.mjs +2 -1
  271. package/dist/test-utils/test-instance.d.mts +4110 -224
  272. package/dist/test-utils/test-instance.mjs +11 -2
  273. package/dist/types/auth.d.mts +4 -0
  274. package/dist/utils/index.d.mts +1 -1
  275. package/dist/utils/url.d.mts +2 -1
  276. package/dist/utils/url.mjs +9 -3
  277. package/dist/version.mjs +1 -1
  278. package/package.json +14 -14
  279. package/dist/oauth2/error-codes.d.mts +0 -20
  280. package/dist/plugins/generic-oauth/client.d.mts +0 -32
  281. package/dist/plugins/generic-oauth/client.mjs +0 -19
  282. package/dist/plugins/generic-oauth/error-codes.d.mts +0 -10
package/README.md CHANGED
@@ -1,32 +1,31 @@
1
- <p align="center">
1
+ <div align="center">
2
2
  <picture>
3
- <source media="(prefers-color-scheme: dark)" srcset="https://github.com/better-auth/better-auth/blob/main/banner-dark.png?raw=true" />
4
- <source media="(prefers-color-scheme: light)" srcset="https://github.com/better-auth/better-auth/blob/main/banner.png?raw=true" />
5
- <img alt="Better Auth Logo" src="https://github.com/better-auth/better-auth/blob/main/banner.png?raw=true" />
3
+ <source srcset="https://github.com/better-auth/better-auth/blob/main/banner-dark.png?raw=true" media="(prefers-color-scheme: dark)"/>
4
+ <source srcset="https://github.com/better-auth/better-auth/blob/main/banner-light.png?raw=true" media="(prefers-color-scheme: light)"/>
5
+ <img src="https://github.com/better-auth/better-auth/blob/main/banner-light.png?raw=true" alt="Better Auth Logo"/>
6
6
  </picture>
7
7
 
8
- <h1 align="center">
9
- Better Auth
10
- </h1>
8
+ [![npm](https://img.shields.io/npm/dm/better-auth?style=flat&colorA=000000&colorB=000000)](https://npm.chart.dev/better-auth?primary=neutral&gray=neutral&theme=dark)
9
+ [![npm version](https://img.shields.io/npm/v/better-auth.svg?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/better-auth)
10
+ [![GitHub stars](https://img.shields.io/github/stars/better-auth/better-auth?style=flat&colorA=000000&colorB=000000)](https://github.com/better-auth/better-auth/stargazers)
11
11
 
12
- <p align="center">
13
- The most comprehensive authentication framework for TypeScript
14
- <br />
15
- <a href="https://better-auth.com"><strong>Learn more »</strong></a>
16
- <br />
17
- <br />
12
+ <p>
18
13
  <a href="https://discord.gg/better-auth">Discord</a>
19
14
  ·
20
15
  <a href="https://better-auth.com">Website</a>
21
16
  ·
22
17
  <a href="https://github.com/better-auth/better-auth/issues">Issues</a>
23
18
  </p>
24
- </p>
19
+ </div>
20
+
21
+ ## Better Auth
22
+
23
+ Better Auth is a framework-agnostic authentication (and authorization) framework for TypeScript. It provides a comprehensive set of features out of the box and includes a plugin ecosystem that simplifies adding advanced functionalities with minimal code in a short amount of time. Whether you need 2FA, multi-tenant support, or other complex features, it lets you focus on building your actual application instead of reinventing the wheel.
25
24
 
26
25
  ## Getting Started
27
26
 
28
27
  ```bash
29
- pnpm install better-auth
28
+ npm i better-auth
30
29
  ```
31
30
 
32
31
  Read the [Installation Guide](https://better-auth.com/docs/installation) to
@@ -1,8 +1,12 @@
1
+ import { createRequire } from "node:module";
1
2
  //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
2
4
  var __defProp = Object.defineProperty;
3
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
5
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
6
10
  var __exportAll = (all, no_symbols) => {
7
11
  let target = {};
8
12
  for (var name in all) __defProp(target, name, {
@@ -23,5 +27,10 @@ var __copyProps = (to, from, except, desc) => {
23
27
  return to;
24
28
  };
25
29
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
30
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
31
+ value: mod,
32
+ enumerable: true
33
+ }) : target, mod));
34
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
26
35
  //#endregion
27
- export { __exportAll, __reExport };
36
+ export { __commonJSMin, __exportAll, __reExport, __require, __toESM };
@@ -110,6 +110,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
110
110
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
111
111
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
112
112
  loginHint: zod.ZodOptional<zod.ZodString>;
113
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
113
114
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
114
115
  }, zod_v4_core0.$strip>;
115
116
  metadata: {
@@ -137,6 +138,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
137
138
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
138
139
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
139
140
  loginHint: zod.ZodOptional<zod.ZodString>;
141
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
140
142
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
141
143
  }, zod_v4_core0.$strip>>;
142
144
  returned: {
@@ -178,7 +180,6 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
178
180
  };
179
181
  redirect: {
180
182
  type: string;
181
- enum: boolean[];
182
183
  };
183
184
  };
184
185
  required: string[];
@@ -330,6 +331,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
330
331
  callbackURL: zod.ZodOptional<zod.ZodString>;
331
332
  rememberMe: zod.ZodOptional<zod.ZodBoolean>;
332
333
  }, zod_v4_core0.$strip>, zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
334
+ cloneRequest: true;
333
335
  metadata: {
334
336
  allowedMediaTypes: string[];
335
337
  $Infer: {
@@ -496,6 +498,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
496
498
  method: "POST";
497
499
  operationId: string;
498
500
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>)[];
501
+ cloneRequest: true;
499
502
  body: zod.ZodObject<{
500
503
  email: zod.ZodString;
501
504
  password: zod.ZodString;
@@ -727,6 +730,7 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
727
730
  readonly sendVerificationEmail: better_call0.StrictEndpoint<"/send-verification-email", {
728
731
  method: "POST";
729
732
  operationId: string;
733
+ cloneRequest: true;
730
734
  body: zod.ZodObject<{
731
735
  email: zod.ZodEmail;
732
736
  callbackURL: zod.ZodOptional<zod.ZodString>;
@@ -1583,6 +1587,8 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
1583
1587
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
1584
1588
  errorCallbackURL: zod.ZodOptional<zod.ZodString>;
1585
1589
  disableRedirect: zod.ZodOptional<zod.ZodBoolean>;
1590
+ loginHint: zod.ZodOptional<zod.ZodString>;
1591
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
1586
1592
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
1587
1593
  }, zod_v4_core0.$strip>;
1588
1594
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
@@ -1931,29 +1937,6 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
1931
1937
  }>;
1932
1938
  readonly accountInfo: better_call0.StrictEndpoint<"/account-info", {
1933
1939
  method: "GET";
1934
- use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
1935
- session: {
1936
- session: Record<string, any> & {
1937
- id: string;
1938
- createdAt: Date;
1939
- updatedAt: Date;
1940
- userId: string;
1941
- expiresAt: Date;
1942
- token: string;
1943
- ipAddress?: string | null | undefined;
1944
- userAgent?: string | null | undefined;
1945
- };
1946
- user: Record<string, any> & {
1947
- id: string;
1948
- createdAt: Date;
1949
- updatedAt: Date;
1950
- email: string;
1951
- emailVerified: boolean;
1952
- name: string;
1953
- image?: string | null | undefined;
1954
- };
1955
- };
1956
- }>)[];
1957
1940
  metadata: {
1958
1941
  openapi: {
1959
1942
  description: string;
@@ -2003,6 +1986,8 @@ declare function getEndpoints<Option extends BetterAuthOptions>(ctx: Awaitable<A
2003
1986
  };
2004
1987
  query: zod.ZodOptional<zod.ZodObject<{
2005
1988
  accountId: zod.ZodOptional<zod.ZodString>;
1989
+ providerId: zod.ZodOptional<zod.ZodString>;
1990
+ userId: zod.ZodOptional<zod.ZodString>;
2006
1991
  }, zod_v4_core0.$strip>>;
2007
1992
  }, {
2008
1993
  user: _better_auth_core_oauth20.OAuth2UserInfo;
@@ -2101,6 +2086,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2101
2086
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
2102
2087
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
2103
2088
  loginHint: zod.ZodOptional<zod.ZodString>;
2089
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
2104
2090
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
2105
2091
  }, zod_v4_core0.$strip>;
2106
2092
  metadata: {
@@ -2128,6 +2114,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2128
2114
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
2129
2115
  requestSignUp: zod.ZodOptional<zod.ZodBoolean>;
2130
2116
  loginHint: zod.ZodOptional<zod.ZodString>;
2117
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
2131
2118
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
2132
2119
  }, zod_v4_core0.$strip>>;
2133
2120
  returned: {
@@ -2169,7 +2156,6 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2169
2156
  };
2170
2157
  redirect: {
2171
2158
  type: string;
2172
- enum: boolean[];
2173
2159
  };
2174
2160
  };
2175
2161
  required: string[];
@@ -2321,6 +2307,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2321
2307
  callbackURL: zod.ZodOptional<zod.ZodString>;
2322
2308
  rememberMe: zod.ZodOptional<zod.ZodBoolean>;
2323
2309
  }, zod_v4_core0.$strip>, zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
2310
+ cloneRequest: true;
2324
2311
  metadata: {
2325
2312
  allowedMediaTypes: string[];
2326
2313
  $Infer: {
@@ -2487,6 +2474,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2487
2474
  method: "POST";
2488
2475
  operationId: string;
2489
2476
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>)[];
2477
+ cloneRequest: true;
2490
2478
  body: zod.ZodObject<{
2491
2479
  email: zod.ZodString;
2492
2480
  password: zod.ZodString;
@@ -2718,6 +2706,7 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
2718
2706
  readonly sendVerificationEmail: better_call0.StrictEndpoint<"/send-verification-email", {
2719
2707
  method: "POST";
2720
2708
  operationId: string;
2709
+ cloneRequest: true;
2721
2710
  body: zod.ZodObject<{
2722
2711
  email: zod.ZodEmail;
2723
2712
  callbackURL: zod.ZodOptional<zod.ZodString>;
@@ -3574,6 +3563,8 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
3574
3563
  scopes: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
3575
3564
  errorCallbackURL: zod.ZodOptional<zod.ZodString>;
3576
3565
  disableRedirect: zod.ZodOptional<zod.ZodBoolean>;
3566
+ loginHint: zod.ZodOptional<zod.ZodString>;
3567
+ additionalParams: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodString>>;
3577
3568
  additionalData: zod.ZodOptional<zod.ZodRecord<zod.ZodString, zod.ZodAny>>;
3578
3569
  }, zod_v4_core0.$strip>;
3579
3570
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
@@ -3922,29 +3913,6 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
3922
3913
  }>;
3923
3914
  readonly accountInfo: better_call0.StrictEndpoint<"/account-info", {
3924
3915
  method: "GET";
3925
- use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
3926
- session: {
3927
- session: Record<string, any> & {
3928
- id: string;
3929
- createdAt: Date;
3930
- updatedAt: Date;
3931
- userId: string;
3932
- expiresAt: Date;
3933
- token: string;
3934
- ipAddress?: string | null | undefined;
3935
- userAgent?: string | null | undefined;
3936
- };
3937
- user: Record<string, any> & {
3938
- id: string;
3939
- createdAt: Date;
3940
- updatedAt: Date;
3941
- email: string;
3942
- emailVerified: boolean;
3943
- name: string;
3944
- image?: string | null | undefined;
3945
- };
3946
- };
3947
- }>)[];
3948
3916
  metadata: {
3949
3917
  openapi: {
3950
3918
  description: string;
@@ -3994,6 +3962,8 @@ declare const router: <Option extends BetterAuthOptions>(ctx: AuthContext, optio
3994
3962
  };
3995
3963
  query: zod.ZodOptional<zod.ZodObject<{
3996
3964
  accountId: zod.ZodOptional<zod.ZodString>;
3965
+ providerId: zod.ZodOptional<zod.ZodString>;
3966
+ userId: zod.ZodOptional<zod.ZodString>;
3997
3967
  }, zod_v4_core0.$strip>>;
3998
3968
  }, {
3999
3969
  user: _better_auth_core_oauth20.OAuth2UserInfo;
@@ -104,6 +104,8 @@ declare const linkSocialAccount: better_call0.StrictEndpoint<"/link-social", {
104
104
  scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
105
105
  errorCallbackURL: z.ZodOptional<z.ZodString>;
106
106
  disableRedirect: z.ZodOptional<z.ZodBoolean>;
107
+ loginHint: z.ZodOptional<z.ZodString>;
108
+ additionalParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
107
109
  additionalData: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
108
110
  }, z.core.$strip>;
109
111
  use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
@@ -328,29 +330,6 @@ declare const refreshToken: better_call0.StrictEndpoint<"/refresh-token", {
328
330
  }>;
329
331
  declare const accountInfo: better_call0.StrictEndpoint<"/account-info", {
330
332
  method: "GET";
331
- use: ((inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<{
332
- session: {
333
- session: Record<string, any> & {
334
- id: string;
335
- createdAt: Date;
336
- updatedAt: Date;
337
- userId: string;
338
- expiresAt: Date;
339
- token: string;
340
- ipAddress?: string | null | undefined;
341
- userAgent?: string | null | undefined;
342
- };
343
- user: Record<string, any> & {
344
- id: string;
345
- createdAt: Date;
346
- updatedAt: Date;
347
- email: string;
348
- emailVerified: boolean;
349
- name: string;
350
- image?: string | null | undefined;
351
- };
352
- };
353
- }>)[];
354
333
  metadata: {
355
334
  openapi: {
356
335
  description: string;
@@ -400,6 +379,8 @@ declare const accountInfo: better_call0.StrictEndpoint<"/account-info", {
400
379
  };
401
380
  query: z.ZodOptional<z.ZodObject<{
402
381
  accountId: z.ZodOptional<z.ZodString>;
382
+ providerId: z.ZodOptional<z.ZodString>;
383
+ userId: z.ZodOptional<z.ZodString>;
403
384
  }, z.core.$strip>>;
404
385
  }, {
405
386
  user: _better_auth_core_oauth20.OAuth2UserInfo;
@@ -1,10 +1,13 @@
1
1
  import { parseAccountOutput } from "../../db/schema.mjs";
2
2
  import { getAccountCookie, setAccountCookie } from "../../cookies/session-store.mjs";
3
3
  import { getAwaitableValue } from "../../context/helpers.mjs";
4
- import { generateState } from "../../oauth2/state.mjs";
4
+ import { missingEmailLogMessage } from "../../oauth2/errors.mjs";
5
5
  import { decryptOAuthToken, setTokenUtil } from "../../oauth2/utils.mjs";
6
+ import { applyUpdateUserInfoOnLink } from "../../oauth2/link-account.mjs";
7
+ import { generateState } from "../../oauth2/state.mjs";
6
8
  import { freshSessionMiddleware, getSessionFromCtx, sessionMiddleware } from "./session.mjs";
7
9
  import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
10
+ import { additionalAuthorizationParamsSchema } from "@better-auth/core/oauth2";
8
11
  import { SocialProviderListEnum } from "@better-auth/core/social-providers";
9
12
  import { createAuthEndpoint } from "@better-auth/core/api";
10
13
  import * as z from "zod";
@@ -80,6 +83,8 @@ const linkSocialAccount = createAuthEndpoint("/link-social", {
80
83
  scopes: z.array(z.string()).meta({ description: "Additional scopes to request from the provider" }).optional(),
81
84
  errorCallbackURL: z.string().meta({ description: "The URL to redirect to if there is an error during the link process" }).optional(),
82
85
  disableRedirect: z.boolean().meta({ description: "Disable automatic redirection to the provider. Useful for handling the redirection yourself" }).optional(),
86
+ loginHint: z.string().meta({ description: "The login hint to use for the authorization code request" }).optional(),
87
+ additionalParams: additionalAuthorizationParamsSchema,
83
88
  additionalData: z.record(z.string(), z.any()).optional()
84
89
  }),
85
90
  use: [sessionMiddleware],
@@ -133,7 +138,7 @@ const linkSocialAccount = createAuthEndpoint("/link-social", {
133
138
  }
134
139
  const linkingUserId = String(linkingUserInfo.user.id);
135
140
  if (!linkingUserInfo.user.email) {
136
- c.context.logger.error("User email not found", { provider: c.body.provider });
141
+ c.context.logger.error(missingEmailLogMessage(c.body.provider, { source: "id_token" }), { provider: c.body.provider });
137
142
  throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.USER_EMAIL_NOT_FOUND);
138
143
  }
139
144
  if ((await c.context.internalAdapter.findAccounts(session.user.id)).find((a) => a.providerId === provider.id && a.accountId === linkingUserId)) return c.json({
@@ -165,14 +170,7 @@ const linkSocialAccount = createAuthEndpoint("/link-social", {
165
170
  code: "LINKING_FAILED"
166
171
  });
167
172
  }
168
- if (c.context.options.account?.accountLinking?.updateUserInfoOnLink === true) try {
169
- await c.context.internalAdapter.updateUser(session.user.id, {
170
- name: linkingUserInfo.user?.name,
171
- image: linkingUserInfo.user?.image
172
- });
173
- } catch (e) {
174
- console.warn("Could not update user - " + e.toString());
175
- }
173
+ await applyUpdateUserInfoOnLink(c, session.user.id, linkingUserInfo.user);
176
174
  return c.json({
177
175
  url: "",
178
176
  status: true,
@@ -187,7 +185,9 @@ const linkSocialAccount = createAuthEndpoint("/link-social", {
187
185
  state: state.state,
188
186
  codeVerifier: state.codeVerifier,
189
187
  redirectURI: `${c.context.baseURL}/callback/${provider.id}`,
190
- scopes: c.body.scopes
188
+ scopes: c.body.scopes,
189
+ loginHint: c.body.loginHint,
190
+ additionalParams: c.body.additionalParams
191
191
  });
192
192
  if (!c.body.disableRedirect) c.setHeader("Location", url.toString());
193
193
  return c.json({
@@ -221,50 +221,44 @@ const unlinkAccount = createAuthEndpoint("/unlink-account", {
221
221
  await ctx.context.internalAdapter.deleteAccount(accountExist.id);
222
222
  return ctx.json({ status: true });
223
223
  });
224
- const getAccessToken = createAuthEndpoint("/get-access-token", {
225
- method: "POST",
226
- body: z.object({
227
- providerId: z.string().meta({ description: "The provider ID for the OAuth provider" }),
228
- accountId: z.string().meta({ description: "The account ID associated with the refresh token" }).optional(),
229
- userId: z.string().meta({ description: "The user ID associated with the account" }).optional()
230
- }),
231
- metadata: { openapi: {
232
- description: "Get a valid access token, doing a refresh if needed",
233
- responses: {
234
- 200: {
235
- description: "A Valid access token",
236
- content: { "application/json": { schema: {
237
- type: "object",
238
- properties: {
239
- tokenType: { type: "string" },
240
- idToken: { type: "string" },
241
- accessToken: { type: "string" },
242
- accessTokenExpiresAt: {
243
- type: "string",
244
- format: "date-time"
245
- }
246
- }
247
- } } }
248
- },
249
- 400: { description: "Invalid refresh token or provider configuration" }
250
- }
251
- } }
252
- }, async (ctx) => {
253
- const { providerId, accountId, userId } = ctx.body || {};
254
- const req = ctx.request;
224
+ /**
225
+ * Resolves the user id an account-token operation should act on.
226
+ *
227
+ * A caller reaching the server over HTTP (a request or session headers are
228
+ * present) must have a valid session, and that session's user always wins.
229
+ * A trusted server-side `auth.api` caller with no session may instead name a
230
+ * `userId` directly. Throws `UNAUTHORIZED` when an HTTP caller is
231
+ * unauthenticated, and `USER_ID_OR_SESSION_REQUIRED` when neither a session
232
+ * nor a `userId` is available.
233
+ */
234
+ async function resolveUserId(ctx, userId) {
255
235
  const session = await getSessionFromCtx(ctx);
256
- if (req && !session) throw ctx.error("UNAUTHORIZED");
236
+ if (!session && (ctx.request || ctx.headers)) throw ctx.error("UNAUTHORIZED");
257
237
  const resolvedUserId = session?.user?.id || userId;
258
- if (!resolvedUserId) throw ctx.error("UNAUTHORIZED");
238
+ if (!resolvedUserId) throw APIError.from("BAD_REQUEST", {
239
+ message: "Either userId or session is required",
240
+ code: "USER_ID_OR_SESSION_REQUIRED"
241
+ });
242
+ return resolvedUserId;
243
+ }
244
+ /**
245
+ * Fetches a currently-valid access token for a user's provider account,
246
+ * refreshing and persisting it when it is within five seconds of expiry.
247
+ * Shared by the `/get-access-token` endpoint and `/account-info` so both
248
+ * resolve and refresh tokens through one path.
249
+ */
250
+ async function getValidAccessToken(ctx, { resolvedUserId, providerId, accountId, account: resolvedAccount }) {
259
251
  const provider = await getAwaitableValue(ctx.context.socialProviders, { value: providerId });
260
252
  if (!provider) throw APIError.from("BAD_REQUEST", {
261
253
  message: `Provider ${providerId} is not supported.`,
262
254
  code: "PROVIDER_NOT_SUPPORTED"
263
255
  });
264
- const accountData = await getAccountCookie(ctx);
265
- let account = void 0;
266
- if (accountData && accountData.userId === resolvedUserId && providerId === accountData.providerId && (!accountId || accountData.accountId === accountId)) account = accountData;
267
- else account = (await ctx.context.internalAdapter.findAccounts(resolvedUserId)).find((acc) => accountId ? acc.accountId === accountId && acc.providerId === providerId : acc.providerId === providerId);
256
+ let account = resolvedAccount;
257
+ if (!account) {
258
+ const accountData = await getAccountCookie(ctx);
259
+ if (accountData && accountData.userId === resolvedUserId && providerId === accountData.providerId && (!accountId || accountData.accountId === accountId)) account = accountData;
260
+ else account = (await ctx.context.internalAdapter.findAccounts(resolvedUserId)).find((acc) => accountId ? acc.accountId === accountId && acc.providerId === providerId : acc.providerId === providerId);
261
+ }
268
262
  if (!account) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.ACCOUNT_NOT_FOUND);
269
263
  try {
270
264
  let newTokens = null;
@@ -296,19 +290,55 @@ const getAccessToken = createAuthEndpoint("/get-access-token", {
296
290
  return account.accessTokenExpiresAt;
297
291
  }
298
292
  })();
299
- const tokens = {
293
+ return {
300
294
  accessToken: newTokens?.accessToken ?? await decryptOAuthToken(account.accessToken ?? "", ctx.context),
301
295
  accessTokenExpiresAt,
302
296
  scopes: account.scope?.split(",") ?? [],
303
297
  idToken: newTokens?.idToken ?? account.idToken ?? void 0
304
298
  };
305
- return ctx.json(tokens);
306
299
  } catch (_error) {
307
300
  throw APIError.from("BAD_REQUEST", {
308
301
  message: "Failed to get a valid access token",
309
302
  code: "FAILED_TO_GET_ACCESS_TOKEN"
310
303
  });
311
304
  }
305
+ }
306
+ const getAccessToken = createAuthEndpoint("/get-access-token", {
307
+ method: "POST",
308
+ body: z.object({
309
+ providerId: z.string().meta({ description: "The provider ID for the OAuth provider" }),
310
+ accountId: z.string().meta({ description: "The account ID associated with the refresh token" }).optional(),
311
+ userId: z.string().meta({ description: "The user ID associated with the account" }).optional()
312
+ }),
313
+ metadata: { openapi: {
314
+ description: "Get a valid access token, doing a refresh if needed",
315
+ responses: {
316
+ 200: {
317
+ description: "A Valid access token",
318
+ content: { "application/json": { schema: {
319
+ type: "object",
320
+ properties: {
321
+ tokenType: { type: "string" },
322
+ idToken: { type: "string" },
323
+ accessToken: { type: "string" },
324
+ accessTokenExpiresAt: {
325
+ type: "string",
326
+ format: "date-time"
327
+ }
328
+ }
329
+ } } }
330
+ },
331
+ 400: { description: "Invalid refresh token or provider configuration" }
332
+ }
333
+ } }
334
+ }, async (ctx) => {
335
+ const { providerId, accountId, userId } = ctx.body || {};
336
+ const tokens = await getValidAccessToken(ctx, {
337
+ resolvedUserId: await resolveUserId(ctx, userId),
338
+ providerId,
339
+ accountId
340
+ });
341
+ return ctx.json(tokens);
312
342
  });
313
343
  const refreshToken = createAuthEndpoint("/refresh-token", {
314
344
  method: "POST",
@@ -345,14 +375,7 @@ const refreshToken = createAuthEndpoint("/refresh-token", {
345
375
  } }
346
376
  }, async (ctx) => {
347
377
  const { providerId, accountId, userId } = ctx.body;
348
- const req = ctx.request;
349
- const session = await getSessionFromCtx(ctx);
350
- if (req && !session) throw ctx.error("UNAUTHORIZED");
351
- const resolvedUserId = session?.user?.id || userId;
352
- if (!resolvedUserId) throw APIError.from("BAD_REQUEST", {
353
- message: `Either userId or session is required`,
354
- code: "USER_ID_OR_SESSION_REQUIRED"
355
- });
378
+ const resolvedUserId = await resolveUserId(ctx, userId);
356
379
  const provider = await getAwaitableValue(ctx.context.socialProviders, { value: providerId });
357
380
  if (!provider) throw APIError.from("BAD_REQUEST", {
358
381
  message: `Provider ${providerId} is not supported.`,
@@ -417,10 +440,13 @@ const refreshToken = createAuthEndpoint("/refresh-token", {
417
440
  });
418
441
  }
419
442
  });
420
- const accountInfoQuerySchema = z.optional(z.object({ accountId: z.string().meta({ description: "The provider given account id for which to get the account info" }).optional() }));
443
+ const accountInfoQuerySchema = z.optional(z.object({
444
+ accountId: z.string().meta({ description: "The provider given account id for which to get the account info" }).optional(),
445
+ providerId: z.string().meta({ description: "The provider ID to disambiguate provider-issued account IDs" }).optional(),
446
+ userId: z.string().meta({ description: "The user ID associated with the account" }).optional()
447
+ }));
421
448
  const accountInfo = createAuthEndpoint("/account-info", {
422
449
  method: "GET",
423
- use: [sessionMiddleware],
424
450
  metadata: { openapi: {
425
451
  description: "Get the account info provided by the provider",
426
452
  responses: { "200": {
@@ -452,7 +478,8 @@ const accountInfo = createAuthEndpoint("/account-info", {
452
478
  } },
453
479
  query: accountInfoQuerySchema
454
480
  }, async (ctx) => {
455
- const providedAccountId = ctx.query?.accountId;
481
+ const { accountId: providedAccountId, providerId: providedProviderId, userId } = ctx.query || {};
482
+ const resolvedUserId = await resolveUserId(ctx, userId);
456
483
  let account = void 0;
457
484
  if (!providedAccountId) {
458
485
  if (ctx.context.options.account?.storeAccountCookie) {
@@ -460,24 +487,24 @@ const accountInfo = createAuthEndpoint("/account-info", {
460
487
  if (accountData) account = accountData;
461
488
  }
462
489
  } else {
463
- const accountData = await ctx.context.internalAdapter.findAccount(providedAccountId);
464
- if (accountData) account = accountData;
490
+ const matchingAccounts = (await ctx.context.internalAdapter.findAccounts(resolvedUserId)).filter((acc) => acc.accountId === providedAccountId && (!providedProviderId || acc.providerId === providedProviderId));
491
+ if (matchingAccounts.length > 1) throw APIError.from("BAD_REQUEST", {
492
+ message: "Multiple accounts share this account ID. Pass a providerId to disambiguate.",
493
+ code: "AMBIGUOUS_ACCOUNT"
494
+ });
495
+ account = matchingAccounts[0];
465
496
  }
466
- if (!account || account.userId !== ctx.context.session.user.id) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.ACCOUNT_NOT_FOUND);
497
+ if (!account || account.userId !== resolvedUserId) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.ACCOUNT_NOT_FOUND);
467
498
  const provider = await getAwaitableValue(ctx.context.socialProviders, { value: account.providerId });
468
- if (!provider) throw APIError.from("INTERNAL_SERVER_ERROR", {
469
- message: `Provider account provider is ${account.providerId} but it is not configured`,
499
+ if (!provider) throw APIError.from("BAD_REQUEST", {
500
+ message: "Account is not associated with a configured social provider.",
470
501
  code: "PROVIDER_NOT_CONFIGURED"
471
502
  });
472
- const tokens = await getAccessToken({
473
- ...ctx,
474
- method: "POST",
475
- body: {
476
- accountId: account.accountId,
477
- providerId: account.providerId
478
- },
479
- returnHeaders: false,
480
- returnStatus: false
503
+ const tokens = await getValidAccessToken(ctx, {
504
+ resolvedUserId,
505
+ providerId: account.providerId,
506
+ accountId: account.accountId,
507
+ account
481
508
  });
482
509
  if (!tokens.accessToken) throw APIError.from("BAD_REQUEST", {
483
510
  message: "Access token not found",