@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,1544 @@
1
+ import { t as APIError } from "./api-0pR_I-Nx.mjs";
2
+ import { t as getIp } from "./get-request-ip-DSjrEpGo.mjs";
3
+ import { t as safeJSONParse } from "./json-D0TBLy4q.mjs";
4
+ import { r as generateRandomString } from "./crypto-Bb42eMrH.mjs";
5
+ import { n as mergeSchema, t as getDate } from "./date-Cx2yCiC4.mjs";
6
+ import { r as getSessionFromCtx, u as sessionMiddleware } from "./session-Dgp133Yt.mjs";
7
+ import { n as parser_default } from "./parser-DcrIEuXE.mjs";
8
+ import { n as role } from "./access-BO2g7QVe.mjs";
9
+ import { defineErrorCodes } from "@gatwech/core/utils";
10
+ import { createAuthEndpoint, createAuthEndpoint as createAuthEndpoint$1, createAuthMiddleware, createAuthMiddleware as createAuthMiddleware$1, optionsMiddleware } 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
+
15
+ //#region src/plugins/api-key/schema.ts
16
+ const apiKeySchema = ({ timeWindow, rateLimitMax }) => ({ apikey: { fields: {
17
+ name: {
18
+ type: "string",
19
+ required: false,
20
+ input: false
21
+ },
22
+ start: {
23
+ type: "string",
24
+ required: false,
25
+ input: false
26
+ },
27
+ prefix: {
28
+ type: "string",
29
+ required: false,
30
+ input: false
31
+ },
32
+ key: {
33
+ type: "string",
34
+ required: true,
35
+ input: false
36
+ },
37
+ userId: {
38
+ type: "string",
39
+ references: {
40
+ model: "user",
41
+ field: "id",
42
+ onDelete: "cascade"
43
+ },
44
+ required: true,
45
+ input: false
46
+ },
47
+ refillInterval: {
48
+ type: "number",
49
+ required: false,
50
+ input: false
51
+ },
52
+ refillAmount: {
53
+ type: "number",
54
+ required: false,
55
+ input: false
56
+ },
57
+ lastRefillAt: {
58
+ type: "date",
59
+ required: false,
60
+ input: false
61
+ },
62
+ enabled: {
63
+ type: "boolean",
64
+ required: false,
65
+ input: false,
66
+ defaultValue: true
67
+ },
68
+ rateLimitEnabled: {
69
+ type: "boolean",
70
+ required: false,
71
+ input: false,
72
+ defaultValue: true
73
+ },
74
+ rateLimitTimeWindow: {
75
+ type: "number",
76
+ required: false,
77
+ input: false,
78
+ defaultValue: timeWindow
79
+ },
80
+ rateLimitMax: {
81
+ type: "number",
82
+ required: false,
83
+ input: false,
84
+ defaultValue: rateLimitMax
85
+ },
86
+ requestCount: {
87
+ type: "number",
88
+ required: false,
89
+ input: false,
90
+ defaultValue: 0
91
+ },
92
+ remaining: {
93
+ type: "number",
94
+ required: false,
95
+ input: false
96
+ },
97
+ lastRequest: {
98
+ type: "date",
99
+ required: false,
100
+ input: false
101
+ },
102
+ expiresAt: {
103
+ type: "date",
104
+ required: false,
105
+ input: false
106
+ },
107
+ createdAt: {
108
+ type: "date",
109
+ required: true,
110
+ input: false
111
+ },
112
+ updatedAt: {
113
+ type: "date",
114
+ required: true,
115
+ input: false
116
+ },
117
+ permissions: {
118
+ type: "string",
119
+ required: false,
120
+ input: false
121
+ },
122
+ metadata: {
123
+ type: "string",
124
+ required: false,
125
+ input: true,
126
+ transform: {
127
+ input(value) {
128
+ return JSON.stringify(value);
129
+ },
130
+ output(value) {
131
+ if (!value) return null;
132
+ return parser_default(value);
133
+ }
134
+ }
135
+ }
136
+ } } });
137
+
138
+ //#endregion
139
+ //#region src/plugins/api-key/routes/create-api-key.ts
140
+ function createApiKey({ keyGenerator, opts, schema, deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
141
+ return createAuthEndpoint("/api-key/create", {
142
+ method: "POST",
143
+ body: z$1.object({
144
+ name: z$1.string().meta({ description: "Name of the Api Key" }).optional(),
145
+ expiresIn: z$1.number().meta({ description: "Expiration time of the Api Key in seconds" }).min(1).optional().nullable().default(null),
146
+ userId: z$1.coerce.string().meta({ description: "User Id of the user that the Api Key belongs to. server-only. Eg: \"user-id\"" }).optional(),
147
+ prefix: z$1.string().meta({ description: "Prefix of the Api Key" }).regex(/^[a-zA-Z0-9_-]+$/, { message: "Invalid prefix format, must be alphanumeric and contain only underscores and hyphens." }).optional(),
148
+ remaining: z$1.number().meta({ description: "Remaining number of requests. Server side only" }).min(0).optional().nullable().default(null),
149
+ metadata: z$1.any().optional(),
150
+ refillAmount: z$1.number().meta({ description: "Amount to refill the remaining count of the Api Key. server-only. Eg: 100" }).min(1).optional(),
151
+ refillInterval: z$1.number().meta({ description: "Interval to refill the Api Key in milliseconds. server-only. Eg: 1000" }).optional(),
152
+ rateLimitTimeWindow: z$1.number().meta({ description: "The duration in milliseconds where each request is counted. Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset. server-only. Eg: 1000" }).optional(),
153
+ rateLimitMax: z$1.number().meta({ description: "Maximum amount of requests allowed within a window. Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset. server-only. Eg: 100" }).optional(),
154
+ rateLimitEnabled: z$1.boolean().meta({ description: "Whether the key has rate limiting enabled. server-only. Eg: true" }).optional(),
155
+ permissions: z$1.record(z$1.string(), z$1.array(z$1.string())).meta({ description: "Permissions of the Api Key." }).optional()
156
+ }),
157
+ metadata: { openapi: {
158
+ description: "Create a new API key for a user",
159
+ responses: { "200": {
160
+ description: "API key created successfully",
161
+ content: { "application/json": { schema: {
162
+ type: "object",
163
+ properties: {
164
+ id: {
165
+ type: "string",
166
+ description: "Unique identifier of the API key"
167
+ },
168
+ createdAt: {
169
+ type: "string",
170
+ format: "date-time",
171
+ description: "Creation timestamp"
172
+ },
173
+ updatedAt: {
174
+ type: "string",
175
+ format: "date-time",
176
+ description: "Last update timestamp"
177
+ },
178
+ name: {
179
+ type: "string",
180
+ nullable: true,
181
+ description: "Name of the API key"
182
+ },
183
+ prefix: {
184
+ type: "string",
185
+ nullable: true,
186
+ description: "Prefix of the API key"
187
+ },
188
+ start: {
189
+ type: "string",
190
+ nullable: true,
191
+ description: "Starting characters of the key (if configured)"
192
+ },
193
+ key: {
194
+ type: "string",
195
+ description: "The full API key (only returned on creation)"
196
+ },
197
+ enabled: {
198
+ type: "boolean",
199
+ description: "Whether the key is enabled"
200
+ },
201
+ expiresAt: {
202
+ type: "string",
203
+ format: "date-time",
204
+ nullable: true,
205
+ description: "Expiration timestamp"
206
+ },
207
+ userId: {
208
+ type: "string",
209
+ description: "ID of the user owning the key"
210
+ },
211
+ lastRefillAt: {
212
+ type: "string",
213
+ format: "date-time",
214
+ nullable: true,
215
+ description: "Last refill timestamp"
216
+ },
217
+ lastRequest: {
218
+ type: "string",
219
+ format: "date-time",
220
+ nullable: true,
221
+ description: "Last request timestamp"
222
+ },
223
+ metadata: {
224
+ type: "object",
225
+ nullable: true,
226
+ additionalProperties: true,
227
+ description: "Metadata associated with the key"
228
+ },
229
+ rateLimitMax: {
230
+ type: "number",
231
+ nullable: true,
232
+ description: "Maximum requests in time window"
233
+ },
234
+ rateLimitTimeWindow: {
235
+ type: "number",
236
+ nullable: true,
237
+ description: "Rate limit time window in milliseconds"
238
+ },
239
+ remaining: {
240
+ type: "number",
241
+ nullable: true,
242
+ description: "Remaining requests"
243
+ },
244
+ refillAmount: {
245
+ type: "number",
246
+ nullable: true,
247
+ description: "Amount to refill"
248
+ },
249
+ refillInterval: {
250
+ type: "number",
251
+ nullable: true,
252
+ description: "Refill interval in milliseconds"
253
+ },
254
+ rateLimitEnabled: {
255
+ type: "boolean",
256
+ description: "Whether rate limiting is enabled"
257
+ },
258
+ requestCount: {
259
+ type: "number",
260
+ description: "Current request count in window"
261
+ },
262
+ permissions: {
263
+ type: "object",
264
+ nullable: true,
265
+ additionalProperties: {
266
+ type: "array",
267
+ items: { type: "string" }
268
+ },
269
+ description: "Permissions associated with the key"
270
+ }
271
+ },
272
+ required: [
273
+ "id",
274
+ "createdAt",
275
+ "updatedAt",
276
+ "key",
277
+ "enabled",
278
+ "userId",
279
+ "rateLimitEnabled",
280
+ "requestCount"
281
+ ]
282
+ } } }
283
+ } }
284
+ } }
285
+ }, async (ctx) => {
286
+ const { name, expiresIn, prefix, remaining, metadata, refillAmount, refillInterval, permissions, rateLimitMax, rateLimitTimeWindow, rateLimitEnabled } = ctx.body;
287
+ const session = await getSessionFromCtx(ctx);
288
+ const authRequired = ctx.request || ctx.headers;
289
+ const user = authRequired && !session ? null : session?.user || { id: ctx.body.userId };
290
+ if (!user?.id) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.UNAUTHORIZED_SESSION });
291
+ if (session && ctx.body.userId && session?.user.id !== ctx.body.userId) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.UNAUTHORIZED_SESSION });
292
+ if (authRequired) {
293
+ if (refillAmount !== void 0 || refillInterval !== void 0 || rateLimitMax !== void 0 || rateLimitTimeWindow !== void 0 || rateLimitEnabled !== void 0 || permissions !== void 0 || remaining !== null) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.SERVER_ONLY_PROPERTY });
294
+ }
295
+ if (metadata) {
296
+ if (opts.enableMetadata === false) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.METADATA_DISABLED });
297
+ if (typeof metadata !== "object") throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_METADATA_TYPE });
298
+ }
299
+ if (refillAmount && !refillInterval) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.REFILL_AMOUNT_AND_INTERVAL_REQUIRED });
300
+ if (refillInterval && !refillAmount) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.REFILL_INTERVAL_AND_AMOUNT_REQUIRED });
301
+ if (expiresIn) {
302
+ if (opts.keyExpiration.disableCustomExpiresTime === true) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.KEY_DISABLED_EXPIRATION });
303
+ const expiresIn_in_days = expiresIn / (3600 * 24);
304
+ if (opts.keyExpiration.minExpiresIn > expiresIn_in_days) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.EXPIRES_IN_IS_TOO_SMALL });
305
+ else if (opts.keyExpiration.maxExpiresIn < expiresIn_in_days) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.EXPIRES_IN_IS_TOO_LARGE });
306
+ }
307
+ if (prefix) {
308
+ if (prefix.length < opts.minimumPrefixLength) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_PREFIX_LENGTH });
309
+ if (prefix.length > opts.maximumPrefixLength) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_PREFIX_LENGTH });
310
+ }
311
+ if (name) {
312
+ if (name.length < opts.minimumNameLength) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_NAME_LENGTH });
313
+ if (name.length > opts.maximumNameLength) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_NAME_LENGTH });
314
+ } else if (opts.requireName) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.NAME_REQUIRED });
315
+ deleteAllExpiredApiKeys$1(ctx.context);
316
+ const key = await keyGenerator({
317
+ length: opts.defaultKeyLength,
318
+ prefix: prefix || opts.defaultPrefix
319
+ });
320
+ const hashed = opts.disableKeyHashing ? key : await defaultKeyHasher(key);
321
+ let start = null;
322
+ if (opts.startingCharactersConfig.shouldStore) start = key.substring(0, opts.startingCharactersConfig.charactersLength);
323
+ const defaultPermissions = opts.permissions?.defaultPermissions ? typeof opts.permissions.defaultPermissions === "function" ? await opts.permissions.defaultPermissions(user.id, ctx) : opts.permissions.defaultPermissions : void 0;
324
+ const permissionsToApply = permissions ? JSON.stringify(permissions) : defaultPermissions ? JSON.stringify(defaultPermissions) : void 0;
325
+ let data = {
326
+ createdAt: /* @__PURE__ */ new Date(),
327
+ updatedAt: /* @__PURE__ */ new Date(),
328
+ name: name ?? null,
329
+ prefix: prefix ?? opts.defaultPrefix ?? null,
330
+ start,
331
+ key: hashed,
332
+ enabled: true,
333
+ expiresAt: expiresIn ? getDate(expiresIn, "sec") : opts.keyExpiration.defaultExpiresIn ? getDate(opts.keyExpiration.defaultExpiresIn, "sec") : null,
334
+ userId: user.id,
335
+ lastRefillAt: null,
336
+ lastRequest: null,
337
+ metadata: null,
338
+ rateLimitMax: rateLimitMax ?? opts.rateLimit.maxRequests ?? null,
339
+ rateLimitTimeWindow: rateLimitTimeWindow ?? opts.rateLimit.timeWindow ?? null,
340
+ remaining: remaining === null ? remaining : remaining ?? refillAmount ?? null,
341
+ refillAmount: refillAmount ?? null,
342
+ refillInterval: refillInterval ?? null,
343
+ rateLimitEnabled: rateLimitEnabled === void 0 ? opts.rateLimit.enabled ?? true : rateLimitEnabled,
344
+ requestCount: 0,
345
+ permissions: permissionsToApply
346
+ };
347
+ if (metadata) data.metadata = schema.apikey.fields.metadata.transform.input(metadata);
348
+ const apiKey$1 = await ctx.context.adapter.create({
349
+ model: API_KEY_TABLE_NAME,
350
+ data
351
+ });
352
+ return ctx.json({
353
+ ...apiKey$1,
354
+ key,
355
+ metadata: metadata ?? null,
356
+ permissions: apiKey$1.permissions ? safeJSONParse(apiKey$1.permissions) : null
357
+ });
358
+ });
359
+ }
360
+
361
+ //#endregion
362
+ //#region src/plugins/api-key/routes/delete-all-expired-api-keys.ts
363
+ function deleteAllExpiredApiKeysEndpoint({ deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
364
+ return createAuthEndpoint("/api-key/delete-all-expired-api-keys", {
365
+ method: "POST",
366
+ metadata: {
367
+ SERVER_ONLY: true,
368
+ client: false
369
+ }
370
+ }, async (ctx) => {
371
+ try {
372
+ await deleteAllExpiredApiKeys$1(ctx.context, true);
373
+ } catch (error) {
374
+ ctx.context.logger.error("[API KEY PLUGIN] Failed to delete expired API keys:", error);
375
+ return ctx.json({
376
+ success: false,
377
+ error
378
+ });
379
+ }
380
+ return ctx.json({
381
+ success: true,
382
+ error: null
383
+ });
384
+ });
385
+ }
386
+
387
+ //#endregion
388
+ //#region src/plugins/api-key/routes/delete-api-key.ts
389
+ function deleteApiKey({ opts, schema, deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
390
+ return createAuthEndpoint("/api-key/delete", {
391
+ method: "POST",
392
+ body: z$1.object({ keyId: z$1.string().meta({ description: "The id of the Api Key" }) }),
393
+ use: [sessionMiddleware],
394
+ metadata: { openapi: {
395
+ description: "Delete an existing API key",
396
+ requestBody: { content: { "application/json": { schema: {
397
+ type: "object",
398
+ properties: { keyId: {
399
+ type: "string",
400
+ description: "The id of the API key to delete"
401
+ } },
402
+ required: ["keyId"]
403
+ } } } },
404
+ responses: { "200": {
405
+ description: "API key deleted successfully",
406
+ content: { "application/json": { schema: {
407
+ type: "object",
408
+ properties: { success: {
409
+ type: "boolean",
410
+ description: "Indicates if the API key was successfully deleted"
411
+ } },
412
+ required: ["success"]
413
+ } } }
414
+ } }
415
+ } }
416
+ }, async (ctx) => {
417
+ const { keyId } = ctx.body;
418
+ const session = ctx.context.session;
419
+ if (session.user.banned === true) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.USER_BANNED });
420
+ const apiKey$1 = await ctx.context.adapter.findOne({
421
+ model: API_KEY_TABLE_NAME,
422
+ where: [{
423
+ field: "id",
424
+ value: keyId
425
+ }]
426
+ });
427
+ if (!apiKey$1 || apiKey$1.userId !== session.user.id) throw new APIError("NOT_FOUND", { message: ERROR_CODES.KEY_NOT_FOUND });
428
+ try {
429
+ await ctx.context.adapter.delete({
430
+ model: API_KEY_TABLE_NAME,
431
+ where: [{
432
+ field: "id",
433
+ value: apiKey$1.id
434
+ }]
435
+ });
436
+ } catch (error) {
437
+ throw new APIError("INTERNAL_SERVER_ERROR", { message: error?.message });
438
+ }
439
+ deleteAllExpiredApiKeys$1(ctx.context);
440
+ return ctx.json({ success: true });
441
+ });
442
+ }
443
+
444
+ //#endregion
445
+ //#region src/plugins/api-key/routes/get-api-key.ts
446
+ function getApiKey({ opts, schema, deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
447
+ return createAuthEndpoint("/api-key/get", {
448
+ method: "GET",
449
+ query: z$1.object({ id: z$1.string().meta({ description: "The id of the Api Key" }) }),
450
+ use: [sessionMiddleware],
451
+ metadata: { openapi: {
452
+ description: "Retrieve an existing API key by ID",
453
+ responses: { "200": {
454
+ description: "API key retrieved successfully",
455
+ content: { "application/json": { schema: {
456
+ type: "object",
457
+ properties: {
458
+ id: {
459
+ type: "string",
460
+ description: "ID"
461
+ },
462
+ name: {
463
+ type: "string",
464
+ nullable: true,
465
+ description: "The name of the key"
466
+ },
467
+ start: {
468
+ type: "string",
469
+ nullable: true,
470
+ description: "Shows the first few characters of the API key, including the prefix. This allows you to show those few characters in the UI to make it easier for users to identify the API key."
471
+ },
472
+ prefix: {
473
+ type: "string",
474
+ nullable: true,
475
+ description: "The API Key prefix. Stored as plain text."
476
+ },
477
+ userId: {
478
+ type: "string",
479
+ description: "The owner of the user id"
480
+ },
481
+ refillInterval: {
482
+ type: "number",
483
+ nullable: true,
484
+ description: "The interval in milliseconds between refills of the `remaining` count. Example: 3600000 // refill every hour (3600000ms = 1h)"
485
+ },
486
+ refillAmount: {
487
+ type: "number",
488
+ nullable: true,
489
+ description: "The amount to refill"
490
+ },
491
+ lastRefillAt: {
492
+ type: "string",
493
+ format: "date-time",
494
+ nullable: true,
495
+ description: "The last refill date"
496
+ },
497
+ enabled: {
498
+ type: "boolean",
499
+ description: "Sets if key is enabled or disabled",
500
+ default: true
501
+ },
502
+ rateLimitEnabled: {
503
+ type: "boolean",
504
+ description: "Whether the key has rate limiting enabled"
505
+ },
506
+ rateLimitTimeWindow: {
507
+ type: "number",
508
+ nullable: true,
509
+ description: "The duration in milliseconds"
510
+ },
511
+ rateLimitMax: {
512
+ type: "number",
513
+ nullable: true,
514
+ description: "Maximum amount of requests allowed within a window"
515
+ },
516
+ requestCount: {
517
+ type: "number",
518
+ description: "The number of requests made within the rate limit time window"
519
+ },
520
+ remaining: {
521
+ type: "number",
522
+ nullable: true,
523
+ description: "Remaining requests (every time api key is used this should updated and should be updated on refill as well)"
524
+ },
525
+ lastRequest: {
526
+ type: "string",
527
+ format: "date-time",
528
+ nullable: true,
529
+ description: "When last request occurred"
530
+ },
531
+ expiresAt: {
532
+ type: "string",
533
+ format: "date-time",
534
+ nullable: true,
535
+ description: "Expiry date of a key"
536
+ },
537
+ createdAt: {
538
+ type: "string",
539
+ format: "date-time",
540
+ description: "created at"
541
+ },
542
+ updatedAt: {
543
+ type: "string",
544
+ format: "date-time",
545
+ description: "updated at"
546
+ },
547
+ metadata: {
548
+ type: "object",
549
+ nullable: true,
550
+ additionalProperties: true,
551
+ description: "Extra metadata about the apiKey"
552
+ },
553
+ permissions: {
554
+ type: "string",
555
+ nullable: true,
556
+ description: "Permissions for the api key (stored as JSON string)"
557
+ }
558
+ },
559
+ required: [
560
+ "id",
561
+ "userId",
562
+ "enabled",
563
+ "rateLimitEnabled",
564
+ "requestCount",
565
+ "createdAt",
566
+ "updatedAt"
567
+ ]
568
+ } } }
569
+ } }
570
+ } }
571
+ }, async (ctx) => {
572
+ const { id } = ctx.query;
573
+ const session = ctx.context.session;
574
+ let apiKey$1 = await ctx.context.adapter.findOne({
575
+ model: API_KEY_TABLE_NAME,
576
+ where: [{
577
+ field: "id",
578
+ value: id
579
+ }, {
580
+ field: "userId",
581
+ value: session.user.id
582
+ }]
583
+ });
584
+ if (!apiKey$1) throw new APIError("NOT_FOUND", { message: ERROR_CODES.KEY_NOT_FOUND });
585
+ deleteAllExpiredApiKeys$1(ctx.context);
586
+ apiKey$1.metadata = schema.apikey.fields.metadata.transform.output(apiKey$1.metadata);
587
+ const { key,...returningApiKey } = apiKey$1;
588
+ return ctx.json({
589
+ ...returningApiKey,
590
+ permissions: returningApiKey.permissions ? safeJSONParse(returningApiKey.permissions) : null
591
+ });
592
+ });
593
+ }
594
+
595
+ //#endregion
596
+ //#region src/plugins/api-key/routes/list-api-keys.ts
597
+ function listApiKeys({ opts, schema, deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
598
+ return createAuthEndpoint("/api-key/list", {
599
+ method: "GET",
600
+ use: [sessionMiddleware],
601
+ metadata: { openapi: {
602
+ description: "List all API keys for the authenticated user",
603
+ responses: { "200": {
604
+ description: "API keys retrieved successfully",
605
+ content: { "application/json": { schema: {
606
+ type: "array",
607
+ items: {
608
+ type: "object",
609
+ properties: {
610
+ id: {
611
+ type: "string",
612
+ description: "ID"
613
+ },
614
+ name: {
615
+ type: "string",
616
+ nullable: true,
617
+ description: "The name of the key"
618
+ },
619
+ start: {
620
+ type: "string",
621
+ nullable: true,
622
+ description: "Shows the first few characters of the API key, including the prefix. This allows you to show those few characters in the UI to make it easier for users to identify the API key."
623
+ },
624
+ prefix: {
625
+ type: "string",
626
+ nullable: true,
627
+ description: "The API Key prefix. Stored as plain text."
628
+ },
629
+ userId: {
630
+ type: "string",
631
+ description: "The owner of the user id"
632
+ },
633
+ refillInterval: {
634
+ type: "number",
635
+ nullable: true,
636
+ description: "The interval in milliseconds between refills of the `remaining` count. Example: 3600000 // refill every hour (3600000ms = 1h)"
637
+ },
638
+ refillAmount: {
639
+ type: "number",
640
+ nullable: true,
641
+ description: "The amount to refill"
642
+ },
643
+ lastRefillAt: {
644
+ type: "string",
645
+ format: "date-time",
646
+ nullable: true,
647
+ description: "The last refill date"
648
+ },
649
+ enabled: {
650
+ type: "boolean",
651
+ description: "Sets if key is enabled or disabled",
652
+ default: true
653
+ },
654
+ rateLimitEnabled: {
655
+ type: "boolean",
656
+ description: "Whether the key has rate limiting enabled"
657
+ },
658
+ rateLimitTimeWindow: {
659
+ type: "number",
660
+ nullable: true,
661
+ description: "The duration in milliseconds"
662
+ },
663
+ rateLimitMax: {
664
+ type: "number",
665
+ nullable: true,
666
+ description: "Maximum amount of requests allowed within a window"
667
+ },
668
+ requestCount: {
669
+ type: "number",
670
+ description: "The number of requests made within the rate limit time window"
671
+ },
672
+ remaining: {
673
+ type: "number",
674
+ nullable: true,
675
+ description: "Remaining requests (every time api key is used this should updated and should be updated on refill as well)"
676
+ },
677
+ lastRequest: {
678
+ type: "string",
679
+ format: "date-time",
680
+ nullable: true,
681
+ description: "When last request occurred"
682
+ },
683
+ expiresAt: {
684
+ type: "string",
685
+ format: "date-time",
686
+ nullable: true,
687
+ description: "Expiry date of a key"
688
+ },
689
+ createdAt: {
690
+ type: "string",
691
+ format: "date-time",
692
+ description: "created at"
693
+ },
694
+ updatedAt: {
695
+ type: "string",
696
+ format: "date-time",
697
+ description: "updated at"
698
+ },
699
+ metadata: {
700
+ type: "object",
701
+ nullable: true,
702
+ additionalProperties: true,
703
+ description: "Extra metadata about the apiKey"
704
+ },
705
+ permissions: {
706
+ type: "string",
707
+ nullable: true,
708
+ description: "Permissions for the api key (stored as JSON string)"
709
+ }
710
+ },
711
+ required: [
712
+ "id",
713
+ "userId",
714
+ "enabled",
715
+ "rateLimitEnabled",
716
+ "requestCount",
717
+ "createdAt",
718
+ "updatedAt"
719
+ ]
720
+ }
721
+ } } }
722
+ } }
723
+ } }
724
+ }, async (ctx) => {
725
+ const session = ctx.context.session;
726
+ let apiKeys = await ctx.context.adapter.findMany({
727
+ model: API_KEY_TABLE_NAME,
728
+ where: [{
729
+ field: "userId",
730
+ value: session.user.id
731
+ }]
732
+ });
733
+ deleteAllExpiredApiKeys$1(ctx.context);
734
+ apiKeys = apiKeys.map((apiKey$1) => {
735
+ return {
736
+ ...apiKey$1,
737
+ metadata: schema.apikey.fields.metadata.transform.output(apiKey$1.metadata)
738
+ };
739
+ });
740
+ let returningApiKey = apiKeys.map((x) => {
741
+ const { key,...returningApiKey$1 } = x;
742
+ return {
743
+ ...returningApiKey$1,
744
+ permissions: returningApiKey$1.permissions ? safeJSONParse(returningApiKey$1.permissions) : null
745
+ };
746
+ });
747
+ return ctx.json(returningApiKey);
748
+ });
749
+ }
750
+
751
+ //#endregion
752
+ //#region src/plugins/api-key/routes/update-api-key.ts
753
+ function updateApiKey({ opts, schema, deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
754
+ return createAuthEndpoint("/api-key/update", {
755
+ method: "POST",
756
+ body: z$1.object({
757
+ keyId: z$1.string().meta({ description: "The id of the Api Key" }),
758
+ userId: z$1.coerce.string().meta({ description: "The id of the user which the api key belongs to. server-only. Eg: \"some-user-id\"" }).optional(),
759
+ name: z$1.string().meta({ description: "The name of the key" }).optional(),
760
+ enabled: z$1.boolean().meta({ description: "Whether the Api Key is enabled or not" }).optional(),
761
+ remaining: z$1.number().meta({ description: "The number of remaining requests" }).min(1).optional(),
762
+ refillAmount: z$1.number().meta({ description: "The refill amount" }).optional(),
763
+ refillInterval: z$1.number().meta({ description: "The refill interval" }).optional(),
764
+ metadata: z$1.any().optional(),
765
+ expiresIn: z$1.number().meta({ description: "Expiration time of the Api Key in seconds" }).min(1).optional().nullable(),
766
+ rateLimitEnabled: z$1.boolean().meta({ description: "Whether the key has rate limiting enabled." }).optional(),
767
+ rateLimitTimeWindow: z$1.number().meta({ description: "The duration in milliseconds where each request is counted. server-only. Eg: 1000" }).optional(),
768
+ rateLimitMax: z$1.number().meta({ description: "Maximum amount of requests allowed within a window. Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset. server-only. Eg: 100" }).optional(),
769
+ permissions: z$1.record(z$1.string(), z$1.array(z$1.string())).meta({ description: "Update the permissions on the API Key. server-only." }).optional().nullable()
770
+ }),
771
+ metadata: { openapi: {
772
+ description: "Update an existing API key by ID",
773
+ responses: { "200": {
774
+ description: "API key updated successfully",
775
+ content: { "application/json": { schema: {
776
+ type: "object",
777
+ properties: {
778
+ id: {
779
+ type: "string",
780
+ description: "ID"
781
+ },
782
+ name: {
783
+ type: "string",
784
+ nullable: true,
785
+ description: "The name of the key"
786
+ },
787
+ start: {
788
+ type: "string",
789
+ nullable: true,
790
+ description: "Shows the first few characters of the API key, including the prefix. This allows you to show those few characters in the UI to make it easier for users to identify the API key."
791
+ },
792
+ prefix: {
793
+ type: "string",
794
+ nullable: true,
795
+ description: "The API Key prefix. Stored as plain text."
796
+ },
797
+ userId: {
798
+ type: "string",
799
+ description: "The owner of the user id"
800
+ },
801
+ refillInterval: {
802
+ type: "number",
803
+ nullable: true,
804
+ description: "The interval in milliseconds between refills of the `remaining` count. Example: 3600000 // refill every hour (3600000ms = 1h)"
805
+ },
806
+ refillAmount: {
807
+ type: "number",
808
+ nullable: true,
809
+ description: "The amount to refill"
810
+ },
811
+ lastRefillAt: {
812
+ type: "string",
813
+ format: "date-time",
814
+ nullable: true,
815
+ description: "The last refill date"
816
+ },
817
+ enabled: {
818
+ type: "boolean",
819
+ description: "Sets if key is enabled or disabled",
820
+ default: true
821
+ },
822
+ rateLimitEnabled: {
823
+ type: "boolean",
824
+ description: "Whether the key has rate limiting enabled"
825
+ },
826
+ rateLimitTimeWindow: {
827
+ type: "number",
828
+ nullable: true,
829
+ description: "The duration in milliseconds"
830
+ },
831
+ rateLimitMax: {
832
+ type: "number",
833
+ nullable: true,
834
+ description: "Maximum amount of requests allowed within a window"
835
+ },
836
+ requestCount: {
837
+ type: "number",
838
+ description: "The number of requests made within the rate limit time window"
839
+ },
840
+ remaining: {
841
+ type: "number",
842
+ nullable: true,
843
+ description: "Remaining requests (every time api key is used this should updated and should be updated on refill as well)"
844
+ },
845
+ lastRequest: {
846
+ type: "string",
847
+ format: "date-time",
848
+ nullable: true,
849
+ description: "When last request occurred"
850
+ },
851
+ expiresAt: {
852
+ type: "string",
853
+ format: "date-time",
854
+ nullable: true,
855
+ description: "Expiry date of a key"
856
+ },
857
+ createdAt: {
858
+ type: "string",
859
+ format: "date-time",
860
+ description: "created at"
861
+ },
862
+ updatedAt: {
863
+ type: "string",
864
+ format: "date-time",
865
+ description: "updated at"
866
+ },
867
+ metadata: {
868
+ type: "object",
869
+ nullable: true,
870
+ additionalProperties: true,
871
+ description: "Extra metadata about the apiKey"
872
+ },
873
+ permissions: {
874
+ type: "string",
875
+ nullable: true,
876
+ description: "Permissions for the api key (stored as JSON string)"
877
+ }
878
+ },
879
+ required: [
880
+ "id",
881
+ "userId",
882
+ "enabled",
883
+ "rateLimitEnabled",
884
+ "requestCount",
885
+ "createdAt",
886
+ "updatedAt"
887
+ ]
888
+ } } }
889
+ } }
890
+ } }
891
+ }, async (ctx) => {
892
+ const { keyId, expiresIn, enabled, metadata, refillAmount, refillInterval, remaining, name, permissions, rateLimitEnabled, rateLimitTimeWindow, rateLimitMax } = ctx.body;
893
+ const session = await getSessionFromCtx(ctx);
894
+ const authRequired = ctx.request || ctx.headers;
895
+ const user = authRequired && !session ? null : session?.user || { id: ctx.body.userId };
896
+ if (!user?.id) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.UNAUTHORIZED_SESSION });
897
+ if (session && ctx.body.userId && session?.user.id !== ctx.body.userId) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.UNAUTHORIZED_SESSION });
898
+ if (authRequired) {
899
+ if (refillAmount !== void 0 || refillInterval !== void 0 || rateLimitMax !== void 0 || rateLimitTimeWindow !== void 0 || rateLimitEnabled !== void 0 || remaining !== void 0 || permissions !== void 0) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.SERVER_ONLY_PROPERTY });
900
+ }
901
+ const apiKey$1 = await ctx.context.adapter.findOne({
902
+ model: API_KEY_TABLE_NAME,
903
+ where: [{
904
+ field: "id",
905
+ value: keyId
906
+ }, {
907
+ field: "userId",
908
+ value: user.id
909
+ }]
910
+ });
911
+ if (!apiKey$1) throw new APIError("NOT_FOUND", { message: ERROR_CODES.KEY_NOT_FOUND });
912
+ let newValues = {};
913
+ if (name !== void 0) {
914
+ if (name.length < opts.minimumNameLength) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_NAME_LENGTH });
915
+ else if (name.length > opts.maximumNameLength) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_NAME_LENGTH });
916
+ newValues.name = name;
917
+ }
918
+ if (enabled !== void 0) newValues.enabled = enabled;
919
+ if (expiresIn !== void 0) {
920
+ if (opts.keyExpiration.disableCustomExpiresTime === true) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.KEY_DISABLED_EXPIRATION });
921
+ if (expiresIn !== null) {
922
+ const expiresIn_in_days = expiresIn / (3600 * 24);
923
+ if (expiresIn_in_days < opts.keyExpiration.minExpiresIn) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.EXPIRES_IN_IS_TOO_SMALL });
924
+ else if (expiresIn_in_days > opts.keyExpiration.maxExpiresIn) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.EXPIRES_IN_IS_TOO_LARGE });
925
+ }
926
+ newValues.expiresAt = expiresIn ? getDate(expiresIn, "sec") : null;
927
+ }
928
+ if (metadata !== void 0) {
929
+ if (typeof metadata !== "object") throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_METADATA_TYPE });
930
+ newValues.metadata = schema.apikey.fields.metadata.transform.input(metadata);
931
+ }
932
+ if (remaining !== void 0) newValues.remaining = remaining;
933
+ if (refillAmount !== void 0 || refillInterval !== void 0) {
934
+ if (refillAmount !== void 0 && refillInterval === void 0) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.REFILL_AMOUNT_AND_INTERVAL_REQUIRED });
935
+ else if (refillInterval !== void 0 && refillAmount === void 0) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.REFILL_INTERVAL_AND_AMOUNT_REQUIRED });
936
+ newValues.refillAmount = refillAmount;
937
+ newValues.refillInterval = refillInterval;
938
+ }
939
+ if (rateLimitEnabled !== void 0) newValues.rateLimitEnabled = rateLimitEnabled;
940
+ if (rateLimitTimeWindow !== void 0) newValues.rateLimitTimeWindow = rateLimitTimeWindow;
941
+ if (rateLimitMax !== void 0) newValues.rateLimitMax = rateLimitMax;
942
+ if (permissions !== void 0) newValues.permissions = JSON.stringify(permissions);
943
+ if (Object.keys(newValues).length === 0) throw new APIError("BAD_REQUEST", { message: ERROR_CODES.NO_VALUES_TO_UPDATE });
944
+ let newApiKey = apiKey$1;
945
+ try {
946
+ let result = await ctx.context.adapter.update({
947
+ model: API_KEY_TABLE_NAME,
948
+ where: [{
949
+ field: "id",
950
+ value: apiKey$1.id
951
+ }],
952
+ update: { ...newValues }
953
+ });
954
+ if (result) newApiKey = result;
955
+ } catch (error) {
956
+ throw new APIError("INTERNAL_SERVER_ERROR", { message: error?.message });
957
+ }
958
+ deleteAllExpiredApiKeys$1(ctx.context);
959
+ newApiKey.metadata = schema.apikey.fields.metadata.transform.output(newApiKey.metadata);
960
+ const { key,...returningApiKey } = newApiKey;
961
+ return ctx.json({
962
+ ...returningApiKey,
963
+ permissions: returningApiKey.permissions ? safeJSONParse(returningApiKey.permissions) : null
964
+ });
965
+ });
966
+ }
967
+
968
+ //#endregion
969
+ //#region src/plugins/api-key/rate-limit.ts
970
+ /**
971
+ * Determines if a request is allowed based on rate limiting parameters.
972
+ *
973
+ * @returns An object indicating whether the request is allowed and, if not,
974
+ * a message and updated ApiKey data.
975
+ */
976
+ function isRateLimited(apiKey$1, opts) {
977
+ const now = /* @__PURE__ */ new Date();
978
+ const lastRequest = apiKey$1.lastRequest;
979
+ const rateLimitTimeWindow = apiKey$1.rateLimitTimeWindow;
980
+ const rateLimitMax = apiKey$1.rateLimitMax;
981
+ let requestCount = apiKey$1.requestCount;
982
+ if (opts.rateLimit.enabled === false) return {
983
+ success: true,
984
+ message: null,
985
+ update: { lastRequest: now },
986
+ tryAgainIn: null
987
+ };
988
+ if (apiKey$1.rateLimitEnabled === false) return {
989
+ success: true,
990
+ message: null,
991
+ update: { lastRequest: now },
992
+ tryAgainIn: null
993
+ };
994
+ if (rateLimitTimeWindow === null || rateLimitMax === null) return {
995
+ success: true,
996
+ message: null,
997
+ update: null,
998
+ tryAgainIn: null
999
+ };
1000
+ if (lastRequest === null) return {
1001
+ success: true,
1002
+ message: null,
1003
+ update: {
1004
+ lastRequest: now,
1005
+ requestCount: 1
1006
+ },
1007
+ tryAgainIn: null
1008
+ };
1009
+ const timeSinceLastRequest = now.getTime() - new Date(lastRequest).getTime();
1010
+ if (timeSinceLastRequest > rateLimitTimeWindow) return {
1011
+ success: true,
1012
+ message: null,
1013
+ update: {
1014
+ lastRequest: now,
1015
+ requestCount: 1
1016
+ },
1017
+ tryAgainIn: null
1018
+ };
1019
+ if (requestCount >= rateLimitMax) return {
1020
+ success: false,
1021
+ message: ERROR_CODES.RATE_LIMIT_EXCEEDED,
1022
+ update: null,
1023
+ tryAgainIn: Math.ceil(rateLimitTimeWindow - timeSinceLastRequest)
1024
+ };
1025
+ requestCount++;
1026
+ return {
1027
+ success: true,
1028
+ message: null,
1029
+ tryAgainIn: null,
1030
+ update: {
1031
+ lastRequest: now,
1032
+ requestCount
1033
+ }
1034
+ };
1035
+ }
1036
+
1037
+ //#endregion
1038
+ //#region src/plugins/api-key/routes/verify-api-key.ts
1039
+ async function validateApiKey({ hashedKey, ctx, opts, schema, permissions }) {
1040
+ const apiKey$1 = await ctx.context.adapter.findOne({
1041
+ model: API_KEY_TABLE_NAME,
1042
+ where: [{
1043
+ field: "key",
1044
+ value: hashedKey
1045
+ }]
1046
+ });
1047
+ if (!apiKey$1) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.INVALID_API_KEY });
1048
+ if (apiKey$1.enabled === false) throw new APIError("UNAUTHORIZED", {
1049
+ message: ERROR_CODES.KEY_DISABLED,
1050
+ code: "KEY_DISABLED"
1051
+ });
1052
+ if (apiKey$1.expiresAt) {
1053
+ if ((/* @__PURE__ */ new Date()).getTime() > new Date(apiKey$1.expiresAt).getTime()) {
1054
+ try {
1055
+ ctx.context.adapter.delete({
1056
+ model: API_KEY_TABLE_NAME,
1057
+ where: [{
1058
+ field: "id",
1059
+ value: apiKey$1.id
1060
+ }]
1061
+ });
1062
+ } catch (error) {
1063
+ ctx.context.logger.error(`Failed to delete expired API keys:`, error);
1064
+ }
1065
+ throw new APIError("UNAUTHORIZED", {
1066
+ message: ERROR_CODES.KEY_EXPIRED,
1067
+ code: "KEY_EXPIRED"
1068
+ });
1069
+ }
1070
+ }
1071
+ if (permissions) {
1072
+ const apiKeyPermissions = apiKey$1.permissions ? safeJSONParse(apiKey$1.permissions) : null;
1073
+ if (!apiKeyPermissions) throw new APIError("UNAUTHORIZED", {
1074
+ message: ERROR_CODES.KEY_NOT_FOUND,
1075
+ code: "KEY_NOT_FOUND"
1076
+ });
1077
+ if (!role(apiKeyPermissions).authorize(permissions).success) throw new APIError("UNAUTHORIZED", {
1078
+ message: ERROR_CODES.KEY_NOT_FOUND,
1079
+ code: "KEY_NOT_FOUND"
1080
+ });
1081
+ }
1082
+ let remaining = apiKey$1.remaining;
1083
+ let lastRefillAt = apiKey$1.lastRefillAt;
1084
+ if (apiKey$1.remaining === 0 && apiKey$1.refillAmount === null) {
1085
+ try {
1086
+ ctx.context.adapter.delete({
1087
+ model: API_KEY_TABLE_NAME,
1088
+ where: [{
1089
+ field: "id",
1090
+ value: apiKey$1.id
1091
+ }]
1092
+ });
1093
+ } catch (error) {
1094
+ ctx.context.logger.error(`Failed to delete expired API keys:`, error);
1095
+ }
1096
+ throw new APIError("TOO_MANY_REQUESTS", {
1097
+ message: ERROR_CODES.USAGE_EXCEEDED,
1098
+ code: "USAGE_EXCEEDED"
1099
+ });
1100
+ } else if (remaining !== null) {
1101
+ let now = (/* @__PURE__ */ new Date()).getTime();
1102
+ const refillInterval = apiKey$1.refillInterval;
1103
+ const refillAmount = apiKey$1.refillAmount;
1104
+ let lastTime = new Date(lastRefillAt ?? apiKey$1.createdAt).getTime();
1105
+ if (refillInterval && refillAmount) {
1106
+ if (now - lastTime > refillInterval) {
1107
+ remaining = refillAmount;
1108
+ lastRefillAt = /* @__PURE__ */ new Date();
1109
+ }
1110
+ }
1111
+ if (remaining === 0) throw new APIError("TOO_MANY_REQUESTS", {
1112
+ message: ERROR_CODES.USAGE_EXCEEDED,
1113
+ code: "USAGE_EXCEEDED"
1114
+ });
1115
+ else remaining--;
1116
+ }
1117
+ const { message, success, update, tryAgainIn } = isRateLimited(apiKey$1, opts);
1118
+ const newApiKey = await ctx.context.adapter.update({
1119
+ model: API_KEY_TABLE_NAME,
1120
+ where: [{
1121
+ field: "id",
1122
+ value: apiKey$1.id
1123
+ }],
1124
+ update: {
1125
+ ...update,
1126
+ remaining,
1127
+ lastRefillAt
1128
+ }
1129
+ });
1130
+ if (!newApiKey) throw new APIError("INTERNAL_SERVER_ERROR", {
1131
+ message: ERROR_CODES.FAILED_TO_UPDATE_API_KEY,
1132
+ code: "INTERNAL_SERVER_ERROR"
1133
+ });
1134
+ if (success === false) throw new APIError("UNAUTHORIZED", {
1135
+ message: message ?? void 0,
1136
+ code: "RATE_LIMITED",
1137
+ details: { tryAgainIn }
1138
+ });
1139
+ return newApiKey;
1140
+ }
1141
+ function verifyApiKey({ opts, schema, deleteAllExpiredApiKeys: deleteAllExpiredApiKeys$1 }) {
1142
+ return createAuthEndpoint("/api-key/verify", {
1143
+ method: "POST",
1144
+ body: z$1.object({
1145
+ key: z$1.string().meta({ description: "The key to verify" }),
1146
+ permissions: z$1.record(z$1.string(), z$1.array(z$1.string())).meta({ description: "The permissions to verify." }).optional()
1147
+ }),
1148
+ metadata: { SERVER_ONLY: true }
1149
+ }, async (ctx) => {
1150
+ const { key } = ctx.body;
1151
+ if (key.length < opts.defaultKeyLength) return ctx.json({
1152
+ valid: false,
1153
+ error: {
1154
+ message: ERROR_CODES.INVALID_API_KEY,
1155
+ code: "KEY_NOT_FOUND"
1156
+ },
1157
+ key: null
1158
+ });
1159
+ if (opts.customAPIKeyValidator) {
1160
+ if (!await opts.customAPIKeyValidator({
1161
+ ctx,
1162
+ key
1163
+ })) return ctx.json({
1164
+ valid: false,
1165
+ error: {
1166
+ message: ERROR_CODES.INVALID_API_KEY,
1167
+ code: "KEY_NOT_FOUND"
1168
+ },
1169
+ key: null
1170
+ });
1171
+ }
1172
+ const hashed = opts.disableKeyHashing ? key : await defaultKeyHasher(key);
1173
+ let apiKey$1 = null;
1174
+ try {
1175
+ apiKey$1 = await validateApiKey({
1176
+ hashedKey: hashed,
1177
+ permissions: ctx.body.permissions,
1178
+ ctx,
1179
+ opts,
1180
+ schema
1181
+ });
1182
+ await deleteAllExpiredApiKeys$1(ctx.context);
1183
+ } catch (error) {
1184
+ if (error instanceof APIError) return ctx.json({
1185
+ valid: false,
1186
+ error: {
1187
+ message: error.body?.message,
1188
+ code: error.body?.code
1189
+ },
1190
+ key: null
1191
+ });
1192
+ return ctx.json({
1193
+ valid: false,
1194
+ error: {
1195
+ message: ERROR_CODES.INVALID_API_KEY,
1196
+ code: "INVALID_API_KEY"
1197
+ },
1198
+ key: null
1199
+ });
1200
+ }
1201
+ const { key: _,...returningApiKey } = apiKey$1 ?? {
1202
+ key: 1,
1203
+ permissions: void 0
1204
+ };
1205
+ if ("metadata" in returningApiKey) returningApiKey.metadata = schema.apikey.fields.metadata.transform.output(returningApiKey.metadata);
1206
+ returningApiKey.permissions = returningApiKey.permissions ? safeJSONParse(returningApiKey.permissions) : null;
1207
+ return ctx.json({
1208
+ valid: true,
1209
+ error: null,
1210
+ key: apiKey$1 === null ? null : returningApiKey
1211
+ });
1212
+ });
1213
+ }
1214
+
1215
+ //#endregion
1216
+ //#region src/plugins/api-key/routes/index.ts
1217
+ let lastChecked = null;
1218
+ async function deleteAllExpiredApiKeys(ctx, byPassLastCheckTime = false) {
1219
+ if (lastChecked && !byPassLastCheckTime) {
1220
+ if ((/* @__PURE__ */ new Date()).getTime() - lastChecked.getTime() < 1e4) return;
1221
+ }
1222
+ lastChecked = /* @__PURE__ */ new Date();
1223
+ await ctx.adapter.deleteMany({
1224
+ model: API_KEY_TABLE_NAME,
1225
+ where: [{
1226
+ field: "expiresAt",
1227
+ operator: "lt",
1228
+ value: /* @__PURE__ */ new Date()
1229
+ }, {
1230
+ field: "expiresAt",
1231
+ operator: "ne",
1232
+ value: null
1233
+ }]
1234
+ }).catch((error) => {
1235
+ ctx.logger.error(`Failed to delete expired API keys:`, error);
1236
+ });
1237
+ }
1238
+ function createApiKeyRoutes({ keyGenerator, opts, schema }) {
1239
+ return {
1240
+ createApiKey: createApiKey({
1241
+ keyGenerator,
1242
+ opts,
1243
+ schema,
1244
+ deleteAllExpiredApiKeys
1245
+ }),
1246
+ verifyApiKey: verifyApiKey({
1247
+ opts,
1248
+ schema,
1249
+ deleteAllExpiredApiKeys
1250
+ }),
1251
+ getApiKey: getApiKey({
1252
+ opts,
1253
+ schema,
1254
+ deleteAllExpiredApiKeys
1255
+ }),
1256
+ updateApiKey: updateApiKey({
1257
+ opts,
1258
+ schema,
1259
+ deleteAllExpiredApiKeys
1260
+ }),
1261
+ deleteApiKey: deleteApiKey({
1262
+ opts,
1263
+ schema,
1264
+ deleteAllExpiredApiKeys
1265
+ }),
1266
+ listApiKeys: listApiKeys({
1267
+ opts,
1268
+ schema,
1269
+ deleteAllExpiredApiKeys
1270
+ }),
1271
+ deleteAllExpiredApiKeys: deleteAllExpiredApiKeysEndpoint({ deleteAllExpiredApiKeys })
1272
+ };
1273
+ }
1274
+
1275
+ //#endregion
1276
+ //#region src/plugins/api-key/index.ts
1277
+ const defaultKeyHasher = async (key) => {
1278
+ const hash = await createHash("SHA-256", "none").digest(new TextEncoder().encode(key));
1279
+ return base64Url.encode(new Uint8Array(hash), { padding: false });
1280
+ };
1281
+ const ERROR_CODES = defineErrorCodes({
1282
+ INVALID_METADATA_TYPE: "metadata must be an object or undefined",
1283
+ REFILL_AMOUNT_AND_INTERVAL_REQUIRED: "refillAmount is required when refillInterval is provided",
1284
+ REFILL_INTERVAL_AND_AMOUNT_REQUIRED: "refillInterval is required when refillAmount is provided",
1285
+ USER_BANNED: "User is banned",
1286
+ UNAUTHORIZED_SESSION: "Unauthorized or invalid session",
1287
+ KEY_NOT_FOUND: "API Key not found",
1288
+ KEY_DISABLED: "API Key is disabled",
1289
+ KEY_EXPIRED: "API Key has expired",
1290
+ USAGE_EXCEEDED: "API Key has reached its usage limit",
1291
+ KEY_NOT_RECOVERABLE: "API Key is not recoverable",
1292
+ EXPIRES_IN_IS_TOO_SMALL: "The expiresIn is smaller than the predefined minimum value.",
1293
+ EXPIRES_IN_IS_TOO_LARGE: "The expiresIn is larger than the predefined maximum value.",
1294
+ INVALID_REMAINING: "The remaining count is either too large or too small.",
1295
+ INVALID_PREFIX_LENGTH: "The prefix length is either too large or too small.",
1296
+ INVALID_NAME_LENGTH: "The name length is either too large or too small.",
1297
+ METADATA_DISABLED: "Metadata is disabled.",
1298
+ RATE_LIMIT_EXCEEDED: "Rate limit exceeded.",
1299
+ NO_VALUES_TO_UPDATE: "No values to update.",
1300
+ KEY_DISABLED_EXPIRATION: "Custom key expiration values are disabled.",
1301
+ INVALID_API_KEY: "Invalid API key.",
1302
+ INVALID_USER_ID_FROM_API_KEY: "The user id from the API key is invalid.",
1303
+ INVALID_API_KEY_GETTER_RETURN_TYPE: "API Key getter returned an invalid key type. Expected string.",
1304
+ SERVER_ONLY_PROPERTY: "The property you're trying to set can only be set from the server auth instance only.",
1305
+ FAILED_TO_UPDATE_API_KEY: "Failed to update API key",
1306
+ NAME_REQUIRED: "API Key name is required."
1307
+ });
1308
+ const API_KEY_TABLE_NAME = "apikey";
1309
+ const apiKey = (options) => {
1310
+ const opts = {
1311
+ ...options,
1312
+ apiKeyHeaders: options?.apiKeyHeaders ?? "x-api-key",
1313
+ defaultKeyLength: options?.defaultKeyLength || 64,
1314
+ maximumPrefixLength: options?.maximumPrefixLength ?? 32,
1315
+ minimumPrefixLength: options?.minimumPrefixLength ?? 1,
1316
+ maximumNameLength: options?.maximumNameLength ?? 32,
1317
+ minimumNameLength: options?.minimumNameLength ?? 1,
1318
+ enableMetadata: options?.enableMetadata ?? false,
1319
+ disableKeyHashing: options?.disableKeyHashing ?? false,
1320
+ requireName: options?.requireName ?? false,
1321
+ rateLimit: {
1322
+ enabled: options?.rateLimit?.enabled === void 0 ? true : options?.rateLimit?.enabled,
1323
+ timeWindow: options?.rateLimit?.timeWindow ?? 1e3 * 60 * 60 * 24,
1324
+ maxRequests: options?.rateLimit?.maxRequests ?? 10
1325
+ },
1326
+ keyExpiration: {
1327
+ defaultExpiresIn: options?.keyExpiration?.defaultExpiresIn ?? null,
1328
+ disableCustomExpiresTime: options?.keyExpiration?.disableCustomExpiresTime ?? false,
1329
+ maxExpiresIn: options?.keyExpiration?.maxExpiresIn ?? 365,
1330
+ minExpiresIn: options?.keyExpiration?.minExpiresIn ?? 1
1331
+ },
1332
+ startingCharactersConfig: {
1333
+ shouldStore: options?.startingCharactersConfig?.shouldStore ?? true,
1334
+ charactersLength: options?.startingCharactersConfig?.charactersLength ?? 6
1335
+ },
1336
+ enableSessionForAPIKeys: options?.enableSessionForAPIKeys ?? false
1337
+ };
1338
+ const schema = mergeSchema(apiKeySchema({
1339
+ rateLimitMax: opts.rateLimit.maxRequests,
1340
+ timeWindow: opts.rateLimit.timeWindow
1341
+ }), opts.schema);
1342
+ const getter = opts.customAPIKeyGetter || ((ctx) => {
1343
+ if (Array.isArray(opts.apiKeyHeaders)) for (const header of opts.apiKeyHeaders) {
1344
+ const value = ctx.headers?.get(header);
1345
+ if (value) return value;
1346
+ }
1347
+ else return ctx.headers?.get(opts.apiKeyHeaders);
1348
+ });
1349
+ const routes = createApiKeyRoutes({
1350
+ keyGenerator: opts.customKeyGenerator || (async (options$1) => {
1351
+ const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1352
+ let apiKey$1 = `${options$1.prefix || ""}`;
1353
+ for (let i = 0; i < options$1.length; i++) {
1354
+ const randomIndex = Math.floor(Math.random() * 52);
1355
+ apiKey$1 += characters[randomIndex];
1356
+ }
1357
+ return apiKey$1;
1358
+ }),
1359
+ opts,
1360
+ schema
1361
+ });
1362
+ return {
1363
+ id: "api-key",
1364
+ $ERROR_CODES: ERROR_CODES,
1365
+ hooks: { before: [{
1366
+ matcher: (ctx) => !!getter(ctx) && opts.enableSessionForAPIKeys,
1367
+ handler: createAuthMiddleware(async (ctx) => {
1368
+ const key = getter(ctx);
1369
+ if (typeof key !== "string") throw new APIError("BAD_REQUEST", { message: ERROR_CODES.INVALID_API_KEY_GETTER_RETURN_TYPE });
1370
+ if (key.length < opts.defaultKeyLength) throw new APIError("FORBIDDEN", { message: ERROR_CODES.INVALID_API_KEY });
1371
+ if (opts.customAPIKeyValidator) {
1372
+ if (!await opts.customAPIKeyValidator({
1373
+ ctx,
1374
+ key
1375
+ })) throw new APIError("FORBIDDEN", { message: ERROR_CODES.INVALID_API_KEY });
1376
+ }
1377
+ const apiKey$1 = await validateApiKey({
1378
+ hashedKey: opts.disableKeyHashing ? key : await defaultKeyHasher(key),
1379
+ ctx,
1380
+ opts,
1381
+ schema
1382
+ });
1383
+ deleteAllExpiredApiKeys(ctx.context).catch((err) => {
1384
+ ctx.context.logger.error("Failed to delete expired API keys:", err);
1385
+ });
1386
+ const user = await ctx.context.internalAdapter.findUserById(apiKey$1.userId);
1387
+ if (!user) throw new APIError("UNAUTHORIZED", { message: ERROR_CODES.INVALID_USER_ID_FROM_API_KEY });
1388
+ const session = {
1389
+ user,
1390
+ session: {
1391
+ id: apiKey$1.id,
1392
+ token: key,
1393
+ userId: apiKey$1.userId,
1394
+ userAgent: ctx.request?.headers.get("user-agent") ?? null,
1395
+ ipAddress: ctx.request ? getIp(ctx.request, ctx.context.options) : null,
1396
+ createdAt: /* @__PURE__ */ new Date(),
1397
+ updatedAt: /* @__PURE__ */ new Date(),
1398
+ expiresAt: apiKey$1.expiresAt || getDate(ctx.context.options.session?.expiresIn || 3600 * 24 * 7, "ms")
1399
+ }
1400
+ };
1401
+ ctx.context.session = session;
1402
+ if (ctx.path === "/get-session") return session;
1403
+ else return { context: ctx };
1404
+ })
1405
+ }] },
1406
+ endpoints: {
1407
+ createApiKey: routes.createApiKey,
1408
+ verifyApiKey: routes.verifyApiKey,
1409
+ getApiKey: routes.getApiKey,
1410
+ updateApiKey: routes.updateApiKey,
1411
+ deleteApiKey: routes.deleteApiKey,
1412
+ listApiKeys: routes.listApiKeys,
1413
+ deleteAllExpiredApiKeys: routes.deleteAllExpiredApiKeys
1414
+ },
1415
+ schema
1416
+ };
1417
+ };
1418
+
1419
+ //#endregion
1420
+ //#region src/plugins/last-login-method/index.ts
1421
+ /**
1422
+ * Plugin to track the last used login method
1423
+ */
1424
+ const lastLoginMethod = (userConfig) => {
1425
+ const paths = [
1426
+ "/callback/:id",
1427
+ "/oauth2/callback/:id",
1428
+ "/sign-in/email",
1429
+ "/sign-up/email"
1430
+ ];
1431
+ const defaultResolveMethod = (ctx) => {
1432
+ if (paths.includes(ctx.path)) return ctx.params?.id ? ctx.params.id : ctx.path.split("/").pop();
1433
+ return null;
1434
+ };
1435
+ const config = {
1436
+ cookieName: "payvo-auth.last_used_login_method",
1437
+ maxAge: 3600 * 24 * 30,
1438
+ ...userConfig
1439
+ };
1440
+ return {
1441
+ id: "last-login-method",
1442
+ init(ctx) {
1443
+ return { options: { databaseHooks: {
1444
+ user: { create: { async before(user, context) {
1445
+ if (!config.storeInDatabase) return;
1446
+ if (!context) return;
1447
+ const lastUsedLoginMethod = config.customResolveMethod?.(context) ?? defaultResolveMethod(context);
1448
+ if (lastUsedLoginMethod) return { data: {
1449
+ ...user,
1450
+ lastLoginMethod: lastUsedLoginMethod
1451
+ } };
1452
+ } } },
1453
+ session: { create: { async after(session, context) {
1454
+ if (!config.storeInDatabase) return;
1455
+ if (!context) return;
1456
+ const lastUsedLoginMethod = config.customResolveMethod?.(context) ?? defaultResolveMethod(context);
1457
+ if (lastUsedLoginMethod && session?.userId) try {
1458
+ await ctx.internalAdapter.updateUser(session.userId, { lastLoginMethod: lastUsedLoginMethod });
1459
+ } catch (error) {
1460
+ ctx.logger.error("Failed to update lastLoginMethod", error);
1461
+ }
1462
+ } } }
1463
+ } } };
1464
+ },
1465
+ hooks: { after: [{
1466
+ matcher() {
1467
+ return true;
1468
+ },
1469
+ handler: createAuthMiddleware(async (ctx) => {
1470
+ const lastUsedLoginMethod = config.customResolveMethod?.(ctx) ?? defaultResolveMethod(ctx);
1471
+ if (lastUsedLoginMethod) {
1472
+ const setCookie = ctx.context.responseHeaders?.get("set-cookie");
1473
+ const sessionTokenName = ctx.context.authCookies.sessionToken.name;
1474
+ if (setCookie && setCookie.includes(sessionTokenName)) {
1475
+ const cookieAttributes = {
1476
+ ...ctx.context.authCookies.sessionToken.options,
1477
+ maxAge: config.maxAge,
1478
+ httpOnly: false
1479
+ };
1480
+ ctx.setCookie(config.cookieName, lastUsedLoginMethod, cookieAttributes);
1481
+ }
1482
+ }
1483
+ })
1484
+ }] },
1485
+ schema: config.storeInDatabase ? { user: { fields: { lastLoginMethod: {
1486
+ type: "string",
1487
+ input: false,
1488
+ required: false,
1489
+ fieldName: config.schema?.user?.lastLoginMethod || "lastLoginMethod"
1490
+ } } } } : void 0
1491
+ };
1492
+ };
1493
+
1494
+ //#endregion
1495
+ //#region src/plugins/one-time-token/index.ts
1496
+ const oneTimeToken = (options) => {
1497
+ const opts = {
1498
+ storeToken: "plain",
1499
+ ...options
1500
+ };
1501
+ async function storeToken(ctx, token) {
1502
+ if (opts.storeToken === "hashed") return await defaultKeyHasher(token);
1503
+ if (typeof opts.storeToken === "object" && "type" in opts.storeToken && opts.storeToken.type === "custom-hasher") return await opts.storeToken.hash(token);
1504
+ return token;
1505
+ }
1506
+ return {
1507
+ id: "one-time-token",
1508
+ endpoints: {
1509
+ generateOneTimeToken: createAuthEndpoint("/one-time-token/generate", {
1510
+ method: "GET",
1511
+ use: [sessionMiddleware]
1512
+ }, async (c) => {
1513
+ if (opts?.disableClientRequest && c.request) throw c.error("BAD_REQUEST", { message: "Client requests are disabled" });
1514
+ const session = c.context.session;
1515
+ const token = opts?.generateToken ? await opts.generateToken(session, c) : generateRandomString(32);
1516
+ const expiresAt = new Date(Date.now() + (opts?.expiresIn ?? 3) * 60 * 1e3);
1517
+ const storedToken = await storeToken(c, token);
1518
+ await c.context.internalAdapter.createVerificationValue({
1519
+ value: session.session.token,
1520
+ identifier: `one-time-token:${storedToken}`,
1521
+ expiresAt
1522
+ });
1523
+ return c.json({ token });
1524
+ }),
1525
+ verifyOneTimeToken: createAuthEndpoint("/one-time-token/verify", {
1526
+ method: "POST",
1527
+ body: z$1.object({ token: z$1.string().meta({ description: "The token to verify. Eg: \"some-token\"" }) })
1528
+ }, async (c) => {
1529
+ const { token } = c.body;
1530
+ const storedToken = await storeToken(c, token);
1531
+ const verificationValue = await c.context.internalAdapter.findVerificationValue(`one-time-token:${storedToken}`);
1532
+ if (!verificationValue) throw c.error("BAD_REQUEST", { message: "Invalid token" });
1533
+ await c.context.internalAdapter.deleteVerificationValue(verificationValue.id);
1534
+ if (verificationValue.expiresAt < /* @__PURE__ */ new Date()) throw c.error("BAD_REQUEST", { message: "Token expired" });
1535
+ const session = await c.context.internalAdapter.findSession(verificationValue.value);
1536
+ if (!session) throw c.error("BAD_REQUEST", { message: "Session not found" });
1537
+ return c.json(session);
1538
+ })
1539
+ }
1540
+ };
1541
+ };
1542
+
1543
+ //#endregion
1544
+ export { lastLoginMethod as a, apiKey as c, oneTimeToken as i, defaultKeyHasher as l, createAuthMiddleware$1 as n, API_KEY_TABLE_NAME as o, optionsMiddleware as r, ERROR_CODES as s, createAuthEndpoint$1 as t };