@masheev/better-auth 0.0.0-stage → 1.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +31 -2
  3. package/TYPE-PATCH-NOTICE.md +9 -0
  4. package/TYPE-PATCH-PROVENANCE.json +267 -0
  5. package/dist/_virtual/_rolldown/runtime.mjs +27 -0
  6. package/dist/adapters/drizzle-adapter/index.d.mts +1 -0
  7. package/dist/adapters/drizzle-adapter/index.mjs +2 -0
  8. package/dist/adapters/index.d.mts +26 -0
  9. package/dist/adapters/index.mjs +9 -0
  10. package/dist/adapters/kysely-adapter/index.d.mts +1 -0
  11. package/dist/adapters/kysely-adapter/index.mjs +2 -0
  12. package/dist/adapters/memory-adapter/index.d.mts +1 -0
  13. package/dist/adapters/memory-adapter/index.mjs +2 -0
  14. package/dist/adapters/mongodb-adapter/index.d.mts +1 -0
  15. package/dist/adapters/mongodb-adapter/index.mjs +2 -0
  16. package/dist/adapters/prisma-adapter/index.d.mts +1 -0
  17. package/dist/adapters/prisma-adapter/index.mjs +2 -0
  18. package/dist/api/dispatch.d.mts +34 -0
  19. package/dist/api/dispatch.mjs +275 -0
  20. package/dist/api/index.d.mts +4053 -0
  21. package/dist/api/index.mjs +220 -0
  22. package/dist/api/middlewares/authorization.d.mts +69 -0
  23. package/dist/api/middlewares/authorization.mjs +78 -0
  24. package/dist/api/middlewares/index.d.mts +2 -0
  25. package/dist/api/middlewares/origin-check.d.mts +17 -0
  26. package/dist/api/middlewares/origin-check.mjs +155 -0
  27. package/dist/api/rate-limiter/index.mjs +318 -0
  28. package/dist/api/routes/account.d.mts +413 -0
  29. package/dist/api/routes/account.mjs +619 -0
  30. package/dist/api/routes/callback.d.mts +32 -0
  31. package/dist/api/routes/callback.mjs +261 -0
  32. package/dist/api/routes/email-verification.d.mts +160 -0
  33. package/dist/api/routes/email-verification.mjs +324 -0
  34. package/dist/api/routes/error.d.mts +27 -0
  35. package/dist/api/routes/error.mjs +387 -0
  36. package/dist/api/routes/index.d.mts +12 -0
  37. package/dist/api/routes/ok.d.mts +35 -0
  38. package/dist/api/routes/ok.mjs +27 -0
  39. package/dist/api/routes/password.d.mts +182 -0
  40. package/dist/api/routes/password.mjs +206 -0
  41. package/dist/api/routes/session.d.mts +450 -0
  42. package/dist/api/routes/session.mjs +481 -0
  43. package/dist/api/routes/sign-in.d.mts +186 -0
  44. package/dist/api/routes/sign-in.mjs +368 -0
  45. package/dist/api/routes/sign-out.d.mts +51 -0
  46. package/dist/api/routes/sign-out.mjs +96 -0
  47. package/dist/api/routes/sign-up.d.mts +159 -0
  48. package/dist/api/routes/sign-up.mjs +275 -0
  49. package/dist/api/routes/update-session.d.mts +74 -0
  50. package/dist/api/routes/update-session.mjs +57 -0
  51. package/dist/api/routes/update-user.d.mts +428 -0
  52. package/dist/api/routes/update-user.mjs +522 -0
  53. package/dist/api/state/oauth.d.mts +53 -0
  54. package/dist/api/state/oauth.mjs +38 -0
  55. package/dist/api/state/should-session-refresh.d.mts +12 -0
  56. package/dist/api/state/should-session-refresh.mjs +13 -0
  57. package/dist/api/to-auth-endpoints.mjs +60 -0
  58. package/dist/auth/base.mjs +66 -0
  59. package/dist/auth/full.d.mts +28 -0
  60. package/dist/auth/full.mjs +29 -0
  61. package/dist/auth/minimal.d.mts +10 -0
  62. package/dist/auth/minimal.mjs +11 -0
  63. package/dist/auth/trusted-origins.mjs +106 -0
  64. package/dist/client/broadcast-channel.d.mts +19 -0
  65. package/dist/client/broadcast-channel.mjs +44 -0
  66. package/dist/client/config.d.mts +90 -0
  67. package/dist/client/config.mjs +113 -0
  68. package/dist/client/equality.d.mts +19 -0
  69. package/dist/client/equality.mjs +42 -0
  70. package/dist/client/fetch-plugins.mjs +17 -0
  71. package/dist/client/focus-manager.d.mts +10 -0
  72. package/dist/client/focus-manager.mjs +30 -0
  73. package/dist/client/index.d.mts +35 -0
  74. package/dist/client/index.mjs +22 -0
  75. package/dist/client/lynx/index.d.mts +43 -0
  76. package/dist/client/lynx/index.mjs +22 -0
  77. package/dist/client/lynx/lynx-store.d.mts +46 -0
  78. package/dist/client/lynx/lynx-store.mjs +44 -0
  79. package/dist/client/online-manager.d.mts +11 -0
  80. package/dist/client/online-manager.mjs +33 -0
  81. package/dist/client/parser.d.mts +10 -0
  82. package/dist/client/parser.mjs +70 -0
  83. package/dist/client/path-to-object.d.mts +113 -0
  84. package/dist/client/plugins/index.d.mts +44 -0
  85. package/dist/client/plugins/index.mjs +30 -0
  86. package/dist/client/plugins/infer-plugin.d.mts +16 -0
  87. package/dist/client/plugins/infer-plugin.mjs +11 -0
  88. package/dist/client/proxy.mjs +78 -0
  89. package/dist/client/query.d.mts +23 -0
  90. package/dist/client/query.mjs +124 -0
  91. package/dist/client/react/index.d.mts +44 -0
  92. package/dist/client/react/index.mjs +22 -0
  93. package/dist/client/react/react-store.d.mts +46 -0
  94. package/dist/client/react/react-store.mjs +44 -0
  95. package/dist/client/session-atom.d.mts +11 -0
  96. package/dist/client/session-atom.mjs +178 -0
  97. package/dist/client/session-refresh.d.mts +20 -0
  98. package/dist/client/session-refresh.mjs +131 -0
  99. package/dist/client/solid/index.d.mts +44 -0
  100. package/dist/client/solid/index.mjs +22 -0
  101. package/dist/client/solid/solid-store.mjs +21 -0
  102. package/dist/client/svelte/index.d.mts +44 -0
  103. package/dist/client/svelte/index.mjs +18 -0
  104. package/dist/client/types.d.mts +51 -0
  105. package/dist/client/vanilla.d.mts +42 -0
  106. package/dist/client/vanilla.mjs +18 -0
  107. package/dist/client/vue/index.d.mts +67 -0
  108. package/dist/client/vue/index.mjs +54 -0
  109. package/dist/client/vue/vue-store.mjs +23 -0
  110. package/dist/context/create-context.mjs +235 -0
  111. package/dist/context/helpers.mjs +158 -0
  112. package/dist/context/init-minimal.mjs +17 -0
  113. package/dist/context/init.mjs +19 -0
  114. package/dist/context/secret-utils.mjs +53 -0
  115. package/dist/context/store-capabilities.mjs +12 -0
  116. package/dist/cookies/cache.mjs +33 -0
  117. package/dist/cookies/cookie-utils.d.mts +72 -0
  118. package/dist/cookies/cookie-utils.mjs +203 -0
  119. package/dist/cookies/index.d.mts +124 -0
  120. package/dist/cookies/index.mjs +350 -0
  121. package/dist/cookies/jwt.mjs +44 -0
  122. package/dist/cookies/session-store.d.mts +32 -0
  123. package/dist/cookies/session-store.mjs +183 -0
  124. package/dist/crypto/buffer.d.mts +7 -0
  125. package/dist/crypto/buffer.mjs +16 -0
  126. package/dist/crypto/index.d.mts +32 -0
  127. package/dist/crypto/index.mjs +69 -0
  128. package/dist/crypto/jwt.d.mts +9 -0
  129. package/dist/crypto/jwt.mjs +141 -0
  130. package/dist/crypto/password.d.mts +13 -0
  131. package/dist/crypto/password.mjs +14 -0
  132. package/dist/crypto/random.d.mts +4 -0
  133. package/dist/crypto/random.mjs +5 -0
  134. package/dist/db/adapter-base.d.mts +7 -0
  135. package/dist/db/adapter-base.mjs +25 -0
  136. package/dist/db/adapter-kysely.d.mts +7 -0
  137. package/dist/db/adapter-kysely.mjs +17 -0
  138. package/dist/db/field-converter.d.mts +7 -0
  139. package/dist/db/field-converter.mjs +19 -0
  140. package/dist/db/field.d.mts +41 -0
  141. package/dist/db/get-migration.d.mts +56 -0
  142. package/dist/db/get-migration.mjs +685 -0
  143. package/dist/db/get-schema.d.mts +13 -0
  144. package/dist/db/get-schema.mjs +39 -0
  145. package/dist/db/index.d.mts +10 -0
  146. package/dist/db/index.mjs +35 -0
  147. package/dist/db/internal-adapter.d.mts +14 -0
  148. package/dist/db/internal-adapter.mjs +951 -0
  149. package/dist/db/revoke-unproven-account-access.d.mts +21 -0
  150. package/dist/db/revoke-unproven-account-access.mjs +58 -0
  151. package/dist/db/schema.d.mts +62 -0
  152. package/dist/db/schema.mjs +161 -0
  153. package/dist/db/to-zod.d.mts +35 -0
  154. package/dist/db/to-zod.mjs +23 -0
  155. package/dist/db/verification-token-storage.mjs +25 -0
  156. package/dist/db/with-hooks.d.mts +37 -0
  157. package/dist/db/with-hooks.mjs +255 -0
  158. package/dist/index.d.mts +30 -0
  159. package/dist/index.mjs +17 -0
  160. package/dist/integrations/cookie-plugin-guard.mjs +18 -0
  161. package/dist/integrations/next-js.d.mts +29 -0
  162. package/dist/integrations/next-js.mjs +105 -0
  163. package/dist/integrations/node.d.mts +11 -0
  164. package/dist/integrations/node.mjs +13 -0
  165. package/dist/integrations/solid-start.d.mts +22 -0
  166. package/dist/integrations/solid-start.mjs +15 -0
  167. package/dist/integrations/svelte-kit.d.mts +38 -0
  168. package/dist/integrations/svelte-kit.mjs +57 -0
  169. package/dist/integrations/tanstack-start-solid.d.mts +33 -0
  170. package/dist/integrations/tanstack-start-solid.mjs +57 -0
  171. package/dist/integrations/tanstack-start.d.mts +33 -0
  172. package/dist/integrations/tanstack-start.mjs +57 -0
  173. package/dist/oauth2/account-key.mjs +43 -0
  174. package/dist/oauth2/errors.mjs +49 -0
  175. package/dist/oauth2/index.d.mts +5 -0
  176. package/dist/oauth2/index.mjs +5 -0
  177. package/dist/oauth2/link-account.d.mts +96 -0
  178. package/dist/oauth2/link-account.mjs +329 -0
  179. package/dist/oauth2/state.d.mts +54 -0
  180. package/dist/oauth2/state.mjs +67 -0
  181. package/dist/oauth2/utils.d.mts +11 -0
  182. package/dist/oauth2/utils.mjs +33 -0
  183. package/dist/package.mjs +4 -0
  184. package/dist/plugins/access/access.d.mts +17 -0
  185. package/dist/plugins/access/access.mjs +78 -0
  186. package/dist/plugins/access/index.d.mts +3 -0
  187. package/dist/plugins/access/index.mjs +2 -0
  188. package/dist/plugins/access/types.d.mts +24 -0
  189. package/dist/plugins/additional-fields/client.d.mts +100 -0
  190. package/dist/plugins/additional-fields/client.mjs +11 -0
  191. package/dist/plugins/admin/access/index.d.mts +2 -0
  192. package/dist/plugins/admin/access/index.mjs +2 -0
  193. package/dist/plugins/admin/access/statement.d.mts +51 -0
  194. package/dist/plugins/admin/access/statement.mjs +52 -0
  195. package/dist/plugins/admin/admin.d.mts +911 -0
  196. package/dist/plugins/admin/admin.mjs +89 -0
  197. package/dist/plugins/admin/client.d.mts +81 -0
  198. package/dist/plugins/admin/client.mjs +39 -0
  199. package/dist/plugins/admin/error-codes.d.mts +30 -0
  200. package/dist/plugins/admin/error-codes.mjs +29 -0
  201. package/dist/plugins/admin/has-permission.mjs +12 -0
  202. package/dist/plugins/admin/index.d.mts +3 -0
  203. package/dist/plugins/admin/index.mjs +2 -0
  204. package/dist/plugins/admin/routes.mjs +919 -0
  205. package/dist/plugins/admin/schema.d.mts +40 -0
  206. package/dist/plugins/admin/schema.mjs +33 -0
  207. package/dist/plugins/admin/types.d.mts +88 -0
  208. package/dist/plugins/anonymous/client.d.mts +32 -0
  209. package/dist/plugins/anonymous/client.mjs +21 -0
  210. package/dist/plugins/anonymous/error-codes.d.mts +15 -0
  211. package/dist/plugins/anonymous/error-codes.mjs +14 -0
  212. package/dist/plugins/anonymous/index.d.mts +175 -0
  213. package/dist/plugins/anonymous/index.mjs +219 -0
  214. package/dist/plugins/anonymous/schema.d.mts +15 -0
  215. package/dist/plugins/anonymous/schema.mjs +9 -0
  216. package/dist/plugins/anonymous/types.d.mts +65 -0
  217. package/dist/plugins/bearer/index.d.mts +45 -0
  218. package/dist/plugins/bearer/index.mjs +74 -0
  219. package/dist/plugins/captcha/constants.d.mts +9 -0
  220. package/dist/plugins/captcha/constants.mjs +27 -0
  221. package/dist/plugins/captcha/error-codes.mjs +13 -0
  222. package/dist/plugins/captcha/index.d.mts +27 -0
  223. package/dist/plugins/captcha/index.mjs +79 -0
  224. package/dist/plugins/captcha/types.d.mts +52 -0
  225. package/dist/plugins/captcha/utils.mjs +9 -0
  226. package/dist/plugins/captcha/verify-handlers/captchafox.mjs +27 -0
  227. package/dist/plugins/captcha/verify-handlers/cloudflare-turnstile.mjs +47 -0
  228. package/dist/plugins/captcha/verify-handlers/google-recaptcha.mjs +32 -0
  229. package/dist/plugins/captcha/verify-handlers/h-captcha.mjs +27 -0
  230. package/dist/plugins/custom-session/client.d.mts +17 -0
  231. package/dist/plugins/custom-session/client.mjs +7 -0
  232. package/dist/plugins/custom-session/index.d.mts +73 -0
  233. package/dist/plugins/custom-session/index.mjs +65 -0
  234. package/dist/plugins/device-authorization/client.d.mts +17 -0
  235. package/dist/plugins/device-authorization/client.mjs +18 -0
  236. package/dist/plugins/device-authorization/error-codes.mjs +19 -0
  237. package/dist/plugins/device-authorization/index.d.mts +558 -0
  238. package/dist/plugins/device-authorization/index.mjs +87 -0
  239. package/dist/plugins/device-authorization/routes.d.mts +32 -0
  240. package/dist/plugins/device-authorization/routes.mjs +725 -0
  241. package/dist/plugins/device-authorization/schema.d.mts +18 -0
  242. package/dist/plugins/device-authorization/schema.mjs +63 -0
  243. package/dist/plugins/email-otp/client.d.mts +21 -0
  244. package/dist/plugins/email-otp/client.mjs +17 -0
  245. package/dist/plugins/email-otp/error-codes.d.mts +10 -0
  246. package/dist/plugins/email-otp/error-codes.mjs +9 -0
  247. package/dist/plugins/email-otp/index.d.mts +551 -0
  248. package/dist/plugins/email-otp/index.mjs +145 -0
  249. package/dist/plugins/email-otp/otp-token.mjs +55 -0
  250. package/dist/plugins/email-otp/routes.mjs +784 -0
  251. package/dist/plugins/email-otp/types.d.mts +109 -0
  252. package/dist/plugins/email-otp/utils.mjs +17 -0
  253. package/dist/plugins/generic-oauth/error-codes.mjs +8 -0
  254. package/dist/plugins/generic-oauth/index.d.mts +52 -0
  255. package/dist/plugins/generic-oauth/index.mjs +279 -0
  256. package/dist/plugins/generic-oauth/providers/auth0.d.mts +36 -0
  257. package/dist/plugins/generic-oauth/providers/auth0.mjs +49 -0
  258. package/dist/plugins/generic-oauth/providers/gumroad.d.mts +31 -0
  259. package/dist/plugins/generic-oauth/providers/gumroad.mjs +62 -0
  260. package/dist/plugins/generic-oauth/providers/hubspot.d.mts +36 -0
  261. package/dist/plugins/generic-oauth/providers/hubspot.mjs +62 -0
  262. package/dist/plugins/generic-oauth/providers/index.d.mts +10 -0
  263. package/dist/plugins/generic-oauth/providers/keycloak.d.mts +36 -0
  264. package/dist/plugins/generic-oauth/providers/keycloak.mjs +47 -0
  265. package/dist/plugins/generic-oauth/providers/line.d.mts +54 -0
  266. package/dist/plugins/generic-oauth/providers/line.mjs +93 -0
  267. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.d.mts +39 -0
  268. package/dist/plugins/generic-oauth/providers/microsoft-entra-id.mjs +104 -0
  269. package/dist/plugins/generic-oauth/providers/okta.d.mts +36 -0
  270. package/dist/plugins/generic-oauth/providers/okta.mjs +47 -0
  271. package/dist/plugins/generic-oauth/providers/patreon.d.mts +29 -0
  272. package/dist/plugins/generic-oauth/providers/patreon.mjs +61 -0
  273. package/dist/plugins/generic-oauth/providers/slack.d.mts +29 -0
  274. package/dist/plugins/generic-oauth/providers/slack.mjs +63 -0
  275. package/dist/plugins/generic-oauth/providers/yandex.d.mts +29 -0
  276. package/dist/plugins/generic-oauth/providers/yandex.mjs +67 -0
  277. package/dist/plugins/generic-oauth/types.d.mts +268 -0
  278. package/dist/plugins/haveibeenpwned/index.d.mts +63 -0
  279. package/dist/plugins/haveibeenpwned/index.mjs +81 -0
  280. package/dist/plugins/index.d.mts +69 -0
  281. package/dist/plugins/index.mjs +49 -0
  282. package/dist/plugins/jwt/adapter.mjs +68 -0
  283. package/dist/plugins/jwt/client.d.mts +41 -0
  284. package/dist/plugins/jwt/client.mjs +19 -0
  285. package/dist/plugins/jwt/cookie-cache.mjs +77 -0
  286. package/dist/plugins/jwt/index.d.mts +246 -0
  287. package/dist/plugins/jwt/index.mjs +214 -0
  288. package/dist/plugins/jwt/schema.d.mts +33 -0
  289. package/dist/plugins/jwt/schema.mjs +29 -0
  290. package/dist/plugins/jwt/sign.d.mts +128 -0
  291. package/dist/plugins/jwt/sign.mjs +130 -0
  292. package/dist/plugins/jwt/types.d.mts +256 -0
  293. package/dist/plugins/jwt/utils.d.mts +41 -0
  294. package/dist/plugins/jwt/utils.mjs +64 -0
  295. package/dist/plugins/jwt/verify.d.mts +11 -0
  296. package/dist/plugins/jwt/verify.mjs +45 -0
  297. package/dist/plugins/last-login-method/client.d.mts +48 -0
  298. package/dist/plugins/last-login-method/client.mjs +48 -0
  299. package/dist/plugins/last-login-method/index.d.mts +127 -0
  300. package/dist/plugins/last-login-method/index.mjs +98 -0
  301. package/dist/plugins/magic-link/client.d.mts +10 -0
  302. package/dist/plugins/magic-link/client.mjs +11 -0
  303. package/dist/plugins/magic-link/index.d.mts +213 -0
  304. package/dist/plugins/magic-link/index.mjs +208 -0
  305. package/dist/plugins/magic-link/utils.mjs +9 -0
  306. package/dist/plugins/multi-session/client.d.mts +19 -0
  307. package/dist/plugins/multi-session/client.mjs +19 -0
  308. package/dist/plugins/multi-session/error-codes.d.mts +8 -0
  309. package/dist/plugins/multi-session/error-codes.mjs +5 -0
  310. package/dist/plugins/multi-session/index.d.mts +212 -0
  311. package/dist/plugins/multi-session/index.mjs +217 -0
  312. package/dist/plugins/oauth-popup/client.d.mts +82 -0
  313. package/dist/plugins/oauth-popup/client.mjs +203 -0
  314. package/dist/plugins/oauth-popup/constants.d.mts +11 -0
  315. package/dist/plugins/oauth-popup/constants.mjs +11 -0
  316. package/dist/plugins/oauth-popup/error-codes.d.mts +11 -0
  317. package/dist/plugins/oauth-popup/error-codes.mjs +10 -0
  318. package/dist/plugins/oauth-popup/index.d.mts +67 -0
  319. package/dist/plugins/oauth-popup/index.mjs +232 -0
  320. package/dist/plugins/oauth-popup/types.d.mts +30 -0
  321. package/dist/plugins/oauth-proxy/index.d.mts +130 -0
  322. package/dist/plugins/oauth-proxy/index.mjs +407 -0
  323. package/dist/plugins/oauth-proxy/utils.mjs +55 -0
  324. package/dist/plugins/one-tap/client.d.mts +174 -0
  325. package/dist/plugins/one-tap/client.mjs +208 -0
  326. package/dist/plugins/one-tap/index.d.mts +82 -0
  327. package/dist/plugins/one-tap/index.mjs +100 -0
  328. package/dist/plugins/one-time-token/client.d.mts +10 -0
  329. package/dist/plugins/one-time-token/client.mjs +11 -0
  330. package/dist/plugins/one-time-token/index.d.mts +132 -0
  331. package/dist/plugins/one-time-token/index.mjs +107 -0
  332. package/dist/plugins/one-time-token/utils.mjs +9 -0
  333. package/dist/plugins/open-api/generator.d.mts +126 -0
  334. package/dist/plugins/open-api/generator.mjs +557 -0
  335. package/dist/plugins/open-api/index.d.mts +97 -0
  336. package/dist/plugins/open-api/index.mjs +65 -0
  337. package/dist/plugins/open-api/logo.mjs +13 -0
  338. package/dist/plugins/organization/access/index.d.mts +2 -0
  339. package/dist/plugins/organization/access/index.mjs +2 -0
  340. package/dist/plugins/organization/access/statement.d.mts +113 -0
  341. package/dist/plugins/organization/access/statement.mjs +77 -0
  342. package/dist/plugins/organization/adapter.d.mts +815 -0
  343. package/dist/plugins/organization/adapter.mjs +813 -0
  344. package/dist/plugins/organization/call.mjs +15 -0
  345. package/dist/plugins/organization/client.d.mts +375 -0
  346. package/dist/plugins/organization/client.mjs +104 -0
  347. package/dist/plugins/organization/error-codes.d.mts +66 -0
  348. package/dist/plugins/organization/error-codes.mjs +65 -0
  349. package/dist/plugins/organization/has-permission.d.mts +17 -0
  350. package/dist/plugins/organization/has-permission.mjs +34 -0
  351. package/dist/plugins/organization/index.d.mts +6 -0
  352. package/dist/plugins/organization/index.mjs +4 -0
  353. package/dist/plugins/organization/organization.d.mts +420 -0
  354. package/dist/plugins/organization/organization.mjs +886 -0
  355. package/dist/plugins/organization/permission.d.mts +15 -0
  356. package/dist/plugins/organization/permission.mjs +14 -0
  357. package/dist/plugins/organization/routes/crud-access-control.d.mts +511 -0
  358. package/dist/plugins/organization/routes/crud-access-control.mjs +674 -0
  359. package/dist/plugins/organization/routes/crud-invites.d.mts +1154 -0
  360. package/dist/plugins/organization/routes/crud-invites.mjs +602 -0
  361. package/dist/plugins/organization/routes/crud-members.d.mts +1057 -0
  362. package/dist/plugins/organization/routes/crud-members.mjs +518 -0
  363. package/dist/plugins/organization/routes/crud-org.d.mts +918 -0
  364. package/dist/plugins/organization/routes/crud-org.mjs +455 -0
  365. package/dist/plugins/organization/routes/crud-team.d.mts +1238 -0
  366. package/dist/plugins/organization/routes/crud-team.mjs +766 -0
  367. package/dist/plugins/organization/schema.d.mts +390 -0
  368. package/dist/plugins/organization/schema.mjs +65 -0
  369. package/dist/plugins/organization/types.d.mts +691 -0
  370. package/dist/plugins/phone-number/client.d.mts +31 -0
  371. package/dist/plugins/phone-number/client.mjs +19 -0
  372. package/dist/plugins/phone-number/error-codes.d.mts +19 -0
  373. package/dist/plugins/phone-number/error-codes.mjs +18 -0
  374. package/dist/plugins/phone-number/index.d.mts +360 -0
  375. package/dist/plugins/phone-number/index.mjs +57 -0
  376. package/dist/plugins/phone-number/routes.mjs +529 -0
  377. package/dist/plugins/phone-number/schema.d.mts +22 -0
  378. package/dist/plugins/phone-number/schema.mjs +18 -0
  379. package/dist/plugins/phone-number/types.d.mts +116 -0
  380. package/dist/plugins/siwe/client.d.mts +14 -0
  381. package/dist/plugins/siwe/client.mjs +15 -0
  382. package/dist/plugins/siwe/index.d.mts +62 -0
  383. package/dist/plugins/siwe/index.mjs +272 -0
  384. package/dist/plugins/siwe/parse-message.mjs +60 -0
  385. package/dist/plugins/siwe/schema.d.mts +35 -0
  386. package/dist/plugins/siwe/schema.mjs +30 -0
  387. package/dist/plugins/siwe/types.d.mts +43 -0
  388. package/dist/plugins/test-utils/auth-helpers.mjs +33 -0
  389. package/dist/plugins/test-utils/cookie-builder.mjs +55 -0
  390. package/dist/plugins/test-utils/db-helpers.mjs +65 -0
  391. package/dist/plugins/test-utils/factories.mjs +38 -0
  392. package/dist/plugins/test-utils/index.d.mts +73 -0
  393. package/dist/plugins/test-utils/index.mjs +97 -0
  394. package/dist/plugins/test-utils/otp-sink.mjs +21 -0
  395. package/dist/plugins/test-utils/types.d.mts +51 -0
  396. package/dist/plugins/two-factor/backup-codes/index.d.mts +291 -0
  397. package/dist/plugins/two-factor/backup-codes/index.mjs +341 -0
  398. package/dist/plugins/two-factor/client.d.mts +76 -0
  399. package/dist/plugins/two-factor/client.mjs +41 -0
  400. package/dist/plugins/two-factor/constant.mjs +6 -0
  401. package/dist/plugins/two-factor/error-code.d.mts +20 -0
  402. package/dist/plugins/two-factor/error-code.mjs +19 -0
  403. package/dist/plugins/two-factor/index.d.mts +720 -0
  404. package/dist/plugins/two-factor/index.mjs +349 -0
  405. package/dist/plugins/two-factor/otp/index.d.mts +216 -0
  406. package/dist/plugins/two-factor/otp/index.mjs +252 -0
  407. package/dist/plugins/two-factor/schema.d.mts +59 -0
  408. package/dist/plugins/two-factor/schema.mjs +53 -0
  409. package/dist/plugins/two-factor/totp/index.d.mts +219 -0
  410. package/dist/plugins/two-factor/totp/index.mjs +230 -0
  411. package/dist/plugins/two-factor/types.d.mts +111 -0
  412. package/dist/plugins/two-factor/utils.mjs +9 -0
  413. package/dist/plugins/two-factor/verify-two-factor.mjs +205 -0
  414. package/dist/plugins/username/client.d.mts +38 -0
  415. package/dist/plugins/username/client.mjs +17 -0
  416. package/dist/plugins/username/error-codes.d.mts +16 -0
  417. package/dist/plugins/username/error-codes.mjs +15 -0
  418. package/dist/plugins/username/index.d.mts +326 -0
  419. package/dist/plugins/username/index.mjs +312 -0
  420. package/dist/plugins/username/schema.d.mts +50 -0
  421. package/dist/plugins/username/schema.mjs +25 -0
  422. package/dist/social-providers/index.d.mts +1 -0
  423. package/dist/social-providers/index.mjs +2 -0
  424. package/dist/state.d.mts +48 -0
  425. package/dist/state.mjs +149 -0
  426. package/dist/test-utils/headers.d.mts +8 -0
  427. package/dist/test-utils/headers.mjs +17 -0
  428. package/dist/test-utils/http-test-instance.d.mts +413 -0
  429. package/dist/test-utils/http-test-instance.mjs +107 -0
  430. package/dist/test-utils/index.d.mts +4 -0
  431. package/dist/test-utils/index.mjs +4 -0
  432. package/dist/test-utils/test-instance.d.mts +56 -0
  433. package/dist/test-utils/test-instance.mjs +242 -0
  434. package/dist/types/adapter.d.mts +2 -0
  435. package/dist/types/api.d.mts +28 -0
  436. package/dist/types/auth.d.mts +32 -0
  437. package/dist/types/helper.d.mts +26 -0
  438. package/dist/types/index.d.mts +10 -0
  439. package/dist/types/index.mjs +1 -0
  440. package/dist/types/models.d.mts +10 -0
  441. package/dist/types/plugins.d.mts +19 -0
  442. package/dist/utils/boolean.mjs +6 -0
  443. package/dist/utils/constants.mjs +4 -0
  444. package/dist/utils/date.mjs +6 -0
  445. package/dist/utils/hashing.mjs +18 -0
  446. package/dist/utils/hide-metadata.d.mts +6 -0
  447. package/dist/utils/hide-metadata.mjs +4 -0
  448. package/dist/utils/index.d.mts +4 -0
  449. package/dist/utils/is-api-error.d.mts +2 -0
  450. package/dist/utils/is-api-error.mjs +2 -0
  451. package/dist/utils/is-atom.mjs +6 -0
  452. package/dist/utils/is-promise.mjs +6 -0
  453. package/dist/utils/middleware-response.mjs +7 -0
  454. package/dist/utils/password.mjs +32 -0
  455. package/dist/utils/plugin-helper.mjs +14 -0
  456. package/dist/utils/request.mjs +23 -0
  457. package/dist/utils/shim.mjs +22 -0
  458. package/dist/utils/time.d.mts +48 -0
  459. package/dist/utils/time.mjs +98 -0
  460. package/dist/utils/url.d.mts +78 -0
  461. package/dist/utils/url.mjs +238 -0
  462. package/dist/utils/validate-user-info.mjs +44 -0
  463. package/dist/utils/wildcard.mjs +106 -0
  464. package/dist/version.mjs +5 -0
  465. package/package.json +595 -3
