@masheev/better-auth 0.0.0-stage → 1.7.5

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 (465) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +31 -2
  3. package/TYPE-PATCH-NOTICE.md +9 -0
  4. package/TYPE-PATCH-PROVENANCE.json +267 -0
  5. package/dist/_virtual/_rolldown/runtime.mjs +27 -0
  6. package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
  7. package/dist/adapters/drizzle-adapter/index.mjs +2 -0
  8. package/dist/adapters/index.d.mts +26 -0
  9. package/dist/adapters/index.mjs +9 -0
  10. package/dist/adapters/kysely-adapter/index.d.mts +1 -0
  11. package/dist/adapters/kysely-adapter/index.mjs +2 -0
  12. package/dist/adapters/memory-adapter/index.d.mts +1 -0
  13. package/dist/adapters/memory-adapter/index.mjs +2 -0
  14. package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
  15. package/dist/adapters/mongodb-adapter/index.mjs +2 -0
  16. package/dist/adapters/prisma-adapter/index.d.mts +1 -0
  17. package/dist/adapters/prisma-adapter/index.mjs +2 -0
  18. package/dist/api/dispatch.d.mts +34 -0
  19. package/dist/api/dispatch.mjs +275 -0
  20. package/dist/api/index.d.mts +4053 -0
  21. package/dist/api/index.mjs +220 -0
  22. package/dist/api/middlewares/authorization.d.mts +69 -0
  23. package/dist/api/middlewares/authorization.mjs +78 -0
  24. package/dist/api/middlewares/index.d.mts +2 -0
  25. package/dist/api/middlewares/origin-check.d.mts +17 -0
  26. package/dist/api/middlewares/origin-check.mjs +155 -0
  27. package/dist/api/rate-limiter/index.mjs +318 -0
  28. package/dist/api/routes/account.d.mts +413 -0
  29. package/dist/api/routes/account.mjs +619 -0
  30. package/dist/api/routes/callback.d.mts +32 -0
  31. package/dist/api/routes/callback.mjs +261 -0
  32. package/dist/api/routes/email-verification.d.mts +160 -0
  33. package/dist/api/routes/email-verification.mjs +324 -0
  34. package/dist/api/routes/error.d.mts +27 -0
  35. package/dist/api/routes/error.mjs +387 -0
  36. package/dist/api/routes/index.d.mts +12 -0
  37. package/dist/api/routes/ok.d.mts +35 -0
  38. package/dist/api/routes/ok.mjs +27 -0
  39. package/dist/api/routes/password.d.mts +182 -0
  40. package/dist/api/routes/password.mjs +206 -0
  41. package/dist/api/routes/session.d.mts +450 -0
  42. package/dist/api/routes/session.mjs +481 -0
  43. package/dist/api/routes/sign-in.d.mts +186 -0
  44. package/dist/api/routes/sign-in.mjs +368 -0
  45. package/dist/api/routes/sign-out.d.mts +51 -0
  46. package/dist/api/routes/sign-out.mjs +96 -0
  47. package/dist/api/routes/sign-up.d.mts +159 -0
  48. package/dist/api/routes/sign-up.mjs +275 -0
  49. package/dist/api/routes/update-session.d.mts +74 -0
  50. package/dist/api/routes/update-session.mjs +57 -0
  51. package/dist/api/routes/update-user.d.mts +428 -0
  52. package/dist/api/routes/update-user.mjs +522 -0
  53. package/dist/api/state/oauth.d.mts +53 -0
  54. package/dist/api/state/oauth.mjs +38 -0
  55. package/dist/api/state/should-session-refresh.d.mts +12 -0
  56. package/dist/api/state/should-session-refresh.mjs +13 -0
  57. package/dist/api/to-auth-endpoints.mjs +60 -0
  58. package/dist/auth/base.mjs +66 -0
  59. package/dist/auth/full.d.mts +28 -0
  60. package/dist/auth/full.mjs +29 -0
  61. package/dist/auth/minimal.d.mts +10 -0
  62. package/dist/auth/minimal.mjs +11 -0
  63. package/dist/auth/trusted-origins.mjs +106 -0
  64. package/dist/client/broadcast-channel.d.mts +19 -0
  65. package/dist/client/broadcast-channel.mjs +44 -0
  66. package/dist/client/config.d.mts +90 -0
  67. package/dist/client/config.mjs +113 -0
  68. package/dist/client/equality.d.mts +19 -0
  69. package/dist/client/equality.mjs +42 -0
  70. package/dist/client/fetch-plugins.mjs +17 -0
  71. package/dist/client/focus-manager.d.mts +10 -0
  72. package/dist/client/focus-manager.mjs +30 -0
  73. package/dist/client/index.d.mts +35 -0
  74. package/dist/client/index.mjs +22 -0
  75. package/dist/client/lynx/index.d.mts +43 -0
  76. package/dist/client/lynx/index.mjs +22 -0
  77. package/dist/client/lynx/lynx-store.d.mts +46 -0
  78. package/dist/client/lynx/lynx-store.mjs +44 -0
  79. package/dist/client/online-manager.d.mts +11 -0
  80. package/dist/client/online-manager.mjs +33 -0
  81. package/dist/client/parser.d.mts +10 -0
  82. package/dist/client/parser.mjs +70 -0
  83. package/dist/client/path-to-object.d.mts +113 -0
  84. package/dist/client/plugins/index.d.mts +44 -0
  85. package/dist/client/plugins/index.mjs +30 -0
  86. package/dist/client/plugins/infer-plugin.d.mts +16 -0
  87. package/dist/client/plugins/infer-plugin.mjs +11 -0
  88. package/dist/client/proxy.mjs +78 -0
  89. package/dist/client/query.d.mts +23 -0
  90. package/dist/client/query.mjs +124 -0
  91. package/dist/client/react/index.d.mts +44 -0
  92. package/dist/client/react/index.mjs +22 -0
  93. package/dist/client/react/react-store.d.mts +46 -0
  94. package/dist/client/react/react-store.mjs +44 -0
  95. package/dist/client/session-atom.d.mts +11 -0
  96. package/dist/client/session-atom.mjs +178 -0
  97. package/dist/client/session-refresh.d.mts +20 -0
  98. package/dist/client/session-refresh.mjs +131 -0
  99. package/dist/client/solid/index.d.mts +44 -0
  100. package/dist/client/solid/index.mjs +22 -0
  101. package/dist/client/solid/solid-store.mjs +21 -0
  102. package/dist/client/svelte/index.d.mts +44 -0
  103. package/dist/client/svelte/index.mjs +18 -0
  104. package/dist/client/types.d.mts +51 -0
  105. package/dist/client/vanilla.d.mts +42 -0
  106. package/dist/client/vanilla.mjs +18 -0
  107. package/dist/client/vue/index.d.mts +67 -0
  108. package/dist/client/vue/index.mjs +54 -0
  109. package/dist/client/vue/vue-store.mjs +23 -0
  110. package/dist/context/create-context.mjs +235 -0
  111. package/dist/context/helpers.mjs +158 -0
  112. package/dist/context/init-minimal.mjs +17 -0
  113. package/dist/context/init.mjs +19 -0
  114. package/dist/context/secret-utils.mjs +53 -0
  115. package/dist/context/store-capabilities.mjs +12 -0
  116. package/dist/cookies/cache.mjs +33 -0
  117. package/dist/cookies/cookie-utils.d.mts +72 -0
  118. package/dist/cookies/cookie-utils.mjs +203 -0
  119. package/dist/cookies/index.d.mts +124 -0
  120. package/dist/cookies/index.mjs +350 -0
  121. package/dist/cookies/jwt.mjs +44 -0
  122. package/dist/cookies/session-store.d.mts +32 -0
  123. package/dist/cookies/session-store.mjs +183 -0
  124. package/dist/crypto/buffer.d.mts +7 -0
  125. package/dist/crypto/buffer.mjs +16 -0
  126. package/dist/crypto/index.d.mts +32 -0
  127. package/dist/crypto/index.mjs +69 -0
  128. package/dist/crypto/jwt.d.mts +9 -0
  129. package/dist/crypto/jwt.mjs +141 -0
  130. package/dist/crypto/password.d.mts +13 -0
  131. package/dist/crypto/password.mjs +14 -0
  132. package/dist/crypto/random.d.mts +4 -0
  133. package/dist/crypto/random.mjs +5 -0
  134. package/dist/db/adapter-base.d.mts +7 -0
  135. package/dist/db/adapter-base.mjs +25 -0
  136. package/dist/db/adapter-kysely.d.mts +7 -0
  137. package/dist/db/adapter-kysely.mjs +17 -0
  138. package/dist/db/field-converter.d.mts +7 -0
  139. package/dist/db/field-converter.mjs +19 -0
  140. package/dist/db/field.d.mts +41 -0
  141. package/dist/db/get-migration.d.mts +56 -0
  142. package/dist/db/get-migration.mjs +685 -0
  143. package/dist/db/get-schema.d.mts +13 -0
  144. package/dist/db/get-schema.mjs +39 -0
  145. package/dist/db/index.d.mts +10 -0
  146. package/dist/db/index.mjs +35 -0
  147. package/dist/db/internal-adapter.d.mts +14 -0
  148. package/dist/db/internal-adapter.mjs +951 -0
  149. package/dist/db/revoke-unproven-account-access.d.mts +21 -0
  150. package/dist/db/revoke-unproven-account-access.mjs +58 -0
  151. package/dist/db/schema.d.mts +62 -0
  152. package/dist/db/schema.mjs +161 -0
  153. package/dist/db/to-zod.d.mts +35 -0
  154. package/dist/db/to-zod.mjs +23 -0
  155. package/dist/db/verification-token-storage.mjs +25 -0
  156. package/dist/db/with-hooks.d.mts +37 -0
  157. package/dist/db/with-hooks.mjs +255 -0
  158. package/dist/index.d.mts +30 -0
  159. package/dist/index.mjs +17 -0
  160. package/dist/integrations/cookie-plugin-guard.mjs +18 -0
  161. package/dist/integrations/next-js.d.mts +29 -0
  162. package/dist/integrations/next-js.mjs +105 -0
  163. package/dist/integrations/node.d.mts +11 -0
  164. package/dist/integrations/node.mjs +13 -0
  165. package/dist/integrations/solid-start.d.mts +22 -0
  166. package/dist/integrations/solid-start.mjs +15 -0
  167. package/dist/integrations/svelte-kit.d.mts +38 -0
  168. package/dist/integrations/svelte-kit.mjs +57 -0
  169. package/dist/integrations/tanstack-start-solid.d.mts +33 -0
  170. package/dist/integrations/tanstack-start-solid.mjs +57 -0
  171. package/dist/integrations/tanstack-start.d.mts +33 -0
  172. package/dist/integrations/tanstack-start.mjs +57 -0
  173. package/dist/oauth2/account-key.mjs +43 -0
  174. package/dist/oauth2/errors.mjs +49 -0
  175. package/dist/oauth2/index.d.mts +5 -0
  176. package/dist/oauth2/index.mjs +5 -0
  177. package/dist/oauth2/link-account.d.mts +96 -0
  178. package/dist/oauth2/link-account.mjs +329 -0
  179. package/dist/oauth2/state.d.mts +54 -0
  180. package/dist/oauth2/state.mjs +67 -0
  181. package/dist/oauth2/utils.d.mts +11 -0
  182. package/dist/oauth2/utils.mjs +33 -0
  183. package/dist/package.mjs +4 -0
  184. package/dist/plugins/access/access.d.mts +17 -0
  185. package/dist/plugins/access/access.mjs +78 -0
  186. package/dist/plugins/access/index.d.mts +3 -0
  187. package/dist/plugins/access/index.mjs +2 -0
  188. package/dist/plugins/access/types.d.mts +24 -0
  189. package/dist/plugins/additional-fields/client.d.mts +100 -0
  190. package/dist/plugins/additional-fields/client.mjs +11 -0
  191. package/dist/plugins/admin/access/index.d.mts +2 -0
  192. package/dist/plugins/admin/access/index.mjs +2 -0
  193. package/dist/plugins/admin/access/statement.d.mts +51 -0
  194. package/dist/plugins/admin/access/statement.mjs +52 -0
  195. package/dist/plugins/admin/admin.d.mts +911 -0
  196. package/dist/plugins/admin/admin.mjs +89 -0
  197. package/dist/plugins/admin/client.d.mts +81 -0
  198. package/dist/plugins/admin/client.mjs +39 -0
  199. package/dist/plugins/admin/error-codes.d.mts +30 -0
  200. package/dist/plugins/admin/error-codes.mjs +29 -0
  201. package/dist/plugins/admin/has-permission.mjs +12 -0
  202. package/dist/plugins/admin/index.d.mts +3 -0
  203. package/dist/plugins/admin/index.mjs +2 -0
  204. package/dist/plugins/admin/routes.mjs +919 -0
  205. package/dist/plugins/admin/schema.d.mts +40 -0
  206. package/dist/plugins/admin/schema.mjs +33 -0
  207. package/dist/plugins/admin/types.d.mts +88 -0
  208. package/dist/plugins/anonymous/client.d.mts +32 -0
  209. package/dist/plugins/anonymous/client.mjs +21 -0
  210. package/dist/plugins/anonymous/error-codes.d.mts +15 -0
  211. package/dist/plugins/anonymous/error-codes.mjs +14 -0
  212. package/dist/plugins/anonymous/index.d.mts +175 -0
  213. package/dist/plugins/anonymous/index.mjs +219 -0
  214. package/dist/plugins/anonymous/schema.d.mts +15 -0
  215. package/dist/plugins/anonymous/schema.mjs +9 -0
  216. package/dist/plugins/anonymous/types.d.mts +65 -0
  217. package/dist/plugins/bearer/index.d.mts +45 -0
  218. package/dist/plugins/bearer/index.mjs +74 -0
  219. package/dist/plugins/captcha/constants.d.mts +9 -0
  220. package/dist/plugins/captcha/constants.mjs +27 -0
  221. package/dist/plugins/captcha/error-codes.mjs +13 -0
  222. package/dist/plugins/captcha/index.d.mts +27 -0
  223. package/dist/plugins/captcha/index.mjs +79 -0
  224. package/dist/plugins/captcha/types.d.mts +52 -0
  225. package/dist/plugins/captcha/utils.mjs +9 -0
  226. package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
  227. package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +47 -0
  228. package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +32 -0
  229. package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
  230. package/dist/plugins/custom-session/client.d.mts +17 -0
  231. package/dist/plugins/custom-session/client.mjs +7 -0
  232. package/dist/plugins/custom-session/index.d.mts +73 -0
  233. package/dist/plugins/custom-session/index.mjs +65 -0
  234. package/dist/plugins/device-authorization/client.d.mts +17 -0
  235. package/dist/plugins/device-authorization/client.mjs +18 -0
  236. package/dist/plugins/device-authorization/error-codes.mjs +19 -0
  237. package/dist/plugins/device-authorization/index.d.mts +558 -0
  238. package/dist/plugins/device-authorization/index.mjs +87 -0
  239. package/dist/plugins/device-authorization/routes.d.mts +32 -0
  240. package/dist/plugins/device-authorization/routes.mjs +725 -0
  241. package/dist/plugins/device-authorization/schema.d.mts +18 -0
  242. package/dist/plugins/device-authorization/schema.mjs +63 -0
  243. package/dist/plugins/email-otp/client.d.mts +21 -0
  244. package/dist/plugins/email-otp/client.mjs +17 -0
  245. package/dist/plugins/email-otp/error-codes.d.mts +10 -0
  246. package/dist/plugins/email-otp/error-codes.mjs +9 -0
  247. package/dist/plugins/email-otp/index.d.mts +551 -0
  248. package/dist/plugins/email-otp/index.mjs +145 -0
  249. package/dist/plugins/email-otp/otp-token.mjs +55 -0
  250. package/dist/plugins/email-otp/routes.mjs +784 -0
  251. package/dist/plugins/email-otp/types.d.mts +109 -0
  252. package/dist/plugins/email-otp/utils.mjs +17 -0
  253. package/dist/plugins/generic-oauth/error-codes.mjs +8 -0
  254. package/dist/plugins/generic-oauth/index.d.mts +52 -0
  255. package/dist/plugins/generic-oauth/index.mjs +279 -0
  256. package/dist/plugins/generic-oauth/providers/auth0.d.mts +36 -0
  257. package/dist/plugins/generic-oauth/providers/auth0.mjs +49 -0
  258. package/dist/plugins/generic-oauth/providers/gumroad.d.mts +31 -0
  259. package/dist/plugins/generic-oauth/providers/gumroad.mjs +62 -0
  260. package/dist/plugins/generic-oauth/providers/hubspot.d.mts +36 -0
  261. package/dist/plugins/generic-oauth/providers/hubspot.mjs +62 -0
  262. package/dist/plugins/generic-oauth/providers/index.d.mts +10 -0
  263. package/dist/plugins/generic-oauth/providers/keycloak.d.mts +36 -0
  264. package/dist/plugins/generic-oauth/providers/keycloak.mjs +47 -0
  265. package/dist/plugins/generic-oauth/providers/line.d.mts +54 -0
  266. package/dist/plugins/generic-oauth/providers/line.mjs +93 -0
  267. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +39 -0
  268. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +104 -0
  269. package/dist/plugins/generic-oauth/providers/okta.d.mts +36 -0
  270. package/dist/plugins/generic-oauth/providers/okta.mjs +47 -0
  271. package/dist/plugins/generic-oauth/providers/patreon.d.mts +29 -0
  272. package/dist/plugins/generic-oauth/providers/patreon.mjs +61 -0
  273. package/dist/plugins/generic-oauth/providers/slack.d.mts +29 -0
  274. package/dist/plugins/generic-oauth/providers/slack.mjs +63 -0
  275. package/dist/plugins/generic-oauth/providers/yandex.d.mts +29 -0
  276. package/dist/plugins/generic-oauth/providers/yandex.mjs +67 -0
  277. package/dist/plugins/generic-oauth/types.d.mts +268 -0
  278. package/dist/plugins/haveibeenpwned/index.d.mts +63 -0
  279. package/dist/plugins/haveibeenpwned/index.mjs +81 -0
  280. package/dist/plugins/index.d.mts +69 -0
  281. package/dist/plugins/index.mjs +49 -0
  282. package/dist/plugins/jwt/adapter.mjs +68 -0
  283. package/dist/plugins/jwt/client.d.mts +41 -0
  284. package/dist/plugins/jwt/client.mjs +19 -0
  285. package/dist/plugins/jwt/cookie-cache.mjs +77 -0
  286. package/dist/plugins/jwt/index.d.mts +246 -0
  287. package/dist/plugins/jwt/index.mjs +214 -0
  288. package/dist/plugins/jwt/schema.d.mts +33 -0
  289. package/dist/plugins/jwt/schema.mjs +29 -0
  290. package/dist/plugins/jwt/sign.d.mts +128 -0
  291. package/dist/plugins/jwt/sign.mjs +130 -0
  292. package/dist/plugins/jwt/types.d.mts +256 -0
  293. package/dist/plugins/jwt/utils.d.mts +41 -0
  294. package/dist/plugins/jwt/utils.mjs +64 -0
  295. package/dist/plugins/jwt/verify.d.mts +11 -0
  296. package/dist/plugins/jwt/verify.mjs +45 -0
  297. package/dist/plugins/last-login-method/client.d.mts +48 -0
  298. package/dist/plugins/last-login-method/client.mjs +48 -0
  299. package/dist/plugins/last-login-method/index.d.mts +127 -0
  300. package/dist/plugins/last-login-method/index.mjs +98 -0
  301. package/dist/plugins/magic-link/client.d.mts +10 -0
  302. package/dist/plugins/magic-link/client.mjs +11 -0
  303. package/dist/plugins/magic-link/index.d.mts +213 -0
  304. package/dist/plugins/magic-link/index.mjs +208 -0
  305. package/dist/plugins/magic-link/utils.mjs +9 -0
  306. package/dist/plugins/multi-session/client.d.mts +19 -0
  307. package/dist/plugins/multi-session/client.mjs +19 -0
  308. package/dist/plugins/multi-session/error-codes.d.mts +8 -0
  309. package/dist/plugins/multi-session/error-codes.mjs +5 -0
  310. package/dist/plugins/multi-session/index.d.mts +212 -0
  311. package/dist/plugins/multi-session/index.mjs +217 -0
  312. package/dist/plugins/oauth-popup/client.d.mts +82 -0
  313. package/dist/plugins/oauth-popup/client.mjs +203 -0
  314. package/dist/plugins/oauth-popup/constants.d.mts +11 -0
  315. package/dist/plugins/oauth-popup/constants.mjs +11 -0
  316. package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
  317. package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
  318. package/dist/plugins/oauth-popup/index.d.mts +67 -0
  319. package/dist/plugins/oauth-popup/index.mjs +232 -0
  320. package/dist/plugins/oauth-popup/types.d.mts +30 -0
  321. package/dist/plugins/oauth-proxy/index.d.mts +130 -0
  322. package/dist/plugins/oauth-proxy/index.mjs +407 -0
  323. package/dist/plugins/oauth-proxy/utils.mjs +55 -0
  324. package/dist/plugins/one-tap/client.d.mts +174 -0
  325. package/dist/plugins/one-tap/client.mjs +208 -0
  326. package/dist/plugins/one-tap/index.d.mts +82 -0
  327. package/dist/plugins/one-tap/index.mjs +100 -0
  328. package/dist/plugins/one-time-token/client.d.mts +10 -0
  329. package/dist/plugins/one-time-token/client.mjs +11 -0
  330. package/dist/plugins/one-time-token/index.d.mts +132 -0
  331. package/dist/plugins/one-time-token/index.mjs +107 -0
  332. package/dist/plugins/one-time-token/utils.mjs +9 -0
  333. package/dist/plugins/open-api/generator.d.mts +126 -0
  334. package/dist/plugins/open-api/generator.mjs +557 -0
  335. package/dist/plugins/open-api/index.d.mts +97 -0
  336. package/dist/plugins/open-api/index.mjs +65 -0
  337. package/dist/plugins/open-api/logo.mjs +13 -0
  338. package/dist/plugins/organization/access/index.d.mts +2 -0
  339. package/dist/plugins/organization/access/index.mjs +2 -0
  340. package/dist/plugins/organization/access/statement.d.mts +113 -0
  341. package/dist/plugins/organization/access/statement.mjs +77 -0
  342. package/dist/plugins/organization/adapter.d.mts +815 -0
  343. package/dist/plugins/organization/adapter.mjs +813 -0
  344. package/dist/plugins/organization/call.mjs +15 -0
  345. package/dist/plugins/organization/client.d.mts +375 -0
  346. package/dist/plugins/organization/client.mjs +104 -0
  347. package/dist/plugins/organization/error-codes.d.mts +66 -0
  348. package/dist/plugins/organization/error-codes.mjs +65 -0
  349. package/dist/plugins/organization/has-permission.d.mts +17 -0
  350. package/dist/plugins/organization/has-permission.mjs +34 -0
  351. package/dist/plugins/organization/index.d.mts +6 -0
  352. package/dist/plugins/organization/index.mjs +4 -0
  353. package/dist/plugins/organization/organization.d.mts +420 -0
  354. package/dist/plugins/organization/organization.mjs +886 -0
  355. package/dist/plugins/organization/permission.d.mts +15 -0
  356. package/dist/plugins/organization/permission.mjs +14 -0
  357. package/dist/plugins/organization/routes/crud-access-control.d.mts +511 -0
  358. package/dist/plugins/organization/routes/crud-access-control.mjs +674 -0
  359. package/dist/plugins/organization/routes/crud-invites.d.mts +1154 -0
  360. package/dist/plugins/organization/routes/crud-invites.mjs +602 -0
  361. package/dist/plugins/organization/routes/crud-members.d.mts +1057 -0
  362. package/dist/plugins/organization/routes/crud-members.mjs +518 -0
  363. package/dist/plugins/organization/routes/crud-org.d.mts +918 -0
  364. package/dist/plugins/organization/routes/crud-org.mjs +455 -0
  365. package/dist/plugins/organization/routes/crud-team.d.mts +1238 -0
  366. package/dist/plugins/organization/routes/crud-team.mjs +766 -0
  367. package/dist/plugins/organization/schema.d.mts +390 -0
  368. package/dist/plugins/organization/schema.mjs +65 -0
  369. package/dist/plugins/organization/types.d.mts +691 -0
  370. package/dist/plugins/phone-number/client.d.mts +31 -0
  371. package/dist/plugins/phone-number/client.mjs +19 -0
  372. package/dist/plugins/phone-number/error-codes.d.mts +19 -0
  373. package/dist/plugins/phone-number/error-codes.mjs +18 -0
  374. package/dist/plugins/phone-number/index.d.mts +360 -0
  375. package/dist/plugins/phone-number/index.mjs +57 -0
  376. package/dist/plugins/phone-number/routes.mjs +529 -0
  377. package/dist/plugins/phone-number/schema.d.mts +22 -0
  378. package/dist/plugins/phone-number/schema.mjs +18 -0
  379. package/dist/plugins/phone-number/types.d.mts +116 -0
  380. package/dist/plugins/siwe/client.d.mts +14 -0
  381. package/dist/plugins/siwe/client.mjs +15 -0
  382. package/dist/plugins/siwe/index.d.mts +62 -0
  383. package/dist/plugins/siwe/index.mjs +272 -0
  384. package/dist/plugins/siwe/parse-message.mjs +60 -0
  385. package/dist/plugins/siwe/schema.d.mts +35 -0
  386. package/dist/plugins/siwe/schema.mjs +30 -0
  387. package/dist/plugins/siwe/types.d.mts +43 -0
  388. package/dist/plugins/test-utils/auth-helpers.mjs +33 -0
  389. package/dist/plugins/test-utils/cookie-builder.mjs +55 -0
  390. package/dist/plugins/test-utils/db-helpers.mjs +65 -0
  391. package/dist/plugins/test-utils/factories.mjs +38 -0
  392. package/dist/plugins/test-utils/index.d.mts +73 -0
  393. package/dist/plugins/test-utils/index.mjs +97 -0
  394. package/dist/plugins/test-utils/otp-sink.mjs +21 -0
  395. package/dist/plugins/test-utils/types.d.mts +51 -0
  396. package/dist/plugins/two-factor/backup-codes/index.d.mts +291 -0
  397. package/dist/plugins/two-factor/backup-codes/index.mjs +341 -0
  398. package/dist/plugins/two-factor/client.d.mts +76 -0
  399. package/dist/plugins/two-factor/client.mjs +41 -0
  400. package/dist/plugins/two-factor/constant.mjs +6 -0
  401. package/dist/plugins/two-factor/error-code.d.mts +20 -0
  402. package/dist/plugins/two-factor/error-code.mjs +19 -0
  403. package/dist/plugins/two-factor/index.d.mts +720 -0
  404. package/dist/plugins/two-factor/index.mjs +349 -0
  405. package/dist/plugins/two-factor/otp/index.d.mts +216 -0
  406. package/dist/plugins/two-factor/otp/index.mjs +252 -0
  407. package/dist/plugins/two-factor/schema.d.mts +59 -0
  408. package/dist/plugins/two-factor/schema.mjs +53 -0
  409. package/dist/plugins/two-factor/totp/index.d.mts +219 -0
  410. package/dist/plugins/two-factor/totp/index.mjs +230 -0
  411. package/dist/plugins/two-factor/types.d.mts +111 -0
  412. package/dist/plugins/two-factor/utils.mjs +9 -0
  413. package/dist/plugins/two-factor/verify-two-factor.mjs +205 -0
  414. package/dist/plugins/username/client.d.mts +38 -0
  415. package/dist/plugins/username/client.mjs +17 -0
  416. package/dist/plugins/username/error-codes.d.mts +16 -0
  417. package/dist/plugins/username/error-codes.mjs +15 -0
  418. package/dist/plugins/username/index.d.mts +326 -0
  419. package/dist/plugins/username/index.mjs +312 -0
  420. package/dist/plugins/username/schema.d.mts +50 -0
  421. package/dist/plugins/username/schema.mjs +25 -0
  422. package/dist/social-providers/index.d.mts +1 -0
  423. package/dist/social-providers/index.mjs +2 -0
  424. package/dist/state.d.mts +48 -0
  425. package/dist/state.mjs +149 -0
  426. package/dist/test-utils/headers.d.mts +8 -0
  427. package/dist/test-utils/headers.mjs +17 -0
  428. package/dist/test-utils/http-test-instance.d.mts +413 -0
  429. package/dist/test-utils/http-test-instance.mjs +107 -0
  430. package/dist/test-utils/index.d.mts +4 -0
  431. package/dist/test-utils/index.mjs +4 -0
  432. package/dist/test-utils/test-instance.d.mts +56 -0
  433. package/dist/test-utils/test-instance.mjs +242 -0
  434. package/dist/types/adapter.d.mts +2 -0
  435. package/dist/types/api.d.mts +28 -0
  436. package/dist/types/auth.d.mts +32 -0
  437. package/dist/types/helper.d.mts +26 -0
  438. package/dist/types/index.d.mts +10 -0
  439. package/dist/types/index.mjs +1 -0
  440. package/dist/types/models.d.mts +10 -0
  441. package/dist/types/plugins.d.mts +19 -0
  442. package/dist/utils/boolean.mjs +6 -0
  443. package/dist/utils/constants.mjs +4 -0
  444. package/dist/utils/date.mjs +6 -0
  445. package/dist/utils/hashing.mjs +18 -0
  446. package/dist/utils/hide-metadata.d.mts +6 -0
  447. package/dist/utils/hide-metadata.mjs +4 -0
  448. package/dist/utils/index.d.mts +4 -0
  449. package/dist/utils/is-api-error.d.mts +2 -0
  450. package/dist/utils/is-api-error.mjs +2 -0
  451. package/dist/utils/is-atom.mjs +6 -0
  452. package/dist/utils/is-promise.mjs +6 -0
  453. package/dist/utils/middleware-response.mjs +7 -0
  454. package/dist/utils/password.mjs +32 -0
  455. package/dist/utils/plugin-helper.mjs +14 -0
  456. package/dist/utils/request.mjs +23 -0
  457. package/dist/utils/shim.mjs +22 -0
  458. package/dist/utils/time.d.mts +48 -0
  459. package/dist/utils/time.mjs +98 -0
  460. package/dist/utils/url.d.mts +78 -0
  461. package/dist/utils/url.mjs +238 -0
  462. package/dist/utils/validate-user-info.mjs +44 -0
  463. package/dist/utils/wildcard.mjs +106 -0
  464. package/dist/version.mjs +5 -0
  465. package/package.json +595 -3
