@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,230 @@
1
+ import { symmetricDecrypt } from "../../../crypto/index.mjs";
2
+ import { setSessionCookie } from "../../../cookies/index.mjs";
3
+ import { sessionMiddleware } from "../../../api/routes/session.mjs";
4
+ import { shouldRequirePassword } from "../../../utils/password.mjs";
5
+ import { PACKAGE_VERSION } from "../../../version.mjs";
6
+ import { TWO_FACTOR_ERROR_CODES } from "../error-code.mjs";
7
+ import { assertTwoFactorNotLocked, recordTwoFactorFailure, resetTwoFactorFailures, verifyTwoFactor } from "../verify-two-factor.mjs";
8
+ import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
9
+ import { createAuthEndpoint } from "@better-auth/core/api";
10
+ import * as z from "zod";
11
+ import { createOTP } from "@better-auth/utils/otp";
12
+ //#region src/plugins/two-factor/totp/index.ts
13
+ const generateTOTPBodySchema = z.object({ secret: z.string().meta({ description: "The secret to generate the TOTP code" }) });
14
+ const verifyTOTPBodySchema = z.object({
15
+ code: z.string().meta({ description: "The otp code to verify. Eg: \"012345\"" }),
16
+ /**
17
+ * if true, the device will be trusted
18
+ * for 30 days. It'll be refreshed on
19
+ * every sign in request within this time.
20
+ */
21
+ trustDevice: z.boolean().meta({ description: "If true, the device will be trusted for 30 days. It'll be refreshed on every sign in request within this time. Eg: true" }).optional()
22
+ });
23
+ const totp2fa = (options) => {
24
+ const opts = {
25
+ ...options,
26
+ digits: options?.digits || 6,
27
+ period: options?.period || 30
28
+ };
29
+ const passwordSchema = z.string().meta({ description: "User password" });
30
+ const getTOTPURIBodySchema = options?.allowPasswordless ? z.object({ password: passwordSchema.optional() }) : z.object({ password: passwordSchema });
31
+ const twoFactorTable = "twoFactor";
32
+ return {
33
+ id: "totp",
34
+ version: PACKAGE_VERSION,
35
+ endpoints: {
36
+ /**
37
+ * ### Endpoint
38
+ *
39
+ * POST `/totp/generate`
40
+ *
41
+ * ### API Methods
42
+ *
43
+ * **server:**
44
+ * `auth.api.generateTOTP`
45
+ *
46
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/2fa#totp)
47
+ */
48
+ generateTOTP: createAuthEndpoint.serverOnly({
49
+ method: "POST",
50
+ body: generateTOTPBodySchema,
51
+ metadata: { openapi: {
52
+ summary: "Generate TOTP code",
53
+ description: "Use this endpoint to generate a TOTP code",
54
+ responses: { 200: {
55
+ description: "Successful response",
56
+ content: { "application/json": { schema: {
57
+ type: "object",
58
+ properties: { code: { type: "string" } }
59
+ } } }
60
+ } }
61
+ } }
62
+ }, async (ctx) => {
63
+ if (options?.disable) {
64
+ ctx.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp");
65
+ throw APIError.from("BAD_REQUEST", {
66
+ message: "totp isn't configured",
67
+ code: "TOTP_NOT_CONFIGURED"
68
+ });
69
+ }
70
+ return { code: await createOTP(ctx.body.secret, {
71
+ period: opts.period,
72
+ digits: opts.digits
73
+ }).totp() };
74
+ }),
75
+ /**
76
+ * ### Endpoint
77
+ *
78
+ * POST `/two-factor/get-totp-uri`
79
+ *
80
+ * ### API Methods
81
+ *
82
+ * **server:**
83
+ * `auth.api.getTOTPURI`
84
+ *
85
+ * **client:**
86
+ * `authClient.twoFactor.getTotpUri`
87
+ *
88
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/2fa#getting-totp-uri)
89
+ */
90
+ getTOTPURI: createAuthEndpoint("/two-factor/get-totp-uri", {
91
+ method: "POST",
92
+ use: [sessionMiddleware],
93
+ body: getTOTPURIBodySchema,
94
+ metadata: { openapi: {
95
+ summary: "Get TOTP URI",
96
+ description: "Use this endpoint to get the TOTP URI",
97
+ responses: { 200: {
98
+ description: "Successful response",
99
+ content: { "application/json": { schema: {
100
+ type: "object",
101
+ properties: { totpURI: { type: "string" } }
102
+ } } }
103
+ } }
104
+ } }
105
+ }, async (ctx) => {
106
+ if (options?.disable) {
107
+ ctx.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp");
108
+ throw APIError.from("BAD_REQUEST", {
109
+ message: "totp isn't configured",
110
+ code: "TOTP_NOT_CONFIGURED"
111
+ });
112
+ }
113
+ const user = ctx.context.session.user;
114
+ const twoFactor = await ctx.context.adapter.findOne({
115
+ model: twoFactorTable,
116
+ where: [{
117
+ field: "userId",
118
+ value: user.id
119
+ }]
120
+ });
121
+ if (!twoFactor) throw APIError.from("BAD_REQUEST", TWO_FACTOR_ERROR_CODES.TOTP_NOT_ENABLED);
122
+ const secret = await symmetricDecrypt({
123
+ key: ctx.context.secretConfig,
124
+ data: twoFactor.secret
125
+ });
126
+ if (await shouldRequirePassword(ctx, user.id, options?.allowPasswordless)) {
127
+ if (!ctx.body.password) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_PASSWORD);
128
+ await ctx.context.password.checkPassword(user.id, ctx);
129
+ }
130
+ return { totpURI: createOTP(secret, {
131
+ digits: opts.digits,
132
+ period: opts.period
133
+ }).url(options?.issuer || ctx.context.appName, user.email) };
134
+ }),
135
+ /**
136
+ * ### Endpoint
137
+ *
138
+ * POST `/two-factor/verify-totp`
139
+ *
140
+ * ### API Methods
141
+ *
142
+ * **server:**
143
+ * `auth.api.verifyTOTP`
144
+ *
145
+ * **client:**
146
+ * `authClient.twoFactor.verifyTotp`
147
+ *
148
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/2fa#verifying-totp)
149
+ */
150
+ verifyTOTP: createAuthEndpoint("/two-factor/verify-totp", {
151
+ method: "POST",
152
+ body: verifyTOTPBodySchema,
153
+ metadata: { openapi: {
154
+ summary: "Verify two factor TOTP",
155
+ description: "Verify two factor TOTP",
156
+ responses: { 200: {
157
+ description: "Successful response",
158
+ content: { "application/json": { schema: {
159
+ type: "object",
160
+ properties: { status: { type: "boolean" } }
161
+ } } }
162
+ } }
163
+ } }
164
+ }, async (ctx) => {
165
+ if (options?.disable) {
166
+ ctx.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp");
167
+ throw APIError.from("BAD_REQUEST", {
168
+ message: "totp isn't configured",
169
+ code: "TOTP_NOT_CONFIGURED"
170
+ });
171
+ }
172
+ const { session, valid, invalid, beginAttempt } = await verifyTwoFactor(ctx);
173
+ const user = session.user;
174
+ const isSignIn = !session.session;
175
+ const twoFactor = await ctx.context.adapter.findOne({
176
+ model: twoFactorTable,
177
+ where: [{
178
+ field: "userId",
179
+ value: user.id
180
+ }]
181
+ });
182
+ if (!twoFactor) throw APIError.from("BAD_REQUEST", TWO_FACTOR_ERROR_CODES.TOTP_NOT_ENABLED);
183
+ if (isSignIn && twoFactor.verified === false) throw APIError.from("BAD_REQUEST", TWO_FACTOR_ERROR_CODES.TOTP_NOT_ENABLED);
184
+ if (isSignIn) await assertTwoFactorNotLocked(ctx, twoFactorTable, twoFactor);
185
+ const attempt = isSignIn ? await beginAttempt(5) : null;
186
+ let status;
187
+ try {
188
+ status = await createOTP(await symmetricDecrypt({
189
+ key: ctx.context.secretConfig,
190
+ data: twoFactor.secret
191
+ }), {
192
+ period: opts.period,
193
+ digits: opts.digits
194
+ }).verify(ctx.body.code);
195
+ } catch (error) {
196
+ await attempt?.restore();
197
+ throw error;
198
+ }
199
+ if (!status) {
200
+ await attempt?.recordFailure();
201
+ if (isSignIn) await recordTwoFactorFailure(ctx, twoFactorTable, twoFactor);
202
+ return invalid("INVALID_CODE");
203
+ }
204
+ if (isSignIn) await resetTwoFactorFailures(ctx, twoFactorTable, twoFactor);
205
+ if (twoFactor.verified !== true) {
206
+ if (!user.twoFactorEnabled) {
207
+ const activeSession = session.session;
208
+ const updatedUser = await ctx.context.internalAdapter.updateUser(user.id, { twoFactorEnabled: true });
209
+ await setSessionCookie(ctx, {
210
+ session: await ctx.context.internalAdapter.createSession(user.id, false, activeSession),
211
+ user: updatedUser
212
+ });
213
+ await ctx.context.internalAdapter.deleteSession(activeSession.token);
214
+ }
215
+ await ctx.context.adapter.update({
216
+ model: twoFactorTable,
217
+ update: { verified: true },
218
+ where: [{
219
+ field: "id",
220
+ value: twoFactor.id
221
+ }]
222
+ });
223
+ }
224
+ return valid(ctx);
225
+ })
226
+ }
227
+ };
228
+ };
229
+ //#endregion
230
+ export { totp2fa };
@@ -0,0 +1,111 @@
1
+ import { User } from "../../types/models.mjs";
2
+ import { InferOptionSchema } from "../../types/plugins.mjs";
3
+ import { BackupCodeOptions } from "./backup-codes/index.mjs";
4
+ import { OTPOptions } from "./otp/index.mjs";
5
+ import { schema } from "./schema.mjs";
6
+ import { TOTPOptions } from "./totp/index.mjs";
7
+ import { BetterAuthPlugin, LiteralString } from "@better-auth/core";
8
+
9
+ //#region src/plugins/two-factor/types.d.ts
10
+ interface TwoFactorOptions {
11
+ /**
12
+ * Application Name
13
+ */
14
+ issuer?: string | undefined;
15
+ /**
16
+ * The name of the table that stores the two factor
17
+ * authentication data.
18
+ *
19
+ * @default "twoFactor"
20
+ */
21
+ twoFactorTable?: string | undefined;
22
+ /**
23
+ * TOTP OPtions
24
+ */
25
+ totpOptions?: Omit<TOTPOptions, "issuer"> | undefined;
26
+ /**
27
+ * OTP Options
28
+ */
29
+ otpOptions?: OTPOptions | undefined;
30
+ /**
31
+ * Backup code options
32
+ */
33
+ backupCodeOptions?: BackupCodeOptions | undefined;
34
+ /**
35
+ * Skip verification on enabling two factor authentication.
36
+ * @default false
37
+ */
38
+ skipVerificationOnEnable?: boolean | undefined;
39
+ /**
40
+ * Allow enabling and managing 2FA without a password when the user does not
41
+ * have a credential account (e.g. passkey-only users).
42
+ * When enabled, password is still required if a credential account exists.
43
+ * @default false
44
+ */
45
+ allowPasswordless?: boolean | undefined;
46
+ /**
47
+ * Custom schema for the two factor plugin
48
+ */
49
+ schema?: InferOptionSchema<typeof schema> | undefined;
50
+ /**
51
+ * Maximum age (in seconds) for the two-factor verification cookie.
52
+ * This controls how long users have to complete the 2FA flow
53
+ * after signing in.
54
+ *
55
+ * @default 600 (10 minutes)
56
+ */
57
+ twoFactorCookieMaxAge?: number | undefined;
58
+ /**
59
+ * Maximum age (in seconds) for the trusted device cookie.
60
+ * When a user opts to trust a device, this controls how long
61
+ * the device stays trusted before requiring 2FA again.
62
+ *
63
+ * @default 2592000 (30 days)
64
+ */
65
+ trustDeviceMaxAge?: number | undefined;
66
+ /**
67
+ * Account-level lockout for failed second-factor verifications during
68
+ * sign-in. Caps consecutive failed attempts per account, across challenges
69
+ * and factors, and resets on a successful verification.
70
+ */
71
+ accountLockout?: {
72
+ /**
73
+ * Whether account-level lockout is enforced.
74
+ * @default true
75
+ */
76
+ enabled?: boolean | undefined;
77
+ /**
78
+ * Consecutive failed verifications, across challenges and factors,
79
+ * before the account is locked.
80
+ * @default 10
81
+ */
82
+ maxFailedAttempts?: number | undefined;
83
+ /**
84
+ * How long the account stays locked, in seconds.
85
+ * @default 900 (15 minutes)
86
+ */
87
+ durationSeconds?: number | undefined;
88
+ } | undefined;
89
+ }
90
+ interface UserWithTwoFactor extends User {
91
+ /**
92
+ * If the user has enabled two factor authentication.
93
+ */
94
+ twoFactorEnabled: boolean;
95
+ }
96
+ interface TwoFactorProvider {
97
+ id: LiteralString;
98
+ version?: string | undefined;
99
+ endpoints?: BetterAuthPlugin["endpoints"] | undefined;
100
+ }
101
+ interface TwoFactorTable {
102
+ id: string;
103
+ userId: string;
104
+ secret: string;
105
+ backupCodes: string;
106
+ verified: boolean;
107
+ failedVerificationCount?: number;
108
+ lockedUntil?: Date | null;
109
+ }
110
+ //#endregion
111
+ export { TwoFactorOptions, TwoFactorProvider, TwoFactorTable, UserWithTwoFactor };
@@ -0,0 +1,9 @@
1
+ import { base64Url } from "@better-auth/utils/base64";
2
+ import { createHash } from "@better-auth/utils/hash";
3
+ //#region src/plugins/two-factor/utils.ts
4
+ const defaultKeyHasher = async (token) => {
5
+ const hash = await createHash("SHA-256").digest(new TextEncoder().encode(token));
6
+ return base64Url.encode(new Uint8Array(hash), { padding: false });
7
+ };
8
+ //#endregion
9
+ export { defaultKeyHasher };
@@ -0,0 +1,205 @@
1
+ import { parseUserOutput } from "../../db/schema.mjs";
2
+ import { generateRandomString } from "../../crypto/random.mjs";
3
+ import { expireCookie, setSessionCookie } from "../../cookies/index.mjs";
4
+ import { getSessionFromCtx } from "../../api/routes/session.mjs";
5
+ import { TWO_FACTOR_ERROR_CODES } from "./error-code.mjs";
6
+ import { TRUST_DEVICE_COOKIE_NAME, TWO_FACTOR_COOKIE_NAME } from "./constant.mjs";
7
+ import { APIError } from "@better-auth/core/error";
8
+ import { createHMAC } from "@better-auth/utils/hmac";
9
+ //#region src/plugins/two-factor/verify-two-factor.ts
10
+ async function verifyTwoFactor(ctx) {
11
+ const invalid = (errorKey) => {
12
+ throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES[errorKey]);
13
+ };
14
+ const session = await getSessionFromCtx(ctx);
15
+ if (!session) {
16
+ const twoFactorCookie = ctx.context.createAuthCookie(TWO_FACTOR_COOKIE_NAME);
17
+ const signedTwoFactorCookie = await ctx.getSignedCookie(twoFactorCookie.name, ctx.context.secret);
18
+ if (!signedTwoFactorCookie) throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE);
19
+ const verificationToken = await ctx.context.internalAdapter.findVerificationValue(signedTwoFactorCookie);
20
+ if (!verificationToken) throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE);
21
+ const user = await ctx.context.internalAdapter.findUserById(verificationToken.value);
22
+ if (!user) throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE);
23
+ const dontRememberMe = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
24
+ return {
25
+ valid: async (ctx) => {
26
+ const consumed = await ctx.context.internalAdapter.consumeVerificationValue(signedTwoFactorCookie);
27
+ if (!consumed || consumed.value !== user.id) {
28
+ expireCookie(ctx, twoFactorCookie);
29
+ throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE);
30
+ }
31
+ const session = await ctx.context.internalAdapter.createSession(consumed.value, !!dontRememberMe);
32
+ if (!session) throw APIError.from("INTERNAL_SERVER_ERROR", {
33
+ message: "failed to create session",
34
+ code: "FAILED_TO_CREATE_SESSION"
35
+ });
36
+ await setSessionCookie(ctx, {
37
+ session,
38
+ user
39
+ });
40
+ expireCookie(ctx, twoFactorCookie);
41
+ if (ctx.body.trustDevice) {
42
+ const maxAge = ctx.context.getPlugin("two-factor").options?.trustDeviceMaxAge ?? 2592e3;
43
+ const trustDeviceCookie = ctx.context.createAuthCookie(TRUST_DEVICE_COOKIE_NAME, { maxAge });
44
+ /**
45
+ * Create a random identifier for the trust device record.
46
+ * Store it in the verification table with an expiration
47
+ * so the server can validate and revoke it.
48
+ */
49
+ const trustIdentifier = `trust-device-${generateRandomString(32)}`;
50
+ const token = await createHMAC("SHA-256", "base64urlnopad").sign(ctx.context.secret, `${user.id}!${trustIdentifier}`);
51
+ await ctx.context.internalAdapter.createVerificationValue({
52
+ value: user.id,
53
+ identifier: trustIdentifier,
54
+ expiresAt: new Date(Date.now() + maxAge * 1e3)
55
+ });
56
+ await ctx.setSignedCookie(trustDeviceCookie.name, `${token}!${trustIdentifier}`, ctx.context.secret, trustDeviceCookie.attributes);
57
+ expireCookie(ctx, ctx.context.authCookies.dontRememberToken);
58
+ }
59
+ return ctx.json({
60
+ token: session.token,
61
+ user: parseUserOutput(ctx.context.options, user)
62
+ });
63
+ },
64
+ invalid,
65
+ session: {
66
+ session: null,
67
+ user
68
+ },
69
+ key: signedTwoFactorCookie,
70
+ beginAttempt: async (allowedAttempts) => {
71
+ const identifier = `2fa-attempts-${signedTwoFactorCookie}`;
72
+ const consumed = await ctx.context.internalAdapter.consumeVerificationValue(identifier).catch(() => null);
73
+ if (!consumed) throw APIError.from("UNAUTHORIZED", TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE);
74
+ const parsed = Number(consumed.value);
75
+ const attempts = Number.isInteger(parsed) && parsed >= 0 ? parsed : allowedAttempts;
76
+ if (attempts >= allowedAttempts) {
77
+ try {
78
+ await ctx.context.internalAdapter.consumeVerificationValue(signedTwoFactorCookie);
79
+ } catch {
80
+ expireCookie(ctx, twoFactorCookie);
81
+ throw APIError.from("INTERNAL_SERVER_ERROR", {
82
+ message: "Failed to invalidate two-factor challenge",
83
+ code: "FAILED_TO_INVALIDATE_TWO_FACTOR_CHALLENGE"
84
+ });
85
+ }
86
+ expireCookie(ctx, twoFactorCookie);
87
+ throw APIError.from("BAD_REQUEST", TWO_FACTOR_ERROR_CODES.TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE);
88
+ }
89
+ const rearm = (count) => ctx.context.internalAdapter.createVerificationValue({
90
+ value: `${count}`,
91
+ identifier,
92
+ expiresAt: verificationToken.expiresAt
93
+ }).catch(() => {});
94
+ return {
95
+ recordFailure: () => rearm(attempts + 1),
96
+ restore: () => rearm(attempts)
97
+ };
98
+ }
99
+ };
100
+ }
101
+ return {
102
+ valid: async (ctx) => {
103
+ return ctx.json({
104
+ token: session.session.token,
105
+ user: parseUserOutput(ctx.context.options, session.user)
106
+ });
107
+ },
108
+ invalid,
109
+ session,
110
+ key: `${session.user.id}!${session.session.id}`,
111
+ beginAttempt: async (_allowedAttempts) => ({
112
+ recordFailure: async () => {},
113
+ restore: async () => {}
114
+ })
115
+ };
116
+ }
117
+ function resolveAccountLockoutConfig(ctx) {
118
+ const lockout = (ctx.context.getPlugin("two-factor")?.options)?.accountLockout;
119
+ return {
120
+ enabled: lockout?.enabled ?? true,
121
+ maxFailedAttempts: lockout?.maxFailedAttempts ?? 10,
122
+ durationMs: (lockout?.durationSeconds ?? 900) * 1e3
123
+ };
124
+ }
125
+ /**
126
+ * Reject the verification when the account is locked, and lazily clear an
127
+ * expired lock. The lock caps consecutive failed verifications per account,
128
+ * across challenges and factors (NIST SP 800-63B §5.2.2).
129
+ */
130
+ async function assertTwoFactorNotLocked(ctx, twoFactorTable, twoFactor) {
131
+ const { enabled } = resolveAccountLockoutConfig(ctx);
132
+ if (!enabled || !twoFactor.lockedUntil) return;
133
+ if (new Date(twoFactor.lockedUntil).getTime() > Date.now()) throw APIError.from("TOO_MANY_REQUESTS", TWO_FACTOR_ERROR_CODES.ACCOUNT_TEMPORARILY_LOCKED);
134
+ await ctx.context.adapter.incrementOne({
135
+ model: twoFactorTable,
136
+ where: [{
137
+ field: "id",
138
+ value: twoFactor.id
139
+ }, {
140
+ field: "lockedUntil",
141
+ operator: "lte",
142
+ value: /* @__PURE__ */ new Date()
143
+ }],
144
+ increment: {},
145
+ set: {
146
+ failedVerificationCount: 0,
147
+ lockedUntil: null
148
+ }
149
+ });
150
+ }
151
+ /**
152
+ * Count one failed verification toward the account-level budget, and lock the
153
+ * account once the budget is spent. The increment is atomic, so concurrent
154
+ * failures cannot lose updates. It is unguarded so it still applies to a row
155
+ * whose counter is null or absent (a row created before the migration, or a
156
+ * document-store record predating the column), where a guarded comparison
157
+ * would never match.
158
+ */
159
+ async function recordTwoFactorFailure(ctx, twoFactorTable, twoFactor) {
160
+ const { enabled, maxFailedAttempts, durationMs } = resolveAccountLockoutConfig(ctx);
161
+ if (!enabled) return;
162
+ if (((await ctx.context.adapter.incrementOne({
163
+ model: twoFactorTable,
164
+ where: [{
165
+ field: "id",
166
+ value: twoFactor.id
167
+ }],
168
+ increment: { failedVerificationCount: 1 }
169
+ }))?.failedVerificationCount ?? 0) >= maxFailedAttempts) await ctx.context.adapter.incrementOne({
170
+ model: twoFactorTable,
171
+ where: [{
172
+ field: "id",
173
+ value: twoFactor.id
174
+ }, {
175
+ field: "failedVerificationCount",
176
+ operator: "gte",
177
+ value: maxFailedAttempts
178
+ }],
179
+ increment: {},
180
+ set: { lockedUntil: new Date(Date.now() + durationMs) }
181
+ });
182
+ }
183
+ /**
184
+ * Clear the account-level failure budget after a successful verification, so the
185
+ * count tracks only consecutive failures. The write is unconditional: a snapshot
186
+ * read at the start of the request can miss a concurrent failure, so skipping it
187
+ * could leave the counter non-zero after a success.
188
+ */
189
+ async function resetTwoFactorFailures(ctx, twoFactorTable, twoFactor) {
190
+ const { enabled } = resolveAccountLockoutConfig(ctx);
191
+ if (!enabled) return;
192
+ await ctx.context.adapter.update({
193
+ model: twoFactorTable,
194
+ where: [{
195
+ field: "id",
196
+ value: twoFactor.id
197
+ }],
198
+ update: {
199
+ failedVerificationCount: 0,
200
+ lockedUntil: null
201
+ }
202
+ });
203
+ }
204
+ //#endregion
205
+ export { assertTwoFactorNotLocked, recordTwoFactorFailure, resetTwoFactorFailures, verifyTwoFactor };
@@ -0,0 +1,38 @@
1
+ import { USERNAME_ERROR_CODES } from "./error-codes.mjs";
2
+ import { UsernamePlugin, UsernamePluginWithoutDisplayUsername } from "./index.mjs";
3
+ import * as _$_better_auth_core_utils_error_codes0 from "@better-auth/core/utils/error-codes";
4
+
5
+ //#region src/plugins/username/client.d.ts
6
+ type UsernameClientOptions = {
7
+ /**
8
+ * Whether the server has the `displayUsername` field enabled.
9
+ *
10
+ * This must mirror the `displayUsername` option passed to the server
11
+ * `username` plugin so the client infers the correct user/session types.
12
+ *
13
+ * @default true
14
+ */
15
+ displayUsername?: boolean | undefined;
16
+ };
17
+ declare const usernameClient: <O extends UsernameClientOptions = UsernameClientOptions>(options?: O) => {
18
+ id: "username";
19
+ version: string;
20
+ $InferServerPlugin: O["displayUsername"] extends false ? UsernamePluginWithoutDisplayUsername : UsernamePlugin;
21
+ atomListeners: {
22
+ matcher: (path: string) => path is "/sign-in/username";
23
+ signal: "$sessionSignal";
24
+ }[];
25
+ $ERROR_CODES: {
26
+ EMAIL_NOT_VERIFIED: _$_better_auth_core_utils_error_codes0.RawError<"EMAIL_NOT_VERIFIED">;
27
+ UNEXPECTED_ERROR: _$_better_auth_core_utils_error_codes0.RawError<"UNEXPECTED_ERROR">;
28
+ INVALID_USERNAME_OR_PASSWORD: _$_better_auth_core_utils_error_codes0.RawError<"INVALID_USERNAME_OR_PASSWORD">;
29
+ USERNAME_IS_ALREADY_TAKEN: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_IS_ALREADY_TAKEN">;
30
+ USERNAME_TOO_SHORT: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_TOO_SHORT">;
31
+ USERNAME_TOO_LONG: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_TOO_LONG">;
32
+ INVALID_USERNAME: _$_better_auth_core_utils_error_codes0.RawError<"INVALID_USERNAME">;
33
+ INVALID_DISPLAY_USERNAME: _$_better_auth_core_utils_error_codes0.RawError<"INVALID_DISPLAY_USERNAME">;
34
+ USERNAME_IS_IMMUTABLE: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_IS_IMMUTABLE">;
35
+ };
36
+ };
37
+ //#endregion
38
+ export { UsernameClientOptions, usernameClient };
@@ -0,0 +1,17 @@
1
+ import { PACKAGE_VERSION } from "../../version.mjs";
2
+ import { USERNAME_ERROR_CODES } from "./error-codes.mjs";
3
+ //#region src/plugins/username/client.ts
4
+ const usernameClient = (options) => {
5
+ return {
6
+ id: "username",
7
+ version: PACKAGE_VERSION,
8
+ $InferServerPlugin: {},
9
+ atomListeners: [{
10
+ matcher: (path) => path === "/sign-in/username",
11
+ signal: "$sessionSignal"
12
+ }],
13
+ $ERROR_CODES: USERNAME_ERROR_CODES
14
+ };
15
+ };
16
+ //#endregion
17
+ export { usernameClient };
@@ -0,0 +1,16 @@
1
+ import * as _$_better_auth_core_utils_error_codes0 from "@better-auth/core/utils/error-codes";
2
+
3
+ //#region src/plugins/username/error-codes.d.ts
4
+ declare const USERNAME_ERROR_CODES: {
5
+ EMAIL_NOT_VERIFIED: _$_better_auth_core_utils_error_codes0.RawError<"EMAIL_NOT_VERIFIED">;
6
+ UNEXPECTED_ERROR: _$_better_auth_core_utils_error_codes0.RawError<"UNEXPECTED_ERROR">;
7
+ INVALID_USERNAME_OR_PASSWORD: _$_better_auth_core_utils_error_codes0.RawError<"INVALID_USERNAME_OR_PASSWORD">;
8
+ USERNAME_IS_ALREADY_TAKEN: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_IS_ALREADY_TAKEN">;
9
+ USERNAME_TOO_SHORT: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_TOO_SHORT">;
10
+ USERNAME_TOO_LONG: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_TOO_LONG">;
11
+ INVALID_USERNAME: _$_better_auth_core_utils_error_codes0.RawError<"INVALID_USERNAME">;
12
+ INVALID_DISPLAY_USERNAME: _$_better_auth_core_utils_error_codes0.RawError<"INVALID_DISPLAY_USERNAME">;
13
+ USERNAME_IS_IMMUTABLE: _$_better_auth_core_utils_error_codes0.RawError<"USERNAME_IS_IMMUTABLE">;
14
+ };
15
+ //#endregion
16
+ export { USERNAME_ERROR_CODES };
@@ -0,0 +1,15 @@
1
+ import { defineErrorCodes } from "@better-auth/core/utils/error-codes";
2
+ //#region src/plugins/username/error-codes.ts
3
+ const USERNAME_ERROR_CODES = defineErrorCodes({
4
+ INVALID_USERNAME_OR_PASSWORD: "Invalid username or password",
5
+ EMAIL_NOT_VERIFIED: "Email not verified",
6
+ UNEXPECTED_ERROR: "Unexpected error",
7
+ USERNAME_IS_ALREADY_TAKEN: "Username is already taken. Please try another.",
8
+ USERNAME_TOO_SHORT: "Username is too short",
9
+ USERNAME_TOO_LONG: "Username is too long",
10
+ INVALID_USERNAME: "Username is invalid",
11
+ INVALID_DISPLAY_USERNAME: "Display username is invalid",
12
+ USERNAME_IS_IMMUTABLE: "Username cannot be updated"
13
+ });
14
+ //#endregion
15
+ export { USERNAME_ERROR_CODES };