@gatwech/auth 1.0.0-beta.18

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 (422) hide show
  1. package/README.md +31 -0
  2. package/dist/access-BO2g7QVe.mjs +45 -0
  3. package/dist/access-C6O_osEz.mjs +79 -0
  4. package/dist/access-DT1f6l5k.mjs +51 -0
  5. package/dist/adapter-factory-BZ2Qiqpn.mjs +640 -0
  6. package/dist/adapters/drizzle-adapter/index.d.mts +47 -0
  7. package/dist/adapters/drizzle-adapter/index.mjs +208 -0
  8. package/dist/adapters/index.d.mts +132 -0
  9. package/dist/adapters/index.mjs +18 -0
  10. package/dist/adapters/kysely-adapter/index.d.mts +47 -0
  11. package/dist/adapters/kysely-adapter/index.mjs +11 -0
  12. package/dist/adapters/memory-adapter/index.d.mts +14 -0
  13. package/dist/adapters/memory-adapter/index.mjs +154 -0
  14. package/dist/adapters/mongodb-adapter/index.d.mts +35 -0
  15. package/dist/adapters/mongodb-adapter/index.mjs +315 -0
  16. package/dist/adapters/prisma-adapter/index.d.mts +34 -0
  17. package/dist/adapters/prisma-adapter/index.mjs +159 -0
  18. package/dist/adapters/test.d.mts +81 -0
  19. package/dist/adapters/test.mjs +793 -0
  20. package/dist/admin-Bcq53Nwj.mjs +743 -0
  21. package/dist/admin-DtfO1PLg.d.mts +1689 -0
  22. package/dist/anonymous-CRt1imBW.mjs +107 -0
  23. package/dist/api/index.d.mts +6 -0
  24. package/dist/api/index.mjs +17 -0
  25. package/dist/api-0pR_I-Nx.mjs +3139 -0
  26. package/dist/auth-CBUoBX6o.mjs +233 -0
  27. package/dist/bearer-Djf_awfo.mjs +63 -0
  28. package/dist/bun-sqlite-dialect-CeNvMaZz.mjs +155 -0
  29. package/dist/captcha-BqaMxlKC.mjs +178 -0
  30. package/dist/chunk-BK_LfMhE.mjs +40 -0
  31. package/dist/client/index.d.mts +186 -0
  32. package/dist/client/index.mjs +7 -0
  33. package/dist/client/plugins/index.d.mts +949 -0
  34. package/dist/client/plugins/index.mjs +539 -0
  35. package/dist/client/react/index.d.mts +179 -0
  36. package/dist/client/react/index.mjs +69 -0
  37. package/dist/client-BOX93C3d.d.mts +1250 -0
  38. package/dist/client-CNY0tn9g.d.mts +628 -0
  39. package/dist/client-CygJhqeB.mjs +29 -0
  40. package/dist/client-WiN43tAS.mjs +17 -0
  41. package/dist/client-aExCkfwm.mjs +30 -0
  42. package/dist/cookies/index.d.mts +7 -0
  43. package/dist/cookies/index.mjs +7 -0
  44. package/dist/cookies-cJObLwn1.mjs +597 -0
  45. package/dist/crypto/index.d.mts +44 -0
  46. package/dist/crypto/index.mjs +4 -0
  47. package/dist/crypto-Bb42eMrH.mjs +70 -0
  48. package/dist/custom-session-L3t7ecsd.mjs +67 -0
  49. package/dist/date-Cx2yCiC4.mjs +115 -0
  50. package/dist/db/index.d.mts +7 -0
  51. package/dist/db/index.mjs +15 -0
  52. package/dist/db-BrstmDhc.mjs +1124 -0
  53. package/dist/device-authorization-V4s3h4Mj.mjs +557 -0
  54. package/dist/dialect-CeddeGHf.mjs +72 -0
  55. package/dist/email-otp-BtDHSw14.mjs +592 -0
  56. package/dist/esm-C-QicDNz.mjs +4090 -0
  57. package/dist/generic-oauth-CL5X27ZI.mjs +445 -0
  58. package/dist/get-request-ip-DSjrEpGo.mjs +27 -0
  59. package/dist/get-tables-BQP7YW9c.mjs +249 -0
  60. package/dist/has-permission-BpAr7uCn.mjs +14 -0
  61. package/dist/haveibeenpwned-cMpJvmzI.mjs +43 -0
  62. package/dist/helper-tmxW3BHj.d.mts +21 -0
  63. package/dist/index-34ONrP8l.d.mts +503 -0
  64. package/dist/index-65G5U5DB-DSdjzreF.d.mts +2543 -0
  65. package/dist/index-B-XKqFvY.d.mts +30 -0
  66. package/dist/index-B3n8e37d.d.mts +165 -0
  67. package/dist/index-BBm8nQ9Q.d.mts +42 -0
  68. package/dist/index-BHoQlf7a.d.mts +7699 -0
  69. package/dist/index-BYMI9r_d.d.mts +257 -0
  70. package/dist/index-BqhKCbPH.d.mts +36 -0
  71. package/dist/index-Buhn3hkR.d.mts +433 -0
  72. package/dist/index-C-u1h_WX.d.mts +174 -0
  73. package/dist/index-C7fQuk-V.d.mts +41 -0
  74. package/dist/index-CM-CFWwr.d.mts +1919 -0
  75. package/dist/index-CuFzhoS6.d.mts +359 -0
  76. package/dist/index-Cxi7TbLE.d.mts +11347 -0
  77. package/dist/index-DB7t8whN.d.mts +1 -0
  78. package/dist/index-DKNNV1kb.d.mts +626 -0
  79. package/dist/index-DR0xXno9.d.mts +113 -0
  80. package/dist/index-D_k662QG.d.mts +833 -0
  81. package/dist/index-DaBcikv9.d.mts +118 -0
  82. package/dist/index-DlaMq1nb.d.mts +955 -0
  83. package/dist/index-DoXZYQpq.d.mts +290 -0
  84. package/dist/index-G6V0Z_Mn.d.mts +125 -0
  85. package/dist/index-z0KSvE5i.d.mts +246 -0
  86. package/dist/index-zjjNBRY2.d.mts +95 -0
  87. package/dist/index.d.mts +12 -0
  88. package/dist/index.mjs +33 -0
  89. package/dist/integrations/next-js.d.mts +21 -0
  90. package/dist/integrations/next-js.mjs +62 -0
  91. package/dist/integrations/node.d.mts +15 -0
  92. package/dist/integrations/node.mjs +15 -0
  93. package/dist/integrations/react-start.d.mts +15 -0
  94. package/dist/integrations/react-start.mjs +46 -0
  95. package/dist/json-D0TBLy4q.mjs +24 -0
  96. package/dist/jwt-CmxZAGe2.mjs +94 -0
  97. package/dist/jwt-lHV4QHpD.mjs +387 -0
  98. package/dist/kysely-adapter-DpzYO8Yf.mjs +181 -0
  99. package/dist/magic-link-Bk-ueorR.mjs +176 -0
  100. package/dist/misc-beA1w3XV.mjs +7 -0
  101. package/dist/multi-session-DRrLKrg9.mjs +144 -0
  102. package/dist/node-sqlite-dialect-BcKxBQnm.mjs +155 -0
  103. package/dist/oauth-proxy-D1sWh9B_.mjs +133 -0
  104. package/dist/oauth2/index.d.mts +60 -0
  105. package/dist/oauth2/index.mjs +19 -0
  106. package/dist/one-tap-DMswkTEc.mjs +113 -0
  107. package/dist/organization-BArHO_5v.mjs +3857 -0
  108. package/dist/parser-DcrIEuXE.mjs +73 -0
  109. package/dist/passkey-CcD4CnhM.mjs +558 -0
  110. package/dist/password-sVC4nePO.mjs +25 -0
  111. package/dist/permission-DLYUF3cW.mjs +15 -0
  112. package/dist/phone-number-rHDIlh-2.mjs +485 -0
  113. package/dist/plugin-helper-4L-lzsjZ.mjs +16 -0
  114. package/dist/plugins/access/index.d.mts +3 -0
  115. package/dist/plugins/access/index.mjs +3 -0
  116. package/dist/plugins/admin/access/index.d.mts +116 -0
  117. package/dist/plugins/admin/access/index.mjs +4 -0
  118. package/dist/plugins/admin/index.d.mts +9 -0
  119. package/dist/plugins/admin/index.mjs +22 -0
  120. package/dist/plugins/anonymous/index.d.mts +7 -0
  121. package/dist/plugins/anonymous/index.mjs +18 -0
  122. package/dist/plugins/bearer/index.d.mts +2 -0
  123. package/dist/plugins/bearer/index.mjs +8 -0
  124. package/dist/plugins/captcha/index.d.mts +2 -0
  125. package/dist/plugins/captcha/index.mjs +4 -0
  126. package/dist/plugins/custom-session/index.d.mts +7 -0
  127. package/dist/plugins/custom-session/index.mjs +19 -0
  128. package/dist/plugins/device-authorization/index.d.mts +4 -0
  129. package/dist/plugins/device-authorization/index.mjs +18 -0
  130. package/dist/plugins/email-otp/index.d.mts +3 -0
  131. package/dist/plugins/email-otp/index.mjs +19 -0
  132. package/dist/plugins/generic-oauth/index.d.mts +7 -0
  133. package/dist/plugins/generic-oauth/index.mjs +18 -0
  134. package/dist/plugins/haveibeenpwned/index.d.mts +2 -0
  135. package/dist/plugins/haveibeenpwned/index.mjs +18 -0
  136. package/dist/plugins/index.d.mts +139 -0
  137. package/dist/plugins/index.mjs +47 -0
  138. package/dist/plugins/jwt/index.d.mts +7 -0
  139. package/dist/plugins/jwt/index.mjs +18 -0
  140. package/dist/plugins/magic-link/index.d.mts +2 -0
  141. package/dist/plugins/magic-link/index.mjs +18 -0
  142. package/dist/plugins/multi-session/index.d.mts +3 -0
  143. package/dist/plugins/multi-session/index.mjs +18 -0
  144. package/dist/plugins/oauth-proxy/index.d.mts +2 -0
  145. package/dist/plugins/oauth-proxy/index.mjs +18 -0
  146. package/dist/plugins/one-tap/index.d.mts +2 -0
  147. package/dist/plugins/one-tap/index.mjs +18 -0
  148. package/dist/plugins/one-time-token/index.d.mts +7 -0
  149. package/dist/plugins/one-time-token/index.mjs +47 -0
  150. package/dist/plugins/organization/access/index.d.mts +4 -0
  151. package/dist/plugins/organization/access/index.mjs +4 -0
  152. package/dist/plugins/organization/index.d.mts +9 -0
  153. package/dist/plugins/organization/index.mjs +22 -0
  154. package/dist/plugins/passkey/index.d.mts +7 -0
  155. package/dist/plugins/passkey/index.mjs +18 -0
  156. package/dist/plugins/phone-number/index.d.mts +7 -0
  157. package/dist/plugins/phone-number/index.mjs +18 -0
  158. package/dist/plugins/two-factor/index.d.mts +7 -0
  159. package/dist/plugins/two-factor/index.mjs +20 -0
  160. package/dist/plugins/username/index.d.mts +4 -0
  161. package/dist/plugins/username/index.mjs +18 -0
  162. package/dist/plugins-3jfNste3.mjs +1544 -0
  163. package/dist/plugins-hFZT3hmK.d.mts +14 -0
  164. package/dist/promise-8rrEHRXd.mjs +23154 -0
  165. package/dist/proxy-CL9PZXJA.mjs +441 -0
  166. package/dist/session-Dgp133Yt.mjs +413 -0
  167. package/dist/social-providers/index.d.mts +1 -0
  168. package/dist/social-providers/index.mjs +3 -0
  169. package/dist/src/adapters/adapter-factory/index.d.ts +10 -0
  170. package/dist/src/adapters/adapter-factory/types.d.ts +124 -0
  171. package/dist/src/adapters/create-test-suite.d.ts +97 -0
  172. package/dist/src/adapters/drizzle-adapter/drizzle-adapter.d.ts +43 -0
  173. package/dist/src/adapters/drizzle-adapter/index.d.ts +1 -0
  174. package/dist/src/adapters/drizzle-adapter/test/generate-schema.d.ts +12 -0
  175. package/dist/src/adapters/index.d.ts +21 -0
  176. package/dist/src/adapters/kysely-adapter/bun-sqlite-dialect.d.ts +58 -0
  177. package/dist/src/adapters/kysely-adapter/dialect.d.ts +13 -0
  178. package/dist/src/adapters/kysely-adapter/index.d.ts +3 -0
  179. package/dist/src/adapters/kysely-adapter/kysely-adapter.d.ts +32 -0
  180. package/dist/src/adapters/kysely-adapter/node-sqlite-dialect.d.ts +58 -0
  181. package/dist/src/adapters/kysely-adapter/types.d.ts +1 -0
  182. package/dist/src/adapters/memory-adapter/index.d.ts +1 -0
  183. package/dist/src/adapters/memory-adapter/memory-adapter.d.ts +9 -0
  184. package/dist/src/adapters/mongodb-adapter/index.d.ts +1 -0
  185. package/dist/src/adapters/mongodb-adapter/mongodb-adapter.d.ts +31 -0
  186. package/dist/src/adapters/prisma-adapter/index.d.ts +1 -0
  187. package/dist/src/adapters/prisma-adapter/prisma-adapter.d.ts +32 -0
  188. package/dist/src/adapters/prisma-adapter/test/auth.d.ts +3 -0
  189. package/dist/src/adapters/prisma-adapter/test/generate-auth-config.d.ts +2 -0
  190. package/dist/src/adapters/prisma-adapter/test/generate-prisma-schema.d.ts +3 -0
  191. package/dist/src/adapters/prisma-adapter/test/get-prisma-client.d.ts +7 -0
  192. package/dist/src/adapters/prisma-adapter/test/push-prisma-schema.d.ts +1 -0
  193. package/dist/src/adapters/test-adapter.d.ts +61 -0
  194. package/dist/src/adapters/test.d.ts +78 -0
  195. package/dist/src/adapters/tests/auth-flow.d.ts +22 -0
  196. package/dist/src/adapters/tests/index.d.ts +5 -0
  197. package/dist/src/adapters/tests/normal.d.ts +87 -0
  198. package/dist/src/adapters/tests/number-id.d.ts +17 -0
  199. package/dist/src/adapters/tests/performance.d.ts +24 -0
  200. package/dist/src/adapters/tests/transactions.d.ts +20 -0
  201. package/dist/src/adapters/utils.d.ts +3 -0
  202. package/dist/src/api/index.d.ts +7150 -0
  203. package/dist/src/api/middlewares/index.d.ts +2 -0
  204. package/dist/src/api/middlewares/oauth.d.ts +15 -0
  205. package/dist/src/api/middlewares/origin-check.d.ts +8 -0
  206. package/dist/src/api/rate-limiter/index.d.ts +13 -0
  207. package/dist/src/api/routes/account.d.ts +623 -0
  208. package/dist/src/api/routes/callback.d.ts +68 -0
  209. package/dist/src/api/routes/email-verification.d.ts +266 -0
  210. package/dist/src/api/routes/error.d.ts +51 -0
  211. package/dist/src/api/routes/index.d.ts +11 -0
  212. package/dist/src/api/routes/ok.d.ts +61 -0
  213. package/dist/src/api/routes/reset-password.d.ts +203 -0
  214. package/dist/src/api/routes/session.d.ts +586 -0
  215. package/dist/src/api/routes/sign-in.d.ts +298 -0
  216. package/dist/src/api/routes/sign-out.d.ts +59 -0
  217. package/dist/src/api/routes/sign-up.d.ts +625 -0
  218. package/dist/src/api/routes/update-user.d.ts +862 -0
  219. package/dist/src/api/to-auth-endpoints.d.ts +3 -0
  220. package/dist/src/auth.d.ts +25 -0
  221. package/dist/src/client/broadcast-channel.d.ts +12 -0
  222. package/dist/src/client/config.d.ts +85 -0
  223. package/dist/src/client/fetch-plugins.d.ts +14 -0
  224. package/dist/src/client/index.d.ts +15 -0
  225. package/dist/src/client/parser.d.ts +12 -0
  226. package/dist/src/client/path-to-object.d.ts +63 -0
  227. package/dist/src/client/plugins/index.d.ts +21 -0
  228. package/dist/src/client/plugins/infer-plugin.d.ts +11 -0
  229. package/dist/src/client/proxy.d.ts +8 -0
  230. package/dist/src/client/query.d.ts +16 -0
  231. package/dist/src/client/react/index.d.ts +130 -0
  232. package/dist/src/client/react/react-store.d.ts +43 -0
  233. package/dist/src/client/session-atom.d.ts +18 -0
  234. package/dist/src/client/session-refresh.d.ts +17 -0
  235. package/dist/src/client/test-plugin.d.ts +147 -0
  236. package/dist/src/client/types.d.ts +49 -0
  237. package/dist/src/client/vanilla.d.ts +124 -0
  238. package/dist/src/cookies/check-cookies.d.ts +4 -0
  239. package/dist/src/cookies/cookie-utils.d.ts +16 -0
  240. package/dist/src/cookies/index.d.ts +56 -0
  241. package/dist/src/cookies/session-store.d.ts +43 -0
  242. package/dist/src/crypto/buffer.d.ts +4 -0
  243. package/dist/src/crypto/index.d.ts +14 -0
  244. package/dist/src/crypto/jwt.d.ts +4 -0
  245. package/dist/src/crypto/password.d.ts +5 -0
  246. package/dist/src/crypto/random.d.ts +1 -0
  247. package/dist/src/db/field.d.ts +97 -0
  248. package/dist/src/db/get-migration.d.ts +18 -0
  249. package/dist/src/db/get-schema.d.ts +6 -0
  250. package/dist/src/db/get-tables.d.ts +3 -0
  251. package/dist/src/db/index.d.ts +10 -0
  252. package/dist/src/db/internal-adapter.d.ts +9 -0
  253. package/dist/src/db/schema.d.ts +76 -0
  254. package/dist/src/db/to-zod.d.ts +31 -0
  255. package/dist/src/db/utils.d.ts +6 -0
  256. package/dist/src/db/with-hooks.d.ts +27 -0
  257. package/dist/src/index.d.ts +14 -0
  258. package/dist/src/init.d.ts +2 -0
  259. package/dist/src/integrations/next-js.d.ts +15 -0
  260. package/dist/src/integrations/node.d.ts +6 -0
  261. package/dist/src/integrations/react-start.d.ts +9 -0
  262. package/dist/src/oauth2/index.d.ts +4 -0
  263. package/dist/src/oauth2/link-account.d.ts +41 -0
  264. package/dist/src/oauth2/state.d.ts +21 -0
  265. package/dist/src/oauth2/utils.d.ts +3 -0
  266. package/dist/src/plugins/access/access.d.ts +25 -0
  267. package/dist/src/plugins/access/index.d.ts +2 -0
  268. package/dist/src/plugins/access/types.d.ts +14 -0
  269. package/dist/src/plugins/additional-fields/client.d.ts +91 -0
  270. package/dist/src/plugins/admin/access/index.d.ts +1 -0
  271. package/dist/src/plugins/admin/access/statement.d.ts +110 -0
  272. package/dist/src/plugins/admin/admin.d.ts +1570 -0
  273. package/dist/src/plugins/admin/client.d.ts +62 -0
  274. package/dist/src/plugins/admin/error-codes.d.ts +21 -0
  275. package/dist/src/plugins/admin/has-permission.d.ts +21 -0
  276. package/dist/src/plugins/admin/index.d.ts +2 -0
  277. package/dist/src/plugins/admin/schema.d.ts +36 -0
  278. package/dist/src/plugins/admin/types.d.ts +77 -0
  279. package/dist/src/plugins/anonymous/client.d.ts +8 -0
  280. package/dist/src/plugins/anonymous/index.d.ts +159 -0
  281. package/dist/src/plugins/api-key/client.d.ts +11 -0
  282. package/dist/src/plugins/api-key/index.d.ts +1431 -0
  283. package/dist/src/plugins/api-key/rate-limit.d.ts +20 -0
  284. package/dist/src/plugins/api-key/routes/create-api-key.d.ts +244 -0
  285. package/dist/src/plugins/api-key/routes/delete-all-expired-api-keys.d.ts +45 -0
  286. package/dist/src/plugins/api-key/routes/delete-api-key.d.ts +112 -0
  287. package/dist/src/plugins/api-key/routes/get-api-key.d.ts +234 -0
  288. package/dist/src/plugins/api-key/routes/index.d.ts +1136 -0
  289. package/dist/src/plugins/api-key/routes/list-api-keys.d.ts +231 -0
  290. package/dist/src/plugins/api-key/routes/update-api-key.d.ts +235 -0
  291. package/dist/src/plugins/api-key/routes/verify-api-key.d.ts +80 -0
  292. package/dist/src/plugins/api-key/schema.d.ts +188 -0
  293. package/dist/src/plugins/api-key/types.d.ts +285 -0
  294. package/dist/src/plugins/bearer/index.d.ts +31 -0
  295. package/dist/src/plugins/captcha/constants.d.ts +9 -0
  296. package/dist/src/plugins/captcha/error-codes.d.ts +9 -0
  297. package/dist/src/plugins/captcha/index.d.ts +7 -0
  298. package/dist/src/plugins/captcha/types.d.ts +23 -0
  299. package/dist/src/plugins/captcha/utils.d.ts +1 -0
  300. package/dist/src/plugins/captcha/verify-handlers/captchafox.d.ts +11 -0
  301. package/dist/src/plugins/captcha/verify-handlers/cloudflare-turnstile.d.ts +10 -0
  302. package/dist/src/plugins/captcha/verify-handlers/google-recaptcha.d.ts +11 -0
  303. package/dist/src/plugins/captcha/verify-handlers/h-captcha.d.ts +11 -0
  304. package/dist/src/plugins/captcha/verify-handlers/index.d.ts +4 -0
  305. package/dist/src/plugins/custom-session/client.d.ts +12 -0
  306. package/dist/src/plugins/custom-session/index.d.ts +89 -0
  307. package/dist/src/plugins/device-authorization/client.d.ts +12 -0
  308. package/dist/src/plugins/device-authorization/index.d.ts +568 -0
  309. package/dist/src/plugins/device-authorization/schema.d.ts +56 -0
  310. package/dist/src/plugins/email-otp/client.d.ts +9 -0
  311. package/dist/src/plugins/email-otp/index.d.ts +826 -0
  312. package/dist/src/plugins/email-otp/utils.d.ts +2 -0
  313. package/dist/src/plugins/generic-oauth/client.d.ts +5 -0
  314. package/dist/src/plugins/generic-oauth/index.d.ts +428 -0
  315. package/dist/src/plugins/haveibeenpwned/index.d.ts +25 -0
  316. package/dist/src/plugins/index.d.ts +28 -0
  317. package/dist/src/plugins/jwt/adapter.d.ts +8 -0
  318. package/dist/src/plugins/jwt/client.d.ts +5 -0
  319. package/dist/src/plugins/jwt/index.d.ts +276 -0
  320. package/dist/src/plugins/jwt/schema.d.ts +18 -0
  321. package/dist/src/plugins/jwt/sign.d.ts +8 -0
  322. package/dist/src/plugins/jwt/types.d.ts +175 -0
  323. package/dist/src/plugins/jwt/utils.d.ts +46 -0
  324. package/dist/src/plugins/last-login-method/client.d.ts +34 -0
  325. package/dist/src/plugins/last-login-method/index.d.ts +103 -0
  326. package/dist/src/plugins/magic-link/client.d.ts +5 -0
  327. package/dist/src/plugins/magic-link/index.d.ts +253 -0
  328. package/dist/src/plugins/magic-link/utils.d.ts +1 -0
  329. package/dist/src/plugins/multi-session/client.d.ts +9 -0
  330. package/dist/src/plugins/multi-session/index.d.ts +284 -0
  331. package/dist/src/plugins/oauth-proxy/index.d.ts +119 -0
  332. package/dist/src/plugins/one-tap/client.d.ts +81 -0
  333. package/dist/src/plugins/one-tap/index.d.ts +114 -0
  334. package/dist/src/plugins/one-time-token/client.d.ts +5 -0
  335. package/dist/src/plugins/one-time-token/index.d.ts +170 -0
  336. package/dist/src/plugins/one-time-token/utils.d.ts +1 -0
  337. package/dist/src/plugins/organization/access/index.d.ts +1 -0
  338. package/dist/src/plugins/organization/access/statement.d.ts +241 -0
  339. package/dist/src/plugins/organization/adapter.d.ts +685 -0
  340. package/dist/src/plugins/organization/call.d.ts +55 -0
  341. package/dist/src/plugins/organization/client.d.ts +344 -0
  342. package/dist/src/plugins/organization/error-codes.d.ts +58 -0
  343. package/dist/src/plugins/organization/has-permission.d.ts +13 -0
  344. package/dist/src/plugins/organization/index.d.ts +4 -0
  345. package/dist/src/plugins/organization/organization.d.ts +412 -0
  346. package/dist/src/plugins/organization/permission.d.ts +27 -0
  347. package/dist/src/plugins/organization/routes/crud-access-control.d.ts +701 -0
  348. package/dist/src/plugins/organization/routes/crud-invites.d.ts +1522 -0
  349. package/dist/src/plugins/organization/routes/crud-members.d.ts +1220 -0
  350. package/dist/src/plugins/organization/routes/crud-org.d.ts +1399 -0
  351. package/dist/src/plugins/organization/routes/crud-team.d.ts +1323 -0
  352. package/dist/src/plugins/organization/schema.d.ts +366 -0
  353. package/dist/src/plugins/organization/types.d.ts +737 -0
  354. package/dist/src/plugins/passkey/client.d.ts +190 -0
  355. package/dist/src/plugins/passkey/error-codes.d.ts +9 -0
  356. package/dist/src/plugins/passkey/index.d.ts +838 -0
  357. package/dist/src/plugins/passkey/schema.d.ts +50 -0
  358. package/dist/src/plugins/passkey/types.d.ts +69 -0
  359. package/dist/src/plugins/passkey/utils.d.ts +2 -0
  360. package/dist/src/plugins/phone-number/client.d.ts +9 -0
  361. package/dist/src/plugins/phone-number/index.d.ts +622 -0
  362. package/dist/src/plugins/phone-number/phone-number-error.d.ts +10 -0
  363. package/dist/src/plugins/two-factor/backup-codes/index.d.ts +387 -0
  364. package/dist/src/plugins/two-factor/client.d.ts +28 -0
  365. package/dist/src/plugins/two-factor/constant.d.ts +2 -0
  366. package/dist/src/plugins/two-factor/error-code.d.ts +11 -0
  367. package/dist/src/plugins/two-factor/index.d.ts +1014 -0
  368. package/dist/src/plugins/two-factor/otp/index.d.ts +282 -0
  369. package/dist/src/plugins/two-factor/schema.d.ts +35 -0
  370. package/dist/src/plugins/two-factor/totp/index.d.ts +298 -0
  371. package/dist/src/plugins/two-factor/types.d.ts +50 -0
  372. package/dist/src/plugins/two-factor/utils.d.ts +1 -0
  373. package/dist/src/plugins/two-factor/verify-two-factor.d.ts +59 -0
  374. package/dist/src/plugins/username/client.d.ts +5 -0
  375. package/dist/src/plugins/username/error-codes.d.ts +10 -0
  376. package/dist/src/plugins/username/index.d.ts +313 -0
  377. package/dist/src/plugins/username/schema.d.ts +27 -0
  378. package/dist/src/social-providers/index.d.ts +1 -0
  379. package/dist/src/test-utils/headers.d.ts +5 -0
  380. package/dist/src/test-utils/index.d.ts +2 -0
  381. package/dist/src/test-utils/test-instance.d.ts +17849 -0
  382. package/dist/src/types/adapter.d.ts +21 -0
  383. package/dist/src/types/api.d.ts +29 -0
  384. package/dist/src/types/helper.d.ts +32 -0
  385. package/dist/src/types/index.d.ts +7 -0
  386. package/dist/src/types/models.d.ts +13 -0
  387. package/dist/src/types/plugins.d.ts +14 -0
  388. package/dist/src/utils/await-object.d.ts +3 -0
  389. package/dist/src/utils/boolean.d.ts +1 -0
  390. package/dist/src/utils/clone.d.ts +1 -0
  391. package/dist/src/utils/constants.d.ts +1 -0
  392. package/dist/src/utils/date.d.ts +1 -0
  393. package/dist/src/utils/ensure-utc.d.ts +1 -0
  394. package/dist/src/utils/get-request-ip.d.ts +2 -0
  395. package/dist/src/utils/hashing.d.ts +6 -0
  396. package/dist/src/utils/hide-metadata.d.ts +3 -0
  397. package/dist/src/utils/id.d.ts +1 -0
  398. package/dist/src/utils/import-util.d.ts +1 -0
  399. package/dist/src/utils/index.d.ts +5 -0
  400. package/dist/src/utils/is-atom.d.ts +2 -0
  401. package/dist/src/utils/is-promise.d.ts +1 -0
  402. package/dist/src/utils/json.d.ts +1 -0
  403. package/dist/src/utils/merger.d.ts +1 -0
  404. package/dist/src/utils/middleware-response.d.ts +8 -0
  405. package/dist/src/utils/misc.d.ts +1 -0
  406. package/dist/src/utils/password.d.ts +6 -0
  407. package/dist/src/utils/plugin-helper.d.ts +5 -0
  408. package/dist/src/utils/shim.d.ts +3 -0
  409. package/dist/src/utils/time.d.ts +4 -0
  410. package/dist/src/utils/url.d.ts +4 -0
  411. package/dist/src/utils/wildcard.d.ts +45 -0
  412. package/dist/test-utils/index.d.mts +17870 -0
  413. package/dist/test-utils/index.mjs +272 -0
  414. package/dist/two-factor-ClUXxom2.mjs +914 -0
  415. package/dist/types/index.d.mts +6 -0
  416. package/dist/types/index.mjs +3 -0
  417. package/dist/types-B1OL7hyf.d.mts +4 -0
  418. package/dist/types-Bjn15Uy6.mjs +1 -0
  419. package/dist/url-VB2gAbTI.mjs +59 -0
  420. package/dist/username-DiGklOGl.mjs +278 -0
  421. package/dist/utils-SOMB4Px5.mjs +132 -0
  422. package/package.json +447 -0