@@ -0,0 +1,619 @@
1
+ import { shouldBindAccountCookieToSessionUser } from "../../context/store-capabilities.mjs";
2
+ import { parseAccountOutput } from "../../db/schema.mjs";
3
+ import { getAccountCookie, setAccountCookie } from "../../cookies/session-store.mjs";
4
+ import { getAwaitableValue } from "../../context/helpers.mjs";
5
+ import { resolveOAuthAccountKeyForAPI } from "../../oauth2/account-key.mjs";
6
+ import { missingEmailLogMessage } from "../../oauth2/errors.mjs";
7
+ import { decryptOAuthToken, getOAuthCallbackPath, setTokenUtil } from "../../oauth2/utils.mjs";
8
+ import { applyUpdateUserInfoOnLink } from "../../oauth2/link-account.mjs";
9
+ import { generateIdTokenNonce, generateState } from "../../oauth2/state.mjs";
10
+ import { freshSessionMiddleware, getSessionFromCtx, isStateful, sessionMiddleware } from "./session.mjs";
11
+ import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
12
+ import { additionalAuthorizationParamsSchema, supportsIdTokenSignIn, verifyProviderIdToken } from "@better-auth/core/oauth2";
13
+ import { SocialProviderListEnum } from "@better-auth/core/social-providers";
14
+ import { createAuthEndpoint } from "@better-auth/core/api";
15
+ import * as z from "zod";
16
+ //#region src/api/routes/account.ts
17
+ function parseStoredScopes(scope) {
18
+ if (!scope) return [];
19
+ return scope.split(",").map((s) => s.trim()).filter(Boolean);
20
+ }
21
+ const listUserAccounts = createAuthEndpoint("/list-accounts", {
22
+ method: "GET",
23
+ use: [sessionMiddleware],
24
+ metadata: { openapi: {
25
+ operationId: "listUserAccounts",
26
+ description: "List all accounts linked to the user",
27
+ responses: { "200": {
28
+ description: "Success",
29
+ content: { "application/json": { schema: {
30
+ type: "array",
31
+ items: {
32
+ type: "object",
33
+ properties: {
34
+ id: { type: "string" },
35
+ providerId: { type: "string" },
36
+ createdAt: {
37
+ type: "string",
38
+ format: "date-time"
39
+ },
40
+ updatedAt: {
41
+ type: "string",
42
+ format: "date-time"
43
+ },
44
+ accountId: { type: "string" },
45
+ userId: { type: "string" },
46
+ scopes: {
47
+ type: "array",
48
+ items: { type: "string" }
49
+ }
50
+ },
51
+ required: [
52
+ "id",
53
+ "providerId",
54
+ "createdAt",
55
+ "updatedAt",
56
+ "accountId",
57
+ "userId",
58
+ "scopes"
59
+ ]
60
+ }
61
+ } } }
62
+ } }
63
+ } }
64
+ }, async (c) => {
65
+ const session = c.context.session;
66
+ const accounts = await c.context.internalAdapter.findAccounts(session.user.id);
67
+ return c.json(accounts.map((a) => {
68
+ const { scope, ...parsed } = parseAccountOutput(c.context.options, a);
69
+ return {
70
+ ...parsed,
71
+ scopes: parseStoredScopes(scope)
72
+ };
73
+ }));
74
+ });
75
+ const linkSocialAccount = createAuthEndpoint("/link-social", {
76
+ method: "POST",
77
+ requireHeaders: true,
78
+ body: z.object({
79
+ /**
80
+ * Callback URL to redirect to after the user has signed in.
81
+ */
82
+ callbackURL: z.string().meta({ description: "The URL to redirect to after the user has signed in" }).optional(),
83
+ /**
84
+ * OAuth2 provider to use
85
+ */
86
+ provider: SocialProviderListEnum,
87
+ /**
88
+ * ID Token for direct authentication without redirect
89
+ */
90
+ idToken: z.object({
91
+ token: z.string(),
92
+ nonce: z.string().optional(),
93
+ accessToken: z.string().optional(),
94
+ refreshToken: z.string().optional()
95
+ }).optional(),
96
+ /**
97
+ * Whether to allow sign up for new users
98
+ */
99
+ requestSignUp: z.boolean().optional(),
100
+ /**
101
+ * Additional scopes to request when linking the account.
102
+ * This is useful for requesting additional permissions when
103
+ * linking a social account compared to the initial authentication.
104
+ */
105
+ scopes: z.array(z.string()).meta({ description: "Additional scopes to request from the provider" }).optional(),
106
+ /**
107
+ * The URL to redirect to if there is an error during the link process.
108
+ */
109
+ errorCallbackURL: z.string().meta({ description: "The URL to redirect to if there is an error during the link process" }).optional(),
110
+ /**
111
+ * Disable automatic redirection to the provider
112
+ *
113
+ * This is useful if you want to handle the redirection
114
+ * yourself like in a popup or a different tab.
115
+ */
116
+ disableRedirect: z.boolean().meta({ description: "Disable automatic redirection to the provider. Useful for handling the redirection yourself" }).optional(),
117
+ /**
118
+ * The login hint to forward to the provider authorization endpoint.
119
+ */
120
+ loginHint: z.string().meta({ description: "The login hint to use for the authorization code request" }).optional(),
121
+ /**
122
+ * Extra query parameters to append to the provider authorization URL.
123
+ * Reserved OAuth keys (state, client_id, redirect_uri, response_type,
124
+ * code_challenge, code_challenge_method, nonce, scope) are rejected.
125
+ */
126
+ additionalParams: additionalAuthorizationParamsSchema,
127
+ /**
128
+ * Any additional data to pass through the oauth flow.
129
+ */
130
+ additionalData: z.record(z.string(), z.any()).optional()
131
+ }),
132
+ use: [sessionMiddleware],
133
+ metadata: { openapi: {
134
+ description: "Link a social account to the user",
135
+ operationId: "linkSocialAccount",
136
+ responses: { "200": {
137
+ description: "Success",
138
+ content: { "application/json": { schema: {
139
+ type: "object",
140
+ properties: {
141
+ url: {
142
+ type: "string",
143
+ description: "The authorization URL to redirect the user to"
144
+ },
145
+ redirect: {
146
+ type: "boolean",
147
+ description: "Indicates if the user should be redirected to the authorization URL"
148
+ },
149
+ status: { type: "boolean" }
150
+ },
151
+ required: ["redirect"]
152
+ } } }
153
+ } }
154
+ } }
155
+ }, async (c) => {
156
+ const session = c.context.session;
157
+ const provider = await getAwaitableValue(c.context.socialProviders, { value: c.body.provider });
158
+ if (!provider) {
159
+ c.context.logger.error("Provider not found. Make sure to add the provider in your auth config", { provider: c.body.provider });
160
+ throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.PROVIDER_NOT_FOUND);
161
+ }
162
+ if (c.body.idToken) {
163
+ if (!supportsIdTokenSignIn(provider)) {
164
+ c.context.logger.error("Provider does not support id token verification", { provider: c.body.provider });
165
+ throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.ID_TOKEN_NOT_SUPPORTED);
166
+ }
167
+ const { token, nonce } = c.body.idToken;
168
+ if (!await verifyProviderIdToken(provider, token, nonce, c)) {
169
+ c.context.logger.warn("Invalid id token", { provider: c.body.provider });
170
+ throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.INVALID_TOKEN);
171
+ }
172
+ const linkingUserInfo = await provider.getUserInfo({
173
+ idToken: token,
174
+ accessToken: c.body.idToken.accessToken,
175
+ refreshToken: c.body.idToken.refreshToken
176
+ });
177
+ if (!linkingUserInfo || !linkingUserInfo?.user) {
178
+ c.context.logger.error("Failed to get user info", { provider: c.body.provider });
179
+ throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.FAILED_TO_GET_USER_INFO);
180
+ }
181
+ if (!linkingUserInfo.user.email) {
182
+ c.context.logger.error(missingEmailLogMessage(c.body.provider, { source: "id_token" }), { provider: c.body.provider });
183
+ throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.USER_EMAIL_NOT_FOUND);
184
+ }
185
+ const accountKey = await resolveOAuthAccountKeyForAPI(provider, {
186
+ idToken: token,
187
+ accessToken: c.body.idToken.accessToken,
188
+ refreshToken: c.body.idToken.refreshToken
189
+ }, linkingUserInfo.data);
190
+ const linkedAccount = await c.context.internalAdapter.findAccountByKey(accountKey);
191
+ if (linkedAccount?.userId === session.user.id) {
192
+ const updateData = Object.fromEntries(Object.entries({
193
+ providerId: provider.id,
194
+ accessToken: await setTokenUtil(c.body.idToken.accessToken, c.context),
195
+ idToken: token,
196
+ refreshToken: await setTokenUtil(c.body.idToken.refreshToken, c.context)
197
+ }).filter(([_, value]) => value !== void 0));
198
+ await c.context.internalAdapter.updateAccount(linkedAccount.id, updateData);
199
+ await applyUpdateUserInfoOnLink(c, session.user.id, linkingUserInfo.user);
200
+ return c.json({
201
+ url: "",
202
+ status: true,
203
+ redirect: false
204
+ });
205
+ }
206
+ if (linkedAccount) throw APIError.from("CONFLICT", BASE_ERROR_CODES.SOCIAL_ACCOUNT_ALREADY_LINKED);
207
+ if (!c.context.trustedProviders.includes(provider.id) && !linkingUserInfo.user.emailVerified || c.context.options.account?.accountLinking?.enabled === false) throw APIError.from("UNAUTHORIZED", {
208
+ message: "Account not linked - linking not allowed",
209
+ code: "LINKING_NOT_ALLOWED"
210
+ });
211
+ if (linkingUserInfo.user.email?.toLowerCase() !== session.user.email.toLowerCase() && c.context.options.account?.accountLinking?.allowDifferentEmails !== true) throw APIError.from("UNAUTHORIZED", {
212
+ message: "Account not linked - different emails not allowed",
213
+ code: "LINKING_DIFFERENT_EMAILS_NOT_ALLOWED"
214
+ });
215
+ try {
216
+ await c.context.internalAdapter.createAccount({
217
+ userId: session.user.id,
218
+ ...accountKey,
219
+ accessToken: await setTokenUtil(c.body.idToken.accessToken, c.context),
220
+ idToken: token,
221
+ refreshToken: await setTokenUtil(c.body.idToken.refreshToken, c.context)
222
+ });
223
+ } catch {
224
+ throw APIError.from("EXPECTATION_FAILED", {
225
+ message: "Account not linked - unable to create account",
226
+ code: "LINKING_FAILED"
227
+ });
228
+ }
229
+ await applyUpdateUserInfoOnLink(c, session.user.id, linkingUserInfo.user);
230
+ return c.json({
231
+ url: "",
232
+ status: true,
233
+ redirect: false
234
+ });
235
+ }
236
+ const idTokenNonce = generateIdTokenNonce(provider);
237
+ const state = await generateState(c, {
238
+ link: {
239
+ userId: session.user.id,
240
+ email: session.user.email
241
+ },
242
+ additionalData: c.body.additionalData,
243
+ idTokenNonce
244
+ });
245
+ const url = await provider.createAuthorizationURL({
246
+ state: state.state,
247
+ codeVerifier: state.codeVerifier,
248
+ idTokenNonce,
249
+ redirectURI: `${c.context.baseURL}${getOAuthCallbackPath(provider)}`,
250
+ scopes: c.body.scopes,
251
+ loginHint: c.body.loginHint,
252
+ additionalParams: c.body.additionalParams
253
+ });
254
+ if (!c.body.disableRedirect) c.setHeader("Location", url.toString());
255
+ return c.json({
256
+ url: url.toString(),
257
+ redirect: !c.body.disableRedirect
258
+ });
259
+ });
260
+ const unlinkAccount = createAuthEndpoint("/unlink-account", {
261
+ method: "POST",
262
+ body: z.object({ accountId: z.string().meta({ description: "The Better Auth account ID to unlink" }) }),
263
+ use: [freshSessionMiddleware],
264
+ metadata: { openapi: {
265
+ description: "Unlink an account",
266
+ responses: { "200": {
267
+ description: "Success",
268
+ content: { "application/json": { schema: {
269
+ type: "object",
270
+ properties: { status: { type: "boolean" } }
271
+ } } }
272
+ } }
273
+ } }
274
+ }, async (ctx) => {
275
+ const { accountId } = ctx.body;
276
+ const accounts = await ctx.context.internalAdapter.findAccounts(ctx.context.session.user.id);
277
+ if (accounts.length === 1 && !ctx.context.options.account?.accountLinking?.allowUnlinkingAll) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.FAILED_TO_UNLINK_LAST_ACCOUNT);
278
+ const accountExist = accounts.find((account) => account.id === accountId);
279
+ if (!accountExist) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.ACCOUNT_NOT_FOUND);
280
+ await ctx.context.internalAdapter.deleteAccount(accountExist.id);
281
+ return ctx.json({ status: true });
282
+ });
283
+ /**
284
+ * Resolves the user id an account-token operation should act on.
285
+ *
286
+ * A caller reaching the server over HTTP (a request or session headers are
287
+ * present) must have a valid session, and that session's user always wins.
288
+ * A trusted server-side `auth.api` caller with no session may instead name a
289
+ * `userId` directly. Throws `UNAUTHORIZED` when an HTTP caller is
290
+ * unauthenticated, and `USER_ID_OR_SESSION_REQUIRED` when neither a session
291
+ * nor a `userId` is available.
292
+ *
293
+ * When a durable store is authoritative, bypasses the cookie cache: these
294
+ * routes mint or refresh provider access tokens, so a server-side session
295
+ * revocation must take effect immediately rather than waiting for the cached
296
+ * cookie to expire. DB-less deployments keep the session in the cookie itself,
297
+ * so the cache is left in place for them.
298
+ */
299
+ async function resolveUserId(ctx, userId) {
300
+ const session = await getSessionFromCtx(ctx, { disableCookieCache: isStateful(ctx) });
301
+ if (!session && (ctx.request || ctx.headers)) throw ctx.error("UNAUTHORIZED");
302
+ const resolvedUserId = session?.user?.id || userId;
303
+ if (!resolvedUserId) throw APIError.from("BAD_REQUEST", {
304
+ message: "Either userId or session is required",
305
+ code: "USER_ID_OR_SESSION_REQUIRED"
306
+ });
307
+ return resolvedUserId;
308
+ }
309
+ const accountSelectionSchema = z.union([z.strictObject({
310
+ accountId: z.string().meta({ description: "The Better Auth account ID" }),
311
+ userId: z.string().meta({ description: "The user ID associated with the account" }).optional()
312
+ }), z.strictObject({
313
+ useAccountCookie: z.literal(true).meta({ description: "Select the current OAuth account from its signed cookie" }),
314
+ userId: z.string().meta({ description: "The user ID associated with the account" }).optional()
315
+ })]);
316
+ function matchesAccountSelection(ctx, account, { resolvedUserId, selection }) {
317
+ return (!shouldBindAccountCookieToSessionUser(ctx.context.options) || account.userId === resolvedUserId) && ("accountId" in selection ? account.id === selection.accountId : true);
318
+ }
319
+ /**
320
+ * Resolves an account from exactly one explicit source.
321
+ *
322
+ * A local account ID is resolved from the database. A signed account cookie is
323
+ * used only when the caller explicitly selects it, which keeps stateless OAuth
324
+ * flows usable without letting cached cookie data satisfy a row-ID lookup.
325
+ */
326
+ async function resolveUserAccount(ctx, { resolvedUserId, selection }) {
327
+ if ("accountId" in selection) {
328
+ const account = (await ctx.context.internalAdapter.findAccounts(resolvedUserId)).find((candidate) => candidate.id === selection.accountId);
329
+ if (account) return {
330
+ account,
331
+ accountCookie: null
332
+ };
333
+ } else if (ctx.context.options.account?.storeAccountCookie) {
334
+ const accountCookie = await getAccountCookie(ctx);
335
+ if (accountCookie && matchesAccountSelection(ctx, accountCookie, {
336
+ resolvedUserId,
337
+ selection
338
+ })) return {
339
+ account: accountCookie,
340
+ accountCookie
341
+ };
342
+ }
343
+ throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.ACCOUNT_NOT_FOUND);
344
+ }
345
+ /**
346
+ * Fetches a currently-valid access token for a user's provider account,
347
+ * refreshing and persisting it when it is within five seconds of expiry.
348
+ * Shared by the `/get-access-token` endpoint and `/account-info` so both
349
+ * resolve and refresh tokens through one path.
350
+ */
351
+ async function getValidAccessToken(ctx, { resolvedUserId, selection, account: resolvedAccount }) {
352
+ const account = resolvedAccount ?? (await resolveUserAccount(ctx, {
353
+ resolvedUserId,
354
+ selection
355
+ })).account;
356
+ if (!matchesAccountSelection(ctx, account, {
357
+ resolvedUserId,
358
+ selection
359
+ })) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.ACCOUNT_NOT_FOUND);
360
+ const provider = await getAwaitableValue(ctx.context.socialProviders, { value: account.providerId });
361
+ if (!provider) throw APIError.from("BAD_REQUEST", {
362
+ message: `Provider ${account.providerId} is not supported.`,
363
+ code: "PROVIDER_NOT_SUPPORTED"
364
+ });
365
+ try {
366
+ let newTokens = null;
367
+ const accessTokenExpired = account.accessTokenExpiresAt && new Date(account.accessTokenExpiresAt).getTime() - Date.now() < 5e3;
368
+ if (account.refreshToken && accessTokenExpired && provider.refreshAccessToken) {
369
+ const refreshToken = await decryptOAuthToken(account.refreshToken, ctx.context);
370
+ newTokens = await provider.refreshAccessToken(refreshToken, ctx);
371
+ const updatedData = {
372
+ accessToken: await setTokenUtil(newTokens?.accessToken, ctx.context),
373
+ accessTokenExpiresAt: newTokens?.accessTokenExpiresAt,
374
+ refreshToken: newTokens?.refreshToken ? await setTokenUtil(newTokens.refreshToken, ctx.context) : account.refreshToken,
375
+ refreshTokenExpiresAt: newTokens?.refreshTokenExpiresAt ?? account.refreshTokenExpiresAt,
376
+ idToken: newTokens?.idToken || account.idToken
377
+ };
378
+ let updatedAccount = null;
379
+ if (account.id) updatedAccount = await ctx.context.internalAdapter.updateAccount(account.id, updatedData);
380
+ if (ctx.context.options.account?.storeAccountCookie) await setAccountCookie(ctx, {
381
+ ...account,
382
+ ...updatedAccount ?? updatedData
383
+ });
384
+ }
385
+ const accessTokenExpiresAt = (() => {
386
+ if (newTokens?.accessTokenExpiresAt) {
387
+ if (typeof newTokens.accessTokenExpiresAt === "string") return new Date(newTokens.accessTokenExpiresAt);
388
+ return newTokens.accessTokenExpiresAt;
389
+ }
390
+ if (account.accessTokenExpiresAt) {
391
+ if (typeof account.accessTokenExpiresAt === "string") return new Date(account.accessTokenExpiresAt);
392
+ return account.accessTokenExpiresAt;
393
+ }
394
+ })();
395
+ return {
396
+ accessToken: newTokens?.accessToken ?? await decryptOAuthToken(account.accessToken ?? "", ctx.context),
397
+ accessTokenExpiresAt,
398
+ scopes: parseStoredScopes(account.scope),
399
+ idToken: newTokens?.idToken ?? account.idToken ?? void 0
400
+ };
401
+ } catch (_error) {
402
+ throw APIError.from("BAD_REQUEST", {
403
+ message: "Failed to get a valid access token",
404
+ code: "FAILED_TO_GET_ACCESS_TOKEN"
405
+ });
406
+ }
407
+ }
408
+ const getAccessToken = createAuthEndpoint("/get-access-token", {
409
+ method: "POST",
410
+ body: accountSelectionSchema,
411
+ metadata: { openapi: {
412
+ description: "Get a valid access token, doing a refresh if needed",
413
+ responses: {
414
+ 200: {
415
+ description: "A Valid access token",
416
+ content: { "application/json": { schema: {
417
+ type: "object",
418
+ properties: {
419
+ tokenType: { type: "string" },
420
+ idToken: { type: "string" },
421
+ accessToken: { type: "string" },
422
+ accessTokenExpiresAt: {
423
+ type: "string",
424
+ format: "date-time"
425
+ }
426
+ }
427
+ } } }
428
+ },
429
+ 400: { description: "Invalid refresh token or provider configuration" }
430
+ }
431
+ } }
432
+ }, async (ctx) => {
433
+ const { userId } = ctx.body;
434
+ const tokens = await getValidAccessToken(ctx, {
435
+ resolvedUserId: await resolveUserId(ctx, userId),
436
+ selection: ctx.body
437
+ });
438
+ return ctx.json(tokens);
439
+ });
440
+ const refreshToken = createAuthEndpoint("/refresh-token", {
441
+ method: "POST",
442
+ body: accountSelectionSchema,
443
+ metadata: { openapi: {
444
+ description: "Refresh the access token using a refresh token",
445
+ responses: {
446
+ 200: {
447
+ description: "Access token refreshed successfully",
448
+ content: { "application/json": { schema: {
449
+ type: "object",
450
+ properties: {
451
+ tokenType: { type: "string" },
452
+ idToken: { type: "string" },
453
+ accessToken: { type: "string" },
454
+ refreshToken: { type: "string" },
455
+ accessTokenExpiresAt: {
456
+ type: "string",
457
+ format: "date-time"
458
+ },
459
+ refreshTokenExpiresAt: {
460
+ type: "string",
461
+ format: "date-time"
462
+ }
463
+ }
464
+ } } }
465
+ },
466
+ 400: { description: "Invalid refresh token or provider configuration" }
467
+ }
468
+ } }
469
+ }, async (ctx) => {
470
+ const { userId } = ctx.body;
471
+ const { account, accountCookie } = await resolveUserAccount(ctx, {
472
+ resolvedUserId: await resolveUserId(ctx, userId),
473
+ selection: ctx.body
474
+ });
475
+ const provider = await getAwaitableValue(ctx.context.socialProviders, { value: account.providerId });
476
+ if (!provider) throw APIError.from("BAD_REQUEST", {
477
+ message: `Provider ${account.providerId} is not supported.`,
478
+ code: "PROVIDER_NOT_SUPPORTED"
479
+ });
480
+ if (!provider.refreshAccessToken) throw APIError.from("BAD_REQUEST", {
481
+ message: `Provider ${account.providerId} does not support token refreshing.`,
482
+ code: "TOKEN_REFRESH_NOT_SUPPORTED"
483
+ });
484
+ const refreshToken = account.refreshToken ?? void 0;
485
+ if (!refreshToken) throw APIError.from("BAD_REQUEST", {
486
+ message: "Refresh token not found",
487
+ code: "REFRESH_TOKEN_NOT_FOUND"
488
+ });
489
+ try {
490
+ const decryptedRefreshToken = await decryptOAuthToken(refreshToken, ctx.context);
491
+ const tokens = await provider.refreshAccessToken(decryptedRefreshToken, ctx);
492
+ const resolvedRefreshToken = tokens.refreshToken ? await setTokenUtil(tokens.refreshToken, ctx.context) : refreshToken;
493
+ const resolvedRefreshTokenExpiresAt = tokens.refreshTokenExpiresAt ?? account.refreshTokenExpiresAt;
494
+ const updatedTokenData = {
495
+ accessToken: await setTokenUtil(tokens.accessToken, ctx.context),
496
+ refreshToken: resolvedRefreshToken,
497
+ accessTokenExpiresAt: tokens.accessTokenExpiresAt,
498
+ refreshTokenExpiresAt: resolvedRefreshTokenExpiresAt,
499
+ idToken: tokens.idToken || account.idToken
500
+ };
501
+ let updatedAccount = null;
502
+ if (account.id)
503
+ /**
504
+ * `scope` intentionally omitted. Refresh response may be narrower.
505
+ *
506
+ * @see {@link Account.scope}
507
+ */
508
+ updatedAccount = await ctx.context.internalAdapter.updateAccount(account.id, updatedTokenData);
509
+ if (accountCookie?.id === account.id && ctx.context.options.account?.storeAccountCookie) await setAccountCookie(ctx, {
510
+ ...accountCookie,
511
+ ...updatedAccount ?? updatedTokenData
512
+ });
513
+ const responseScope = updatedAccount?.scope ?? account.scope;
514
+ return ctx.json({
515
+ accessToken: tokens.accessToken,
516
+ refreshToken: tokens.refreshToken ?? decryptedRefreshToken,
517
+ accessTokenExpiresAt: tokens.accessTokenExpiresAt,
518
+ refreshTokenExpiresAt: resolvedRefreshTokenExpiresAt,
519
+ scope: responseScope,
520
+ idToken: tokens.idToken || account.idToken,
521
+ providerId: account.providerId,
522
+ accountId: account.id
523
+ });
524
+ } catch (_error) {
525
+ throw APIError.from("BAD_REQUEST", {
526
+ message: "Failed to refresh access token",
527
+ code: "FAILED_TO_REFRESH_ACCESS_TOKEN"
528
+ });
529
+ }
530
+ });
531
+ const accountInfo = createAuthEndpoint("/account-info", {
532
+ method: "GET",
533
+ metadata: { openapi: {
534
+ description: "Get the account info provided by the provider",
535
+ responses: { "200": {
536
+ description: "Success",
537
+ content: { "application/json": { schema: {
538
+ type: "object",
539
+ properties: {
540
+ user: {
541
+ type: "object",
542
+ properties: {
543
+ name: { type: "string" },
544
+ email: {
545
+ type: "string",
546
+ nullable: true
547
+ },
548
+ image: { type: "string" },
549
+ emailVerified: { type: "boolean" }
550
+ },
551
+ required: ["emailVerified"]
552
+ },
553
+ account: {
554
+ type: "object",
555
+ properties: {
556
+ id: { type: "string" },
557
+ providerId: { type: "string" },
558
+ accountId: { type: "string" }
559
+ },
560
+ required: [
561
+ "id",
562
+ "providerId",
563
+ "accountId"
564
+ ],
565
+ additionalProperties: false
566
+ },
567
+ data: {
568
+ type: "object",
569
+ properties: {},
570
+ additionalProperties: true
571
+ }
572
+ },
573
+ required: [
574
+ "user",
575
+ "data",
576
+ "account"
577
+ ],
578
+ additionalProperties: false
579
+ } } }
580
+ } }
581
+ } },
582
+ query: accountSelectionSchema
583
+ }, async (ctx) => {
584
+ const { userId } = ctx.query;
585
+ const resolvedUserId = await resolveUserId(ctx, userId);
586
+ const { account } = await resolveUserAccount(ctx, {
587
+ resolvedUserId,
588
+ selection: ctx.query
589
+ });
590
+ const provider = await getAwaitableValue(ctx.context.socialProviders, { value: account.providerId });
591
+ if (!provider) throw APIError.from("BAD_REQUEST", {
592
+ message: "Account is not associated with a configured social provider.",
593
+ code: "PROVIDER_NOT_CONFIGURED"
594
+ });
595
+ const tokens = await getValidAccessToken(ctx, {
596
+ resolvedUserId,
597
+ selection: ctx.query,
598
+ account
599
+ });
600
+ if (!tokens.accessToken) throw APIError.from("BAD_REQUEST", {
601
+ message: "Access token not found",
602
+ code: "ACCESS_TOKEN_NOT_FOUND"
603
+ });
604
+ const info = await provider.getUserInfo({
605
+ ...tokens,
606
+ accessToken: tokens.accessToken
607
+ });
608
+ if (!info) throw APIError.from("UNAUTHORIZED", BASE_ERROR_CODES.FAILED_TO_GET_USER_INFO);
609
+ return ctx.json({
610
+ ...info,
611
+ account: {
612
+ id: account.id,
613
+ providerId: account.providerId,
614
+ accountId: account.accountId
615
+ }
616
+ });
617
+ });
618
+ //#endregion
619
+ export { accountInfo, getAccessToken, linkSocialAccount, listUserAccounts, refreshToken, unlinkAccount };
@@ -0,0 +1,32 @@
1
+ import * as _$better_call0 from "better-call";
2
+ import * as z from "zod";
3
+
4
+ //#region src/api/routes/callback.d.ts
5
+ declare const callbackOAuth: _$better_call0.StrictEndpoint<"/callback/:id", {
6
+ method: ("GET" | "POST")[];
7
+ operationId: string;
8
+ body: z.ZodOptional<z.ZodObject<{
9
+ code: z.ZodOptional<z.ZodString>;
10
+ error: z.ZodOptional<z.ZodString>;
11
+ device_id: z.ZodOptional<z.ZodString>;
12
+ error_description: z.ZodOptional<z.ZodString>;
13
+ state: z.ZodOptional<z.ZodString>;
14
+ user: z.ZodOptional<z.ZodString>;
15
+ iss: z.ZodOptional<z.ZodString>;
16
+ }, z.core.$strip>>;
17
+ query: z.ZodOptional<z.ZodObject<{
18
+ code: z.ZodOptional<z.ZodString>;
19
+ error: z.ZodOptional<z.ZodString>;
20
+ device_id: z.ZodOptional<z.ZodString>;
21
+ error_description: z.ZodOptional<z.ZodString>;
22
+ state: z.ZodOptional<z.ZodString>;
23
+ user: z.ZodOptional<z.ZodString>;
24
+ iss: z.ZodOptional<z.ZodString>;
25
+ }, z.core.$strip>>;
26
+ metadata: {
27
+ allowedMediaTypes: string[];
28
+ scope: "server";
29
+ };
30
+ }, void>;
31
+ //#endregion
32
+ export { callbackOAuth };