@@ -0,0 +1,766 @@
1
+ import { setSessionCookie } from "../../../cookies/index.mjs";
2
+ import { toZodSchema } from "../../../db/to-zod.mjs";
3
+ import { getSessionFromCtx } from "../../../api/routes/session.mjs";
4
+ import { ORGANIZATION_ERROR_CODES } from "../error-codes.mjs";
5
+ import { getOrgAdapter } from "../adapter.mjs";
6
+ import { orgMiddleware, orgSessionMiddleware } from "../call.mjs";
7
+ import { hasPermission } from "../has-permission.mjs";
8
+ import { teamSchema } from "../schema.mjs";
9
+ import { getCurrentAdapter, runWithTransaction } from "@better-auth/core/context";
10
+ import { APIError } from "@better-auth/core/error";
11
+ import { createAuthEndpoint } from "@better-auth/core/api";
12
+ import * as z from "zod";
13
+ //#region src/plugins/organization/routes/crud-team.ts
14
+ const teamBaseSchema = z.object({
15
+ name: z.string().meta({ description: "The name of the team. Eg: \"my-team\"" }),
16
+ organizationId: z.string().meta({ description: "The organization ID which the team will be created in. Defaults to the active organization. Eg: \"organization-id\"" }).optional()
17
+ });
18
+ const createTeam = (options) => {
19
+ const additionalFieldsSchema = toZodSchema({
20
+ fields: options?.schema?.team?.additionalFields ?? {},
21
+ isClientSide: true
22
+ });
23
+ return createAuthEndpoint("/organization/create-team", {
24
+ method: "POST",
25
+ body: z.object({
26
+ ...teamBaseSchema.shape,
27
+ ...additionalFieldsSchema.shape
28
+ }),
29
+ use: [orgMiddleware],
30
+ metadata: {
31
+ $Infer: { body: {} },
32
+ openapi: {
33
+ description: "Create a new team within an organization",
34
+ responses: { "200": {
35
+ description: "Team created successfully",
36
+ content: { "application/json": { schema: {
37
+ type: "object",
38
+ properties: {
39
+ id: {
40
+ type: "string",
41
+ description: "Unique identifier of the created team"
42
+ },
43
+ name: {
44
+ type: "string",
45
+ description: "Name of the team"
46
+ },
47
+ organizationId: {
48
+ type: "string",
49
+ description: "ID of the organization the team belongs to"
50
+ },
51
+ createdAt: {
52
+ type: "string",
53
+ format: "date-time",
54
+ description: "Timestamp when the team was created"
55
+ },
56
+ updatedAt: {
57
+ type: "string",
58
+ format: "date-time",
59
+ description: "Timestamp when the team was last updated"
60
+ }
61
+ },
62
+ required: [
63
+ "id",
64
+ "name",
65
+ "organizationId",
66
+ "createdAt",
67
+ "updatedAt"
68
+ ]
69
+ } } }
70
+ } }
71
+ }
72
+ }
73
+ }, async (ctx) => {
74
+ const session = await getSessionFromCtx(ctx);
75
+ const organizationId = ctx.body.organizationId || session?.session.activeOrganizationId;
76
+ if (!session && (ctx.request || ctx.headers)) throw APIError.fromStatus("UNAUTHORIZED");
77
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
78
+ const adapter = getOrgAdapter(ctx.context, options);
79
+ if (session) {
80
+ const member = await adapter.findMemberByOrgId({
81
+ userId: session.user.id,
82
+ organizationId
83
+ });
84
+ if (!member) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_INVITE_USERS_TO_THIS_ORGANIZATION);
85
+ if (!await hasPermission({
86
+ role: member.role,
87
+ options: ctx.context.orgOptions,
88
+ permissions: { team: ["create"] },
89
+ organizationId
90
+ }, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CREATE_TEAMS_IN_THIS_ORGANIZATION);
91
+ }
92
+ const existingTeams = await adapter.listTeams(organizationId);
93
+ const maximum = typeof ctx.context.orgOptions.teams?.maximumTeams === "function" ? await ctx.context.orgOptions.teams?.maximumTeams({
94
+ organizationId,
95
+ session
96
+ }, ctx) : ctx.context.orgOptions.teams?.maximumTeams;
97
+ if (maximum ? existingTeams.length >= maximum : false) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.YOU_HAVE_REACHED_THE_MAXIMUM_NUMBER_OF_TEAMS);
98
+ const { name, organizationId: _, ...additionalFields } = ctx.body;
99
+ const organization = await adapter.findOrganizationById(organizationId);
100
+ if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
101
+ let teamData = {
102
+ name,
103
+ organizationId,
104
+ createdAt: /* @__PURE__ */ new Date(),
105
+ updatedAt: /* @__PURE__ */ new Date(),
106
+ ...additionalFields
107
+ };
108
+ if (options?.organizationHooks?.beforeCreateTeam) {
109
+ const response = await options?.organizationHooks.beforeCreateTeam({
110
+ team: {
111
+ name,
112
+ organizationId,
113
+ ...additionalFields
114
+ },
115
+ user: session?.user,
116
+ organization
117
+ });
118
+ if (response && typeof response === "object" && "data" in response) teamData = {
119
+ ...teamData,
120
+ ...response.data
121
+ };
122
+ }
123
+ const createdTeam = await adapter.createTeam(teamData);
124
+ if (options?.organizationHooks?.afterCreateTeam) await options?.organizationHooks.afterCreateTeam({
125
+ team: createdTeam,
126
+ user: session?.user,
127
+ organization
128
+ });
129
+ return ctx.json(createdTeam);
130
+ });
131
+ };
132
+ const removeTeamBodySchema = z.object({
133
+ teamId: z.string().meta({ description: `The team ID of the team to remove. Eg: "team-id"` }),
134
+ organizationId: z.string().meta({ description: `The organization ID which the team falls under. If not provided, it will default to the user's active organization. Eg: "organization-id"` }).optional()
135
+ });
136
+ const removeTeam = (options) => createAuthEndpoint("/organization/remove-team", {
137
+ method: "POST",
138
+ body: removeTeamBodySchema,
139
+ use: [orgMiddleware],
140
+ metadata: { openapi: {
141
+ description: "Remove a team from an organization",
142
+ responses: { "200": {
143
+ description: "Team removed successfully",
144
+ content: { "application/json": { schema: {
145
+ type: "object",
146
+ properties: { message: {
147
+ type: "string",
148
+ description: "Confirmation message indicating successful removal",
149
+ enum: ["Team removed successfully."]
150
+ } },
151
+ required: ["message"]
152
+ } } }
153
+ } }
154
+ } }
155
+ }, async (ctx) => {
156
+ const session = await getSessionFromCtx(ctx);
157
+ const organizationId = ctx.body.organizationId || session?.session.activeOrganizationId;
158
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
159
+ if (!session && (ctx.request || ctx.headers)) throw APIError.fromStatus("UNAUTHORIZED");
160
+ const adapter = getOrgAdapter(ctx.context, options);
161
+ if (session) {
162
+ const member = await adapter.findMemberByOrgId({
163
+ userId: session.user.id,
164
+ organizationId
165
+ });
166
+ if (!member || session.session?.activeTeamId === ctx.body.teamId) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_DELETE_THIS_TEAM);
167
+ if (!await hasPermission({
168
+ role: member.role,
169
+ options: ctx.context.orgOptions,
170
+ permissions: { team: ["delete"] },
171
+ organizationId
172
+ }, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_DELETE_TEAMS_IN_THIS_ORGANIZATION);
173
+ }
174
+ const team = await adapter.findTeamById({
175
+ teamId: ctx.body.teamId,
176
+ organizationId
177
+ });
178
+ if (!team || team.organizationId !== organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
179
+ if (!ctx.context.orgOptions.teams?.allowRemovingAllTeams) {
180
+ if ((await adapter.listTeams(organizationId)).length <= 1) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.UNABLE_TO_REMOVE_LAST_TEAM);
181
+ }
182
+ const organization = await adapter.findOrganizationById(organizationId);
183
+ if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
184
+ if (options?.organizationHooks?.beforeDeleteTeam) await options?.organizationHooks.beforeDeleteTeam({
185
+ team,
186
+ user: session?.user,
187
+ organization
188
+ });
189
+ await runWithTransaction(ctx.context.adapter, async () => {
190
+ await adapter.deleteTeam(team.id);
191
+ const pendingInvitations = await adapter.findPendingInvitations({ organizationId });
192
+ const trx = await getCurrentAdapter(ctx.context.adapter);
193
+ for (const invitation of pendingInvitations) {
194
+ if (!("teamId" in invitation) || !invitation.teamId) continue;
195
+ const teamIds = invitation.teamId.split(",");
196
+ if (!teamIds.includes(team.id)) continue;
197
+ const remainingTeamIds = teamIds.filter((id) => id !== team.id);
198
+ await trx.update({
199
+ model: "invitation",
200
+ where: [{
201
+ field: "id",
202
+ value: invitation.id
203
+ }],
204
+ update: { teamId: remainingTeamIds.length > 0 ? remainingTeamIds.join(",") : null }
205
+ });
206
+ }
207
+ });
208
+ if (options?.organizationHooks?.afterDeleteTeam) await options?.organizationHooks.afterDeleteTeam({
209
+ team,
210
+ user: session?.user,
211
+ organization
212
+ });
213
+ return ctx.json({ message: "Team removed successfully." });
214
+ });
215
+ const updateTeam = (options) => {
216
+ const additionalFieldsSchema = toZodSchema({
217
+ fields: options?.schema?.team?.additionalFields ?? {},
218
+ isClientSide: true
219
+ });
220
+ return createAuthEndpoint("/organization/update-team", {
221
+ method: "POST",
222
+ body: z.object({
223
+ teamId: z.string().meta({ description: `The ID of the team to be updated. Eg: "team-id"` }),
224
+ data: z.object({
225
+ ...teamSchema.omit({
226
+ id: true,
227
+ createdAt: true,
228
+ updatedAt: true
229
+ }).shape,
230
+ ...additionalFieldsSchema.shape
231
+ }).partial()
232
+ }),
233
+ requireHeaders: true,
234
+ use: [orgMiddleware, orgSessionMiddleware],
235
+ metadata: {
236
+ $Infer: { body: {} },
237
+ openapi: {
238
+ description: "Update an existing team in an organization",
239
+ responses: { "200": {
240
+ description: "Team updated successfully",
241
+ content: { "application/json": { schema: {
242
+ type: "object",
243
+ properties: {
244
+ id: {
245
+ type: "string",
246
+ description: "Unique identifier of the updated team"
247
+ },
248
+ name: {
249
+ type: "string",
250
+ description: "Updated name of the team"
251
+ },
252
+ organizationId: {
253
+ type: "string",
254
+ description: "ID of the organization the team belongs to"
255
+ },
256
+ createdAt: {
257
+ type: "string",
258
+ format: "date-time",
259
+ description: "Timestamp when the team was created"
260
+ },
261
+ updatedAt: {
262
+ type: "string",
263
+ format: "date-time",
264
+ description: "Timestamp when the team was last updated"
265
+ }
266
+ },
267
+ required: [
268
+ "id",
269
+ "name",
270
+ "organizationId",
271
+ "createdAt",
272
+ "updatedAt"
273
+ ]
274
+ } } }
275
+ } }
276
+ }
277
+ }
278
+ }, async (ctx) => {
279
+ const session = ctx.context.session;
280
+ const organizationId = ctx.body.data.organizationId || session.session.activeOrganizationId;
281
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
282
+ const adapter = getOrgAdapter(ctx.context, options);
283
+ const member = await adapter.findMemberByOrgId({
284
+ userId: session.user.id,
285
+ organizationId
286
+ });
287
+ if (!member) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_TEAM);
288
+ if (!await hasPermission({
289
+ role: member.role,
290
+ options: ctx.context.orgOptions,
291
+ permissions: { team: ["update"] },
292
+ organizationId
293
+ }, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_TEAM);
294
+ const team = await adapter.findTeamById({
295
+ teamId: ctx.body.teamId,
296
+ organizationId
297
+ });
298
+ if (!team || team.organizationId !== organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
299
+ const { name, organizationId: __, ...additionalFields } = ctx.body.data;
300
+ const organization = await adapter.findOrganizationById(organizationId);
301
+ if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
302
+ const updates = {
303
+ name,
304
+ ...additionalFields
305
+ };
306
+ if (options?.organizationHooks?.beforeUpdateTeam) {
307
+ const response = await options?.organizationHooks.beforeUpdateTeam({
308
+ team,
309
+ updates,
310
+ user: session.user,
311
+ organization
312
+ });
313
+ if (response && typeof response === "object" && "data" in response) {
314
+ const modifiedUpdates = response.data;
315
+ const updatedTeam = await adapter.updateTeam(team.id, modifiedUpdates);
316
+ if (options?.organizationHooks?.afterUpdateTeam) await options?.organizationHooks.afterUpdateTeam({
317
+ team: updatedTeam,
318
+ user: session.user,
319
+ organization
320
+ });
321
+ return ctx.json(updatedTeam);
322
+ }
323
+ }
324
+ const updatedTeam = await adapter.updateTeam(team.id, updates);
325
+ if (options?.organizationHooks?.afterUpdateTeam) await options?.organizationHooks.afterUpdateTeam({
326
+ team: updatedTeam,
327
+ user: session.user,
328
+ organization
329
+ });
330
+ return ctx.json(updatedTeam);
331
+ });
332
+ };
333
+ const listOrganizationTeamsQuerySchema = z.optional(z.object({ organizationId: z.string().meta({ description: `The organization ID which the teams are under to list. Defaults to the users active organization. Eg: "organization-id"` }).optional() }));
334
+ const listOrganizationTeams = (options) => createAuthEndpoint("/organization/list-teams", {
335
+ method: "GET",
336
+ query: listOrganizationTeamsQuerySchema,
337
+ metadata: { openapi: {
338
+ description: "List all teams in an organization",
339
+ responses: { "200": {
340
+ description: "Teams retrieved successfully",
341
+ content: { "application/json": { schema: {
342
+ type: "array",
343
+ items: {
344
+ type: "object",
345
+ properties: {
346
+ id: {
347
+ type: "string",
348
+ description: "Unique identifier of the team"
349
+ },
350
+ name: {
351
+ type: "string",
352
+ description: "Name of the team"
353
+ },
354
+ organizationId: {
355
+ type: "string",
356
+ description: "ID of the organization the team belongs to"
357
+ },
358
+ createdAt: {
359
+ type: "string",
360
+ format: "date-time",
361
+ description: "Timestamp when the team was created"
362
+ },
363
+ updatedAt: {
364
+ type: "string",
365
+ format: "date-time",
366
+ description: "Timestamp when the team was last updated"
367
+ }
368
+ },
369
+ required: [
370
+ "id",
371
+ "name",
372
+ "organizationId",
373
+ "createdAt",
374
+ "updatedAt"
375
+ ]
376
+ },
377
+ description: "Array of team objects within the organization"
378
+ } } }
379
+ } }
380
+ } },
381
+ requireHeaders: true,
382
+ use: [orgMiddleware, orgSessionMiddleware]
383
+ }, async (ctx) => {
384
+ const session = ctx.context.session;
385
+ const organizationId = ctx.query?.organizationId || session?.session.activeOrganizationId;
386
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
387
+ const adapter = getOrgAdapter(ctx.context, options);
388
+ if (!await adapter.findMemberByOrgId({
389
+ userId: session.user.id,
390
+ organizationId: organizationId || ""
391
+ })) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_ACCESS_THIS_ORGANIZATION);
392
+ const teams = await adapter.listTeams(organizationId);
393
+ return ctx.json(teams);
394
+ });
395
+ const setActiveTeamBodySchema = z.object({ teamId: z.string().meta({ description: "The team id to set as active. It can be null to unset the active team" }).nullable().optional() });
396
+ const setActiveTeam = (options) => createAuthEndpoint("/organization/set-active-team", {
397
+ method: "POST",
398
+ body: setActiveTeamBodySchema,
399
+ requireHeaders: true,
400
+ use: [orgSessionMiddleware, orgMiddleware],
401
+ metadata: { openapi: {
402
+ description: "Set the active team for the current active organization",
403
+ responses: { "200": {
404
+ description: "Success",
405
+ content: { "application/json": { schema: {
406
+ type: "object",
407
+ description: "The team",
408
+ $ref: "#/components/schemas/Team"
409
+ } } }
410
+ } }
411
+ } }
412
+ }, async (ctx) => {
413
+ const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
414
+ const session = ctx.context.session;
415
+ if (ctx.body.teamId === null) {
416
+ if (!session.session.activeTeamId) return ctx.json(null);
417
+ await setSessionCookie(ctx, {
418
+ session: await adapter.setActiveTeam(session.session.token, null, ctx),
419
+ user: session.user
420
+ });
421
+ return ctx.json(null);
422
+ }
423
+ let teamId;
424
+ if (!ctx.body.teamId) {
425
+ const sessionTeamId = session.session.activeTeamId;
426
+ if (!sessionTeamId) return ctx.json(null);
427
+ else teamId = sessionTeamId;
428
+ } else teamId = ctx.body.teamId;
429
+ const activeOrganizationId = session.session.activeOrganizationId;
430
+ if (!activeOrganizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
431
+ const team = await adapter.findTeamById({
432
+ teamId,
433
+ organizationId: activeOrganizationId
434
+ });
435
+ if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
436
+ if (!await adapter.findTeamMember({
437
+ teamId,
438
+ userId: session.user.id
439
+ })) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
440
+ await setSessionCookie(ctx, {
441
+ session: await adapter.setActiveTeam(session.session.token, team.id, ctx),
442
+ user: session.user
443
+ });
444
+ return ctx.json(team);
445
+ });
446
+ const listUserTeams = (options) => createAuthEndpoint("/organization/list-user-teams", {
447
+ method: "GET",
448
+ query: z.object({
449
+ userId: z.string().optional().meta({ description: "The user ID to list teams for. Defaults to the current session user." }),
450
+ organizationId: z.string().optional().meta({ description: "The organization ID to scope the team list to. When omitted on a self-query, teams are returned across every organization the user belongs to. When querying another user, falls back to the session's active organization and is required if there is no active organization." })
451
+ }).optional(),
452
+ metadata: { openapi: {
453
+ description: "List teams for a user. Without parameters, returns teams for the current user across every organization they belong to. Pass `organizationId` to scope the result to a specific organization. Pass `userId` to list teams for another member; this requires `member:update` permission in the target organization (the explicit `organizationId` if provided, otherwise the session's active organization).",
454
+ responses: { "200": {
455
+ description: "Teams retrieved successfully",
456
+ content: { "application/json": { schema: {
457
+ type: "array",
458
+ items: {
459
+ type: "object",
460
+ description: "The team",
461
+ $ref: "#/components/schemas/Team"
462
+ },
463
+ description: "Array of team objects within the organization"
464
+ } } }
465
+ } }
466
+ } },
467
+ requireHeaders: true,
468
+ use: [orgMiddleware, orgSessionMiddleware]
469
+ }, async (ctx) => {
470
+ const session = ctx.context.session;
471
+ const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
472
+ const targetUserId = ctx.query?.userId || session.user.id;
473
+ const isSelf = targetUserId === session.user.id;
474
+ const organizationId = ctx.query?.organizationId || session.session.activeOrganizationId;
475
+ const isExplicitOrg = Boolean(ctx.query?.organizationId);
476
+ if (!isSelf) {
477
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
478
+ const requesterMember = await adapter.findMemberByOrgId({
479
+ userId: session.user.id,
480
+ organizationId
481
+ });
482
+ if (!requesterMember) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION);
483
+ if (!await hasPermission({
484
+ role: requesterMember.role,
485
+ options: ctx.context.orgOptions,
486
+ permissions: { member: ["update"] },
487
+ organizationId
488
+ }, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_THIS_MEMBER);
489
+ if (!await adapter.findMemberByOrgId({
490
+ userId: targetUserId,
491
+ organizationId
492
+ })) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
493
+ const teams = await adapter.listTeamsByUser({ userId: targetUserId });
494
+ return ctx.json(teams.filter((t) => t.organizationId === organizationId));
495
+ }
496
+ if (isExplicitOrg && organizationId) {
497
+ if (!await adapter.findMemberByOrgId({
498
+ userId: session.user.id,
499
+ organizationId
500
+ })) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_A_MEMBER_OF_THIS_ORGANIZATION);
501
+ const teams = await adapter.listTeamsByUser({ userId: session.user.id });
502
+ return ctx.json(teams.filter((t) => t.organizationId === organizationId));
503
+ }
504
+ const teams = await adapter.listTeamsByUser({ userId: session.user.id });
505
+ const orgIds = [...new Set(teams.map((team) => team.organizationId))];
506
+ const memberships = await Promise.all(orgIds.map((organizationId) => adapter.checkMembership({
507
+ userId: session.user.id,
508
+ organizationId
509
+ })));
510
+ const memberOrgIds = new Set(orgIds.filter((_, index) => memberships[index]));
511
+ return ctx.json(teams.filter((team) => memberOrgIds.has(team.organizationId)));
512
+ });
513
+ const listTeamMembersQuerySchema = z.optional(z.object({ teamId: z.string().optional().meta({ description: "The team whose members we should return. If this is not provided the members of the current active team get returned." }) }));
514
+ const listTeamMembers = (options) => createAuthEndpoint("/organization/list-team-members", {
515
+ method: "GET",
516
+ query: listTeamMembersQuerySchema,
517
+ metadata: { openapi: {
518
+ description: "List the members of the given team.",
519
+ responses: { "200": {
520
+ description: "Teams retrieved successfully",
521
+ content: { "application/json": { schema: {
522
+ type: "array",
523
+ items: {
524
+ type: "object",
525
+ description: "The team member",
526
+ properties: {
527
+ id: {
528
+ type: "string",
529
+ description: "Unique identifier of the team member"
530
+ },
531
+ userId: {
532
+ type: "string",
533
+ description: "The user ID of the team member"
534
+ },
535
+ teamId: {
536
+ type: "string",
537
+ description: "The team ID of the team the team member is in"
538
+ },
539
+ createdAt: {
540
+ type: "string",
541
+ format: "date-time",
542
+ description: "Timestamp when the team member was created"
543
+ }
544
+ },
545
+ required: [
546
+ "id",
547
+ "userId",
548
+ "teamId",
549
+ "createdAt"
550
+ ]
551
+ },
552
+ description: "Array of team member objects within the team"
553
+ } } }
554
+ } }
555
+ } },
556
+ requireHeaders: true,
557
+ use: [orgMiddleware, orgSessionMiddleware]
558
+ }, async (ctx) => {
559
+ const session = ctx.context.session;
560
+ const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
561
+ const teamId = ctx.query?.teamId || session?.session.activeTeamId;
562
+ if (!teamId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.YOU_DO_NOT_HAVE_AN_ACTIVE_TEAM);
563
+ const team = await adapter.findTeamById({ teamId });
564
+ if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
565
+ if (!await adapter.checkMembership({
566
+ userId: session.user.id,
567
+ organizationId: team.organizationId
568
+ })) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
569
+ if (!await adapter.findTeamMember({
570
+ userId: session.user.id,
571
+ teamId
572
+ })) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
573
+ const members = await adapter.listTeamMembers({ teamId });
574
+ return ctx.json(members);
575
+ });
576
+ const addTeamMemberBodySchema = z.object({
577
+ teamId: z.string().meta({ description: "The team the user should be a member of." }),
578
+ userId: z.coerce.string().meta({ description: "The user Id which represents the user to be added as a member." }),
579
+ organizationId: z.string().meta({ description: "The organization ID which the team falls under. If not provided, it will default to the user's active organization." }).optional()
580
+ });
581
+ const addTeamMember = (options) => createAuthEndpoint("/organization/add-team-member", {
582
+ method: "POST",
583
+ body: addTeamMemberBodySchema,
584
+ metadata: { openapi: {
585
+ description: "The newly created member",
586
+ responses: { "200": {
587
+ description: "Team member created successfully",
588
+ content: { "application/json": { schema: {
589
+ type: "object",
590
+ description: "The team member",
591
+ properties: {
592
+ id: {
593
+ type: "string",
594
+ description: "Unique identifier of the team member"
595
+ },
596
+ userId: {
597
+ type: "string",
598
+ description: "The user ID of the team member"
599
+ },
600
+ teamId: {
601
+ type: "string",
602
+ description: "The team ID of the team the team member is in"
603
+ },
604
+ createdAt: {
605
+ type: "string",
606
+ format: "date-time",
607
+ description: "Timestamp when the team member was created"
608
+ }
609
+ },
610
+ required: [
611
+ "id",
612
+ "userId",
613
+ "teamId",
614
+ "createdAt"
615
+ ]
616
+ } } }
617
+ } }
618
+ } },
619
+ requireHeaders: true,
620
+ use: [orgMiddleware, orgSessionMiddleware]
621
+ }, async (ctx) => {
622
+ const session = ctx.context.session;
623
+ const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
624
+ const organizationId = ctx.body.organizationId || session.session.activeOrganizationId;
625
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
626
+ const currentMember = await adapter.findMemberByOrgId({
627
+ userId: session.user.id,
628
+ organizationId
629
+ });
630
+ if (!currentMember) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
631
+ if (!await hasPermission({
632
+ role: currentMember.role,
633
+ options: ctx.context.orgOptions,
634
+ permissions: { member: ["update"] },
635
+ organizationId
636
+ }, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CREATE_A_NEW_TEAM_MEMBER);
637
+ if (!await adapter.findMemberByOrgId({
638
+ userId: ctx.body.userId,
639
+ organizationId
640
+ })) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
641
+ const team = await adapter.findTeamById({
642
+ teamId: ctx.body.teamId,
643
+ organizationId
644
+ });
645
+ if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
646
+ const organization = await adapter.findOrganizationById(organizationId);
647
+ if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
648
+ const userBeingAdded = await ctx.context.internalAdapter.findUserById(ctx.body.userId);
649
+ if (!userBeingAdded) throw APIError.fromStatus("BAD_REQUEST", { message: "User not found" });
650
+ if (options?.organizationHooks?.beforeAddTeamMember) {
651
+ const response = await options?.organizationHooks.beforeAddTeamMember({
652
+ teamMember: {
653
+ teamId: ctx.body.teamId,
654
+ userId: ctx.body.userId
655
+ },
656
+ team,
657
+ user: userBeingAdded,
658
+ organization
659
+ });
660
+ if (response && typeof response === "object" && "data" in response) {}
661
+ }
662
+ let teamMember;
663
+ if (typeof ctx.context.orgOptions.teams?.maximumMembersPerTeam !== "undefined") {
664
+ const maximumMembersPerTeam = typeof ctx.context.orgOptions.teams.maximumMembersPerTeam === "function" ? await ctx.context.orgOptions.teams.maximumMembersPerTeam({
665
+ teamId: ctx.body.teamId,
666
+ session,
667
+ organizationId
668
+ }) : ctx.context.orgOptions.teams.maximumMembersPerTeam;
669
+ const result = await adapter.addTeamMemberWithLimit({
670
+ teamId: ctx.body.teamId,
671
+ userId: ctx.body.userId,
672
+ maximumMembersPerTeam
673
+ });
674
+ if (result.status === "limitReached") throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.TEAM_MEMBER_LIMIT_REACHED);
675
+ teamMember = result.member;
676
+ } else teamMember = await adapter.findOrCreateTeamMember({
677
+ teamId: ctx.body.teamId,
678
+ userId: ctx.body.userId
679
+ });
680
+ if (options?.organizationHooks?.afterAddTeamMember) await options?.organizationHooks.afterAddTeamMember({
681
+ teamMember,
682
+ team,
683
+ user: userBeingAdded,
684
+ organization
685
+ });
686
+ return ctx.json(teamMember);
687
+ });
688
+ const removeTeamMemberBodySchema = z.object({
689
+ teamId: z.string().meta({ description: "The team the user should be removed from." }),
690
+ userId: z.coerce.string().meta({ description: "The user which should be removed from the team." }),
691
+ organizationId: z.string().meta({ description: "The organization ID which the team falls under. If not provided, it will default to the user's active organization." }).optional()
692
+ });
693
+ const removeTeamMember = (options) => createAuthEndpoint("/organization/remove-team-member", {
694
+ method: "POST",
695
+ body: removeTeamMemberBodySchema,
696
+ metadata: { openapi: {
697
+ description: "Remove a member from a team",
698
+ responses: { "200": {
699
+ description: "Team member removed successfully",
700
+ content: { "application/json": { schema: {
701
+ type: "object",
702
+ properties: { message: {
703
+ type: "string",
704
+ description: "Confirmation message indicating successful removal",
705
+ enum: ["Team member removed successfully."]
706
+ } },
707
+ required: ["message"]
708
+ } } }
709
+ } }
710
+ } },
711
+ requireHeaders: true,
712
+ use: [orgMiddleware, orgSessionMiddleware]
713
+ }, async (ctx) => {
714
+ const session = ctx.context.session;
715
+ const adapter = getOrgAdapter(ctx.context, ctx.context.orgOptions);
716
+ const organizationId = ctx.body.organizationId || session.session.activeOrganizationId;
717
+ if (!organizationId) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.NO_ACTIVE_ORGANIZATION);
718
+ const currentMember = await adapter.findMemberByOrgId({
719
+ userId: session.user.id,
720
+ organizationId
721
+ });
722
+ if (!currentMember) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
723
+ if (!await hasPermission({
724
+ role: currentMember.role,
725
+ options: ctx.context.orgOptions,
726
+ permissions: { member: ["delete"] },
727
+ organizationId
728
+ }, ctx)) throw APIError.from("FORBIDDEN", ORGANIZATION_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REMOVE_A_TEAM_MEMBER);
729
+ if (!await adapter.findMemberByOrgId({
730
+ userId: ctx.body.userId,
731
+ organizationId
732
+ })) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_ORGANIZATION);
733
+ const team = await adapter.findTeamById({
734
+ teamId: ctx.body.teamId,
735
+ organizationId
736
+ });
737
+ if (!team) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.TEAM_NOT_FOUND);
738
+ const organization = await adapter.findOrganizationById(organizationId);
739
+ if (!organization) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.ORGANIZATION_NOT_FOUND);
740
+ const userBeingRemoved = await ctx.context.internalAdapter.findUserById(ctx.body.userId);
741
+ if (!userBeingRemoved) throw APIError.fromStatus("BAD_REQUEST", { message: "User not found" });
742
+ const teamMember = await adapter.findTeamMember({
743
+ teamId: ctx.body.teamId,
744
+ userId: ctx.body.userId
745
+ });
746
+ if (!teamMember) throw APIError.from("BAD_REQUEST", ORGANIZATION_ERROR_CODES.USER_IS_NOT_A_MEMBER_OF_THE_TEAM);
747
+ if (options?.organizationHooks?.beforeRemoveTeamMember) await options?.organizationHooks.beforeRemoveTeamMember({
748
+ teamMember,
749
+ team,
750
+ user: userBeingRemoved,
751
+ organization
752
+ });
753
+ await adapter.removeTeamMember({
754
+ teamId: ctx.body.teamId,
755
+ userId: ctx.body.userId
756
+ });
757
+ if (options?.organizationHooks?.afterRemoveTeamMember) await options?.organizationHooks.afterRemoveTeamMember({
758
+ teamMember,
759
+ team,
760
+ user: userBeingRemoved,
761
+ organization
762
+ });
763
+ return ctx.json({ message: "Team member removed successfully." });
764
+ });
765
+ //#endregion
766
+ export { addTeamMember, createTeam, listOrganizationTeams, listTeamMembers, listUserTeams, removeTeam, removeTeamMember, setActiveTeam, updateTeam };