@@ -0,0 +1,914 @@
1
+ import { t as safeJSONParse } from "./json-D0TBLy4q.mjs";
2
+ import { n as symmetricEncrypt, r as generateRandomString, t as symmetricDecrypt } from "./crypto-Bb42eMrH.mjs";
3
+ import { c as setSessionCookie, n as deleteSessionCookie } from "./cookies-cJObLwn1.mjs";
4
+ import { n as mergeSchema } from "./date-Cx2yCiC4.mjs";
5
+ import { r as getSessionFromCtx, u as sessionMiddleware } from "./session-Dgp133Yt.mjs";
6
+ import { n as validatePassword } from "./password-sVC4nePO.mjs";
7
+ import { BASE_ERROR_CODES } from "@gatwech/core/error";
8
+ import { defineErrorCodes } from "@gatwech/core/utils";
9
+ import { APIError } from "better-call";
10
+ import { createAuthEndpoint, createAuthMiddleware } from "@gatwech/core/api";
11
+ import * as z$1 from "zod";
12
+ import { createHash } from "@gatwech/utils/hash";
13
+ import { base64Url } from "@gatwech/utils/base64";
14
+ import { createHMAC } from "@gatwech/utils/hmac";
15
+ import { createOTP } from "@gatwech/utils/otp";
16
+
17
+ //#region src/plugins/two-factor/error-code.ts
18
+ const TWO_FACTOR_ERROR_CODES = defineErrorCodes({
19
+ OTP_NOT_ENABLED: "OTP not enabled",
20
+ OTP_HAS_EXPIRED: "OTP has expired",
21
+ TOTP_NOT_ENABLED: "TOTP not enabled",
22
+ TWO_FACTOR_NOT_ENABLED: "Two factor isn't enabled",
23
+ BACKUP_CODES_NOT_ENABLED: "Backup codes aren't enabled",
24
+ INVALID_BACKUP_CODE: "Invalid backup code",
25
+ INVALID_CODE: "Invalid code",
26
+ TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE: "Too many attempts. Please request a new code.",
27
+ INVALID_TWO_FACTOR_COOKIE: "Invalid two factor cookie"
28
+ });
29
+
30
+ //#endregion
31
+ //#region src/plugins/two-factor/constant.ts
32
+ const TWO_FACTOR_COOKIE_NAME = "two_factor";
33
+ const TRUST_DEVICE_COOKIE_NAME = "trust_device";
34
+
35
+ //#endregion
36
+ //#region src/plugins/two-factor/verify-two-factor.ts
37
+ async function verifyTwoFactor(ctx) {
38
+ const session = await getSessionFromCtx(ctx);
39
+ if (!session) {
40
+ const cookieName = ctx.context.createAuthCookie(TWO_FACTOR_COOKIE_NAME);
41
+ const twoFactorCookie = await ctx.getSignedCookie(cookieName.name, ctx.context.secret);
42
+ if (!twoFactorCookie) throw new APIError("UNAUTHORIZED", { message: TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE });
43
+ const verificationToken = await ctx.context.internalAdapter.findVerificationValue(twoFactorCookie);
44
+ if (!verificationToken) throw new APIError("UNAUTHORIZED", { message: TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE });
45
+ const user = await ctx.context.internalAdapter.findUserById(verificationToken.value);
46
+ if (!user) throw new APIError("UNAUTHORIZED", { message: TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE });
47
+ const dontRememberMe = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
48
+ return {
49
+ valid: async (ctx$1) => {
50
+ const session$1 = await ctx$1.context.internalAdapter.createSession(verificationToken.value, !!dontRememberMe);
51
+ if (!session$1) throw new APIError("INTERNAL_SERVER_ERROR", { message: "failed to create session" });
52
+ await setSessionCookie(ctx$1, {
53
+ session: session$1,
54
+ user
55
+ });
56
+ if (ctx$1.body.trustDevice) {
57
+ const trustDeviceCookie = ctx$1.context.createAuthCookie(TRUST_DEVICE_COOKIE_NAME, { maxAge: 720 * 60 * 60 });
58
+ /**
59
+ * create a token that will be used to
60
+ * verify the device
61
+ */
62
+ const token = await createHMAC("SHA-256", "base64urlnopad").sign(ctx$1.context.secret, `${user.id}!${session$1.token}`);
63
+ await ctx$1.setSignedCookie(trustDeviceCookie.name, `${token}!${session$1.token}`, ctx$1.context.secret, trustDeviceCookie.attributes);
64
+ ctx$1.setCookie(ctx$1.context.authCookies.dontRememberToken.name, "", { maxAge: 0 });
65
+ ctx$1.setCookie(cookieName.name, "", { maxAge: 0 });
66
+ }
67
+ return ctx$1.json({
68
+ token: session$1.token,
69
+ user: {
70
+ id: user.id,
71
+ email: user.email,
72
+ emailVerified: user.emailVerified,
73
+ name: user.name,
74
+ image: user.image,
75
+ createdAt: user.createdAt,
76
+ updatedAt: user.updatedAt
77
+ }
78
+ });
79
+ },
80
+ invalid: async (errorKey) => {
81
+ throw new APIError("UNAUTHORIZED", { message: TWO_FACTOR_ERROR_CODES[errorKey] });
82
+ },
83
+ session: {
84
+ session: null,
85
+ user
86
+ },
87
+ key: twoFactorCookie
88
+ };
89
+ }
90
+ return {
91
+ valid: async (ctx$1) => {
92
+ return ctx$1.json({
93
+ token: session.session.token,
94
+ user: {
95
+ id: session.user.id,
96
+ email: session.user.email,
97
+ emailVerified: session.user.emailVerified,
98
+ name: session.user.name,
99
+ image: session.user.image,
100
+ createdAt: session.user.createdAt,
101
+ updatedAt: session.user.updatedAt
102
+ }
103
+ });
104
+ },
105
+ invalid: async () => {
106
+ throw new APIError("UNAUTHORIZED", { message: TWO_FACTOR_ERROR_CODES.INVALID_TWO_FACTOR_COOKIE });
107
+ },
108
+ session,
109
+ key: `${session.user.id}!${session.session.id}`
110
+ };
111
+ }
112
+
113
+ //#endregion
114
+ //#region src/plugins/two-factor/backup-codes/index.ts
115
+ function generateBackupCodesFn(options) {
116
+ return Array.from({ length: options?.amount ?? 10 }).fill(null).map(() => generateRandomString(options?.length ?? 10, "a-z", "0-9", "A-Z")).map((code) => `${code.slice(0, 5)}-${code.slice(5)}`);
117
+ }
118
+ async function generateBackupCodes(secret, options) {
119
+ const backupCodes = options?.customBackupCodesGenerate ? options.customBackupCodesGenerate() : generateBackupCodesFn(options);
120
+ if (options?.storeBackupCodes === "encrypted") return {
121
+ backupCodes,
122
+ encryptedBackupCodes: await symmetricEncrypt({
123
+ data: JSON.stringify(backupCodes),
124
+ key: secret
125
+ })
126
+ };
127
+ if (typeof options?.storeBackupCodes === "object" && "encrypt" in options?.storeBackupCodes) return {
128
+ backupCodes,
129
+ encryptedBackupCodes: await options?.storeBackupCodes.encrypt(JSON.stringify(backupCodes))
130
+ };
131
+ return {
132
+ backupCodes,
133
+ encryptedBackupCodes: JSON.stringify(backupCodes)
134
+ };
135
+ }
136
+ async function verifyBackupCode(data, key, options) {
137
+ const codes = await getBackupCodes(data.backupCodes, key, options);
138
+ if (!codes) return {
139
+ status: false,
140
+ updated: null
141
+ };
142
+ return {
143
+ status: codes.includes(data.code),
144
+ updated: codes.filter((code) => code !== data.code)
145
+ };
146
+ }
147
+ async function getBackupCodes(backupCodes, key, options) {
148
+ if (options?.storeBackupCodes === "encrypted") return safeJSONParse(await symmetricDecrypt({
149
+ key,
150
+ data: backupCodes
151
+ }));
152
+ if (typeof options?.storeBackupCodes === "object" && "decrypt" in options?.storeBackupCodes) return safeJSONParse(await options?.storeBackupCodes.decrypt(backupCodes));
153
+ return safeJSONParse(backupCodes);
154
+ }
155
+ const backupCode2fa = (opts) => {
156
+ const twoFactorTable = "twoFactor";
157
+ return {
158
+ id: "backup_code",
159
+ endpoints: {
160
+ verifyBackupCode: createAuthEndpoint("/two-factor/verify-backup-code", {
161
+ method: "POST",
162
+ body: z$1.object({
163
+ code: z$1.string().meta({ description: `A backup code to verify. Eg: "123456"` }),
164
+ disableSession: z$1.boolean().meta({ description: "If true, the session cookie will not be set." }).optional(),
165
+ trustDevice: z$1.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()
166
+ }),
167
+ metadata: { openapi: {
168
+ description: "Verify a backup code for two-factor authentication",
169
+ responses: { "200": {
170
+ description: "Backup code verified successfully",
171
+ content: { "application/json": { schema: {
172
+ type: "object",
173
+ properties: {
174
+ user: {
175
+ type: "object",
176
+ properties: {
177
+ id: {
178
+ type: "string",
179
+ description: "Unique identifier of the user"
180
+ },
181
+ email: {
182
+ type: "string",
183
+ format: "email",
184
+ nullable: true,
185
+ description: "User's email address"
186
+ },
187
+ emailVerified: {
188
+ type: "boolean",
189
+ nullable: true,
190
+ description: "Whether the email is verified"
191
+ },
192
+ name: {
193
+ type: "string",
194
+ nullable: true,
195
+ description: "User's name"
196
+ },
197
+ image: {
198
+ type: "string",
199
+ format: "uri",
200
+ nullable: true,
201
+ description: "User's profile image URL"
202
+ },
203
+ twoFactorEnabled: {
204
+ type: "boolean",
205
+ description: "Whether two-factor authentication is enabled for the user"
206
+ },
207
+ createdAt: {
208
+ type: "string",
209
+ format: "date-time",
210
+ description: "Timestamp when the user was created"
211
+ },
212
+ updatedAt: {
213
+ type: "string",
214
+ format: "date-time",
215
+ description: "Timestamp when the user was last updated"
216
+ }
217
+ },
218
+ required: [
219
+ "id",
220
+ "twoFactorEnabled",
221
+ "createdAt",
222
+ "updatedAt"
223
+ ],
224
+ description: "The authenticated user object with two-factor details"
225
+ },
226
+ session: {
227
+ type: "object",
228
+ properties: {
229
+ token: {
230
+ type: "string",
231
+ description: "Session token"
232
+ },
233
+ userId: {
234
+ type: "string",
235
+ description: "ID of the user associated with the session"
236
+ },
237
+ createdAt: {
238
+ type: "string",
239
+ format: "date-time",
240
+ description: "Timestamp when the session was created"
241
+ },
242
+ expiresAt: {
243
+ type: "string",
244
+ format: "date-time",
245
+ description: "Timestamp when the session expires"
246
+ }
247
+ },
248
+ required: [
249
+ "token",
250
+ "userId",
251
+ "createdAt",
252
+ "expiresAt"
253
+ ],
254
+ description: "The current session object, included unless disableSession is true"
255
+ }
256
+ },
257
+ required: ["user", "session"]
258
+ } } }
259
+ } }
260
+ } }
261
+ }, async (ctx) => {
262
+ const { session, valid } = await verifyTwoFactor(ctx);
263
+ const user = session.user;
264
+ const twoFactor$1 = await ctx.context.adapter.findOne({
265
+ model: twoFactorTable,
266
+ where: [{
267
+ field: "userId",
268
+ value: user.id
269
+ }]
270
+ });
271
+ if (!twoFactor$1) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.BACKUP_CODES_NOT_ENABLED });
272
+ const validate = await verifyBackupCode({
273
+ backupCodes: twoFactor$1.backupCodes,
274
+ code: ctx.body.code
275
+ }, ctx.context.secret, opts);
276
+ if (!validate.status) throw new APIError("UNAUTHORIZED", { message: TWO_FACTOR_ERROR_CODES.INVALID_BACKUP_CODE });
277
+ const updatedBackupCodes = await symmetricEncrypt({
278
+ key: ctx.context.secret,
279
+ data: JSON.stringify(validate.updated)
280
+ });
281
+ await ctx.context.adapter.updateMany({
282
+ model: twoFactorTable,
283
+ update: { backupCodes: updatedBackupCodes },
284
+ where: [{
285
+ field: "userId",
286
+ value: user.id
287
+ }]
288
+ });
289
+ if (!ctx.body.disableSession) return valid(ctx);
290
+ return ctx.json({
291
+ token: session.session?.token,
292
+ user: {
293
+ id: session.user?.id,
294
+ email: session.user.email,
295
+ emailVerified: session.user.emailVerified,
296
+ name: session.user.name,
297
+ image: session.user.image,
298
+ createdAt: session.user.createdAt,
299
+ updatedAt: session.user.updatedAt
300
+ }
301
+ });
302
+ }),
303
+ generateBackupCodes: createAuthEndpoint("/two-factor/generate-backup-codes", {
304
+ method: "POST",
305
+ body: z$1.object({ password: z$1.string().meta({ description: "The users password." }) }),
306
+ use: [sessionMiddleware],
307
+ metadata: { openapi: {
308
+ description: "Generate new backup codes for two-factor authentication",
309
+ responses: { "200": {
310
+ description: "Backup codes generated successfully",
311
+ content: { "application/json": { schema: {
312
+ type: "object",
313
+ properties: {
314
+ status: {
315
+ type: "boolean",
316
+ description: "Indicates if the backup codes were generated successfully",
317
+ enum: [true]
318
+ },
319
+ backupCodes: {
320
+ type: "array",
321
+ items: { type: "string" },
322
+ description: "Array of generated backup codes in plain text"
323
+ }
324
+ },
325
+ required: ["status", "backupCodes"]
326
+ } } }
327
+ } }
328
+ } }
329
+ }, async (ctx) => {
330
+ const user = ctx.context.session.user;
331
+ if (!user.twoFactorEnabled) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.TWO_FACTOR_NOT_ENABLED });
332
+ await ctx.context.password.checkPassword(user.id, ctx);
333
+ const backupCodes = await generateBackupCodes(ctx.context.secret, opts);
334
+ await ctx.context.adapter.updateMany({
335
+ model: twoFactorTable,
336
+ update: { backupCodes: backupCodes.encryptedBackupCodes },
337
+ where: [{
338
+ field: "userId",
339
+ value: ctx.context.session.user.id
340
+ }]
341
+ });
342
+ return ctx.json({
343
+ status: true,
344
+ backupCodes: backupCodes.backupCodes
345
+ });
346
+ }),
347
+ viewBackupCodes: createAuthEndpoint("/two-factor/view-backup-codes", {
348
+ method: "POST",
349
+ body: z$1.object({ userId: z$1.coerce.string().meta({ description: `The user ID to view all backup codes. Eg: "user-id"` }) }),
350
+ metadata: { SERVER_ONLY: true }
351
+ }, async (ctx) => {
352
+ const twoFactor$1 = await ctx.context.adapter.findOne({
353
+ model: twoFactorTable,
354
+ where: [{
355
+ field: "userId",
356
+ value: ctx.body.userId
357
+ }]
358
+ });
359
+ if (!twoFactor$1) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.BACKUP_CODES_NOT_ENABLED });
360
+ const decryptedBackupCodes = await getBackupCodes(twoFactor$1.backupCodes, ctx.context.secret, opts);
361
+ if (!decryptedBackupCodes) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.INVALID_BACKUP_CODE });
362
+ return ctx.json({
363
+ status: true,
364
+ backupCodes: decryptedBackupCodes
365
+ });
366
+ })
367
+ }
368
+ };
369
+ };
370
+
371
+ //#endregion
372
+ //#region src/plugins/two-factor/utils.ts
373
+ const defaultKeyHasher = async (token) => {
374
+ const hash = await createHash("SHA-256", "none").digest(new TextEncoder().encode(token));
375
+ return base64Url.encode(new Uint8Array(hash), { padding: false });
376
+ };
377
+
378
+ //#endregion
379
+ //#region src/plugins/two-factor/otp/index.ts
380
+ /**
381
+ * The otp adapter is created from the totp adapter.
382
+ */
383
+ const otp2fa = (options) => {
384
+ const opts = {
385
+ storeOTP: "plain",
386
+ digits: 6,
387
+ ...options,
388
+ period: (options?.period || 3) * 60 * 1e3
389
+ };
390
+ async function storeOTP(ctx, otp) {
391
+ if (opts.storeOTP === "hashed") return await defaultKeyHasher(otp);
392
+ if (typeof opts.storeOTP === "object" && "hash" in opts.storeOTP) return await opts.storeOTP.hash(otp);
393
+ if (typeof opts.storeOTP === "object" && "encrypt" in opts.storeOTP) return await opts.storeOTP.encrypt(otp);
394
+ if (opts.storeOTP === "encrypted") return await symmetricEncrypt({
395
+ key: ctx.context.secret,
396
+ data: otp
397
+ });
398
+ return otp;
399
+ }
400
+ async function decryptOTP(ctx, otp) {
401
+ if (opts.storeOTP === "hashed") return await defaultKeyHasher(otp);
402
+ if (opts.storeOTP === "encrypted") return await symmetricDecrypt({
403
+ key: ctx.context.secret,
404
+ data: otp
405
+ });
406
+ if (typeof opts.storeOTP === "object" && "encrypt" in opts.storeOTP) return await opts.storeOTP.decrypt(otp);
407
+ if (typeof opts.storeOTP === "object" && "hash" in opts.storeOTP) return await opts.storeOTP.hash(otp);
408
+ return otp;
409
+ }
410
+ return {
411
+ id: "otp",
412
+ endpoints: {
413
+ sendTwoFactorOTP: createAuthEndpoint("/two-factor/send-otp", {
414
+ method: "POST",
415
+ body: z$1.object({ trustDevice: z$1.boolean().optional().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(),
416
+ metadata: { openapi: {
417
+ summary: "Send two factor OTP",
418
+ description: "Send two factor OTP to the user",
419
+ responses: { 200: {
420
+ description: "Successful response",
421
+ content: { "application/json": { schema: {
422
+ type: "object",
423
+ properties: { status: { type: "boolean" } }
424
+ } } }
425
+ } }
426
+ } }
427
+ }, async (ctx) => {
428
+ if (!options || !options.sendOTP) {
429
+ ctx.context.logger.error("send otp isn't configured. Please configure the send otp function on otp options.");
430
+ throw new APIError("BAD_REQUEST", { message: "otp isn't configured" });
431
+ }
432
+ const { session, key } = await verifyTwoFactor(ctx);
433
+ if (!session.user.twoFactorEnabled) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.OTP_NOT_ENABLED });
434
+ const code = generateRandomString(opts.digits, "0-9");
435
+ const hashedCode = await storeOTP(ctx, code);
436
+ await ctx.context.internalAdapter.createVerificationValue({
437
+ value: `${hashedCode}:0`,
438
+ identifier: `2fa-otp-${key}`,
439
+ expiresAt: new Date(Date.now() + opts.period)
440
+ });
441
+ await options.sendOTP({
442
+ user: session.user,
443
+ otp: code
444
+ }, ctx.request);
445
+ return ctx.json({ status: true });
446
+ }),
447
+ verifyTwoFactorOTP: createAuthEndpoint("/two-factor/verify-otp", {
448
+ method: "POST",
449
+ body: z$1.object({
450
+ code: z$1.string().meta({ description: "The otp code to verify. Eg: \"012345\"" }),
451
+ trustDevice: z$1.boolean().optional().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" })
452
+ }),
453
+ metadata: { openapi: {
454
+ summary: "Verify two factor OTP",
455
+ description: "Verify two factor OTP",
456
+ responses: { "200": {
457
+ description: "Two-factor OTP verified successfully",
458
+ content: { "application/json": { schema: {
459
+ type: "object",
460
+ properties: {
461
+ token: {
462
+ type: "string",
463
+ description: "Session token for the authenticated session"
464
+ },
465
+ user: {
466
+ type: "object",
467
+ properties: {
468
+ id: {
469
+ type: "string",
470
+ description: "Unique identifier of the user"
471
+ },
472
+ email: {
473
+ type: "string",
474
+ format: "email",
475
+ nullable: true,
476
+ description: "User's email address"
477
+ },
478
+ emailVerified: {
479
+ type: "boolean",
480
+ nullable: true,
481
+ description: "Whether the email is verified"
482
+ },
483
+ name: {
484
+ type: "string",
485
+ nullable: true,
486
+ description: "User's name"
487
+ },
488
+ image: {
489
+ type: "string",
490
+ format: "uri",
491
+ nullable: true,
492
+ description: "User's profile image URL"
493
+ },
494
+ createdAt: {
495
+ type: "string",
496
+ format: "date-time",
497
+ description: "Timestamp when the user was created"
498
+ },
499
+ updatedAt: {
500
+ type: "string",
501
+ format: "date-time",
502
+ description: "Timestamp when the user was last updated"
503
+ }
504
+ },
505
+ required: [
506
+ "id",
507
+ "createdAt",
508
+ "updatedAt"
509
+ ],
510
+ description: "The authenticated user object"
511
+ }
512
+ },
513
+ required: ["token", "user"]
514
+ } } }
515
+ } }
516
+ } }
517
+ }, async (ctx) => {
518
+ const { session, key, valid, invalid } = await verifyTwoFactor(ctx);
519
+ const toCheckOtp = await ctx.context.internalAdapter.findVerificationValue(`2fa-otp-${key}`);
520
+ const [otp, counter] = toCheckOtp?.value?.split(":") ?? [];
521
+ const decryptedOtp = await decryptOTP(ctx, otp);
522
+ if (!toCheckOtp || toCheckOtp.expiresAt < /* @__PURE__ */ new Date()) {
523
+ if (toCheckOtp) await ctx.context.internalAdapter.deleteVerificationValue(toCheckOtp.id);
524
+ throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.OTP_HAS_EXPIRED });
525
+ }
526
+ const allowedAttempts = options?.allowedAttempts || 5;
527
+ if (parseInt(counter) >= allowedAttempts) {
528
+ await ctx.context.internalAdapter.deleteVerificationValue(toCheckOtp.id);
529
+ throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.TOO_MANY_ATTEMPTS_REQUEST_NEW_CODE });
530
+ }
531
+ if (decryptedOtp === ctx.body.code) {
532
+ if (!session.user.twoFactorEnabled) {
533
+ if (!session.session) throw new APIError("BAD_REQUEST", { message: BASE_ERROR_CODES.FAILED_TO_CREATE_SESSION });
534
+ const updatedUser = await ctx.context.internalAdapter.updateUser(session.user.id, { twoFactorEnabled: true });
535
+ const newSession = await ctx.context.internalAdapter.createSession(session.user.id, false, session.session);
536
+ await ctx.context.internalAdapter.deleteSession(session.session.token);
537
+ await setSessionCookie(ctx, {
538
+ session: newSession,
539
+ user: updatedUser
540
+ });
541
+ return ctx.json({
542
+ token: newSession.token,
543
+ user: {
544
+ id: updatedUser.id,
545
+ email: updatedUser.email,
546
+ emailVerified: updatedUser.emailVerified,
547
+ name: updatedUser.name,
548
+ image: updatedUser.image,
549
+ createdAt: updatedUser.createdAt,
550
+ updatedAt: updatedUser.updatedAt
551
+ }
552
+ });
553
+ }
554
+ return valid(ctx);
555
+ } else {
556
+ await ctx.context.internalAdapter.updateVerificationValue(toCheckOtp.id, { value: `${otp}:${(parseInt(counter, 10) || 0) + 1}` });
557
+ return invalid("INVALID_CODE");
558
+ }
559
+ })
560
+ }
561
+ };
562
+ };
563
+
564
+ //#endregion
565
+ //#region src/plugins/two-factor/schema.ts
566
+ const schema = {
567
+ user: { fields: { twoFactorEnabled: {
568
+ type: "boolean",
569
+ required: false,
570
+ defaultValue: false,
571
+ input: false
572
+ } } },
573
+ twoFactor: { fields: {
574
+ secret: {
575
+ type: "string",
576
+ required: true,
577
+ returned: false
578
+ },
579
+ backupCodes: {
580
+ type: "string",
581
+ required: true,
582
+ returned: false
583
+ },
584
+ userId: {
585
+ type: "string",
586
+ required: true,
587
+ returned: false,
588
+ references: {
589
+ model: "user",
590
+ field: "id"
591
+ }
592
+ }
593
+ } }
594
+ };
595
+
596
+ //#endregion
597
+ //#region src/plugins/two-factor/totp/index.ts
598
+ const totp2fa = (options) => {
599
+ const opts = {
600
+ ...options,
601
+ digits: options?.digits || 6,
602
+ period: options?.period || 30
603
+ };
604
+ const twoFactorTable = "twoFactor";
605
+ return {
606
+ id: "totp",
607
+ endpoints: {
608
+ generateTOTP: createAuthEndpoint("/totp/generate", {
609
+ method: "POST",
610
+ body: z$1.object({ secret: z$1.string().meta({ description: "The secret to generate the TOTP code" }) }),
611
+ metadata: {
612
+ openapi: {
613
+ summary: "Generate TOTP code",
614
+ description: "Use this endpoint to generate a TOTP code",
615
+ responses: { 200: {
616
+ description: "Successful response",
617
+ content: { "application/json": { schema: {
618
+ type: "object",
619
+ properties: { code: { type: "string" } }
620
+ } } }
621
+ } }
622
+ },
623
+ SERVER_ONLY: true
624
+ }
625
+ }, async (ctx) => {
626
+ if (options?.disable) {
627
+ ctx.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp");
628
+ throw new APIError("BAD_REQUEST", { message: "totp isn't configured" });
629
+ }
630
+ return { code: await createOTP(ctx.body.secret, {
631
+ period: opts.period,
632
+ digits: opts.digits
633
+ }).totp() };
634
+ }),
635
+ getTOTPURI: createAuthEndpoint("/two-factor/get-totp-uri", {
636
+ method: "POST",
637
+ use: [sessionMiddleware],
638
+ body: z$1.object({ password: z$1.string().meta({ description: "User password" }) }),
639
+ metadata: { openapi: {
640
+ summary: "Get TOTP URI",
641
+ description: "Use this endpoint to get the TOTP URI",
642
+ responses: { 200: {
643
+ description: "Successful response",
644
+ content: { "application/json": { schema: {
645
+ type: "object",
646
+ properties: { totpURI: { type: "string" } }
647
+ } } }
648
+ } }
649
+ } }
650
+ }, async (ctx) => {
651
+ if (options?.disable) {
652
+ ctx.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp");
653
+ throw new APIError("BAD_REQUEST", { message: "totp isn't configured" });
654
+ }
655
+ const user = ctx.context.session.user;
656
+ const twoFactor$1 = await ctx.context.adapter.findOne({
657
+ model: twoFactorTable,
658
+ where: [{
659
+ field: "userId",
660
+ value: user.id
661
+ }]
662
+ });
663
+ if (!twoFactor$1) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.TOTP_NOT_ENABLED });
664
+ const secret = await symmetricDecrypt({
665
+ key: ctx.context.secret,
666
+ data: twoFactor$1.secret
667
+ });
668
+ await ctx.context.password.checkPassword(user.id, ctx);
669
+ return { totpURI: createOTP(secret, {
670
+ digits: opts.digits,
671
+ period: opts.period
672
+ }).url(options?.issuer || ctx.context.appName, user.email) };
673
+ }),
674
+ verifyTOTP: createAuthEndpoint("/two-factor/verify-totp", {
675
+ method: "POST",
676
+ body: z$1.object({
677
+ code: z$1.string().meta({ description: "The otp code to verify. Eg: \"012345\"" }),
678
+ trustDevice: z$1.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()
679
+ }),
680
+ metadata: { openapi: {
681
+ summary: "Verify two factor TOTP",
682
+ description: "Verify two factor TOTP",
683
+ responses: { 200: {
684
+ description: "Successful response",
685
+ content: { "application/json": { schema: {
686
+ type: "object",
687
+ properties: { status: { type: "boolean" } }
688
+ } } }
689
+ } }
690
+ } }
691
+ }, async (ctx) => {
692
+ if (options?.disable) {
693
+ ctx.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp");
694
+ throw new APIError("BAD_REQUEST", { message: "totp isn't configured" });
695
+ }
696
+ const { session, valid, invalid } = await verifyTwoFactor(ctx);
697
+ const user = session.user;
698
+ const twoFactor$1 = await ctx.context.adapter.findOne({
699
+ model: twoFactorTable,
700
+ where: [{
701
+ field: "userId",
702
+ value: user.id
703
+ }]
704
+ });
705
+ if (!twoFactor$1) throw new APIError("BAD_REQUEST", { message: TWO_FACTOR_ERROR_CODES.TOTP_NOT_ENABLED });
706
+ if (!await createOTP(await symmetricDecrypt({
707
+ key: ctx.context.secret,
708
+ data: twoFactor$1.secret
709
+ }), {
710
+ period: opts.period,
711
+ digits: opts.digits
712
+ }).verify(ctx.body.code, {})) return invalid("INVALID_CODE");
713
+ if (!user.twoFactorEnabled) {
714
+ if (!session.session) throw new APIError("BAD_REQUEST", { message: BASE_ERROR_CODES.FAILED_TO_CREATE_SESSION });
715
+ const updatedUser = await ctx.context.internalAdapter.updateUser(user.id, { twoFactorEnabled: true });
716
+ const newSession = await ctx.context.internalAdapter.createSession(user.id, false, session.session).catch((e) => {
717
+ throw e;
718
+ });
719
+ await ctx.context.internalAdapter.deleteSession(session.session.token);
720
+ await setSessionCookie(ctx, {
721
+ session: newSession,
722
+ user: updatedUser
723
+ });
724
+ }
725
+ return valid(ctx);
726
+ })
727
+ }
728
+ };
729
+ };
730
+
731
+ //#endregion
732
+ //#region src/plugins/two-factor/index.ts
733
+ const twoFactor = (options) => {
734
+ const opts = { twoFactorTable: "twoFactor" };
735
+ const backupCodeOptions = {
736
+ storeBackupCodes: "encrypted",
737
+ ...options?.backupCodeOptions
738
+ };
739
+ const totp = totp2fa(options?.totpOptions);
740
+ const backupCode = backupCode2fa(backupCodeOptions);
741
+ const otp = otp2fa(options?.otpOptions);
742
+ return {
743
+ id: "two-factor",
744
+ endpoints: {
745
+ ...totp.endpoints,
746
+ ...otp.endpoints,
747
+ ...backupCode.endpoints,
748
+ enableTwoFactor: createAuthEndpoint("/two-factor/enable", {
749
+ method: "POST",
750
+ body: z$1.object({
751
+ password: z$1.string().meta({ description: "User password" }),
752
+ issuer: z$1.string().meta({ description: "Custom issuer for the TOTP URI" }).optional()
753
+ }),
754
+ use: [sessionMiddleware],
755
+ metadata: { openapi: {
756
+ summary: "Enable two factor authentication",
757
+ description: "Use this endpoint to enable two factor authentication. This will generate a TOTP URI and backup codes. Once the user verifies the TOTP URI, the two factor authentication will be enabled.",
758
+ responses: { 200: {
759
+ description: "Successful response",
760
+ content: { "application/json": { schema: {
761
+ type: "object",
762
+ properties: {
763
+ totpURI: {
764
+ type: "string",
765
+ description: "TOTP URI"
766
+ },
767
+ backupCodes: {
768
+ type: "array",
769
+ items: { type: "string" },
770
+ description: "Backup codes"
771
+ }
772
+ }
773
+ } } }
774
+ } }
775
+ } }
776
+ }, async (ctx) => {
777
+ const user = ctx.context.session.user;
778
+ const { password, issuer } = ctx.body;
779
+ if (!await validatePassword(ctx, {
780
+ password,
781
+ userId: user.id
782
+ })) throw new APIError("BAD_REQUEST", { message: BASE_ERROR_CODES.INVALID_PASSWORD });
783
+ const secret = generateRandomString(32);
784
+ const encryptedSecret = await symmetricEncrypt({
785
+ key: ctx.context.secret,
786
+ data: secret
787
+ });
788
+ const backupCodes = await generateBackupCodes(ctx.context.secret, backupCodeOptions);
789
+ if (options?.skipVerificationOnEnable) {
790
+ const updatedUser = await ctx.context.internalAdapter.updateUser(user.id, { twoFactorEnabled: true });
791
+ /**
792
+ * Update the session cookie with the new user data
793
+ */
794
+ await setSessionCookie(ctx, {
795
+ session: await ctx.context.internalAdapter.createSession(updatedUser.id, false, ctx.context.session.session),
796
+ user: updatedUser
797
+ });
798
+ await ctx.context.internalAdapter.deleteSession(ctx.context.session.session.token);
799
+ }
800
+ await ctx.context.adapter.deleteMany({
801
+ model: opts.twoFactorTable,
802
+ where: [{
803
+ field: "userId",
804
+ value: user.id
805
+ }]
806
+ });
807
+ await ctx.context.adapter.create({
808
+ model: opts.twoFactorTable,
809
+ data: {
810
+ secret: encryptedSecret,
811
+ backupCodes: backupCodes.encryptedBackupCodes,
812
+ userId: user.id
813
+ }
814
+ });
815
+ const totpURI = createOTP(secret, {
816
+ digits: options?.totpOptions?.digits || 6,
817
+ period: options?.totpOptions?.period
818
+ }).url(issuer || options?.issuer || ctx.context.appName, user.email);
819
+ return ctx.json({
820
+ totpURI,
821
+ backupCodes: backupCodes.backupCodes
822
+ });
823
+ }),
824
+ disableTwoFactor: createAuthEndpoint("/two-factor/disable", {
825
+ method: "POST",
826
+ body: z$1.object({ password: z$1.string().meta({ description: "User password" }) }),
827
+ use: [sessionMiddleware],
828
+ metadata: { openapi: {
829
+ summary: "Disable two factor authentication",
830
+ description: "Use this endpoint to disable two factor authentication.",
831
+ responses: { 200: {
832
+ description: "Successful response",
833
+ content: { "application/json": { schema: {
834
+ type: "object",
835
+ properties: { status: { type: "boolean" } }
836
+ } } }
837
+ } }
838
+ } }
839
+ }, async (ctx) => {
840
+ const user = ctx.context.session.user;
841
+ const { password } = ctx.body;
842
+ if (!await validatePassword(ctx, {
843
+ password,
844
+ userId: user.id
845
+ })) throw new APIError("BAD_REQUEST", { message: "Invalid password" });
846
+ const updatedUser = await ctx.context.internalAdapter.updateUser(user.id, { twoFactorEnabled: false });
847
+ await ctx.context.adapter.delete({
848
+ model: opts.twoFactorTable,
849
+ where: [{
850
+ field: "userId",
851
+ value: updatedUser.id
852
+ }]
853
+ });
854
+ /**
855
+ * Update the session cookie with the new user data
856
+ */
857
+ await setSessionCookie(ctx, {
858
+ session: await ctx.context.internalAdapter.createSession(updatedUser.id, false, ctx.context.session.session),
859
+ user: updatedUser
860
+ });
861
+ await ctx.context.internalAdapter.deleteSession(ctx.context.session.session.token);
862
+ return ctx.json({ status: true });
863
+ })
864
+ },
865
+ options,
866
+ hooks: { after: [{
867
+ matcher(context) {
868
+ return context.path === "/sign-in/email" || context.path === "/sign-in/phone-number";
869
+ },
870
+ handler: createAuthMiddleware(async (ctx) => {
871
+ const data = ctx.context.newSession;
872
+ if (!data) return;
873
+ if (!data?.user.twoFactorEnabled) return;
874
+ const trustDeviceCookieName = ctx.context.createAuthCookie(TRUST_DEVICE_COOKIE_NAME);
875
+ const trustDeviceCookie = await ctx.getSignedCookie(trustDeviceCookieName.name, ctx.context.secret);
876
+ if (trustDeviceCookie) {
877
+ const [token, sessionToken] = trustDeviceCookie.split("!");
878
+ if (token === await createHMAC("SHA-256", "base64urlnopad").sign(ctx.context.secret, `${data.user.id}!${sessionToken}`)) {
879
+ const newToken = await createHMAC("SHA-256", "base64urlnopad").sign(ctx.context.secret, `${data.user.id}!${sessionToken}`);
880
+ await ctx.setSignedCookie(trustDeviceCookieName.name, `${newToken}!${data.session.token}`, ctx.context.secret, trustDeviceCookieName.attributes);
881
+ return;
882
+ }
883
+ }
884
+ /**
885
+ * remove the session cookie. It's set by the sign in credential
886
+ */
887
+ deleteSessionCookie(ctx, true);
888
+ await ctx.context.internalAdapter.deleteSession(data.session.token);
889
+ const maxAge = (options?.otpOptions?.period ?? 3) * 60;
890
+ const twoFactorCookie = ctx.context.createAuthCookie(TWO_FACTOR_COOKIE_NAME, { maxAge });
891
+ const identifier = `2fa-${generateRandomString(20)}`;
892
+ await ctx.context.internalAdapter.createVerificationValue({
893
+ value: data.user.id,
894
+ identifier,
895
+ expiresAt: new Date(Date.now() + maxAge * 1e3)
896
+ });
897
+ await ctx.setSignedCookie(twoFactorCookie.name, identifier, ctx.context.secret, twoFactorCookie.attributes);
898
+ return ctx.json({ twoFactorRedirect: true });
899
+ })
900
+ }] },
901
+ schema: mergeSchema(schema, options?.schema),
902
+ rateLimit: [{
903
+ pathMatcher(path) {
904
+ return path.startsWith("/two-factor/");
905
+ },
906
+ window: 10,
907
+ max: 3
908
+ }],
909
+ $ERROR_CODES: TWO_FACTOR_ERROR_CODES
910
+ };
911
+ };
912
+
913
+ //#endregion
914
+ export { TWO_FACTOR_ERROR_CODES as n, twoFactor as t };