@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,919 @@
1
+ import { parseSessionOutput, parseUserOutput } from "../../db/schema.mjs";
2
+ import { getDate } from "../../utils/date.mjs";
3
+ import { deleteSessionCookie, expireCookie, setSessionCookie } from "../../cookies/index.mjs";
4
+ import { getAuthoritativeSessionFromCtx, getSessionFromCtx } from "../../api/routes/session.mjs";
5
+ import { ADMIN_ERROR_CODES } from "./error-codes.mjs";
6
+ import { hasPermission } from "./has-permission.mjs";
7
+ import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
8
+ import { whereOperators } from "@better-auth/core/db/adapter";
9
+ import { createAuthEndpoint, createAuthMiddleware } from "@better-auth/core/api";
10
+ import * as z from "zod";
11
+ //#region src/plugins/admin/routes.ts
12
+ /**
13
+ * Ensures a valid session, if not will throw.
14
+ * Will also provide additional types on the user to include role types.
15
+ */
16
+ const adminMiddleware = createAuthMiddleware(async (ctx) => {
17
+ const session = await getAuthoritativeSessionFromCtx(ctx);
18
+ if (!session) throw APIError.fromStatus("UNAUTHORIZED");
19
+ return { session };
20
+ });
21
+ function parseRoles(roles) {
22
+ return Array.isArray(roles) ? roles.join(",") : roles;
23
+ }
24
+ const setRoleBodySchema = z.object({
25
+ userId: z.coerce.string().meta({ description: "The user id" }),
26
+ role: z.union([z.string().meta({ description: "The role to set. `admin` or `user` by default" }), z.array(z.string().meta({ description: "The roles to set. `admin` or `user` by default" }))]).meta({ description: "The role to set, this can be a string or an array of strings. Eg: `admin` or `[admin, user]`" })
27
+ });
28
+ /**
29
+ * ### Endpoint
30
+ *
31
+ * POST `/admin/set-role`
32
+ *
33
+ * ### API Methods
34
+ *
35
+ * **server:**
36
+ * `auth.api.setRole`
37
+ *
38
+ * **client:**
39
+ * `authClient.admin.setRole`
40
+ *
41
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-set-role)
42
+ */
43
+ const setRole = (opts) => createAuthEndpoint("/admin/set-role", {
44
+ method: "POST",
45
+ body: setRoleBodySchema,
46
+ requireHeaders: true,
47
+ use: [adminMiddleware],
48
+ metadata: {
49
+ openapi: {
50
+ operationId: "setUserRole",
51
+ summary: "Set the role of a user",
52
+ description: "Set the role of a user",
53
+ responses: { 200: {
54
+ description: "User role updated",
55
+ content: { "application/json": { schema: {
56
+ type: "object",
57
+ properties: { user: { $ref: "#/components/schemas/User" } }
58
+ } } }
59
+ } }
60
+ },
61
+ $Infer: { body: {} }
62
+ }
63
+ }, async (ctx) => {
64
+ if (!hasPermission({
65
+ userId: ctx.context.session.user.id,
66
+ role: ctx.context.session.user.role,
67
+ options: opts,
68
+ permissions: { user: ["set-role"] }
69
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CHANGE_USERS_ROLE);
70
+ const roles = opts.roles;
71
+ if (roles) {
72
+ const inputRoles = Array.isArray(ctx.body.role) ? ctx.body.role : [ctx.body.role];
73
+ for (const role of inputRoles) if (!roles[role]) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_SET_NON_EXISTENT_VALUE);
74
+ }
75
+ if (!await ctx.context.internalAdapter.findUserById(ctx.body.userId)) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
76
+ const updatedUser = await ctx.context.internalAdapter.updateUser(ctx.body.userId, { role: parseRoles(ctx.body.role) });
77
+ return ctx.json({ user: parseUserOutput(ctx.context.options, updatedUser) });
78
+ });
79
+ const getUserQuerySchema = z.object({ id: z.string().meta({ description: "The id of the User" }) });
80
+ const getUser = (opts) => createAuthEndpoint("/admin/get-user", {
81
+ method: "GET",
82
+ query: getUserQuerySchema,
83
+ use: [adminMiddleware],
84
+ metadata: { openapi: {
85
+ operationId: "getUser",
86
+ summary: "Get an existing user",
87
+ description: "Get an existing user",
88
+ responses: { 200: {
89
+ description: "User",
90
+ content: { "application/json": { schema: {
91
+ type: "object",
92
+ properties: { user: { $ref: "#/components/schemas/User" } }
93
+ } } }
94
+ } }
95
+ } }
96
+ }, async (ctx) => {
97
+ const { id } = ctx.query;
98
+ if (!hasPermission({
99
+ userId: ctx.context.session.user.id,
100
+ role: ctx.context.session.user.role,
101
+ options: opts,
102
+ permissions: { user: ["get"] }
103
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_GET_USER);
104
+ const user = await ctx.context.internalAdapter.findUserById(id);
105
+ if (!user) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
106
+ return parseUserOutput(ctx.context.options, user);
107
+ });
108
+ const createUserBodySchema = z.object({
109
+ email: z.string().meta({ description: "The email of the user" }),
110
+ password: z.string().optional().meta({ description: "The password of the user. If not provided, the user will be created without a credential account (useful for magic link or social login only users)." }),
111
+ name: z.string().meta({ description: "The name of the user" }),
112
+ role: z.union([z.string().meta({ description: "The role of the user" }), z.array(z.string().meta({ description: "The roles of user" }))]).optional().meta({ description: `A string or array of strings representing the roles to apply to the new user. Eg: \"user\"` }),
113
+ /**
114
+ * extra fields for user
115
+ */
116
+ data: z.record(z.string(), z.any()).optional().meta({ description: "Extra fields for the user. Including custom additional fields." })
117
+ });
118
+ /**
119
+ * ### Endpoint
120
+ *
121
+ * POST `/admin/create-user`
122
+ *
123
+ * ### API Methods
124
+ *
125
+ * **server:**
126
+ * `auth.api.createUser`
127
+ *
128
+ * **client:**
129
+ * `authClient.admin.createUser`
130
+ *
131
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-create-user)
132
+ */
133
+ const createUser = (opts) => createAuthEndpoint("/admin/create-user", {
134
+ method: "POST",
135
+ body: createUserBodySchema,
136
+ metadata: {
137
+ openapi: {
138
+ operationId: "createUser",
139
+ summary: "Create a new user",
140
+ description: "Create a new user",
141
+ responses: { 200: {
142
+ description: "User created",
143
+ content: { "application/json": { schema: {
144
+ type: "object",
145
+ properties: { user: { $ref: "#/components/schemas/User" } }
146
+ } } }
147
+ } }
148
+ },
149
+ $Infer: { body: {} }
150
+ }
151
+ }, async (ctx) => {
152
+ const session = await getAuthoritativeSessionFromCtx(ctx);
153
+ if (!session && (ctx.request || ctx.headers)) throw ctx.error("UNAUTHORIZED");
154
+ if (session) {
155
+ if (!hasPermission({
156
+ userId: session.user.id,
157
+ role: session.user.role,
158
+ options: opts,
159
+ permissions: { user: ["create"] }
160
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CREATE_USERS);
161
+ }
162
+ const { role: dataRole, ...userData } = ctx.body.data ?? {};
163
+ const requestedRole = ctx.body.role ?? dataRole;
164
+ if (requestedRole !== void 0) {
165
+ if (session) {
166
+ if (!hasPermission({
167
+ userId: session.user.id,
168
+ role: session.user.role,
169
+ options: opts,
170
+ permissions: { user: ["set-role"] }
171
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CHANGE_USERS_ROLE);
172
+ }
173
+ const inputRoles = Array.isArray(requestedRole) ? requestedRole : [requestedRole];
174
+ for (const role of inputRoles) {
175
+ if (typeof role !== "string") throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.INVALID_ROLE_TYPE);
176
+ if (opts.roles && !opts.roles[role]) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_SET_NON_EXISTENT_VALUE);
177
+ }
178
+ }
179
+ if (session && [
180
+ "banned",
181
+ "banReason",
182
+ "banExpires"
183
+ ].some((key) => Object.prototype.hasOwnProperty.call(userData, key))) {
184
+ if (!hasPermission({
185
+ userId: session.user.id,
186
+ role: session.user.role,
187
+ options: opts,
188
+ permissions: { user: ["ban"] }
189
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_BAN_USERS);
190
+ }
191
+ const email = ctx.body.email.toLowerCase();
192
+ if (!z.email().safeParse(email).success) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_EMAIL);
193
+ if (await ctx.context.internalAdapter.findUserByEmail(email)) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL);
194
+ const user = await ctx.context.internalAdapter.createUser({
195
+ ...userData,
196
+ email,
197
+ name: ctx.body.name,
198
+ role: requestedRole !== void 0 ? parseRoles(requestedRole) : opts?.defaultRole ?? "user"
199
+ }, { method: "admin" });
200
+ if (!user) throw APIError.from("INTERNAL_SERVER_ERROR", ADMIN_ERROR_CODES.FAILED_TO_CREATE_USER);
201
+ if (ctx.body.password) {
202
+ const hashedPassword = await ctx.context.password.hash(ctx.body.password);
203
+ await ctx.context.internalAdapter.linkAccount({
204
+ providerId: "credential",
205
+ accountId: user.id,
206
+ password: hashedPassword,
207
+ userId: user.id
208
+ });
209
+ }
210
+ return ctx.json({ user: parseUserOutput(ctx.context.options, user) });
211
+ });
212
+ const adminUpdateUserBodySchema = z.object({
213
+ userId: z.coerce.string().meta({ description: "The user id" }),
214
+ data: z.record(z.any(), z.any()).meta({ description: "The user data to update" })
215
+ });
216
+ /**
217
+ * ### Endpoint
218
+ *
219
+ * POST `/admin/update-user`
220
+ *
221
+ * ### API Methods
222
+ *
223
+ * **server:**
224
+ * `auth.api.adminUpdateUser`
225
+ *
226
+ * **client:**
227
+ * `authClient.admin.updateUser`
228
+ *
229
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-update-user)
230
+ */
231
+ const adminUpdateUser = (opts) => createAuthEndpoint("/admin/update-user", {
232
+ method: "POST",
233
+ body: adminUpdateUserBodySchema,
234
+ use: [adminMiddleware],
235
+ metadata: { openapi: {
236
+ operationId: "adminUpdateUser",
237
+ summary: "Update a user",
238
+ description: "Update a user's details",
239
+ responses: { 200: {
240
+ description: "User updated",
241
+ content: { "application/json": { schema: {
242
+ type: "object",
243
+ properties: { user: { $ref: "#/components/schemas/User" } }
244
+ } } }
245
+ } }
246
+ } }
247
+ }, async (ctx) => {
248
+ if (!hasPermission({
249
+ userId: ctx.context.session.user.id,
250
+ role: ctx.context.session.user.role,
251
+ options: opts,
252
+ permissions: { user: ["update"] }
253
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_UPDATE_USERS);
254
+ if (Object.keys(ctx.body.data).length === 0) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.NO_DATA_TO_UPDATE);
255
+ const updateData = ctx.body.data;
256
+ const hasDataKey = (key) => Object.prototype.hasOwnProperty.call(updateData, key);
257
+ if (hasDataKey("password")) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.PASSWORD_CANNOT_BE_UPDATED_VIA_UPDATE_USER);
258
+ if (Object.prototype.hasOwnProperty.call(ctx.body.data, "role")) {
259
+ if (!hasPermission({
260
+ userId: ctx.context.session.user.id,
261
+ role: ctx.context.session.user.role,
262
+ options: opts,
263
+ permissions: { user: ["set-role"] }
264
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_CHANGE_USERS_ROLE);
265
+ const roleValue = ctx.body.data.role;
266
+ const inputRoles = Array.isArray(roleValue) ? roleValue : [roleValue];
267
+ for (const role of inputRoles) {
268
+ if (typeof role !== "string") throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.INVALID_ROLE_TYPE);
269
+ if (opts.roles && !opts.roles[role]) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_SET_NON_EXISTENT_VALUE);
270
+ }
271
+ ctx.body.data.role = parseRoles(inputRoles);
272
+ }
273
+ if ([
274
+ "banned",
275
+ "banReason",
276
+ "banExpires"
277
+ ].some(hasDataKey)) {
278
+ if (!hasPermission({
279
+ userId: ctx.context.session.user.id,
280
+ role: ctx.context.session.user.role,
281
+ options: opts,
282
+ permissions: { user: ["ban"] }
283
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_BAN_USERS);
284
+ if (updateData.banned === true && ctx.body.userId === ctx.context.session.user.id) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.YOU_CANNOT_BAN_YOURSELF);
285
+ }
286
+ if (hasDataKey("email") || hasDataKey("emailVerified")) {
287
+ if (!hasPermission({
288
+ userId: ctx.context.session.user.id,
289
+ role: ctx.context.session.user.role,
290
+ options: opts,
291
+ permissions: { user: ["set-email"] }
292
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_SET_USERS_EMAIL);
293
+ if (hasDataKey("email")) {
294
+ const email = String(updateData.email).toLowerCase();
295
+ if (!z.email().safeParse(email).success) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.INVALID_EMAIL);
296
+ const existUser = await ctx.context.internalAdapter.findUserByEmail(email);
297
+ if (existUser && existUser.user.id !== ctx.body.userId) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL);
298
+ updateData.email = email;
299
+ }
300
+ }
301
+ if (!await ctx.context.internalAdapter.findUserById(ctx.body.userId)) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
302
+ const updatedUser = await ctx.context.internalAdapter.updateUser(ctx.body.userId, ctx.body.data);
303
+ if (updateData.banned === true) await ctx.context.internalAdapter.deleteUserSessions(ctx.body.userId);
304
+ return ctx.json(parseUserOutput(ctx.context.options, updatedUser));
305
+ });
306
+ const listUsersQuerySchema = z.object({
307
+ searchValue: z.string().optional().meta({ description: "The value to search for. Eg: \"some name\"" }),
308
+ searchField: z.enum(["email", "name"]).meta({ description: "The field to search in, defaults to email. Can be `email` or `name`. Eg: \"name\"" }).optional(),
309
+ searchOperator: z.enum([
310
+ "contains",
311
+ "starts_with",
312
+ "ends_with"
313
+ ]).meta({ description: "The operator to use for the search. Can be `contains`, `starts_with` or `ends_with`. Eg: \"contains\"" }).optional(),
314
+ limit: z.string().meta({ description: "The number of users to return" }).or(z.number()).optional(),
315
+ offset: z.string().meta({ description: "The offset to start from" }).or(z.number()).optional(),
316
+ sortBy: z.string().meta({ description: "The field to sort by" }).optional(),
317
+ sortDirection: z.enum(["asc", "desc"]).meta({ description: "The direction to sort by" }).optional(),
318
+ filterField: z.string().meta({ description: "The field to filter by" }).optional(),
319
+ filterValue: z.string().meta({ description: "The value to filter by" }).or(z.number()).or(z.boolean()).or(z.array(z.string())).or(z.array(z.number())).optional(),
320
+ filterOperator: z.enum(whereOperators).meta({ description: "The operator to use for the filter" }).optional()
321
+ });
322
+ const listUsers = (opts) => createAuthEndpoint("/admin/list-users", {
323
+ method: "GET",
324
+ use: [adminMiddleware],
325
+ query: listUsersQuerySchema,
326
+ metadata: { openapi: {
327
+ operationId: "listUsers",
328
+ summary: "List users",
329
+ description: "List users",
330
+ responses: { 200: {
331
+ description: "List of users",
332
+ content: { "application/json": { schema: {
333
+ type: "object",
334
+ properties: {
335
+ users: {
336
+ type: "array",
337
+ items: { $ref: "#/components/schemas/User" }
338
+ },
339
+ total: { type: "number" },
340
+ limit: { type: "number" },
341
+ offset: { type: "number" }
342
+ },
343
+ required: ["users", "total"]
344
+ } } }
345
+ } }
346
+ } }
347
+ }, async (ctx) => {
348
+ const session = ctx.context.session;
349
+ if (!hasPermission({
350
+ userId: ctx.context.session.user.id,
351
+ role: session.user.role,
352
+ options: opts,
353
+ permissions: { user: ["list"] }
354
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_LIST_USERS);
355
+ const where = [];
356
+ if (ctx.query?.searchValue) where.push({
357
+ field: ctx.query.searchField || "email",
358
+ operator: ctx.query.searchOperator || "contains",
359
+ value: ctx.query.searchValue
360
+ });
361
+ if (ctx.query?.filterValue !== void 0) where.push({
362
+ field: ctx.query.filterField || "email",
363
+ operator: ctx.query.filterOperator || "eq",
364
+ value: ctx.query.filterValue
365
+ });
366
+ try {
367
+ const users = await ctx.context.internalAdapter.listUsers(Number(ctx.query?.limit) || void 0, Number(ctx.query?.offset) || void 0, ctx.query?.sortBy ? {
368
+ field: ctx.query.sortBy,
369
+ direction: ctx.query.sortDirection || "asc"
370
+ } : void 0, where.length ? where : void 0);
371
+ const total = await ctx.context.internalAdapter.countTotalUsers(where.length ? where : void 0);
372
+ return ctx.json({
373
+ users: users.map((user) => parseUserOutput(ctx.context.options, user)),
374
+ total,
375
+ limit: Number(ctx.query?.limit) || void 0,
376
+ offset: Number(ctx.query?.offset) || void 0
377
+ });
378
+ } catch {
379
+ return ctx.json({
380
+ users: [],
381
+ total: 0
382
+ });
383
+ }
384
+ });
385
+ const listUserSessionsBodySchema = z.object({ userId: z.coerce.string().meta({ description: "The user id" }) });
386
+ /**
387
+ * ### Endpoint
388
+ *
389
+ * POST `/admin/list-user-sessions`
390
+ *
391
+ * ### API Methods
392
+ *
393
+ * **server:**
394
+ * `auth.api.listUserSessions`
395
+ *
396
+ * **client:**
397
+ * `authClient.admin.listUserSessions`
398
+ *
399
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-list-user-sessions)
400
+ */
401
+ const listUserSessions = (opts) => createAuthEndpoint("/admin/list-user-sessions", {
402
+ method: "POST",
403
+ use: [adminMiddleware],
404
+ body: listUserSessionsBodySchema,
405
+ metadata: { openapi: {
406
+ operationId: "adminListUserSessions",
407
+ summary: "List user sessions",
408
+ description: "List user sessions",
409
+ responses: { 200: {
410
+ description: "List of user sessions",
411
+ content: { "application/json": { schema: {
412
+ type: "object",
413
+ properties: { sessions: {
414
+ type: "array",
415
+ items: { $ref: "#/components/schemas/Session" }
416
+ } }
417
+ } } }
418
+ } }
419
+ } }
420
+ }, async (ctx) => {
421
+ const session = ctx.context.session;
422
+ if (!hasPermission({
423
+ userId: ctx.context.session.user.id,
424
+ role: session.user.role,
425
+ options: opts,
426
+ permissions: { session: ["list"] }
427
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_LIST_USERS_SESSIONS);
428
+ const sessions = await ctx.context.internalAdapter.listSessions(ctx.body.userId);
429
+ return ctx.json({ sessions: sessions.map((s) => parseSessionOutput(ctx.context.options, s)) });
430
+ });
431
+ const unbanUserBodySchema = z.object({ userId: z.coerce.string().meta({ description: "The user id" }) });
432
+ /**
433
+ * ### Endpoint
434
+ *
435
+ * POST `/admin/unban-user`
436
+ *
437
+ * ### API Methods
438
+ *
439
+ * **server:**
440
+ * `auth.api.unbanUser`
441
+ *
442
+ * **client:**
443
+ * `authClient.admin.unbanUser`
444
+ *
445
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-unban-user)
446
+ */
447
+ const unbanUser = (opts) => createAuthEndpoint("/admin/unban-user", {
448
+ method: "POST",
449
+ body: unbanUserBodySchema,
450
+ use: [adminMiddleware],
451
+ metadata: { openapi: {
452
+ operationId: "unbanUser",
453
+ summary: "Unban a user",
454
+ description: "Unban a user",
455
+ responses: { 200: {
456
+ description: "User unbanned",
457
+ content: { "application/json": { schema: {
458
+ type: "object",
459
+ properties: { user: { $ref: "#/components/schemas/User" } }
460
+ } } }
461
+ } }
462
+ } }
463
+ }, async (ctx) => {
464
+ const session = ctx.context.session;
465
+ if (!hasPermission({
466
+ userId: ctx.context.session.user.id,
467
+ role: session.user.role,
468
+ options: opts,
469
+ permissions: { user: ["ban"] }
470
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_BAN_USERS);
471
+ if (!await ctx.context.internalAdapter.findUserById(ctx.body.userId)) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
472
+ const user = await ctx.context.internalAdapter.updateUser(ctx.body.userId, {
473
+ banned: false,
474
+ banExpires: null,
475
+ banReason: null,
476
+ updatedAt: /* @__PURE__ */ new Date()
477
+ });
478
+ return ctx.json({ user: parseUserOutput(ctx.context.options, user) });
479
+ });
480
+ const banUserBodySchema = z.object({
481
+ userId: z.coerce.string().meta({ description: "The user id" }),
482
+ /**
483
+ * Reason for the ban
484
+ */
485
+ banReason: z.string().meta({ description: "The reason for the ban" }).optional(),
486
+ /**
487
+ * Number of seconds until the ban expires
488
+ */
489
+ banExpiresIn: z.number().meta({ description: "The number of seconds until the ban expires" }).optional()
490
+ });
491
+ /**
492
+ * ### Endpoint
493
+ *
494
+ * POST `/admin/ban-user`
495
+ *
496
+ * ### API Methods
497
+ *
498
+ * **server:**
499
+ * `auth.api.banUser`
500
+ *
501
+ * **client:**
502
+ * `authClient.admin.banUser`
503
+ *
504
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-ban-user)
505
+ */
506
+ const banUser = (opts) => createAuthEndpoint("/admin/ban-user", {
507
+ method: "POST",
508
+ body: banUserBodySchema,
509
+ use: [adminMiddleware],
510
+ metadata: { openapi: {
511
+ operationId: "banUser",
512
+ summary: "Ban a user",
513
+ description: "Ban a user",
514
+ responses: { 200: {
515
+ description: "User banned",
516
+ content: { "application/json": { schema: {
517
+ type: "object",
518
+ properties: { user: { $ref: "#/components/schemas/User" } }
519
+ } } }
520
+ } }
521
+ } }
522
+ }, async (ctx) => {
523
+ const session = ctx.context.session;
524
+ if (!hasPermission({
525
+ userId: ctx.context.session.user.id,
526
+ role: session.user.role,
527
+ options: opts,
528
+ permissions: { user: ["ban"] }
529
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_BAN_USERS);
530
+ if (!await ctx.context.internalAdapter.findUserById(ctx.body.userId)) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
531
+ if (ctx.body.userId === ctx.context.session.user.id) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.YOU_CANNOT_BAN_YOURSELF);
532
+ const user = await ctx.context.internalAdapter.updateUser(ctx.body.userId, {
533
+ banned: true,
534
+ banReason: ctx.body.banReason || opts?.defaultBanReason || "No reason",
535
+ banExpires: ctx.body.banExpiresIn ? getDate(ctx.body.banExpiresIn, "sec") : opts?.defaultBanExpiresIn ? getDate(opts.defaultBanExpiresIn, "sec") : null,
536
+ updatedAt: /* @__PURE__ */ new Date()
537
+ });
538
+ await ctx.context.internalAdapter.deleteUserSessions(ctx.body.userId);
539
+ return ctx.json({ user: parseUserOutput(ctx.context.options, user) });
540
+ });
541
+ const impersonateUserBodySchema = z.object({ userId: z.coerce.string().meta({ description: "The user id" }) });
542
+ /**
543
+ * ### Endpoint
544
+ *
545
+ * POST `/admin/impersonate-user`
546
+ *
547
+ * ### API Methods
548
+ *
549
+ * **server:**
550
+ * `auth.api.impersonateUser`
551
+ *
552
+ * **client:**
553
+ * `authClient.admin.impersonateUser`
554
+ *
555
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-impersonate-user)
556
+ */
557
+ const impersonateUser = (opts) => createAuthEndpoint("/admin/impersonate-user", {
558
+ method: "POST",
559
+ body: impersonateUserBodySchema,
560
+ use: [adminMiddleware],
561
+ metadata: { openapi: {
562
+ operationId: "impersonateUser",
563
+ summary: "Impersonate a user",
564
+ description: "Impersonate a user",
565
+ responses: { 200: {
566
+ description: "Impersonation session created",
567
+ content: { "application/json": { schema: {
568
+ type: "object",
569
+ properties: {
570
+ session: { $ref: "#/components/schemas/Session" },
571
+ user: { $ref: "#/components/schemas/User" }
572
+ }
573
+ } } }
574
+ } }
575
+ } }
576
+ }, async (ctx) => {
577
+ if (!hasPermission({
578
+ userId: ctx.context.session.user.id,
579
+ role: ctx.context.session.user.role,
580
+ options: opts,
581
+ permissions: { user: ["impersonate"] }
582
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_IMPERSONATE_USERS);
583
+ const targetUser = await ctx.context.internalAdapter.findUserById(ctx.body.userId);
584
+ if (!targetUser) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
585
+ const adminRoles = (Array.isArray(opts.adminRoles) ? opts.adminRoles : opts.adminRoles?.split(",") || []).map((role) => role.trim());
586
+ if ((targetUser.role || opts.defaultRole || "user").split(",").some((role) => adminRoles.includes(role)) || !!opts.adminUserIds?.includes(targetUser.id)) {
587
+ if (!(opts.allowImpersonatingAdmins === true || hasPermission({
588
+ userId: ctx.context.session.user.id,
589
+ role: ctx.context.session.user.role,
590
+ options: opts,
591
+ permissions: { user: ["impersonate-admins"] }
592
+ }))) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_CANNOT_IMPERSONATE_ADMINS);
593
+ }
594
+ const session = await ctx.context.internalAdapter.createSession(targetUser.id, true, {
595
+ impersonatedBy: ctx.context.session.user.id,
596
+ expiresAt: opts?.impersonationSessionDuration ? getDate(opts.impersonationSessionDuration, "sec") : getDate(3600, "sec")
597
+ }, true);
598
+ if (!session) throw APIError.from("INTERNAL_SERVER_ERROR", ADMIN_ERROR_CODES.FAILED_TO_CREATE_USER);
599
+ const authCookies = ctx.context.authCookies;
600
+ deleteSessionCookie(ctx);
601
+ const dontRememberMeCookie = await ctx.getSignedCookie(ctx.context.authCookies.dontRememberToken.name, ctx.context.secret);
602
+ const adminCookieProp = ctx.context.createAuthCookie("admin_session");
603
+ await ctx.setSignedCookie(adminCookieProp.name, `${ctx.context.session.session.token}:${dontRememberMeCookie || ""}`, ctx.context.secret, authCookies.sessionToken.attributes);
604
+ await setSessionCookie(ctx, {
605
+ session,
606
+ user: targetUser
607
+ }, true);
608
+ return ctx.json({
609
+ session,
610
+ user: parseUserOutput(ctx.context.options, targetUser)
611
+ });
612
+ });
613
+ /**
614
+ * ### Endpoint
615
+ *
616
+ * POST `/admin/stop-impersonating`
617
+ *
618
+ * ### API Methods
619
+ *
620
+ * **server:**
621
+ * `auth.api.stopImpersonating`
622
+ *
623
+ * **client:**
624
+ * `authClient.admin.stopImpersonating`
625
+ *
626
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-stop-impersonating)
627
+ */
628
+ const stopImpersonating = () => createAuthEndpoint("/admin/stop-impersonating", {
629
+ method: "POST",
630
+ requireHeaders: true
631
+ }, async (ctx) => {
632
+ const session = await getSessionFromCtx(ctx);
633
+ if (!session) throw APIError.fromStatus("UNAUTHORIZED");
634
+ if (!session.session.impersonatedBy) throw APIError.fromStatus("BAD_REQUEST", { message: "You are not impersonating anyone" });
635
+ const user = await ctx.context.internalAdapter.findUserById(session.session.impersonatedBy);
636
+ if (!user) throw APIError.fromStatus("INTERNAL_SERVER_ERROR", { message: "Failed to find user" });
637
+ const adminSessionCookie = ctx.context.createAuthCookie("admin_session");
638
+ const adminCookie = await ctx.getSignedCookie(adminSessionCookie.name, ctx.context.secret);
639
+ if (!adminCookie) throw APIError.fromStatus("INTERNAL_SERVER_ERROR", { message: "Failed to find admin session" });
640
+ const [adminSessionToken, dontRememberMeCookie] = adminCookie?.split(":");
641
+ const adminSession = await ctx.context.internalAdapter.findSession(adminSessionToken);
642
+ if (!adminSession || adminSession.session.userId !== user.id) throw APIError.fromStatus("INTERNAL_SERVER_ERROR", { message: "Failed to find admin session" });
643
+ await ctx.context.internalAdapter.deleteSession(session.session.token);
644
+ await setSessionCookie(ctx, adminSession, !!dontRememberMeCookie);
645
+ expireCookie(ctx, adminSessionCookie);
646
+ return ctx.json({
647
+ session: parseSessionOutput(ctx.context.options, adminSession.session),
648
+ user: parseUserOutput(ctx.context.options, adminSession.user)
649
+ });
650
+ });
651
+ const revokeUserSessionBodySchema = z.object({ sessionToken: z.string().meta({ description: "The session token" }) });
652
+ /**
653
+ * ### Endpoint
654
+ *
655
+ * POST `/admin/revoke-user-session`
656
+ *
657
+ * ### API Methods
658
+ *
659
+ * **server:**
660
+ * `auth.api.revokeUserSession`
661
+ *
662
+ * **client:**
663
+ * `authClient.admin.revokeUserSession`
664
+ *
665
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-revoke-user-session)
666
+ */
667
+ const revokeUserSession = (opts) => createAuthEndpoint("/admin/revoke-user-session", {
668
+ method: "POST",
669
+ body: revokeUserSessionBodySchema,
670
+ use: [adminMiddleware],
671
+ metadata: { openapi: {
672
+ operationId: "revokeUserSession",
673
+ summary: "Revoke a user session",
674
+ description: "Revoke a user session",
675
+ responses: { 200: {
676
+ description: "Session revoked",
677
+ content: { "application/json": { schema: {
678
+ type: "object",
679
+ properties: { success: { type: "boolean" } }
680
+ } } }
681
+ } }
682
+ } }
683
+ }, async (ctx) => {
684
+ const session = ctx.context.session;
685
+ if (!hasPermission({
686
+ userId: ctx.context.session.user.id,
687
+ role: session.user.role,
688
+ options: opts,
689
+ permissions: { session: ["revoke"] }
690
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REVOKE_USERS_SESSIONS);
691
+ await ctx.context.internalAdapter.deleteSession(ctx.body.sessionToken);
692
+ return ctx.json({ success: true });
693
+ });
694
+ const revokeUserSessionsBodySchema = z.object({ userId: z.coerce.string().meta({ description: "The user id" }) });
695
+ /**
696
+ * ### Endpoint
697
+ *
698
+ * POST `/admin/revoke-user-sessions`
699
+ *
700
+ * ### API Methods
701
+ *
702
+ * **server:**
703
+ * `auth.api.revokeUserSessions`
704
+ *
705
+ * **client:**
706
+ * `authClient.admin.revokeUserSessions`
707
+ *
708
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-revoke-user-sessions)
709
+ */
710
+ const revokeUserSessions = (opts) => createAuthEndpoint("/admin/revoke-user-sessions", {
711
+ method: "POST",
712
+ body: revokeUserSessionsBodySchema,
713
+ use: [adminMiddleware],
714
+ metadata: { openapi: {
715
+ operationId: "revokeUserSessions",
716
+ summary: "Revoke all user sessions",
717
+ description: "Revoke all user sessions",
718
+ responses: { 200: {
719
+ description: "Sessions revoked",
720
+ content: { "application/json": { schema: {
721
+ type: "object",
722
+ properties: { success: { type: "boolean" } }
723
+ } } }
724
+ } }
725
+ } }
726
+ }, async (ctx) => {
727
+ const session = ctx.context.session;
728
+ if (!hasPermission({
729
+ userId: ctx.context.session.user.id,
730
+ role: session.user.role,
731
+ options: opts,
732
+ permissions: { session: ["revoke"] }
733
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_REVOKE_USERS_SESSIONS);
734
+ await ctx.context.internalAdapter.deleteUserSessions(ctx.body.userId);
735
+ return ctx.json({ success: true });
736
+ });
737
+ const removeUserBodySchema = z.object({ userId: z.coerce.string().meta({ description: "The user id" }) });
738
+ /**
739
+ * ### Endpoint
740
+ *
741
+ * POST `/admin/remove-user`
742
+ *
743
+ * ### API Methods
744
+ *
745
+ * **server:**
746
+ * `auth.api.removeUser`
747
+ *
748
+ * **client:**
749
+ * `authClient.admin.removeUser`
750
+ *
751
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-remove-user)
752
+ */
753
+ const removeUser = (opts) => createAuthEndpoint("/admin/remove-user", {
754
+ method: "POST",
755
+ body: removeUserBodySchema,
756
+ use: [adminMiddleware],
757
+ metadata: { openapi: {
758
+ operationId: "removeUser",
759
+ summary: "Remove a user",
760
+ description: "Delete a user and all their sessions and accounts. Cannot be undone.",
761
+ responses: { 200: {
762
+ description: "User removed",
763
+ content: { "application/json": { schema: {
764
+ type: "object",
765
+ properties: { success: { type: "boolean" } }
766
+ } } }
767
+ } }
768
+ } }
769
+ }, async (ctx) => {
770
+ const session = ctx.context.session;
771
+ if (!hasPermission({
772
+ userId: ctx.context.session.user.id,
773
+ role: session.user.role,
774
+ options: opts,
775
+ permissions: { user: ["delete"] }
776
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_DELETE_USERS);
777
+ if (ctx.body.userId === ctx.context.session.user.id) throw APIError.from("BAD_REQUEST", ADMIN_ERROR_CODES.YOU_CANNOT_REMOVE_YOURSELF);
778
+ if (!await ctx.context.internalAdapter.findUserById(ctx.body.userId)) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
779
+ await ctx.context.internalAdapter.deleteUserSessions(ctx.body.userId);
780
+ await ctx.context.internalAdapter.deleteUser(ctx.body.userId);
781
+ return ctx.json({ success: true });
782
+ });
783
+ const setUserPasswordBodySchema = z.object({
784
+ newPassword: z.string().nonempty("newPassword cannot be empty").meta({ description: "The new password" }),
785
+ userId: z.coerce.string().nonempty("userId cannot be empty").meta({ description: "The user id" })
786
+ });
787
+ /**
788
+ * ### Endpoint
789
+ *
790
+ * POST `/admin/set-user-password`
791
+ *
792
+ * ### API Methods
793
+ *
794
+ * **server:**
795
+ * `auth.api.setUserPassword`
796
+ *
797
+ * **client:**
798
+ * `authClient.admin.setUserPassword`
799
+ *
800
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-set-user-password)
801
+ */
802
+ const setUserPassword = (opts) => createAuthEndpoint("/admin/set-user-password", {
803
+ method: "POST",
804
+ body: setUserPasswordBodySchema,
805
+ use: [adminMiddleware],
806
+ metadata: { openapi: {
807
+ operationId: "setUserPassword",
808
+ summary: "Set a user's password",
809
+ description: "Set a user's password",
810
+ responses: { 200: {
811
+ description: "Password set",
812
+ content: { "application/json": { schema: {
813
+ type: "object",
814
+ properties: { status: { type: "boolean" } }
815
+ } } }
816
+ } }
817
+ } }
818
+ }, async (ctx) => {
819
+ if (!hasPermission({
820
+ userId: ctx.context.session.user.id,
821
+ role: ctx.context.session.user.role,
822
+ options: opts,
823
+ permissions: { user: ["set-password"] }
824
+ })) throw APIError.from("FORBIDDEN", ADMIN_ERROR_CODES.YOU_ARE_NOT_ALLOWED_TO_SET_USERS_PASSWORD);
825
+ const { newPassword, userId } = ctx.body;
826
+ const minPasswordLength = ctx.context.password.config.minPasswordLength;
827
+ if (newPassword.length < minPasswordLength) {
828
+ ctx.context.logger.warn("Password is too short");
829
+ throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.PASSWORD_TOO_SHORT);
830
+ }
831
+ const maxPasswordLength = ctx.context.password.config.maxPasswordLength;
832
+ if (newPassword.length > maxPasswordLength) {
833
+ ctx.context.logger.warn("Password is too long");
834
+ throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.PASSWORD_TOO_LONG);
835
+ }
836
+ const user = await ctx.context.internalAdapter.findUserById(userId);
837
+ if (!user) throw APIError.from("NOT_FOUND", BASE_ERROR_CODES.USER_NOT_FOUND);
838
+ const hashedPassword = await ctx.context.password.hash(newPassword);
839
+ if (await ctx.context.internalAdapter.findCredentialAccount(userId)) await ctx.context.internalAdapter.updatePassword(userId, hashedPassword);
840
+ else await ctx.context.internalAdapter.createAccount({
841
+ userId,
842
+ providerId: "credential",
843
+ accountId: user.id,
844
+ password: hashedPassword
845
+ });
846
+ return ctx.json({ status: true });
847
+ });
848
+ const userHasPermissionBodySchema = z.object({
849
+ userId: z.coerce.string().optional().meta({ description: `The user id. Eg: "user-id"` }),
850
+ role: z.string().optional().meta({ description: `The role to check permission for. Eg: "admin"` })
851
+ }).and(z.xor([z.object({ permission: z.record(z.string(), z.array(z.string())) }), z.object({ permissions: z.record(z.string(), z.array(z.string())) })]));
852
+ /**
853
+ * ### Endpoint
854
+ *
855
+ * POST `/admin/has-permission`
856
+ *
857
+ * ### API Methods
858
+ *
859
+ * **server:**
860
+ * `auth.api.userHasPermission`
861
+ *
862
+ * **client:**
863
+ * `authClient.admin.hasPermission`
864
+ *
865
+ * @see [Read our docs to learn more.](https://better-auth.com/docs/plugins/admin#api-method-admin-has-permission)
866
+ */
867
+ const userHasPermission = (opts) => {
868
+ return createAuthEndpoint("/admin/has-permission", {
869
+ method: "POST",
870
+ body: userHasPermissionBodySchema,
871
+ metadata: {
872
+ openapi: {
873
+ description: "Check if the user has permission",
874
+ requestBody: { content: { "application/json": { schema: {
875
+ type: "object",
876
+ properties: { permissions: {
877
+ type: "object",
878
+ description: "The permission to check"
879
+ } },
880
+ required: ["permissions"]
881
+ } } } },
882
+ responses: { "200": {
883
+ description: "Success",
884
+ content: { "application/json": { schema: {
885
+ type: "object",
886
+ properties: {
887
+ error: { type: "string" },
888
+ success: { type: "boolean" }
889
+ },
890
+ required: ["success"]
891
+ } } }
892
+ } }
893
+ },
894
+ $Infer: { body: {} }
895
+ }
896
+ }, async (ctx) => {
897
+ if (!ctx.body?.permissions) throw new APIError("BAD_REQUEST", { message: "invalid permission check. no permission(s) were passed." });
898
+ const session = await getAuthoritativeSessionFromCtx(ctx);
899
+ if (!session && (ctx.request || ctx.headers)) throw new APIError("UNAUTHORIZED");
900
+ if (!session && !ctx.body.userId && !ctx.body.role) throw new APIError("BAD_REQUEST", { message: "user id or role is required" });
901
+ const user = session?.user || (ctx.body.role ? {
902
+ id: ctx.body.userId || "",
903
+ role: ctx.body.role
904
+ } : null) || (ctx.body.userId ? await ctx.context.internalAdapter.findUserById(ctx.body.userId) : null);
905
+ if (!user) throw new APIError("BAD_REQUEST", { message: "user not found" });
906
+ const result = hasPermission({
907
+ userId: user.id,
908
+ role: user.role,
909
+ options: opts,
910
+ permissions: ctx.body.permissions
911
+ });
912
+ return ctx.json({
913
+ error: null,
914
+ success: result
915
+ });
916
+ });
917
+ };
918
+ //#endregion
919
+ export { adminUpdateUser, banUser, createUser, getUser, impersonateUser, listUserSessions, listUsers, removeUser, revokeUserSession, revokeUserSessions, setRole, setUserPassword, stopImpersonating, unbanUser, userHasPermission };