@robelest/convex-auth 0.0.4-preview.2 → 0.0.4-preview.21

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 (798) hide show
  1. package/README.md +67 -26
  2. package/dist/authorization/index.d.ts +63 -0
  3. package/dist/authorization/index.d.ts.map +1 -0
  4. package/dist/authorization/index.js +63 -0
  5. package/dist/authorization/index.js.map +1 -0
  6. package/dist/bin.js +6185 -0
  7. package/dist/client/core/types.d.ts +20 -0
  8. package/dist/client/core/types.d.ts.map +1 -0
  9. package/dist/client/index.d.ts +2 -299
  10. package/dist/client/index.d.ts.map +1 -1
  11. package/dist/client/index.js +407 -534
  12. package/dist/client/index.js.map +1 -1
  13. package/dist/component/_generated/api.d.ts +42 -0
  14. package/dist/component/_generated/api.d.ts.map +1 -1
  15. package/dist/component/_generated/api.js.map +1 -1
  16. package/dist/component/_generated/component.d.ts +2546 -90
  17. package/dist/component/_generated/component.d.ts.map +1 -1
  18. package/dist/component/client/core/types.d.ts +2 -0
  19. package/dist/component/client/index.d.ts +2 -0
  20. package/dist/component/convex.config.d.ts +2 -2
  21. package/dist/component/functions.d.ts +11 -9
  22. package/dist/component/functions.d.ts.map +1 -1
  23. package/dist/component/functions.js.map +1 -1
  24. package/dist/component/index.d.ts +7 -11
  25. package/dist/component/index.js +2 -3
  26. package/dist/component/model.d.ts +153 -0
  27. package/dist/component/model.d.ts.map +1 -0
  28. package/dist/component/model.js +349 -0
  29. package/dist/component/model.js.map +1 -0
  30. package/dist/component/providers/anonymous.d.ts +54 -0
  31. package/dist/component/providers/anonymous.d.ts.map +1 -0
  32. package/dist/component/providers/credentials.d.ts +5 -5
  33. package/dist/component/providers/credentials.d.ts.map +1 -1
  34. package/dist/component/providers/device.d.ts +67 -0
  35. package/dist/component/providers/device.d.ts.map +1 -0
  36. package/dist/component/providers/email.d.ts +62 -0
  37. package/dist/component/providers/email.d.ts.map +1 -0
  38. package/dist/component/providers/oauth.d.ts.map +1 -1
  39. package/dist/component/providers/oauth.js.map +1 -1
  40. package/dist/component/providers/passkey.d.ts +57 -0
  41. package/dist/component/providers/passkey.d.ts.map +1 -0
  42. package/dist/component/providers/password.d.ts +88 -0
  43. package/dist/component/providers/password.d.ts.map +1 -0
  44. package/dist/component/providers/phone.d.ts +48 -0
  45. package/dist/component/providers/phone.d.ts.map +1 -0
  46. package/dist/component/providers/sso.d.ts +50 -0
  47. package/dist/component/providers/sso.d.ts.map +1 -0
  48. package/dist/component/providers/totp.d.ts +45 -0
  49. package/dist/component/providers/totp.d.ts.map +1 -0
  50. package/dist/component/public/enterprise/audit.d.ts +73 -0
  51. package/dist/component/public/enterprise/audit.d.ts.map +1 -0
  52. package/dist/component/public/enterprise/audit.js +108 -0
  53. package/dist/component/public/enterprise/audit.js.map +1 -0
  54. package/dist/component/public/enterprise/core.d.ts +176 -0
  55. package/dist/component/public/enterprise/core.d.ts.map +1 -0
  56. package/dist/component/public/enterprise/core.js +292 -0
  57. package/dist/component/public/enterprise/core.js.map +1 -0
  58. package/dist/component/public/enterprise/domains.d.ts +174 -0
  59. package/dist/component/public/enterprise/domains.d.ts.map +1 -0
  60. package/dist/component/public/enterprise/domains.js +271 -0
  61. package/dist/component/public/enterprise/domains.js.map +1 -0
  62. package/dist/component/public/enterprise/scim.d.ts +245 -0
  63. package/dist/component/public/enterprise/scim.d.ts.map +1 -0
  64. package/dist/component/public/enterprise/scim.js +344 -0
  65. package/dist/component/public/enterprise/scim.js.map +1 -0
  66. package/dist/component/public/enterprise/secrets.d.ts +78 -0
  67. package/dist/component/public/enterprise/secrets.d.ts.map +1 -0
  68. package/dist/component/public/enterprise/secrets.js +118 -0
  69. package/dist/component/public/enterprise/secrets.js.map +1 -0
  70. package/dist/component/public/enterprise/webhooks.d.ts +211 -0
  71. package/dist/component/public/enterprise/webhooks.d.ts.map +1 -0
  72. package/dist/component/public/enterprise/webhooks.js +300 -0
  73. package/dist/component/public/enterprise/webhooks.js.map +1 -0
  74. package/dist/component/public/factors/devices.d.ts +157 -0
  75. package/dist/component/public/factors/devices.d.ts.map +1 -0
  76. package/dist/component/public/factors/devices.js +216 -0
  77. package/dist/component/public/factors/devices.js.map +1 -0
  78. package/dist/component/public/factors/passkeys.d.ts +175 -0
  79. package/dist/component/public/factors/passkeys.d.ts.map +1 -0
  80. package/dist/component/public/factors/passkeys.js +238 -0
  81. package/dist/component/public/factors/passkeys.js.map +1 -0
  82. package/dist/component/public/factors/totp.d.ts +189 -0
  83. package/dist/component/public/factors/totp.d.ts.map +1 -0
  84. package/dist/component/public/factors/totp.js +254 -0
  85. package/dist/component/public/factors/totp.js.map +1 -0
  86. package/dist/component/public/groups/core.d.ts +137 -0
  87. package/dist/component/public/groups/core.d.ts.map +1 -0
  88. package/dist/component/public/groups/core.js +321 -0
  89. package/dist/component/public/groups/core.js.map +1 -0
  90. package/dist/component/public/groups/invites.d.ts +217 -0
  91. package/dist/component/public/groups/invites.d.ts.map +1 -0
  92. package/dist/component/public/groups/invites.js +457 -0
  93. package/dist/component/public/groups/invites.js.map +1 -0
  94. package/dist/component/public/groups/members.d.ts +204 -0
  95. package/dist/component/public/groups/members.d.ts.map +1 -0
  96. package/dist/component/public/groups/members.js +355 -0
  97. package/dist/component/public/groups/members.js.map +1 -0
  98. package/dist/component/public/identity/accounts.d.ts +147 -0
  99. package/dist/component/public/identity/accounts.d.ts.map +1 -0
  100. package/dist/component/public/identity/accounts.js +200 -0
  101. package/dist/component/public/identity/accounts.js.map +1 -0
  102. package/dist/component/public/identity/codes.d.ts +104 -0
  103. package/dist/component/public/identity/codes.d.ts.map +1 -0
  104. package/dist/component/public/identity/codes.js +140 -0
  105. package/dist/component/public/identity/codes.js.map +1 -0
  106. package/dist/component/public/identity/sessions.d.ts +128 -0
  107. package/dist/component/public/identity/sessions.d.ts.map +1 -0
  108. package/dist/component/public/identity/sessions.js +192 -0
  109. package/dist/component/public/identity/sessions.js.map +1 -0
  110. package/dist/component/public/identity/tokens.d.ts +169 -0
  111. package/dist/component/public/identity/tokens.d.ts.map +1 -0
  112. package/dist/component/public/identity/tokens.js +227 -0
  113. package/dist/component/public/identity/tokens.js.map +1 -0
  114. package/dist/component/public/identity/users.d.ts +212 -0
  115. package/dist/component/public/identity/users.d.ts.map +1 -0
  116. package/dist/component/public/identity/users.js +311 -0
  117. package/dist/component/public/identity/users.js.map +1 -0
  118. package/dist/component/public/identity/verifiers.d.ts +116 -0
  119. package/dist/component/public/identity/verifiers.d.ts.map +1 -0
  120. package/dist/component/public/identity/verifiers.js +154 -0
  121. package/dist/component/public/identity/verifiers.js.map +1 -0
  122. package/dist/component/public/security/keys.d.ts +209 -0
  123. package/dist/component/public/security/keys.d.ts.map +1 -0
  124. package/dist/component/public/security/keys.js +319 -0
  125. package/dist/component/public/security/keys.js.map +1 -0
  126. package/dist/component/public/security/limits.d.ts +114 -0
  127. package/dist/component/public/security/limits.d.ts.map +1 -0
  128. package/dist/component/public/security/limits.js +169 -0
  129. package/dist/component/public/security/limits.js.map +1 -0
  130. package/dist/component/public.d.ts +24 -271
  131. package/dist/component/public.d.ts.map +1 -1
  132. package/dist/component/public.js +21 -1229
  133. package/dist/component/schema.d.ts +473 -110
  134. package/dist/component/schema.js +162 -73
  135. package/dist/component/schema.js.map +1 -1
  136. package/dist/component/server/auth.d.ts +318 -373
  137. package/dist/component/server/auth.d.ts.map +1 -1
  138. package/dist/component/server/auth.js +204 -123
  139. package/dist/component/server/auth.js.map +1 -1
  140. package/dist/component/server/authError.js +34 -0
  141. package/dist/component/server/authError.js.map +1 -0
  142. package/dist/component/server/{providers.js → config.js} +43 -12
  143. package/dist/component/server/config.js.map +1 -0
  144. package/dist/component/server/cookies.js +3 -0
  145. package/dist/component/server/cookies.js.map +1 -1
  146. package/dist/component/server/core.js +713 -0
  147. package/dist/component/server/core.js.map +1 -0
  148. package/dist/component/server/crypto.js +38 -0
  149. package/dist/component/server/crypto.js.map +1 -0
  150. package/dist/component/server/{implementation/db.js → db.js} +2 -1
  151. package/dist/component/server/db.js.map +1 -0
  152. package/dist/component/server/device.js +109 -0
  153. package/dist/component/server/device.js.map +1 -0
  154. package/dist/component/server/enterprise/config.js +46 -0
  155. package/dist/component/server/enterprise/config.js.map +1 -0
  156. package/dist/component/server/enterprise/domain.js +885 -0
  157. package/dist/component/server/enterprise/domain.js.map +1 -0
  158. package/dist/component/server/enterprise/http.js +766 -0
  159. package/dist/component/server/enterprise/http.js.map +1 -0
  160. package/dist/component/server/enterprise/oidc.js +248 -0
  161. package/dist/component/server/enterprise/oidc.js.map +1 -0
  162. package/dist/component/server/enterprise/policy.js +85 -0
  163. package/dist/component/server/enterprise/policy.js.map +1 -0
  164. package/dist/component/server/enterprise/saml.js +338 -0
  165. package/dist/component/server/enterprise/saml.js.map +1 -0
  166. package/dist/component/server/enterprise/scim.js +97 -0
  167. package/dist/component/server/enterprise/scim.js.map +1 -0
  168. package/dist/component/server/enterprise/shared.js +51 -0
  169. package/dist/component/server/enterprise/shared.js.map +1 -0
  170. package/dist/component/server/errors.d.ts +1 -0
  171. package/dist/component/server/errors.js +24 -16
  172. package/dist/component/server/errors.js.map +1 -1
  173. package/dist/component/server/http.js +288 -0
  174. package/dist/component/server/http.js.map +1 -0
  175. package/dist/component/server/identity.js +13 -0
  176. package/dist/component/server/identity.js.map +1 -0
  177. package/dist/{server/implementation → component/server}/keys.js +9 -31
  178. package/dist/component/server/keys.js.map +1 -0
  179. package/dist/component/server/limits.js +61 -0
  180. package/dist/component/server/limits.js.map +1 -0
  181. package/dist/component/server/mutations/account.js +44 -0
  182. package/dist/component/server/mutations/account.js.map +1 -0
  183. package/dist/component/server/{implementation/mutations → mutations}/code.js +7 -4
  184. package/dist/component/server/mutations/code.js.map +1 -0
  185. package/dist/component/server/mutations/invalidate.js +32 -0
  186. package/dist/component/server/mutations/invalidate.js.map +1 -0
  187. package/dist/component/server/mutations/oauth.js +110 -0
  188. package/dist/component/server/mutations/oauth.js.map +1 -0
  189. package/dist/component/server/mutations/refresh.js +119 -0
  190. package/dist/component/server/mutations/refresh.js.map +1 -0
  191. package/dist/component/server/mutations/register.js +83 -0
  192. package/dist/component/server/mutations/register.js.map +1 -0
  193. package/dist/component/server/mutations/retrieve.js +65 -0
  194. package/dist/component/server/mutations/retrieve.js.map +1 -0
  195. package/dist/component/server/mutations/signature.js +32 -0
  196. package/dist/component/server/mutations/signature.js.map +1 -0
  197. package/dist/component/server/{implementation/mutations → mutations}/signin.js +2 -2
  198. package/dist/component/server/mutations/signin.js.map +1 -0
  199. package/dist/component/server/mutations/signout.js +27 -0
  200. package/dist/component/server/mutations/signout.js.map +1 -0
  201. package/dist/component/server/mutations/store/refs.js +15 -0
  202. package/dist/component/server/mutations/store/refs.js.map +1 -0
  203. package/dist/component/server/mutations/store.js +85 -0
  204. package/dist/component/server/mutations/store.js.map +1 -0
  205. package/dist/component/server/mutations/verifier.js +18 -0
  206. package/dist/component/server/mutations/verifier.js.map +1 -0
  207. package/dist/component/server/mutations/verify.js +98 -0
  208. package/dist/component/server/mutations/verify.js.map +1 -0
  209. package/dist/component/server/oauth.js +106 -60
  210. package/dist/component/server/oauth.js.map +1 -1
  211. package/dist/component/server/passkey.js +328 -0
  212. package/dist/component/server/passkey.js.map +1 -0
  213. package/dist/{server/implementation → component/server}/redirects.js +13 -11
  214. package/dist/component/server/redirects.js.map +1 -0
  215. package/dist/component/server/refresh.js +96 -0
  216. package/dist/component/server/refresh.js.map +1 -0
  217. package/dist/component/server/runtime.d.ts +136 -0
  218. package/dist/component/server/runtime.d.ts.map +1 -0
  219. package/dist/component/server/runtime.js +413 -0
  220. package/dist/component/server/runtime.js.map +1 -0
  221. package/dist/{server/implementation → component/server}/sessions.js +14 -8
  222. package/dist/component/server/sessions.js.map +1 -0
  223. package/dist/component/server/signin.js +201 -0
  224. package/dist/component/server/signin.js.map +1 -0
  225. package/dist/component/server/tokens.js +17 -0
  226. package/dist/component/server/tokens.js.map +1 -0
  227. package/dist/component/server/totp.js +148 -0
  228. package/dist/component/server/totp.js.map +1 -0
  229. package/dist/component/server/types.d.ts +387 -298
  230. package/dist/component/server/types.d.ts.map +1 -1
  231. package/dist/component/server/{implementation/types.js → types.js} +1 -1
  232. package/dist/component/server/types.js.map +1 -0
  233. package/dist/component/server/{implementation/users.js → users.js} +54 -35
  234. package/dist/component/server/users.js.map +1 -0
  235. package/dist/component/server/utils.js +110 -4
  236. package/dist/component/server/utils.js.map +1 -1
  237. package/dist/core/types.d.ts +369 -0
  238. package/dist/core/types.d.ts.map +1 -0
  239. package/dist/factors/device.js +105 -0
  240. package/dist/factors/device.js.map +1 -0
  241. package/dist/factors/passkey.js +181 -0
  242. package/dist/factors/passkey.js.map +1 -0
  243. package/dist/factors/totp.js +122 -0
  244. package/dist/factors/totp.js.map +1 -0
  245. package/dist/providers/anonymous.d.ts +3 -9
  246. package/dist/providers/anonymous.d.ts.map +1 -1
  247. package/dist/providers/anonymous.js +1 -18
  248. package/dist/providers/anonymous.js.map +1 -1
  249. package/dist/providers/credentials.d.ts +8 -10
  250. package/dist/providers/credentials.d.ts.map +1 -1
  251. package/dist/providers/credentials.js +3 -5
  252. package/dist/providers/credentials.js.map +1 -1
  253. package/dist/providers/device.d.ts +18 -10
  254. package/dist/providers/device.d.ts.map +1 -1
  255. package/dist/providers/device.js +4 -8
  256. package/dist/providers/device.js.map +1 -1
  257. package/dist/providers/email.d.ts +50 -23
  258. package/dist/providers/email.d.ts.map +1 -1
  259. package/dist/providers/email.js +58 -34
  260. package/dist/providers/email.js.map +1 -1
  261. package/dist/providers/index.d.ts +7 -3
  262. package/dist/providers/index.js +4 -1
  263. package/dist/providers/oauth.d.ts.map +1 -1
  264. package/dist/providers/oauth.js.map +1 -1
  265. package/dist/providers/passkey.d.ts +12 -9
  266. package/dist/providers/passkey.d.ts.map +1 -1
  267. package/dist/providers/passkey.js +1 -7
  268. package/dist/providers/passkey.js.map +1 -1
  269. package/dist/providers/password.d.ts +6 -12
  270. package/dist/providers/password.d.ts.map +1 -1
  271. package/dist/providers/password.js +189 -89
  272. package/dist/providers/password.js.map +1 -1
  273. package/dist/providers/phone.d.ts +40 -11
  274. package/dist/providers/phone.d.ts.map +1 -1
  275. package/dist/providers/phone.js +52 -21
  276. package/dist/providers/phone.js.map +1 -1
  277. package/dist/providers/sso.d.ts +50 -0
  278. package/dist/providers/sso.d.ts.map +1 -0
  279. package/dist/providers/sso.js +34 -0
  280. package/dist/providers/sso.js.map +1 -0
  281. package/dist/providers/totp.d.ts +12 -9
  282. package/dist/providers/totp.d.ts.map +1 -1
  283. package/dist/providers/totp.js +1 -7
  284. package/dist/providers/totp.js.map +1 -1
  285. package/dist/runtime/browser.js +68 -0
  286. package/dist/runtime/browser.js.map +1 -0
  287. package/dist/runtime/invite.js +51 -0
  288. package/dist/runtime/invite.js.map +1 -0
  289. package/dist/runtime/proxy.js +70 -0
  290. package/dist/runtime/proxy.js.map +1 -0
  291. package/dist/runtime/storage.js +37 -0
  292. package/dist/runtime/storage.js.map +1 -0
  293. package/dist/server/auth.d.ts +335 -370
  294. package/dist/server/auth.d.ts.map +1 -1
  295. package/dist/server/auth.js +204 -123
  296. package/dist/server/auth.js.map +1 -1
  297. package/dist/server/authError.d.ts +46 -0
  298. package/dist/server/authError.d.ts.map +1 -0
  299. package/dist/server/authError.js +34 -0
  300. package/dist/server/authError.js.map +1 -0
  301. package/dist/server/config.d.ts +1 -0
  302. package/dist/server/{providers.js → config.js} +43 -12
  303. package/dist/server/config.js.map +1 -0
  304. package/dist/server/cookies.d.ts +1 -38
  305. package/dist/server/cookies.js +3 -0
  306. package/dist/server/cookies.js.map +1 -1
  307. package/dist/server/core.d.ts +1436 -0
  308. package/dist/server/core.d.ts.map +1 -0
  309. package/dist/server/core.js +713 -0
  310. package/dist/server/core.js.map +1 -0
  311. package/dist/server/crypto.d.ts +8 -0
  312. package/dist/server/crypto.d.ts.map +1 -0
  313. package/dist/server/crypto.js +38 -0
  314. package/dist/server/crypto.js.map +1 -0
  315. package/dist/server/db.d.ts +1 -0
  316. package/dist/server/{implementation/db.js → db.js} +2 -1
  317. package/dist/server/db.js.map +1 -0
  318. package/dist/server/device.d.ts +1 -0
  319. package/dist/server/device.js +109 -0
  320. package/dist/server/device.js.map +1 -0
  321. package/dist/server/enterprise/config.d.ts +1 -0
  322. package/dist/server/enterprise/config.js +46 -0
  323. package/dist/server/enterprise/config.js.map +1 -0
  324. package/dist/server/enterprise/domain.d.ts +409 -0
  325. package/dist/server/enterprise/domain.d.ts.map +1 -0
  326. package/dist/server/enterprise/domain.js +885 -0
  327. package/dist/server/enterprise/domain.js.map +1 -0
  328. package/dist/server/enterprise/http.d.ts +26 -0
  329. package/dist/server/enterprise/http.d.ts.map +1 -0
  330. package/dist/server/enterprise/http.js +766 -0
  331. package/dist/server/enterprise/http.js.map +1 -0
  332. package/dist/server/enterprise/oidc.d.ts +1 -0
  333. package/dist/server/enterprise/oidc.js +248 -0
  334. package/dist/server/enterprise/oidc.js.map +1 -0
  335. package/dist/server/enterprise/policy.d.ts +1 -0
  336. package/dist/server/enterprise/policy.js +85 -0
  337. package/dist/server/enterprise/policy.js.map +1 -0
  338. package/dist/server/enterprise/saml.d.ts +1 -0
  339. package/dist/server/enterprise/saml.js +338 -0
  340. package/dist/server/enterprise/saml.js.map +1 -0
  341. package/dist/server/enterprise/scim.d.ts +1 -0
  342. package/dist/server/enterprise/scim.js +97 -0
  343. package/dist/server/enterprise/scim.js.map +1 -0
  344. package/dist/server/enterprise/shared.d.ts +5 -0
  345. package/dist/server/enterprise/shared.d.ts.map +1 -0
  346. package/dist/server/enterprise/shared.js +51 -0
  347. package/dist/server/enterprise/shared.js.map +1 -0
  348. package/dist/server/enterprise/validators.d.ts +1 -0
  349. package/dist/server/enterprise/validators.js +60 -0
  350. package/dist/server/enterprise/validators.js.map +1 -0
  351. package/dist/server/errors.d.ts +33 -1
  352. package/dist/server/errors.d.ts.map +1 -1
  353. package/dist/server/errors.js +44 -1
  354. package/dist/server/errors.js.map +1 -1
  355. package/dist/server/http.d.ts +59 -0
  356. package/dist/server/http.d.ts.map +1 -0
  357. package/dist/server/http.js +288 -0
  358. package/dist/server/http.js.map +1 -0
  359. package/dist/server/identity.d.ts +1 -0
  360. package/dist/server/identity.js +13 -0
  361. package/dist/server/identity.js.map +1 -0
  362. package/dist/server/index.d.ts +4 -182
  363. package/dist/server/index.js +4 -376
  364. package/dist/server/keys.d.ts +1 -0
  365. package/dist/{component/server/implementation → server}/keys.js +9 -31
  366. package/dist/server/keys.js.map +1 -0
  367. package/dist/server/limits.d.ts +1 -0
  368. package/dist/server/limits.js +61 -0
  369. package/dist/server/limits.js.map +1 -0
  370. package/dist/server/mounts.d.ts +647 -0
  371. package/dist/server/mounts.d.ts.map +1 -0
  372. package/dist/server/mounts.js +643 -0
  373. package/dist/server/mounts.js.map +1 -0
  374. package/dist/server/mutations/account.d.ts +30 -0
  375. package/dist/server/mutations/account.d.ts.map +1 -0
  376. package/dist/server/mutations/account.js +44 -0
  377. package/dist/server/mutations/account.js.map +1 -0
  378. package/dist/server/mutations/code.d.ts +30 -0
  379. package/dist/server/mutations/code.d.ts.map +1 -0
  380. package/dist/server/{implementation/mutations → mutations}/code.js +7 -4
  381. package/dist/server/mutations/code.js.map +1 -0
  382. package/dist/server/mutations/index.d.ts +14 -0
  383. package/dist/server/mutations/index.js +15 -0
  384. package/dist/server/mutations/invalidate.d.ts +20 -0
  385. package/dist/server/mutations/invalidate.d.ts.map +1 -0
  386. package/dist/server/mutations/invalidate.js +32 -0
  387. package/dist/server/mutations/invalidate.js.map +1 -0
  388. package/dist/server/mutations/oauth.d.ts +28 -0
  389. package/dist/server/mutations/oauth.d.ts.map +1 -0
  390. package/dist/server/mutations/oauth.js +110 -0
  391. package/dist/server/mutations/oauth.js.map +1 -0
  392. package/dist/server/mutations/refresh.d.ts +21 -0
  393. package/dist/server/mutations/refresh.d.ts.map +1 -0
  394. package/dist/server/mutations/refresh.js +119 -0
  395. package/dist/server/mutations/refresh.js.map +1 -0
  396. package/dist/server/mutations/register.d.ts +38 -0
  397. package/dist/server/mutations/register.d.ts.map +1 -0
  398. package/dist/server/mutations/register.js +83 -0
  399. package/dist/server/mutations/register.js.map +1 -0
  400. package/dist/server/mutations/retrieve.d.ts +33 -0
  401. package/dist/server/mutations/retrieve.d.ts.map +1 -0
  402. package/dist/server/mutations/retrieve.js +65 -0
  403. package/dist/server/mutations/retrieve.js.map +1 -0
  404. package/dist/server/mutations/signature.d.ts +22 -0
  405. package/dist/server/mutations/signature.d.ts.map +1 -0
  406. package/dist/server/mutations/signature.js +32 -0
  407. package/dist/server/mutations/signature.js.map +1 -0
  408. package/dist/server/mutations/signin.d.ts +22 -0
  409. package/dist/server/mutations/signin.d.ts.map +1 -0
  410. package/dist/server/{implementation/mutations → mutations}/signin.js +2 -2
  411. package/dist/server/mutations/signin.js.map +1 -0
  412. package/dist/server/mutations/signout.d.ts +16 -0
  413. package/dist/server/mutations/signout.d.ts.map +1 -0
  414. package/dist/server/mutations/signout.js +27 -0
  415. package/dist/server/mutations/signout.js.map +1 -0
  416. package/dist/server/mutations/store/refs.d.ts +12 -0
  417. package/dist/server/mutations/store/refs.d.ts.map +1 -0
  418. package/dist/server/mutations/store/refs.js +15 -0
  419. package/dist/server/mutations/store/refs.js.map +1 -0
  420. package/dist/server/mutations/store.d.ts +306 -0
  421. package/dist/server/mutations/store.d.ts.map +1 -0
  422. package/dist/server/mutations/store.js +85 -0
  423. package/dist/server/mutations/store.js.map +1 -0
  424. package/dist/server/mutations/verifier.d.ts +13 -0
  425. package/dist/server/mutations/verifier.d.ts.map +1 -0
  426. package/dist/server/mutations/verifier.js +18 -0
  427. package/dist/server/mutations/verifier.js.map +1 -0
  428. package/dist/server/mutations/verify.d.ts +26 -0
  429. package/dist/server/mutations/verify.d.ts.map +1 -0
  430. package/dist/server/mutations/verify.js +98 -0
  431. package/dist/server/mutations/verify.js.map +1 -0
  432. package/dist/server/oauth.d.ts +1 -48
  433. package/dist/server/oauth.js +107 -64
  434. package/dist/server/oauth.js.map +1 -1
  435. package/dist/server/passkey.d.ts +27 -0
  436. package/dist/server/passkey.d.ts.map +1 -0
  437. package/dist/server/passkey.js +328 -0
  438. package/dist/server/passkey.js.map +1 -0
  439. package/dist/server/redirects.d.ts +1 -0
  440. package/dist/{component/server/implementation → server}/redirects.js +13 -11
  441. package/dist/server/redirects.js.map +1 -0
  442. package/dist/server/refresh.d.ts +1 -0
  443. package/dist/server/refresh.js +96 -0
  444. package/dist/server/refresh.js.map +1 -0
  445. package/dist/server/runtime.d.ts +136 -0
  446. package/dist/server/runtime.d.ts.map +1 -0
  447. package/dist/server/runtime.js +413 -0
  448. package/dist/server/runtime.js.map +1 -0
  449. package/dist/server/sessions.d.ts +1 -0
  450. package/dist/{component/server/implementation → server}/sessions.js +14 -8
  451. package/dist/server/sessions.js.map +1 -0
  452. package/dist/server/signin.d.ts +1 -0
  453. package/dist/server/signin.js +201 -0
  454. package/dist/server/signin.js.map +1 -0
  455. package/dist/server/ssr.d.ts +226 -0
  456. package/dist/server/ssr.d.ts.map +1 -0
  457. package/dist/server/ssr.js +786 -0
  458. package/dist/server/ssr.js.map +1 -0
  459. package/dist/server/templates.d.ts +1 -21
  460. package/dist/server/templates.js +2 -1
  461. package/dist/server/templates.js.map +1 -1
  462. package/dist/server/tokens.d.ts +1 -0
  463. package/dist/server/tokens.js +17 -0
  464. package/dist/server/tokens.js.map +1 -0
  465. package/dist/server/totp.d.ts +1 -0
  466. package/dist/server/totp.js +148 -0
  467. package/dist/server/totp.js.map +1 -0
  468. package/dist/server/types.d.ts +498 -306
  469. package/dist/server/types.d.ts.map +1 -1
  470. package/dist/server/types.js +108 -1
  471. package/dist/server/types.js.map +1 -0
  472. package/dist/server/users.d.ts +1 -0
  473. package/dist/server/{implementation/users.js → users.js} +54 -35
  474. package/dist/server/users.js.map +1 -0
  475. package/dist/server/utils.d.ts +1 -6
  476. package/dist/server/utils.js +110 -4
  477. package/dist/server/utils.js.map +1 -1
  478. package/package.json +49 -46
  479. package/src/authorization/index.ts +83 -0
  480. package/src/cli/bin.ts +5 -0
  481. package/src/cli/command.ts +6 -5
  482. package/src/cli/index.ts +456 -248
  483. package/src/cli/keys.ts +3 -0
  484. package/src/client/core/types.ts +437 -0
  485. package/src/client/factors/device.ts +160 -0
  486. package/src/client/factors/passkey.ts +282 -0
  487. package/src/client/factors/totp.ts +150 -0
  488. package/src/client/index.ts +745 -989
  489. package/src/client/runtime/browser.ts +112 -0
  490. package/src/client/runtime/invite.ts +65 -0
  491. package/src/client/runtime/proxy.ts +111 -0
  492. package/src/client/runtime/storage.ts +79 -0
  493. package/src/component/_generated/api.ts +42 -0
  494. package/src/component/_generated/component.ts +3123 -102
  495. package/src/component/functions.ts +38 -22
  496. package/src/component/index.ts +10 -20
  497. package/src/component/model.ts +449 -0
  498. package/src/component/public/enterprise/audit.ts +120 -0
  499. package/src/component/public/enterprise/core.ts +354 -0
  500. package/src/component/public/enterprise/domains.ts +323 -0
  501. package/src/component/public/enterprise/scim.ts +396 -0
  502. package/src/component/public/enterprise/secrets.ts +132 -0
  503. package/src/component/public/enterprise/webhooks.ts +306 -0
  504. package/src/component/public/factors/devices.ts +223 -0
  505. package/src/component/public/factors/passkeys.ts +242 -0
  506. package/src/component/public/factors/totp.ts +258 -0
  507. package/src/component/public/groups/core.ts +481 -0
  508. package/src/component/public/groups/invites.ts +602 -0
  509. package/src/component/public/groups/members.ts +409 -0
  510. package/src/component/public/identity/accounts.ts +206 -0
  511. package/src/component/public/identity/codes.ts +148 -0
  512. package/src/component/public/identity/sessions.ts +209 -0
  513. package/src/component/public/identity/tokens.ts +250 -0
  514. package/src/component/public/identity/users.ts +354 -0
  515. package/src/component/public/identity/verifiers.ts +157 -0
  516. package/src/component/public/security/keys.ts +365 -0
  517. package/src/component/public/security/limits.ts +173 -0
  518. package/src/component/public.ts +26 -1766
  519. package/src/component/schema.ts +273 -100
  520. package/src/providers/anonymous.ts +10 -20
  521. package/src/providers/credentials.ts +14 -22
  522. package/src/providers/device.ts +3 -14
  523. package/src/providers/email.ts +83 -47
  524. package/src/providers/index.ts +7 -0
  525. package/src/providers/oauth.ts +5 -3
  526. package/src/providers/passkey.ts +0 -13
  527. package/src/providers/password.ts +307 -130
  528. package/src/providers/phone.ts +81 -37
  529. package/src/providers/sso.ts +54 -0
  530. package/src/providers/totp.ts +0 -13
  531. package/src/samlify.d.ts +53 -0
  532. package/src/server/auth.ts +701 -247
  533. package/src/server/authError.ts +44 -0
  534. package/src/server/{providers.ts → config.ts} +84 -15
  535. package/src/server/cookies.ts +8 -1
  536. package/src/server/core.ts +2095 -0
  537. package/src/server/crypto.ts +88 -0
  538. package/src/server/{implementation/db.ts → db.ts} +90 -15
  539. package/src/server/device.ts +221 -0
  540. package/src/server/enterprise/config.ts +51 -0
  541. package/src/server/enterprise/domain.ts +1751 -0
  542. package/src/server/enterprise/http.ts +1324 -0
  543. package/src/server/enterprise/oidc.ts +500 -0
  544. package/src/server/enterprise/policy.ts +128 -0
  545. package/src/server/enterprise/saml.ts +578 -0
  546. package/src/server/enterprise/scim.ts +135 -0
  547. package/src/server/enterprise/shared.ts +134 -0
  548. package/src/server/enterprise/validators.ts +93 -0
  549. package/src/server/errors.ts +130 -119
  550. package/src/server/http.ts +531 -0
  551. package/src/server/identity.ts +18 -0
  552. package/src/server/index.ts +32 -650
  553. package/src/server/{implementation/keys.ts → keys.ts} +16 -44
  554. package/src/server/limits.ts +134 -0
  555. package/src/server/mounts.ts +948 -0
  556. package/src/server/mutations/account.ts +76 -0
  557. package/src/server/{implementation/mutations → mutations}/code.ts +22 -11
  558. package/src/server/mutations/index.ts +13 -0
  559. package/src/server/mutations/invalidate.ts +50 -0
  560. package/src/server/mutations/oauth.ts +237 -0
  561. package/src/server/mutations/refresh.ts +298 -0
  562. package/src/server/mutations/register.ts +200 -0
  563. package/src/server/mutations/retrieve.ts +109 -0
  564. package/src/server/mutations/signature.ts +50 -0
  565. package/src/server/{implementation/mutations → mutations}/signin.ts +9 -7
  566. package/src/server/mutations/signout.ts +43 -0
  567. package/src/server/mutations/store/refs.ts +10 -0
  568. package/src/server/mutations/store.ts +138 -0
  569. package/src/server/mutations/verifier.ts +34 -0
  570. package/src/server/mutations/verify.ts +202 -0
  571. package/src/server/oauth.ts +243 -131
  572. package/src/server/passkey.ts +784 -0
  573. package/src/server/{implementation/redirects.ts → redirects.ts} +21 -16
  574. package/src/server/refresh.ts +222 -0
  575. package/src/server/runtime.ts +880 -0
  576. package/src/server/{implementation/sessions.ts → sessions.ts} +33 -25
  577. package/src/server/signin.ts +438 -0
  578. package/src/server/ssr.ts +1764 -0
  579. package/src/server/templates.ts +8 -3
  580. package/src/server/{implementation/tokens.ts → tokens.ts} +11 -5
  581. package/src/server/totp.ts +349 -0
  582. package/src/server/types.ts +972 -207
  583. package/src/server/{implementation/users.ts → users.ts} +129 -75
  584. package/src/server/utils.ts +192 -5
  585. package/src/test.ts +28 -4
  586. package/dist/bin.cjs +0 -27757
  587. package/dist/component/providers/email.js +0 -47
  588. package/dist/component/providers/email.js.map +0 -1
  589. package/dist/component/public.js.map +0 -1
  590. package/dist/component/server/implementation/db.js.map +0 -1
  591. package/dist/component/server/implementation/device.js +0 -135
  592. package/dist/component/server/implementation/device.js.map +0 -1
  593. package/dist/component/server/implementation/index.d.ts +0 -870
  594. package/dist/component/server/implementation/index.d.ts.map +0 -1
  595. package/dist/component/server/implementation/index.js +0 -610
  596. package/dist/component/server/implementation/index.js.map +0 -1
  597. package/dist/component/server/implementation/keys.js.map +0 -1
  598. package/dist/component/server/implementation/mutations/account.js +0 -39
  599. package/dist/component/server/implementation/mutations/account.js.map +0 -1
  600. package/dist/component/server/implementation/mutations/code.js.map +0 -1
  601. package/dist/component/server/implementation/mutations/index.js +0 -70
  602. package/dist/component/server/implementation/mutations/index.js.map +0 -1
  603. package/dist/component/server/implementation/mutations/invalidate.js +0 -29
  604. package/dist/component/server/implementation/mutations/invalidate.js.map +0 -1
  605. package/dist/component/server/implementation/mutations/oauth.js +0 -51
  606. package/dist/component/server/implementation/mutations/oauth.js.map +0 -1
  607. package/dist/component/server/implementation/mutations/refresh.js +0 -85
  608. package/dist/component/server/implementation/mutations/refresh.js.map +0 -1
  609. package/dist/component/server/implementation/mutations/register.js +0 -65
  610. package/dist/component/server/implementation/mutations/register.js.map +0 -1
  611. package/dist/component/server/implementation/mutations/retrieve.js +0 -50
  612. package/dist/component/server/implementation/mutations/retrieve.js.map +0 -1
  613. package/dist/component/server/implementation/mutations/signature.js +0 -27
  614. package/dist/component/server/implementation/mutations/signature.js.map +0 -1
  615. package/dist/component/server/implementation/mutations/signin.js.map +0 -1
  616. package/dist/component/server/implementation/mutations/signout.js +0 -27
  617. package/dist/component/server/implementation/mutations/signout.js.map +0 -1
  618. package/dist/component/server/implementation/mutations/store.js +0 -12
  619. package/dist/component/server/implementation/mutations/store.js.map +0 -1
  620. package/dist/component/server/implementation/mutations/verifier.js +0 -16
  621. package/dist/component/server/implementation/mutations/verifier.js.map +0 -1
  622. package/dist/component/server/implementation/mutations/verify.js +0 -105
  623. package/dist/component/server/implementation/mutations/verify.js.map +0 -1
  624. package/dist/component/server/implementation/passkey.js +0 -307
  625. package/dist/component/server/implementation/passkey.js.map +0 -1
  626. package/dist/component/server/implementation/provider.js +0 -19
  627. package/dist/component/server/implementation/provider.js.map +0 -1
  628. package/dist/component/server/implementation/ratelimit.js +0 -48
  629. package/dist/component/server/implementation/ratelimit.js.map +0 -1
  630. package/dist/component/server/implementation/redirects.js.map +0 -1
  631. package/dist/component/server/implementation/refresh.js +0 -109
  632. package/dist/component/server/implementation/refresh.js.map +0 -1
  633. package/dist/component/server/implementation/sessions.js.map +0 -1
  634. package/dist/component/server/implementation/signin.js +0 -148
  635. package/dist/component/server/implementation/signin.js.map +0 -1
  636. package/dist/component/server/implementation/tokens.js +0 -15
  637. package/dist/component/server/implementation/tokens.js.map +0 -1
  638. package/dist/component/server/implementation/totp.js +0 -142
  639. package/dist/component/server/implementation/totp.js.map +0 -1
  640. package/dist/component/server/implementation/types.d.ts +0 -42
  641. package/dist/component/server/implementation/types.d.ts.map +0 -1
  642. package/dist/component/server/implementation/types.js.map +0 -1
  643. package/dist/component/server/implementation/users.js.map +0 -1
  644. package/dist/component/server/implementation/utils.js +0 -56
  645. package/dist/component/server/implementation/utils.js.map +0 -1
  646. package/dist/component/server/providers.js.map +0 -1
  647. package/dist/component/server/templates.js +0 -84
  648. package/dist/component/server/templates.js.map +0 -1
  649. package/dist/server/cookies.d.ts.map +0 -1
  650. package/dist/server/implementation/db.d.ts +0 -86
  651. package/dist/server/implementation/db.d.ts.map +0 -1
  652. package/dist/server/implementation/db.js.map +0 -1
  653. package/dist/server/implementation/device.d.ts +0 -30
  654. package/dist/server/implementation/device.d.ts.map +0 -1
  655. package/dist/server/implementation/device.js +0 -135
  656. package/dist/server/implementation/device.js.map +0 -1
  657. package/dist/server/implementation/index.d.ts +0 -870
  658. package/dist/server/implementation/index.d.ts.map +0 -1
  659. package/dist/server/implementation/index.js +0 -610
  660. package/dist/server/implementation/index.js.map +0 -1
  661. package/dist/server/implementation/keys.d.ts +0 -66
  662. package/dist/server/implementation/keys.d.ts.map +0 -1
  663. package/dist/server/implementation/keys.js.map +0 -1
  664. package/dist/server/implementation/mutations/account.d.ts +0 -27
  665. package/dist/server/implementation/mutations/account.d.ts.map +0 -1
  666. package/dist/server/implementation/mutations/account.js +0 -39
  667. package/dist/server/implementation/mutations/account.js.map +0 -1
  668. package/dist/server/implementation/mutations/code.d.ts +0 -29
  669. package/dist/server/implementation/mutations/code.d.ts.map +0 -1
  670. package/dist/server/implementation/mutations/code.js.map +0 -1
  671. package/dist/server/implementation/mutations/index.d.ts +0 -310
  672. package/dist/server/implementation/mutations/index.d.ts.map +0 -1
  673. package/dist/server/implementation/mutations/index.js +0 -70
  674. package/dist/server/implementation/mutations/index.js.map +0 -1
  675. package/dist/server/implementation/mutations/invalidate.d.ts +0 -18
  676. package/dist/server/implementation/mutations/invalidate.d.ts.map +0 -1
  677. package/dist/server/implementation/mutations/invalidate.js +0 -29
  678. package/dist/server/implementation/mutations/invalidate.js.map +0 -1
  679. package/dist/server/implementation/mutations/oauth.d.ts +0 -23
  680. package/dist/server/implementation/mutations/oauth.d.ts.map +0 -1
  681. package/dist/server/implementation/mutations/oauth.js +0 -51
  682. package/dist/server/implementation/mutations/oauth.js.map +0 -1
  683. package/dist/server/implementation/mutations/refresh.d.ts +0 -20
  684. package/dist/server/implementation/mutations/refresh.d.ts.map +0 -1
  685. package/dist/server/implementation/mutations/refresh.js +0 -85
  686. package/dist/server/implementation/mutations/refresh.js.map +0 -1
  687. package/dist/server/implementation/mutations/register.d.ts +0 -37
  688. package/dist/server/implementation/mutations/register.d.ts.map +0 -1
  689. package/dist/server/implementation/mutations/register.js +0 -65
  690. package/dist/server/implementation/mutations/register.js.map +0 -1
  691. package/dist/server/implementation/mutations/retrieve.d.ts +0 -31
  692. package/dist/server/implementation/mutations/retrieve.d.ts.map +0 -1
  693. package/dist/server/implementation/mutations/retrieve.js +0 -50
  694. package/dist/server/implementation/mutations/retrieve.js.map +0 -1
  695. package/dist/server/implementation/mutations/signature.d.ts +0 -19
  696. package/dist/server/implementation/mutations/signature.d.ts.map +0 -1
  697. package/dist/server/implementation/mutations/signature.js +0 -27
  698. package/dist/server/implementation/mutations/signature.js.map +0 -1
  699. package/dist/server/implementation/mutations/signin.d.ts +0 -21
  700. package/dist/server/implementation/mutations/signin.d.ts.map +0 -1
  701. package/dist/server/implementation/mutations/signin.js.map +0 -1
  702. package/dist/server/implementation/mutations/signout.d.ts +0 -14
  703. package/dist/server/implementation/mutations/signout.d.ts.map +0 -1
  704. package/dist/server/implementation/mutations/signout.js +0 -27
  705. package/dist/server/implementation/mutations/signout.js.map +0 -1
  706. package/dist/server/implementation/mutations/store.d.ts +0 -11
  707. package/dist/server/implementation/mutations/store.d.ts.map +0 -1
  708. package/dist/server/implementation/mutations/store.js +0 -12
  709. package/dist/server/implementation/mutations/store.js.map +0 -1
  710. package/dist/server/implementation/mutations/verifier.d.ts +0 -11
  711. package/dist/server/implementation/mutations/verifier.d.ts.map +0 -1
  712. package/dist/server/implementation/mutations/verifier.js +0 -16
  713. package/dist/server/implementation/mutations/verifier.js.map +0 -1
  714. package/dist/server/implementation/mutations/verify.d.ts +0 -25
  715. package/dist/server/implementation/mutations/verify.d.ts.map +0 -1
  716. package/dist/server/implementation/mutations/verify.js +0 -105
  717. package/dist/server/implementation/mutations/verify.js.map +0 -1
  718. package/dist/server/implementation/passkey.d.ts +0 -24
  719. package/dist/server/implementation/passkey.d.ts.map +0 -1
  720. package/dist/server/implementation/passkey.js +0 -307
  721. package/dist/server/implementation/passkey.js.map +0 -1
  722. package/dist/server/implementation/provider.d.ts +0 -10
  723. package/dist/server/implementation/provider.d.ts.map +0 -1
  724. package/dist/server/implementation/provider.js +0 -19
  725. package/dist/server/implementation/provider.js.map +0 -1
  726. package/dist/server/implementation/ratelimit.d.ts +0 -10
  727. package/dist/server/implementation/ratelimit.d.ts.map +0 -1
  728. package/dist/server/implementation/ratelimit.js +0 -48
  729. package/dist/server/implementation/ratelimit.js.map +0 -1
  730. package/dist/server/implementation/redirects.d.ts +0 -10
  731. package/dist/server/implementation/redirects.d.ts.map +0 -1
  732. package/dist/server/implementation/redirects.js.map +0 -1
  733. package/dist/server/implementation/refresh.d.ts +0 -37
  734. package/dist/server/implementation/refresh.d.ts.map +0 -1
  735. package/dist/server/implementation/refresh.js +0 -109
  736. package/dist/server/implementation/refresh.js.map +0 -1
  737. package/dist/server/implementation/sessions.d.ts +0 -29
  738. package/dist/server/implementation/sessions.d.ts.map +0 -1
  739. package/dist/server/implementation/sessions.js.map +0 -1
  740. package/dist/server/implementation/signin.d.ts +0 -55
  741. package/dist/server/implementation/signin.d.ts.map +0 -1
  742. package/dist/server/implementation/signin.js +0 -148
  743. package/dist/server/implementation/signin.js.map +0 -1
  744. package/dist/server/implementation/tokens.d.ts +0 -11
  745. package/dist/server/implementation/tokens.d.ts.map +0 -1
  746. package/dist/server/implementation/tokens.js +0 -15
  747. package/dist/server/implementation/tokens.js.map +0 -1
  748. package/dist/server/implementation/totp.d.ts +0 -31
  749. package/dist/server/implementation/totp.d.ts.map +0 -1
  750. package/dist/server/implementation/totp.js +0 -142
  751. package/dist/server/implementation/totp.js.map +0 -1
  752. package/dist/server/implementation/types.d.ts +0 -189
  753. package/dist/server/implementation/types.d.ts.map +0 -1
  754. package/dist/server/implementation/types.js +0 -97
  755. package/dist/server/implementation/types.js.map +0 -1
  756. package/dist/server/implementation/users.d.ts +0 -30
  757. package/dist/server/implementation/users.d.ts.map +0 -1
  758. package/dist/server/implementation/users.js.map +0 -1
  759. package/dist/server/implementation/utils.d.ts +0 -19
  760. package/dist/server/implementation/utils.d.ts.map +0 -1
  761. package/dist/server/implementation/utils.js +0 -56
  762. package/dist/server/implementation/utils.js.map +0 -1
  763. package/dist/server/index.d.ts.map +0 -1
  764. package/dist/server/index.js.map +0 -1
  765. package/dist/server/oauth.d.ts.map +0 -1
  766. package/dist/server/providers.d.ts +0 -72
  767. package/dist/server/providers.d.ts.map +0 -1
  768. package/dist/server/providers.js.map +0 -1
  769. package/dist/server/templates.d.ts.map +0 -1
  770. package/dist/server/utils.d.ts.map +0 -1
  771. package/dist/server/version.d.ts +0 -5
  772. package/dist/server/version.d.ts.map +0 -1
  773. package/dist/server/version.js +0 -6
  774. package/dist/server/version.js.map +0 -1
  775. package/src/cli/utils.ts +0 -248
  776. package/src/server/implementation/device.ts +0 -307
  777. package/src/server/implementation/index.ts +0 -1583
  778. package/src/server/implementation/mutations/account.ts +0 -50
  779. package/src/server/implementation/mutations/index.ts +0 -157
  780. package/src/server/implementation/mutations/invalidate.ts +0 -42
  781. package/src/server/implementation/mutations/oauth.ts +0 -73
  782. package/src/server/implementation/mutations/refresh.ts +0 -175
  783. package/src/server/implementation/mutations/register.ts +0 -100
  784. package/src/server/implementation/mutations/retrieve.ts +0 -79
  785. package/src/server/implementation/mutations/signature.ts +0 -39
  786. package/src/server/implementation/mutations/signout.ts +0 -35
  787. package/src/server/implementation/mutations/store.ts +0 -7
  788. package/src/server/implementation/mutations/verifier.ts +0 -24
  789. package/src/server/implementation/mutations/verify.ts +0 -194
  790. package/src/server/implementation/passkey.ts +0 -620
  791. package/src/server/implementation/provider.ts +0 -36
  792. package/src/server/implementation/ratelimit.ts +0 -79
  793. package/src/server/implementation/refresh.ts +0 -172
  794. package/src/server/implementation/signin.ts +0 -296
  795. package/src/server/implementation/totp.ts +0 -342
  796. package/src/server/implementation/types.ts +0 -444
  797. package/src/server/implementation/utils.ts +0 -91
  798. package/src/server/version.ts +0 -2
@@ -1,47 +0,0 @@
1
- //#region src/providers/email.ts
2
- /**
3
- * Email providers send a token to the user's email address
4
- * for sign-in.
5
- *
6
- * When you use this function to create your config, by default it
7
- * checks that there is an `email` field during token verification
8
- * that matches the `email` used during the initial `signIn` call.
9
- *
10
- * If you want the "magic link behavior", where only the token is needed,
11
- * you can override the `authorize` method to skip the check:
12
- *
13
- * ```ts
14
- * import email from "@robelest/convex-auth/providers/email";
15
- * import { Auth } from "@robelest/convex-auth/component";
16
- *
17
- * export const { auth, signIn, signOut, store } = Auth({
18
- * providers: [
19
- * email({ authorize: undefined }),
20
- * ],
21
- * });
22
- * ```
23
- *
24
- * Make sure the token has high enough entropy to be secure.
25
- *
26
- * @param config - Email provider options including `sendVerificationRequest`.
27
- * @returns An `EmailConfig` to include in your `providers` array.
28
- */
29
- function email(config) {
30
- return {
31
- id: "email",
32
- type: "email",
33
- name: "Email",
34
- from: "Auth.js <no-reply@authjs.dev>",
35
- maxAge: 3600,
36
- authorize: async (params, account) => {
37
- if (typeof params.email !== "string") throw new Error("Token verification requires an `email` in params of `signIn`.");
38
- if (account.providerAccountId !== params.email) throw new Error("Short verification code requires a matching `email` in params of `signIn`.");
39
- },
40
- sendVerificationRequest: config.sendVerificationRequest,
41
- options: config
42
- };
43
- }
44
-
45
- //#endregion
46
- export { email as default };
47
- //# sourceMappingURL=email.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"email.js","names":[],"sources":["../../../src/providers/email.ts"],"sourcesContent":["/**\n * Simplifies creating custom email providers, such as for sending OTPs.\n *\n * @module\n */\n\nimport { GenericDataModel } from \"convex/server\";\nimport { EmailConfig, EmailUserConfig } from \"../server/types\";\n\n/**\n * Email providers send a token to the user's email address\n * for sign-in.\n *\n * When you use this function to create your config, by default it\n * checks that there is an `email` field during token verification\n * that matches the `email` used during the initial `signIn` call.\n *\n * If you want the \"magic link behavior\", where only the token is needed,\n * you can override the `authorize` method to skip the check:\n *\n * ```ts\n * import email from \"@robelest/convex-auth/providers/email\";\n * import { Auth } from \"@robelest/convex-auth/component\";\n *\n * export const { auth, signIn, signOut, store } = Auth({\n * providers: [\n * email({ authorize: undefined }),\n * ],\n * });\n * ```\n *\n * Make sure the token has high enough entropy to be secure.\n *\n * @param config - Email provider options including `sendVerificationRequest`.\n * @returns An `EmailConfig` to include in your `providers` array.\n */\nexport default function email<DataModel extends GenericDataModel>(\n config: EmailUserConfig<DataModel> &\n Pick<EmailConfig, \"sendVerificationRequest\">,\n): EmailConfig<DataModel> {\n return {\n id: \"email\",\n type: \"email\",\n name: \"Email\",\n from: \"Auth.js <no-reply@authjs.dev>\",\n maxAge: 60 * 60, // 1 hour\n authorize: async (params, account) => {\n if (typeof params.email !== \"string\") {\n throw new Error(\n \"Token verification requires an `email` in params of `signIn`.\",\n );\n }\n if (account.providerAccountId !== params.email) {\n throw new Error(\n \"Short verification code requires a matching `email` \" +\n \"in params of `signIn`.\",\n );\n }\n },\n sendVerificationRequest: config.sendVerificationRequest,\n options: config,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAwB,MACtB,QAEwB;AACxB,QAAO;EACL,IAAI;EACJ,MAAM;EACN,MAAM;EACN,MAAM;EACN,QAAQ;EACR,WAAW,OAAO,QAAQ,YAAY;AACpC,OAAI,OAAO,OAAO,UAAU,SAC1B,OAAM,IAAI,MACR,gEACD;AAEH,OAAI,QAAQ,sBAAsB,OAAO,MACvC,OAAM,IAAI,MACR,6EAED;;EAGL,yBAAyB,OAAO;EAChC,SAAS;EACV"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"public.js","names":[],"sources":["../../src/component/public.ts"],"sourcesContent":["import { ConvexError, v } from \"convex/values\";\nimport { mutation, query } from \"./functions\";\n\n// ============================================================================\n// Tag normalization helpers\n// ============================================================================\n\n/** Validator for a single `{ key, value }` tag pair. */\nconst vTag = v.object({ key: v.string(), value: v.string() });\n\ntype TagPair = { key: string; value: string };\n\n/** Normalize a single tag: trim + lowercase key and value. */\nfunction normalizeTag(tag: TagPair): TagPair {\n return {\n key: tag.key.trim().toLowerCase(),\n value: tag.value.trim().toLowerCase(),\n };\n}\n\n/**\n * Normalize and deduplicate an array of tags.\n * Deduplication is based on the normalized `key\\0value` composite.\n */\nfunction normalizeTags(tags: TagPair[]): TagPair[] {\n const seen = new Set<string>();\n const result: TagPair[] = [];\n for (const raw of tags) {\n const t = normalizeTag(raw);\n const composite = `${t.key}\\0${t.value}`;\n if (!seen.has(composite)) {\n seen.add(composite);\n result.push(t);\n }\n }\n return result;\n}\n\n// ============================================================================\n// Users\n// ============================================================================\n\n/**\n * List users with optional filtering, sorting, and pagination.\n *\n * Returns `{ items, nextCursor }` — pass `nextCursor` back as `cursor`\n * for the next page, or `null` when exhausted.\n */\nexport const userList = query({\n args: {\n where: v.optional(\n v.object({\n email: v.optional(v.string()),\n phone: v.optional(v.string()),\n isAnonymous: v.optional(v.boolean()),\n name: v.optional(v.string()),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"name\"),\n v.literal(\"email\"),\n v.literal(\"phone\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n // Pick index based on where fields\n let q;\n if (where.email !== undefined) {\n q = ctx.db\n .query(\"user\")\n .withIndex(\"email\", (idx) => idx.eq(\"email\", where.email!));\n } else if (where.phone !== undefined) {\n q = ctx.db\n .query(\"user\")\n .withIndex(\"phone\", (idx) => idx.eq(\"phone\", where.phone!));\n } else {\n q = ctx.db.query(\"user\");\n }\n\n // Apply remaining filters\n if (where.isAnonymous !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"isAnonymous\"), where.isAnonymous!));\n }\n if (where.name !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"name\"), where.name!));\n }\n // email/phone filters when not used as index\n if (where.email !== undefined && where.phone !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"phone\"), where.phone!));\n }\n\n q = q.order(order);\n\n // Cursor-based pagination: skip past the cursor ID\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/** Retrieve a user by their document ID. */\nexport const userGetById = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db.get(userId);\n },\n});\n\n/**\n * Find a user by their verified email address. Returns `null` if no user\n * has this email verified, or if multiple users share the same verified email\n * (ambiguous — should not happen in normal operation).\n */\nexport const userFindByVerifiedEmail = query({\n args: { email: v.string() },\n handler: async (ctx, { email }) => {\n const users = await ctx.db\n .query(\"user\")\n .withIndex(\"email\", (q) => q.eq(\"email\", email))\n .filter((q) => q.neq(q.field(\"emailVerificationTime\"), undefined))\n .take(2);\n return users.length === 1 ? users[0] : null;\n },\n});\n\n/**\n * Find a user by their verified phone number. Returns `null` if no user\n * has this phone verified, or if multiple users share the same verified phone\n * (ambiguous — should not happen in normal operation).\n */\nexport const userFindByVerifiedPhone = query({\n args: { phone: v.string() },\n handler: async (ctx, { phone }) => {\n const users = await ctx.db\n .query(\"user\")\n .withIndex(\"phone\", (q) => q.eq(\"phone\", phone))\n .filter((q) => q.neq(q.field(\"phoneVerificationTime\"), undefined))\n .take(2);\n return users.length === 1 ? users[0] : null;\n },\n});\n\n/** Insert a new user document. */\nexport const userInsert = mutation({\n args: { data: v.any() },\n handler: async (ctx, { data }) => {\n return await ctx.db.insert(\"user\", data);\n },\n});\n\n/** Insert a new user or update an existing one. */\nexport const userUpsert = mutation({\n args: { userId: v.optional(v.id(\"user\")), data: v.any() },\n handler: async (ctx, { userId, data }) => {\n if (userId !== undefined) {\n await ctx.db.patch(userId, data);\n return userId;\n }\n return await ctx.db.insert(\"user\", data);\n },\n});\n\n/** Patch an existing user document with partial data. */\nexport const userPatch = mutation({\n args: { userId: v.id(\"user\"), data: v.any() },\n handler: async (ctx, { userId, data }) => {\n await ctx.db.patch(userId, data);\n },\n});\n\n// ============================================================================\n// Accounts\n// ============================================================================\n\n/** List all accounts for a user. */\nexport const accountListByUser = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"account\")\n .withIndex(\"userIdAndProvider\", (q) => q.eq(\"userId\", userId as any))\n .collect();\n },\n});\n\n/** Look up an account by provider and provider-specific account ID. */\nexport const accountGet = query({\n args: { provider: v.string(), providerAccountId: v.string() },\n handler: async (ctx, { provider, providerAccountId }) => {\n return await ctx.db\n .query(\"account\")\n .withIndex(\"providerAndAccountId\", (q) =>\n q.eq(\"provider\", provider).eq(\"providerAccountId\", providerAccountId),\n )\n .unique();\n },\n});\n\n/** Retrieve an account by its document ID. */\nexport const accountGetById = query({\n args: { accountId: v.id(\"account\") },\n handler: async (ctx, { accountId }) => {\n return await ctx.db.get(accountId);\n },\n});\n\n/** Create a new account linking a user to an auth provider. */\nexport const accountInsert = mutation({\n args: {\n userId: v.id(\"user\"),\n provider: v.string(),\n providerAccountId: v.string(),\n secret: v.optional(v.string()),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"account\", args as any);\n },\n});\n\n/** Patch an existing account document with partial data. */\nexport const accountPatch = mutation({\n args: { accountId: v.id(\"account\"), data: v.any() },\n handler: async (ctx, { accountId, data }) => {\n await ctx.db.patch(accountId, data);\n },\n});\n\n/** Delete an account document. */\nexport const accountDelete = mutation({\n args: { accountId: v.id(\"account\") },\n handler: async (ctx, { accountId }) => {\n await ctx.db.delete(accountId);\n },\n});\n\n// ============================================================================\n// Sessions\n// ============================================================================\n\n/**\n * List sessions with optional filtering and pagination.\n *\n * Returns `{ items, nextCursor }`.\n */\nexport const sessionList = query({\n args: {\n where: v.optional(\n v.object({\n userId: v.optional(v.id(\"user\")),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n let q;\n if (where.userId !== undefined) {\n q = ctx.db\n .query(\"session\")\n .withIndex(\"userId\", (idx) => idx.eq(\"userId\", where.userId!));\n } else {\n q = ctx.db.query(\"session\");\n }\n\n q = q.order(order);\n\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/** Create a new session for a user with an expiration time. */\nexport const sessionCreate = mutation({\n args: { userId: v.id(\"user\"), expirationTime: v.number() },\n handler: async (ctx, { userId, expirationTime }) => {\n return await ctx.db.insert(\"session\", {\n userId: userId as any,\n expirationTime,\n });\n },\n});\n\n/** Retrieve a session by its document ID. */\nexport const sessionGetById = query({\n args: { sessionId: v.id(\"session\") },\n handler: async (ctx, { sessionId }) => {\n return await ctx.db.get(sessionId);\n },\n});\n\n/** Delete a session. No-op if the session does not exist. */\nexport const sessionDelete = mutation({\n args: { sessionId: v.id(\"session\") },\n handler: async (ctx, { sessionId }) => {\n if ((await ctx.db.get(sessionId)) !== null) {\n await ctx.db.delete(sessionId);\n }\n },\n});\n\n/** List all sessions for a user. */\nexport const sessionListByUser = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"session\")\n .withIndex(\"userId\", (q) => q.eq(\"userId\", userId as any))\n .collect();\n },\n});\n\n// ============================================================================\n// Verifiers\n// ============================================================================\n\n/** Create a new PKCE verifier, optionally linked to a session. */\nexport const verifierCreate = mutation({\n args: { sessionId: v.optional(v.id(\"session\")) },\n handler: async (ctx, { sessionId }) => {\n return await ctx.db.insert(\"verifier\", { sessionId: sessionId as any });\n },\n});\n\n/** Retrieve a verifier by its document ID. */\nexport const verifierGetById = query({\n args: { verifierId: v.id(\"verifier\") },\n handler: async (ctx, { verifierId }) => {\n return await ctx.db.get(verifierId);\n },\n});\n\n/** Look up a verifier by its cryptographic signature. */\nexport const verifierGetBySignature = query({\n args: { signature: v.string() },\n handler: async (ctx, { signature }) => {\n return await ctx.db\n .query(\"verifier\")\n .withIndex(\"signature\", (q) => q.eq(\"signature\", signature))\n .unique();\n },\n});\n\n/** Patch a verifier document with partial data. */\nexport const verifierPatch = mutation({\n args: { verifierId: v.id(\"verifier\"), data: v.any() },\n handler: async (ctx, { verifierId, data }) => {\n await ctx.db.patch(verifierId, data);\n },\n});\n\n/** Delete a verifier document. */\nexport const verifierDelete = mutation({\n args: { verifierId: v.id(\"verifier\") },\n handler: async (ctx, { verifierId }) => {\n await ctx.db.delete(verifierId);\n },\n});\n\n// ============================================================================\n// Verification Codes\n// ============================================================================\n\n/** Find a verification code by its associated account ID. */\nexport const verificationCodeGetByAccountId = query({\n args: { accountId: v.id(\"account\") },\n handler: async (ctx, { accountId }) => {\n return await ctx.db\n .query(\"verification\")\n .withIndex(\"accountId\", (q) => q.eq(\"accountId\", accountId as any))\n .unique();\n },\n});\n\n/** Find a verification code by its code string. */\nexport const verificationCodeGetByCode = query({\n args: { code: v.string() },\n handler: async (ctx, { code }) => {\n return await ctx.db\n .query(\"verification\")\n .withIndex(\"code\", (q) => q.eq(\"code\", code))\n .unique();\n },\n});\n\n/** Create a new verification code for OTP, magic link, or OAuth flows. */\nexport const verificationCodeCreate = mutation({\n args: {\n accountId: v.id(\"account\"),\n provider: v.string(),\n code: v.string(),\n expirationTime: v.number(),\n verifier: v.optional(v.string()),\n emailVerified: v.optional(v.string()),\n phoneVerified: v.optional(v.string()),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"verification\", args as any);\n },\n});\n\n/** Delete a verification code document. */\nexport const verificationCodeDelete = mutation({\n args: { verificationCodeId: v.id(\"verification\") },\n handler: async (ctx, { verificationCodeId }) => {\n await ctx.db.delete(verificationCodeId);\n },\n});\n\n// ============================================================================\n// Refresh Tokens\n// ============================================================================\n\n/** Create a new refresh token for a session. */\nexport const refreshTokenCreate = mutation({\n args: {\n sessionId: v.id(\"session\"),\n expirationTime: v.number(),\n parentRefreshTokenId: v.optional(v.id(\"token\")),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"token\", args as any);\n },\n});\n\n/** Retrieve a refresh token by its document ID. */\nexport const refreshTokenGetById = query({\n args: { refreshTokenId: v.id(\"token\") },\n handler: async (ctx, { refreshTokenId }) => {\n return await ctx.db.get(refreshTokenId);\n },\n});\n\n/** Patch a refresh token document with partial data. */\nexport const refreshTokenPatch = mutation({\n args: { refreshTokenId: v.id(\"token\"), data: v.any() },\n handler: async (ctx, { refreshTokenId, data }) => {\n await ctx.db.patch(refreshTokenId, data);\n },\n});\n\n/** Get child tokens that were created by exchanging a specific parent token. */\nexport const refreshTokenGetChildren = query({\n args: {\n sessionId: v.id(\"session\"),\n parentRefreshTokenId: v.id(\"token\"),\n },\n handler: async (ctx, { sessionId, parentRefreshTokenId }) => {\n return await ctx.db\n .query(\"token\")\n .withIndex(\"sessionIdAndParentRefreshTokenId\", (q) =>\n q\n .eq(\"sessionId\", sessionId as any)\n .eq(\"parentRefreshTokenId\", parentRefreshTokenId as any),\n )\n .collect();\n },\n});\n\n/** List all refresh tokens for a session. */\nexport const refreshTokenListBySession = query({\n args: { sessionId: v.id(\"session\") },\n handler: async (ctx, { sessionId }) => {\n return await ctx.db\n .query(\"token\")\n .withIndex(\"sessionIdAndParentRefreshTokenId\", (q) =>\n q.eq(\"sessionId\", sessionId as any),\n )\n .collect();\n },\n});\n\n/** Delete all refresh tokens for a session. */\nexport const refreshTokenDeleteAll = mutation({\n args: { sessionId: v.id(\"session\") },\n handler: async (ctx, { sessionId }) => {\n const tokens = await ctx.db\n .query(\"token\")\n .withIndex(\"sessionIdAndParentRefreshTokenId\", (q) =>\n q.eq(\"sessionId\", sessionId as any),\n )\n .collect();\n await Promise.all(tokens.map((token) => ctx.db.delete(token._id)));\n },\n});\n\n/** Get the active (unused) refresh token for a session. */\nexport const refreshTokenGetActive = query({\n args: { sessionId: v.id(\"session\") },\n handler: async (ctx, { sessionId }) => {\n return await ctx.db\n .query(\"token\")\n .withIndex(\"sessionId\", (q) => q.eq(\"sessionId\", sessionId as any))\n .filter((q) => q.eq(q.field(\"firstUsedTime\"), undefined))\n .order(\"desc\")\n .first();\n },\n});\n\n// ============================================================================\n// Passkeys\n// ============================================================================\n\n/** Store a new passkey credential for a user. */\nexport const passkeyInsert = mutation({\n args: {\n userId: v.id(\"user\"),\n credentialId: v.string(),\n publicKey: v.bytes(),\n algorithm: v.number(),\n counter: v.number(),\n transports: v.optional(v.array(v.string())),\n deviceType: v.string(),\n backedUp: v.boolean(),\n name: v.optional(v.string()),\n createdAt: v.number(),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"passkey\", args);\n },\n});\n\n/** Look up a passkey by its credential ID. */\nexport const passkeyGetByCredentialId = query({\n args: { credentialId: v.string() },\n handler: async (ctx, { credentialId }) => {\n return await ctx.db\n .query(\"passkey\")\n .withIndex(\"credentialId\", (q) => q.eq(\"credentialId\", credentialId))\n .unique();\n },\n});\n\n/** List all passkeys for a user. */\nexport const passkeyListByUserId = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"passkey\")\n .withIndex(\"userId\", (q) => q.eq(\"userId\", userId))\n .collect();\n },\n});\n\n/** Update a passkey's counter and last used timestamp after authentication. */\nexport const passkeyUpdateCounter = mutation({\n args: { passkeyId: v.id(\"passkey\"), counter: v.number(), lastUsedAt: v.number() },\n handler: async (ctx, { passkeyId, counter, lastUsedAt }) => {\n await ctx.db.patch(passkeyId, { counter, lastUsedAt });\n },\n});\n\n/** Update a passkey's metadata (name). */\nexport const passkeyUpdateMeta = mutation({\n args: { passkeyId: v.id(\"passkey\"), data: v.any() },\n handler: async (ctx, { passkeyId, data }) => {\n await ctx.db.patch(passkeyId, data);\n },\n});\n\n/** Delete a passkey credential. */\nexport const passkeyDelete = mutation({\n args: { passkeyId: v.id(\"passkey\") },\n handler: async (ctx, { passkeyId }) => {\n await ctx.db.delete(passkeyId);\n },\n});\n\n// ============================================================================\n// TOTP Two-Factor Authentication\n// ============================================================================\n\n/** Store a new TOTP enrollment for a user. */\nexport const totpInsert = mutation({\n args: {\n userId: v.id(\"user\"),\n secret: v.bytes(),\n digits: v.number(),\n period: v.number(),\n verified: v.boolean(),\n name: v.optional(v.string()),\n createdAt: v.number(),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"totp\", args);\n },\n});\n\n/** Get a verified TOTP enrollment for a user (returns first match). */\nexport const totpGetVerifiedByUserId = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"totp\")\n .withIndex(\"userId\", (q) => q.eq(\"userId\", userId))\n .filter((q) => q.eq(q.field(\"verified\"), true))\n .first();\n },\n});\n\n/** List all TOTP enrollments for a user. */\nexport const totpListByUserId = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"totp\")\n .withIndex(\"userId\", (q) => q.eq(\"userId\", userId))\n .collect();\n },\n});\n\n/** Get a TOTP enrollment by its ID. */\nexport const totpGetById = query({\n args: { totpId: v.id(\"totp\") },\n handler: async (ctx, { totpId }) => {\n return await ctx.db.get(totpId);\n },\n});\n\n/** Mark a TOTP enrollment as verified (setup complete). */\nexport const totpMarkVerified = mutation({\n args: { totpId: v.id(\"totp\"), lastUsedAt: v.number() },\n handler: async (ctx, { totpId, lastUsedAt }) => {\n await ctx.db.patch(totpId, { verified: true, lastUsedAt });\n },\n});\n\n/** Update a TOTP enrollment's last used timestamp. */\nexport const totpUpdateLastUsed = mutation({\n args: { totpId: v.id(\"totp\"), lastUsedAt: v.number() },\n handler: async (ctx, { totpId, lastUsedAt }) => {\n await ctx.db.patch(totpId, { lastUsedAt });\n },\n});\n\n/** Delete a TOTP enrollment. */\nexport const totpDelete = mutation({\n args: { totpId: v.id(\"totp\") },\n handler: async (ctx, { totpId }) => {\n await ctx.db.delete(totpId);\n },\n});\n\n// ============================================================================\n// Rate Limits\n// ============================================================================\n\n/** Look up a rate limit entry by its identifier. */\nexport const rateLimitGet = query({\n args: { identifier: v.string() },\n handler: async (ctx, { identifier }) => {\n return await ctx.db\n .query(\"limit\")\n .withIndex(\"identifier\", (q) => q.eq(\"identifier\", identifier))\n .unique();\n },\n});\n\n/** Create a new rate limit entry. */\nexport const rateLimitCreate = mutation({\n args: {\n identifier: v.string(),\n attemptsLeft: v.number(),\n lastAttemptTime: v.number(),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"limit\", args);\n },\n});\n\n/** Patch a rate limit entry with partial data. */\nexport const rateLimitPatch = mutation({\n args: { rateLimitId: v.id(\"limit\"), data: v.any() },\n handler: async (ctx, { rateLimitId, data }) => {\n await ctx.db.patch(rateLimitId, data);\n },\n});\n\n/** Delete a rate limit entry. */\nexport const rateLimitDelete = mutation({\n args: { rateLimitId: v.id(\"limit\") },\n handler: async (ctx, { rateLimitId }) => {\n await ctx.db.delete(rateLimitId);\n },\n});\n\n// ============================================================================\n// Groups\n// ============================================================================\n\n/**\n * Create a new group. Groups are hierarchical — set `parentGroupId` to nest\n * under an existing group, or omit it to create a root-level group.\n *\n * @returns The ID of the newly created group.\n */\nexport const groupCreate = mutation({\n args: {\n name: v.string(),\n slug: v.optional(v.string()),\n type: v.optional(v.string()),\n parentGroupId: v.optional(v.id(\"group\")),\n tags: v.optional(v.array(vTag)),\n extend: v.optional(v.any()),\n },\n handler: async (ctx, args) => {\n const { tags: rawTags, ...rest } = args;\n const normalizedTags = rawTags ? normalizeTags(rawTags) : undefined;\n const groupId = await ctx.db.insert(\"group\", {\n ...rest,\n tags: normalizedTags,\n });\n // Sync companion groupTag rows\n if (normalizedTags) {\n for (const tag of normalizedTags) {\n await ctx.db.insert(\"groupTag\", {\n groupId,\n key: tag.key,\n value: tag.value,\n });\n }\n }\n return groupId;\n },\n});\n\n/** Retrieve a group by its document ID. Returns `null` if not found. */\nexport const groupGet = query({\n args: { groupId: v.id(\"group\") },\n handler: async (ctx, { groupId }) => {\n return await ctx.db.get(groupId);\n },\n});\n\n/**\n * List groups with optional filtering, sorting, and pagination.\n *\n * Returns `{ items, nextCursor }`. Empty `where` returns **all** groups.\n */\nexport const groupList = query({\n args: {\n where: v.optional(\n v.object({\n slug: v.optional(v.string()),\n type: v.optional(v.string()),\n parentGroupId: v.optional(v.id(\"group\")),\n name: v.optional(v.string()),\n isRoot: v.optional(v.boolean()),\n tagsAll: v.optional(v.array(vTag)),\n tagsAny: v.optional(v.array(vTag)),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"name\"),\n v.literal(\"slug\"),\n v.literal(\"type\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n // ---- Resolve tag filters into a Set<Id<\"group\">> ----\n let tagFilteredIds: Set<string> | null = null;\n\n if (where.tagsAll && where.tagsAll.length > 0) {\n // Intersect: group must have ALL specified tags\n let allSet: Set<string> | null = null;\n for (const rawTag of where.tagsAll) {\n const t = normalizeTag(rawTag);\n const rows = await ctx.db\n .query(\"groupTag\")\n .withIndex(\"by_key_value\", (idx) =>\n idx.eq(\"key\", t.key).eq(\"value\", t.value),\n )\n .collect();\n const ids = new Set(rows.map((r) => r.groupId as string));\n if (allSet === null) {\n allSet = ids;\n } else {\n // Intersect\n for (const id of allSet) {\n if (!ids.has(id)) allSet.delete(id);\n }\n }\n // Short-circuit: empty intersection\n if (allSet.size === 0) break;\n }\n tagFilteredIds = allSet ?? new Set();\n }\n\n if (where.tagsAny && where.tagsAny.length > 0) {\n // Union: group must have at least one of the specified tags\n const anySet = new Set<string>();\n for (const rawTag of where.tagsAny) {\n const t = normalizeTag(rawTag);\n const rows = await ctx.db\n .query(\"groupTag\")\n .withIndex(\"by_key_value\", (idx) =>\n idx.eq(\"key\", t.key).eq(\"value\", t.value),\n )\n .collect();\n for (const r of rows) {\n anySet.add(r.groupId as string);\n }\n }\n if (tagFilteredIds !== null) {\n // AND with tagsAll result\n for (const id of tagFilteredIds) {\n if (!anySet.has(id)) tagFilteredIds.delete(id);\n }\n } else {\n tagFilteredIds = anySet;\n }\n }\n\n // ---- Pick best index based on non-tag where fields ----\n let q;\n if (where.type !== undefined && where.parentGroupId !== undefined) {\n q = ctx.db\n .query(\"group\")\n .withIndex(\"typeAndParentGroupId\", (idx) =>\n idx.eq(\"type\", where.type!).eq(\"parentGroupId\", where.parentGroupId!),\n );\n } else if (where.slug !== undefined) {\n q = ctx.db\n .query(\"group\")\n .withIndex(\"slug\", (idx) => idx.eq(\"slug\", where.slug!));\n } else if (where.type !== undefined) {\n q = ctx.db\n .query(\"group\")\n .withIndex(\"type\", (idx) => idx.eq(\"type\", where.type!));\n } else if (where.parentGroupId !== undefined) {\n q = ctx.db\n .query(\"group\")\n .withIndex(\"parentGroupId\", (idx) =>\n idx.eq(\"parentGroupId\", where.parentGroupId!),\n );\n } else {\n q = ctx.db.query(\"group\");\n }\n\n // Apply remaining non-tag filters not covered by index\n if (where.name !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"name\"), where.name!));\n }\n if (where.isRoot === true) {\n q = q.filter((f) => f.eq(f.field(\"parentGroupId\"), undefined));\n } else if (where.isRoot === false) {\n q = q.filter((f) => f.neq(f.field(\"parentGroupId\"), undefined));\n }\n // slug filter when not used as index\n if (where.slug !== undefined && where.type !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"slug\"), where.slug!));\n }\n\n q = q.order(order);\n\n let all = await q.collect();\n\n // Apply tag filter (intersect with resolved groupIds)\n if (tagFilteredIds !== null) {\n all = all.filter((doc) => tagFilteredIds!.has(doc._id as string));\n }\n\n // Cursor-based pagination\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/** Update a group's fields (name, slug, tags, extend, parentGroupId). */\nexport const groupUpdate = mutation({\n args: { groupId: v.id(\"group\"), data: v.any() },\n handler: async (ctx, { groupId, data }) => {\n // If tags are being updated, normalize and replace the full tag set\n if (data.tags !== undefined) {\n const normalizedTags: TagPair[] = Array.isArray(data.tags)\n ? normalizeTags(data.tags as TagPair[])\n : [];\n // Delete existing groupTag rows for this group\n const existingTags = await ctx.db\n .query(\"groupTag\")\n .withIndex(\"by_group\", (idx) => idx.eq(\"groupId\", groupId))\n .collect();\n for (const existing of existingTags) {\n await ctx.db.delete(existing._id);\n }\n // Insert new normalized groupTag rows\n for (const tag of normalizedTags) {\n await ctx.db.insert(\"groupTag\", {\n groupId,\n key: tag.key,\n value: tag.value,\n });\n }\n // Patch group with normalized tags (empty array = clear all)\n await ctx.db.patch(groupId, {\n ...data,\n tags: normalizedTags.length > 0 ? normalizedTags : undefined,\n });\n } else {\n await ctx.db.patch(groupId, data);\n }\n },\n});\n\n/**\n * Delete a group and all of its descendants. This cascades to:\n * - All child groups (recursively)\n * - All members of this group and its descendants\n * - All invites for this group and its descendants\n */\nexport const groupDelete = mutation({\n args: { groupId: v.id(\"group\") },\n handler: async (ctx, { groupId }) => {\n const deleteGroup = async (id: typeof groupId) => {\n const children = await ctx.db\n .query(\"group\")\n .withIndex(\"parentGroupId\", (q) => q.eq(\"parentGroupId\", id))\n .collect();\n for (const child of children) {\n await deleteGroup(child._id);\n }\n\n const members = await ctx.db\n .query(\"member\")\n .withIndex(\"groupId\", (q) => q.eq(\"groupId\", id))\n .collect();\n for (const member of members) {\n await ctx.db.delete(member._id);\n }\n\n const invites = await ctx.db\n .query(\"invite\")\n .withIndex(\"groupId\", (q) => q.eq(\"groupId\", id))\n .collect();\n for (const invite of invites) {\n await ctx.db.delete(invite._id);\n }\n\n // Delete companion groupTag rows\n const tags = await ctx.db\n .query(\"groupTag\")\n .withIndex(\"by_group\", (q) => q.eq(\"groupId\", id))\n .collect();\n for (const tag of tags) {\n await ctx.db.delete(tag._id);\n }\n\n await ctx.db.delete(id);\n };\n\n await deleteGroup(groupId);\n },\n});\n\n// ============================================================================\n// Members\n// ============================================================================\n\n/**\n * Add a user as a member of a group.\n *\n * The `role` field is an application-defined string (e.g. \"owner\", \"admin\",\n * \"member\", \"viewer\"). The auth component stores it but does not enforce\n * access control — your application defines what each role means.\n *\n * Throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` when the user is\n * already a member of the target group.\n *\n * @returns The ID of the new member record.\n */\nexport const memberAdd = mutation({\n args: {\n groupId: v.id(\"group\"),\n userId: v.id(\"user\"),\n role: v.optional(v.string()),\n status: v.optional(v.string()),\n extend: v.optional(v.any()),\n },\n handler: async (ctx, args) => {\n const existingMembership = await ctx.db\n .query(\"member\")\n .withIndex(\"groupIdAndUserId\", (q) =>\n q.eq(\"groupId\", args.groupId).eq(\"userId\", args.userId),\n )\n .unique();\n if (existingMembership !== null) {\n throw new ConvexError({\n code: \"DUPLICATE_MEMBERSHIP\",\n message: \"User is already a member of this group\",\n groupId: args.groupId,\n userId: args.userId,\n existingMemberId: existingMembership._id,\n });\n }\n return await ctx.db.insert(\"member\", args);\n },\n});\n\n/** Retrieve a member record by its document ID. Returns `null` if not found. */\nexport const memberGet = query({\n args: { memberId: v.id(\"member\") },\n handler: async (ctx, { memberId }) => {\n return await ctx.db.get(memberId);\n },\n});\n\n/**\n * List members with optional filtering, sorting, and pagination.\n *\n * Returns `{ items, nextCursor }`. Supports filtering by `groupId`,\n * `userId`, `role`, and `status`.\n */\nexport const memberList = query({\n args: {\n where: v.optional(\n v.object({\n groupId: v.optional(v.id(\"group\")),\n userId: v.optional(v.id(\"user\")),\n role: v.optional(v.string()),\n status: v.optional(v.string()),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"role\"),\n v.literal(\"status\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n let q;\n if (where.groupId !== undefined && where.userId !== undefined) {\n q = ctx.db\n .query(\"member\")\n .withIndex(\"groupIdAndUserId\", (idx) =>\n idx.eq(\"groupId\", where.groupId!).eq(\"userId\", where.userId!),\n );\n } else if (where.groupId !== undefined) {\n q = ctx.db\n .query(\"member\")\n .withIndex(\"groupId\", (idx) => idx.eq(\"groupId\", where.groupId!));\n } else if (where.userId !== undefined) {\n q = ctx.db\n .query(\"member\")\n .withIndex(\"userId\", (idx) => idx.eq(\"userId\", where.userId!));\n } else {\n q = ctx.db.query(\"member\");\n }\n\n if (where.role !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"role\"), where.role!));\n }\n if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n\n q = q.order(order);\n\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/**\n * @deprecated Use `memberList` with `where: { userId }` instead.\n * Kept for backward compatibility with generated component types.\n */\nexport const memberListByUser = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"member\")\n .withIndex(\"userId\", (q) => q.eq(\"userId\", userId))\n .collect();\n },\n});\n\n/**\n * Look up a specific user's membership in a specific group.\n * Returns `null` if the user is not a member of the group.\n */\nexport const memberGetByGroupAndUser = query({\n args: { groupId: v.id(\"group\"), userId: v.id(\"user\") },\n handler: async (ctx, { groupId, userId }) => {\n return await ctx.db\n .query(\"member\")\n .withIndex(\"groupIdAndUserId\", (q) =>\n q.eq(\"groupId\", groupId).eq(\"userId\", userId),\n )\n .unique();\n },\n});\n\n/** Remove a member from a group by deleting the member record. */\nexport const memberRemove = mutation({\n args: { memberId: v.id(\"member\") },\n handler: async (ctx, { memberId }) => {\n await ctx.db.delete(memberId);\n },\n});\n\n/**\n * Update a member record's fields (role, status, extend).\n *\n * Common usage: `memberUpdate({ memberId, data: { role: \"admin\" } })`\n */\nexport const memberUpdate = mutation({\n args: { memberId: v.id(\"member\"), data: v.any() },\n handler: async (ctx, { memberId, data }) => {\n await ctx.db.patch(memberId, data);\n },\n});\n\n// ============================================================================\n// Invites\n// ============================================================================\n\n/**\n * Create a new platform-level invitation. Optionally set `groupId` to tie\n * the invite to a specific group. The invitation is sent to an email address\n * and includes a hashed token for secure acceptance.\n *\n * Throws `ConvexError` with code `DUPLICATE_INVITE` when a pending invite\n * already exists for the same email and scope:\n * - group invite: same `email` + same `groupId`\n * - platform invite: same `email` with no `groupId`\n *\n * @returns The ID of the new invite record.\n */\nexport const inviteCreate = mutation({\n args: {\n groupId: v.optional(v.id(\"group\")),\n invitedByUserId: v.optional(v.id(\"user\")),\n email: v.optional(v.string()),\n tokenHash: v.string(),\n role: v.optional(v.string()),\n status: v.union(\n v.literal(\"pending\"),\n v.literal(\"accepted\"),\n v.literal(\"revoked\"),\n v.literal(\"expired\"),\n ),\n expiresTime: v.optional(v.number()),\n extend: v.optional(v.any()),\n },\n handler: async (ctx, args) => {\n // Only check for duplicates when an email is provided.\n // CLI-generated invites (no email) are always allowed.\n if (args.email !== undefined) {\n if (args.groupId !== undefined) {\n const existingGroupInvite = await ctx.db\n .query(\"invite\")\n .withIndex(\"groupIdAndStatus\", (q) =>\n q.eq(\"groupId\", args.groupId).eq(\"status\", \"pending\"),\n )\n .filter((q) => q.eq(q.field(\"email\"), args.email))\n .first();\n if (existingGroupInvite !== null) {\n throw new ConvexError({\n code: \"DUPLICATE_INVITE\",\n message:\n \"A pending invite already exists for this email in this group\",\n email: args.email,\n groupId: args.groupId,\n existingInviteId: existingGroupInvite._id,\n });\n }\n } else {\n const existingPlatformInvite = await ctx.db\n .query(\"invite\")\n .withIndex(\"emailAndStatus\", (q) =>\n q.eq(\"email\", args.email).eq(\"status\", \"pending\"),\n )\n .filter((q) => q.eq(q.field(\"groupId\"), undefined))\n .first();\n if (existingPlatformInvite !== null) {\n throw new ConvexError({\n code: \"DUPLICATE_INVITE\",\n message:\n \"A pending platform invite already exists for this email\",\n email: args.email,\n existingInviteId: existingPlatformInvite._id,\n });\n }\n }\n }\n return await ctx.db.insert(\"invite\", args);\n },\n});\n\n/** Retrieve an invite by its document ID. Returns `null` if not found. */\nexport const inviteGet = query({\n args: { inviteId: v.id(\"invite\") },\n handler: async (ctx, { inviteId }) => {\n return await ctx.db.get(inviteId);\n },\n});\n\n/**\n * List invites with optional filtering, sorting, and pagination.\n *\n * Returns `{ items, nextCursor }`. Supports filtering by `groupId`,\n * `status`, `email`, `invitedByUserId`, `role`, `acceptedByUserId`, and `tokenHash`.\n */\nexport const inviteList = query({\n args: {\n where: v.optional(\n v.object({\n tokenHash: v.optional(v.string()),\n groupId: v.optional(v.id(\"group\")),\n status: v.optional(\n v.union(\n v.literal(\"pending\"),\n v.literal(\"accepted\"),\n v.literal(\"revoked\"),\n v.literal(\"expired\"),\n ),\n ),\n email: v.optional(v.string()),\n invitedByUserId: v.optional(v.id(\"user\")),\n role: v.optional(v.string()),\n acceptedByUserId: v.optional(v.id(\"user\")),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"status\"),\n v.literal(\"email\"),\n v.literal(\"expiresTime\"),\n v.literal(\"acceptedTime\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n // Pick best index\n let q;\n if (where.tokenHash !== undefined) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"tokenHash\", (idx) => idx.eq(\"tokenHash\", where.tokenHash!));\n } else if (\n where.role !== undefined &&\n where.status !== undefined &&\n where.acceptedByUserId !== undefined\n ) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"roleAndStatusAndAcceptedByUserId\", (idx) =>\n idx\n .eq(\"role\", where.role!)\n .eq(\"status\", where.status!)\n .eq(\"acceptedByUserId\", where.acceptedByUserId!),\n );\n } else if (where.groupId !== undefined && where.status !== undefined) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"groupIdAndStatus\", (idx) =>\n idx.eq(\"groupId\", where.groupId!).eq(\"status\", where.status!),\n );\n } else if (where.email !== undefined && where.status !== undefined) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"emailAndStatus\", (idx) =>\n idx.eq(\"email\", where.email!).eq(\"status\", where.status!),\n );\n } else if (where.invitedByUserId !== undefined && where.status !== undefined) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"invitedByUserIdAndStatus\", (idx) =>\n idx\n .eq(\"invitedByUserId\", where.invitedByUserId!)\n .eq(\"status\", where.status!),\n );\n } else if (where.groupId !== undefined) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"groupId\", (idx) => idx.eq(\"groupId\", where.groupId!));\n } else if (where.status !== undefined) {\n q = ctx.db\n .query(\"invite\")\n .withIndex(\"status\", (idx) => idx.eq(\"status\", where.status!));\n } else {\n q = ctx.db.query(\"invite\");\n }\n\n // Apply remaining filters\n if (where.groupId !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"groupId\"), where.groupId!));\n }\n if (where.status !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"status\"), where.status!));\n }\n if (where.email !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"email\"), where.email!));\n }\n if (where.invitedByUserId !== undefined) {\n q = q.filter((f) =>\n f.eq(f.field(\"invitedByUserId\"), where.invitedByUserId!),\n );\n }\n if (where.role !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"role\"), where.role!));\n }\n if (where.acceptedByUserId !== undefined) {\n q = q.filter((f) =>\n f.eq(f.field(\"acceptedByUserId\"), where.acceptedByUserId!),\n );\n }\n if (where.tokenHash !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"tokenHash\"), where.tokenHash!));\n }\n\n q = q.order(order);\n\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/**\n * Accept a pending invitation.\n *\n * Marks the invite as \"accepted\" and records the acceptance timestamp.\n * Throws a structured `ConvexError` when the invite doesn't exist or is not\n * currently pending.\n *\n * The caller is responsible for creating the corresponding member record.\n */\nexport const inviteAccept = mutation({\n args: {\n inviteId: v.id(\"invite\"),\n acceptedByUserId: v.optional(v.id(\"user\")),\n },\n handler: async (ctx, { inviteId, acceptedByUserId }) => {\n const invite = await ctx.db.get(inviteId);\n if (invite === null) {\n throw new ConvexError({\n code: \"INVITE_NOT_FOUND\",\n message: \"Invite not found\",\n inviteId,\n });\n }\n if (invite.status !== \"pending\") {\n throw new ConvexError({\n code: \"INVITE_NOT_PENDING\",\n message: `Cannot accept invite with status \"${invite.status}\"`,\n inviteId,\n currentStatus: invite.status,\n });\n }\n await ctx.db.patch(inviteId, {\n status: \"accepted\",\n acceptedTime: Date.now(),\n ...(acceptedByUserId ? { acceptedByUserId } : {}),\n });\n },\n});\n\n/**\n * Revoke a pending invitation.\n *\n * Marks the invite as \"revoked\". Throws a structured `ConvexError` when the\n * invite doesn't exist or is not currently pending.\n */\nexport const inviteRevoke = mutation({\n args: { inviteId: v.id(\"invite\") },\n handler: async (ctx, { inviteId }) => {\n const invite = await ctx.db.get(inviteId);\n if (invite === null) {\n throw new ConvexError({\n code: \"INVITE_NOT_FOUND\",\n message: \"Invite not found\",\n inviteId,\n });\n }\n if (invite.status !== \"pending\") {\n throw new ConvexError({\n code: \"INVITE_NOT_PENDING\",\n message: `Cannot revoke invite with status \"${invite.status}\"`,\n inviteId,\n currentStatus: invite.status,\n });\n }\n await ctx.db.patch(inviteId, { status: \"revoked\" });\n },\n});\n\n// ============================================================================\n// API Keys\n// ============================================================================\n\n/**\n * Insert a new API key record.\n *\n * The caller is responsible for hashing the raw key before passing it here —\n * this function only stores the hash and metadata.\n */\nexport const keyInsert = mutation({\n args: {\n userId: v.id(\"user\"),\n prefix: v.string(),\n hashedKey: v.string(),\n name: v.string(),\n scopes: v.array(\n v.object({\n resource: v.string(),\n actions: v.array(v.string()),\n }),\n ),\n rateLimit: v.optional(\n v.object({\n maxRequests: v.number(),\n windowMs: v.number(),\n }),\n ),\n expiresAt: v.optional(v.number()),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"key\", {\n ...args,\n createdAt: Date.now(),\n revoked: false,\n });\n },\n});\n\n/**\n * Look up an API key by its SHA-256 hash.\n *\n * Used during Bearer token verification. Returns the full key record\n * (including rate limit state) or `null` if not found.\n */\nexport const keyGetByHashedKey = query({\n args: { hashedKey: v.string() },\n handler: async (ctx, { hashedKey }) => {\n return await ctx.db\n .query(\"key\")\n .withIndex(\"hashedKey\", (q) => q.eq(\"hashedKey\", hashedKey))\n .first();\n },\n});\n\n/**\n * @deprecated Use `keyList` with `where: { userId }` instead.\n * Kept for backward compatibility with generated component types.\n */\nexport const keyListByUserId = query({\n args: { userId: v.id(\"user\") },\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"key\")\n .withIndex(\"userId\", (q) => q.eq(\"userId\", userId))\n .collect();\n },\n});\n\n/**\n * List API keys with optional filtering, sorting, and pagination.\n *\n * Returns `{ items, nextCursor }`. Supports filtering by `userId`,\n * `revoked`, `name`, and `prefix`.\n */\nexport const keyList = query({\n args: {\n where: v.optional(\n v.object({\n userId: v.optional(v.id(\"user\")),\n revoked: v.optional(v.boolean()),\n name: v.optional(v.string()),\n prefix: v.optional(v.string()),\n }),\n ),\n limit: v.optional(v.number()),\n cursor: v.optional(v.union(v.string(), v.null())),\n orderBy: v.optional(\n v.union(\n v.literal(\"_creationTime\"),\n v.literal(\"name\"),\n v.literal(\"lastUsedAt\"),\n v.literal(\"expiresAt\"),\n v.literal(\"revoked\"),\n ),\n ),\n order: v.optional(v.union(v.literal(\"asc\"), v.literal(\"desc\"))),\n },\n handler: async (ctx, args) => {\n const where = args.where ?? {};\n const limit = Math.min(Math.max(args.limit ?? 50, 1), 100);\n const order = args.order ?? \"desc\";\n\n let q;\n if (where.userId !== undefined) {\n q = ctx.db\n .query(\"key\")\n .withIndex(\"userId\", (idx) => idx.eq(\"userId\", where.userId!));\n } else {\n q = ctx.db.query(\"key\");\n }\n\n if (where.revoked !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"revoked\"), where.revoked!));\n }\n if (where.name !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"name\"), where.name!));\n }\n if (where.prefix !== undefined) {\n q = q.filter((f) => f.eq(f.field(\"prefix\"), where.prefix!));\n }\n\n q = q.order(order);\n\n const all = await q.collect();\n let startIdx = 0;\n if (args.cursor) {\n const cursorIdx = all.findIndex((doc) => doc._id === args.cursor);\n if (cursorIdx !== -1) {\n startIdx = cursorIdx + 1;\n }\n }\n const page = all.slice(startIdx, startIdx + limit + 1);\n const hasMore = page.length > limit;\n const items = hasMore ? page.slice(0, limit) : page;\n const nextCursor = hasMore ? items[items.length - 1]._id : null;\n return { items, nextCursor };\n },\n});\n\n/** Get a single API key by document ID. */\nexport const keyGetById = query({\n args: { keyId: v.id(\"key\") },\n handler: async (ctx, { keyId }) => {\n return await ctx.db.get(keyId);\n },\n});\n\n/**\n * Patch an API key record. Used for updating name, scopes, rate limit config,\n * revocation, and lastUsedAt / rate limit state tracking.\n */\nexport const keyPatch = mutation({\n args: {\n keyId: v.id(\"key\"),\n data: v.object({\n name: v.optional(v.string()),\n scopes: v.optional(\n v.array(\n v.object({\n resource: v.string(),\n actions: v.array(v.string()),\n }),\n ),\n ),\n rateLimit: v.optional(\n v.object({\n maxRequests: v.number(),\n windowMs: v.number(),\n }),\n ),\n rateLimitState: v.optional(\n v.object({\n attemptsLeft: v.number(),\n lastAttemptTime: v.number(),\n }),\n ),\n revoked: v.optional(v.boolean()),\n lastUsedAt: v.optional(v.number()),\n }),\n },\n handler: async (ctx, { keyId, data }) => {\n const key = await ctx.db.get(keyId);\n if (key === null) {\n throw new ConvexError({\n code: \"KEY_NOT_FOUND\",\n message: \"API key not found\",\n keyId,\n });\n }\n await ctx.db.patch(keyId, data);\n },\n});\n\n/** Hard delete an API key record. */\nexport const keyDelete = mutation({\n args: { keyId: v.id(\"key\") },\n handler: async (ctx, { keyId }) => {\n const key = await ctx.db.get(keyId);\n if (key === null) {\n throw new ConvexError({\n code: \"KEY_NOT_FOUND\",\n message: \"API key not found\",\n keyId,\n });\n }\n await ctx.db.delete(keyId);\n },\n});\n\n// ============================================================================\n// Device Authorization (RFC 8628)\n// ============================================================================\n\n/** Insert a new device authorization record. */\nexport const deviceInsert = mutation({\n args: {\n deviceCodeHash: v.string(),\n userCode: v.string(),\n expiresAt: v.number(),\n interval: v.number(),\n status: v.union(\n v.literal(\"pending\"),\n v.literal(\"authorized\"),\n v.literal(\"denied\"),\n ),\n },\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"device\", args);\n },\n});\n\n/** Look up a device authorization by its hashed device code. */\nexport const deviceGetByCodeHash = query({\n args: { deviceCodeHash: v.string() },\n handler: async (ctx, { deviceCodeHash }) => {\n return await ctx.db\n .query(\"device\")\n .withIndex(\"deviceCodeHash\", (q) => q.eq(\"deviceCodeHash\", deviceCodeHash))\n .first();\n },\n});\n\n/** Look up a pending device authorization by its user code. */\nexport const deviceGetByUserCode = query({\n args: { userCode: v.string() },\n handler: async (ctx, { userCode }) => {\n return await ctx.db\n .query(\"device\")\n .withIndex(\"userCode\", (q) =>\n q.eq(\"userCode\", userCode).eq(\"status\", \"pending\"),\n )\n .first();\n },\n});\n\n/** Authorize a device code — link it to a user and session. */\nexport const deviceAuthorize = mutation({\n args: {\n deviceId: v.id(\"device\"),\n userId: v.id(\"user\"),\n sessionId: v.id(\"session\"),\n },\n handler: async (ctx, { deviceId, userId, sessionId }) => {\n await ctx.db.patch(deviceId, {\n status: \"authorized\",\n userId,\n sessionId,\n });\n },\n});\n\n/** Update the last-polled timestamp on a device authorization record. */\nexport const deviceUpdateLastPolled = mutation({\n args: { deviceId: v.id(\"device\"), lastPolledAt: v.number() },\n handler: async (ctx, { deviceId, lastPolledAt }) => {\n await ctx.db.patch(deviceId, { lastPolledAt });\n },\n});\n\n/** Delete a device authorization record (cleanup after use or expiry). */\nexport const deviceDelete = mutation({\n args: { deviceId: v.id(\"device\") },\n handler: async (ctx, { deviceId }) => {\n await ctx.db.delete(deviceId);\n },\n});\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"db.js","names":[],"sources":["../../../../src/server/implementation/db.ts"],"sourcesContent":["import { GenericActionCtx, GenericDataModel, GenericMutationCtx } from \"convex/server\";\nimport { AuthComponentApi } from \"../types\";\n\ntype MutationCtxLike = Pick<GenericMutationCtx<GenericDataModel>, \"runQuery\" | \"runMutation\">;\ntype ActionCtxLike = Pick<\n GenericActionCtx<GenericDataModel>,\n \"runQuery\" | \"runMutation\" | \"runAction\"\n>;\n\ntype CtxLike = MutationCtxLike | ActionCtxLike;\n\nexport type AuthDbConfig = { component: AuthComponentApi };\n\nexport type AuthDb = ReturnType<typeof authDb>;\n\nexport function authDb(ctx: CtxLike, config: AuthDbConfig) {\n const component = config.component;\n return {\n users: {\n getById: (userId: string) =>\n ctx.runQuery(component.public.userGetById, { userId }),\n findByVerifiedEmail: (email: string) =>\n ctx.runQuery(component.public.userFindByVerifiedEmail, { email }),\n findByVerifiedPhone: (phone: string) =>\n ctx.runQuery(component.public.userFindByVerifiedPhone, { phone }),\n insert: (data: Record<string, unknown>) =>\n ctx.runMutation(component.public.userInsert, { data }) as Promise<string>,\n patch: (userId: string, data: Record<string, unknown>) =>\n ctx.runMutation(component.public.userPatch, { userId, data }),\n upsert: (userId: string | undefined, data: Record<string, unknown>) =>\n ctx.runMutation(component.public.userUpsert, { userId, data }) as Promise<string>,\n },\n accounts: {\n get: (provider: string, providerAccountId: string) =>\n ctx.runQuery(component.public.accountGet, { provider, providerAccountId }),\n getById: (accountId: string) =>\n ctx.runQuery(component.public.accountGetById, { accountId }),\n create: (args: {\n userId: string;\n provider: string;\n providerAccountId: string;\n secret?: string;\n }) => ctx.runMutation(component.public.accountInsert, args) as Promise<string>,\n patch: (accountId: string, data: Record<string, unknown>) =>\n ctx.runMutation(component.public.accountPatch, { accountId, data }),\n delete: (accountId: string) =>\n ctx.runMutation(component.public.accountDelete, { accountId }),\n },\n sessions: {\n create: (userId: string, expirationTime: number) =>\n ctx.runMutation(component.public.sessionCreate, { userId, expirationTime }) as Promise<string>,\n getById: (sessionId: string) =>\n ctx.runQuery(component.public.sessionGetById, { sessionId }),\n delete: (sessionId: string) =>\n ctx.runMutation(component.public.sessionDelete, { sessionId }),\n listByUser: (userId: string) =>\n ctx.runQuery(component.public.sessionListByUser, { userId }),\n },\n verifiers: {\n create: (sessionId?: string) =>\n ctx.runMutation(component.public.verifierCreate, { sessionId }) as Promise<string>,\n getById: (verifierId: string) =>\n ctx.runQuery(component.public.verifierGetById, { verifierId }),\n getBySignature: (signature: string) =>\n ctx.runQuery(component.public.verifierGetBySignature, { signature }),\n patch: (verifierId: string, data: Record<string, unknown>) =>\n ctx.runMutation(component.public.verifierPatch, { verifierId, data }),\n delete: (verifierId: string) =>\n ctx.runMutation(component.public.verifierDelete, { verifierId }),\n },\n verificationCodes: {\n getByAccountId: (accountId: string) =>\n ctx.runQuery(component.public.verificationCodeGetByAccountId, { accountId }),\n getByCode: (code: string) =>\n ctx.runQuery(component.public.verificationCodeGetByCode, { code }),\n create: (args: {\n accountId: string;\n provider: string;\n code: string;\n expirationTime: number;\n verifier?: string;\n emailVerified?: string;\n phoneVerified?: string;\n }) =>\n ctx.runMutation(component.public.verificationCodeCreate, args),\n delete: (verificationCodeId: string) =>\n ctx.runMutation(component.public.verificationCodeDelete, {\n verificationCodeId,\n }),\n },\n refreshTokens: {\n create: (args: {\n sessionId: string;\n expirationTime: number;\n parentRefreshTokenId?: string;\n }) =>\n ctx.runMutation(component.public.refreshTokenCreate, args) as Promise<string>,\n getById: (refreshTokenId: string) =>\n ctx.runQuery(component.public.refreshTokenGetById, { refreshTokenId }),\n patch: (refreshTokenId: string, data: Record<string, unknown>) =>\n ctx.runMutation(component.public.refreshTokenPatch, { refreshTokenId, data }),\n getChildren: (sessionId: string, parentRefreshTokenId: string) =>\n ctx.runQuery(component.public.refreshTokenGetChildren, {\n sessionId,\n parentRefreshTokenId,\n }),\n listBySession: (sessionId: string) =>\n ctx.runQuery(component.public.refreshTokenListBySession, { sessionId }),\n deleteAll: (sessionId: string) =>\n ctx.runMutation(component.public.refreshTokenDeleteAll, { sessionId }),\n getActive: (sessionId: string) =>\n ctx.runQuery(component.public.refreshTokenGetActive, { sessionId }),\n },\n rateLimits: {\n get: (identifier: string) =>\n ctx.runQuery(component.public.rateLimitGet, { identifier }),\n create: (args: {\n identifier: string;\n attemptsLeft: number;\n lastAttemptTime: number;\n }) => ctx.runMutation(component.public.rateLimitCreate, args),\n patch: (rateLimitId: string, data: Record<string, unknown>) =>\n ctx.runMutation(component.public.rateLimitPatch, { rateLimitId, data }),\n delete: (rateLimitId: string) =>\n ctx.runMutation(component.public.rateLimitDelete, { rateLimitId }),\n },\n };\n}\n"],"mappings":"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"}
@@ -1,135 +0,0 @@
1
- import { throwAuthError } from "../errors.js";
2
- import { requireEnv } from "../utils.js";
3
- import { generateRandomString, sha256 } from "./utils.js";
4
- import { callSignIn } from "./mutations/signin.js";
5
- import { mutateDeviceAuthorize, mutateDeviceDelete, mutateDeviceInsert, mutateDeviceUpdateLastPolled, queryDeviceByCodeHash, queryDeviceByUserCode } from "./types.js";
6
-
7
- //#region src/server/implementation/device.ts
8
- /** High-entropy device code alphabet (alphanumeric). */
9
- const DEVICE_CODE_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
10
- /** Device code length (40 chars ≈ 238 bits of entropy). */
11
- const DEVICE_CODE_LENGTH = 40;
12
- /**
13
- * Phase 1: Generate a device code + user code pair.
14
- *
15
- * Called by the input-constrained device. Returns the codes and
16
- * verification URIs so the device can display them to the user.
17
- */
18
- async function handleCreate(ctx, provider) {
19
- const deviceCode = generateRandomString(DEVICE_CODE_LENGTH, DEVICE_CODE_ALPHABET);
20
- const deviceCodeHash = await sha256(deviceCode);
21
- const rawUserCode = generateRandomString(provider.userCodeLength, provider.charset);
22
- const mid = Math.floor(rawUserCode.length / 2);
23
- const userCode = rawUserCode.slice(0, mid) + "-" + rawUserCode.slice(mid);
24
- await mutateDeviceInsert(ctx, {
25
- deviceCodeHash,
26
- userCode,
27
- expiresAt: Date.now() + provider.expiresIn * 1e3,
28
- interval: provider.interval,
29
- status: "pending"
30
- });
31
- const verificationUri = provider.verificationUri ?? `${process.env.SITE_URL ?? requireEnv("SITE_URL")}/device`;
32
- return {
33
- kind: "deviceCode",
34
- deviceCode,
35
- userCode,
36
- verificationUri,
37
- verificationUriComplete: `${verificationUri}?user_code=${encodeURIComponent(userCode)}`,
38
- expiresIn: provider.expiresIn,
39
- interval: provider.interval
40
- };
41
- }
42
- /**
43
- * Phase 2: Device polls for authorization status.
44
- *
45
- * Returns tokens when authorized, or throws a structured error
46
- * for pending / slow_down / expired / denied states.
47
- */
48
- async function handlePoll(ctx, _provider, params) {
49
- const rawDeviceCode = params.deviceCode;
50
- if (!rawDeviceCode) throwAuthError("DEVICE_MISSING_FLOW", "Missing `deviceCode` parameter for poll flow.");
51
- const doc = await queryDeviceByCodeHash(ctx, await sha256(rawDeviceCode));
52
- if (!doc) throwAuthError("DEVICE_CODE_EXPIRED");
53
- if (Date.now() > doc.expiresAt) {
54
- await mutateDeviceDelete(ctx, doc._id);
55
- throwAuthError("DEVICE_CODE_EXPIRED");
56
- }
57
- if (doc.lastPolledAt !== void 0) {
58
- if ((Date.now() - doc.lastPolledAt) / 1e3 < doc.interval) throwAuthError("DEVICE_SLOW_DOWN");
59
- }
60
- await mutateDeviceUpdateLastPolled(ctx, doc._id, Date.now());
61
- switch (doc.status) {
62
- case "pending":
63
- throwAuthError("DEVICE_AUTHORIZATION_PENDING");
64
- break;
65
- case "denied":
66
- await mutateDeviceDelete(ctx, doc._id);
67
- throwAuthError("DEVICE_CODE_DENIED");
68
- break;
69
- case "authorized":
70
- if (!doc.userId || !doc.sessionId) throwAuthError("INTERNAL_ERROR", "Authorized device code missing userId or sessionId.");
71
- await mutateDeviceDelete(ctx, doc._id);
72
- return {
73
- kind: "signedIn",
74
- signedIn: await callSignIn(ctx, {
75
- userId: doc.userId,
76
- sessionId: doc.sessionId,
77
- generateTokens: true
78
- })
79
- };
80
- default:
81
- doc.status;
82
- throwAuthError("INTERNAL_ERROR", `Unknown device status: ${doc.status}`);
83
- }
84
- }
85
- /**
86
- * Phase 3: Authenticated user authorizes a device code.
87
- *
88
- * The user enters the user code on a verification page while signed in.
89
- * This links the device code to the user's identity so the device can
90
- * obtain tokens on the next poll.
91
- */
92
- async function handleVerify(ctx, _provider, params) {
93
- const userCode = params.userCode;
94
- if (!userCode) throwAuthError("DEVICE_INVALID_USER_CODE", "Missing `userCode` parameter for verify flow.");
95
- const identity = await ctx.auth.getUserIdentity();
96
- if (identity === null) throwAuthError("NOT_SIGNED_IN", "You must be signed in to authorize a device.");
97
- const [userId] = identity.subject.split("|");
98
- const doc = await queryDeviceByUserCode(ctx, userCode);
99
- if (!doc) throwAuthError("DEVICE_INVALID_USER_CODE");
100
- if (Date.now() > doc.expiresAt) {
101
- await mutateDeviceDelete(ctx, doc._id);
102
- throwAuthError("DEVICE_CODE_EXPIRED");
103
- }
104
- if (doc.status !== "pending") throwAuthError("DEVICE_ALREADY_AUTHORIZED");
105
- const signInResult = await callSignIn(ctx, {
106
- userId,
107
- generateTokens: false
108
- });
109
- await mutateDeviceAuthorize(ctx, doc._id, signInResult.userId, signInResult.sessionId);
110
- return {
111
- kind: "signedIn",
112
- signedIn: null
113
- };
114
- }
115
- /**
116
- * Main device authorization handler dispatched from signIn.ts.
117
- *
118
- * Routes to the appropriate phase based on `params.flow`:
119
- * - (no flow / default) → create device + user codes
120
- * - "poll" → check authorization status
121
- * - "verify" → user authorizes a device code
122
- */
123
- async function handleDevice(ctx, provider, args) {
124
- const flow = args.params?.flow;
125
- if (!flow) return handleCreate(ctx, provider);
126
- switch (flow) {
127
- case "poll": return handlePoll(ctx, provider, args.params ?? {});
128
- case "verify": return handleVerify(ctx, provider, args.params ?? {});
129
- default: throwAuthError("DEVICE_UNKNOWN_FLOW", `Unknown device flow: ${flow}. Expected one of: poll, verify`);
130
- }
131
- }
132
-
133
- //#endregion
134
- export { handleDevice };
135
- //# sourceMappingURL=device.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"device.js","names":[],"sources":["../../../../src/server/implementation/device.ts"],"sourcesContent":["/**\n * Server-side device authorization flow logic (RFC 8628).\n *\n * Handles the three phases of the device flow:\n * 1. (default) — Generate a device code + user code pair\n * 2. poll — Device checks whether the user has authorized yet\n * 3. verify — Authenticated user links a user code to their session\n *\n * Uses `@oslojs/crypto/random` for code generation and\n * `@oslojs/crypto/sha2` for hashing device codes before storage.\n */\n\nimport {\n DeviceProviderConfig,\n GenericActionCtxWithAuthConfig,\n} from \"../types\";\nimport {\n AuthDataModel,\n SessionInfo,\n mutateDeviceInsert,\n queryDeviceByCodeHash,\n queryDeviceByUserCode,\n mutateDeviceAuthorize,\n mutateDeviceUpdateLastPolled,\n mutateDeviceDelete,\n} from \"./types\";\nimport { callSignIn } from \"./mutations/index\";\nimport { generateRandomString, sha256 } from \"./utils\";\nimport { throwAuthError } from \"../errors\";\nimport { requireEnv } from \"../utils\";\n\ntype EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** High-entropy device code alphabet (alphanumeric). */\nconst DEVICE_CODE_ALPHABET =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/** Device code length (40 chars ≈ 238 bits of entropy). */\nconst DEVICE_CODE_LENGTH = 40;\n\n// ============================================================================\n// Create flow (default — no flow param)\n// ============================================================================\n\n/**\n * Phase 1: Generate a device code + user code pair.\n *\n * Called by the input-constrained device. Returns the codes and\n * verification URIs so the device can display them to the user.\n */\nasync function handleCreate(\n ctx: EnrichedActionCtx,\n provider: DeviceProviderConfig,\n): Promise<{\n kind: \"deviceCode\";\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresIn: number;\n interval: number;\n}> {\n // Generate the raw device code (high entropy, never stored raw)\n const deviceCode = generateRandomString(\n DEVICE_CODE_LENGTH,\n DEVICE_CODE_ALPHABET,\n );\n const deviceCodeHash = await sha256(deviceCode);\n\n // Generate the user code (short, no vowels per RFC 8628 §6.1)\n const rawUserCode = generateRandomString(\n provider.userCodeLength,\n provider.charset,\n );\n // Format as XXXX-XXXX for display\n const mid = Math.floor(rawUserCode.length / 2);\n const userCode = rawUserCode.slice(0, mid) + \"-\" + rawUserCode.slice(mid);\n\n const expiresAt = Date.now() + provider.expiresIn * 1000;\n\n // Store in the component DB\n await mutateDeviceInsert(ctx, {\n deviceCodeHash,\n userCode,\n expiresAt,\n interval: provider.interval,\n status: \"pending\",\n });\n\n // Build verification URIs\n // Prefer explicit config; fall back to SITE_URL (Convex HTTP actions URL).\n const verificationUri =\n provider.verificationUri ??\n `${process.env.SITE_URL ?? requireEnv(\"SITE_URL\")}/device`;\n // Use `user_code` param to avoid collision with OAuth `?code=` on SSR frameworks.\n const verificationUriComplete = `${verificationUri}?user_code=${encodeURIComponent(userCode)}`;\n\n return {\n kind: \"deviceCode\",\n deviceCode,\n userCode,\n verificationUri,\n verificationUriComplete,\n expiresIn: provider.expiresIn,\n interval: provider.interval,\n };\n}\n\n// ============================================================================\n// Poll flow\n// ============================================================================\n\n/**\n * Phase 2: Device polls for authorization status.\n *\n * Returns tokens when authorized, or throws a structured error\n * for pending / slow_down / expired / denied states.\n */\nasync function handlePoll(\n ctx: EnrichedActionCtx,\n _provider: DeviceProviderConfig,\n params: Record<string, any>,\n): Promise<{ kind: \"signedIn\"; signedIn: SessionInfo | null }> {\n const rawDeviceCode = params.deviceCode as string | undefined;\n if (!rawDeviceCode) {\n throwAuthError(\"DEVICE_MISSING_FLOW\", \"Missing `deviceCode` parameter for poll flow.\");\n }\n\n const deviceCodeHash = await sha256(rawDeviceCode);\n const doc = await queryDeviceByCodeHash(ctx, deviceCodeHash);\n\n // Unknown or already-consumed code\n if (!doc) {\n throwAuthError(\"DEVICE_CODE_EXPIRED\");\n }\n\n // Check expiry\n if (Date.now() > doc.expiresAt) {\n // Lazy cleanup\n await mutateDeviceDelete(ctx, doc._id);\n throwAuthError(\"DEVICE_CODE_EXPIRED\");\n }\n\n // Enforce polling interval (slow_down)\n if (doc.lastPolledAt !== undefined) {\n const elapsed = (Date.now() - doc.lastPolledAt) / 1000;\n if (elapsed < doc.interval) {\n throwAuthError(\"DEVICE_SLOW_DOWN\");\n }\n }\n\n // Update last polled timestamp\n await mutateDeviceUpdateLastPolled(ctx, doc._id, Date.now());\n\n // Check status\n switch (doc.status) {\n case \"pending\":\n throwAuthError(\"DEVICE_AUTHORIZATION_PENDING\");\n break; // unreachable but satisfies control flow\n\n case \"denied\":\n await mutateDeviceDelete(ctx, doc._id);\n throwAuthError(\"DEVICE_CODE_DENIED\");\n break;\n\n case \"authorized\": {\n // Device is authorized — issue tokens for the linked user/session\n if (!doc.userId || !doc.sessionId) {\n throwAuthError(\"INTERNAL_ERROR\", \"Authorized device code missing userId or sessionId.\");\n }\n\n // Clean up the device code record\n await mutateDeviceDelete(ctx, doc._id);\n\n // Generate tokens for the authorized session\n const signInResult = await callSignIn(ctx, {\n userId: doc.userId,\n sessionId: doc.sessionId,\n generateTokens: true,\n });\n\n return { kind: \"signedIn\", signedIn: signInResult };\n }\n\n default: {\n const _exhaustive: never = doc.status;\n throwAuthError(\"INTERNAL_ERROR\", `Unknown device status: ${doc.status}`);\n }\n }\n}\n\n// ============================================================================\n// Verify flow\n// ============================================================================\n\n/**\n * Phase 3: Authenticated user authorizes a device code.\n *\n * The user enters the user code on a verification page while signed in.\n * This links the device code to the user's identity so the device can\n * obtain tokens on the next poll.\n */\nasync function handleVerify(\n ctx: EnrichedActionCtx,\n _provider: DeviceProviderConfig,\n params: Record<string, any>,\n): Promise<{ kind: \"signedIn\"; signedIn: SessionInfo | null }> {\n const userCode = params.userCode as string | undefined;\n if (!userCode) {\n throwAuthError(\"DEVICE_INVALID_USER_CODE\", \"Missing `userCode` parameter for verify flow.\");\n }\n\n // Require an authenticated user\n const identity = await ctx.auth.getUserIdentity();\n if (identity === null) {\n throwAuthError(\"NOT_SIGNED_IN\", \"You must be signed in to authorize a device.\");\n }\n const [userId] = identity.subject.split(\"|\");\n\n // Look up the pending device code by user code\n const doc = await queryDeviceByUserCode(ctx, userCode);\n if (!doc) {\n throwAuthError(\"DEVICE_INVALID_USER_CODE\");\n }\n\n // Check expiry\n if (Date.now() > doc.expiresAt) {\n await mutateDeviceDelete(ctx, doc._id);\n throwAuthError(\"DEVICE_CODE_EXPIRED\");\n }\n\n // Already authorized (shouldn't happen with the index filter, but be safe)\n if (doc.status !== \"pending\") {\n throwAuthError(\"DEVICE_ALREADY_AUTHORIZED\");\n }\n\n // Create a new session for the device\n const signInResult = await callSignIn(ctx, {\n userId: userId!,\n generateTokens: false, // Device gets tokens via poll, not here\n });\n\n // Authorize the device code with the new session\n await mutateDeviceAuthorize(\n ctx,\n doc._id,\n signInResult.userId,\n signInResult.sessionId,\n );\n\n // Return success (no tokens — the verification page doesn't need them)\n return { kind: \"signedIn\", signedIn: null };\n}\n\n// ============================================================================\n// Main dispatch\n// ============================================================================\n\n/**\n * Main device authorization handler dispatched from signIn.ts.\n *\n * Routes to the appropriate phase based on `params.flow`:\n * - (no flow / default) → create device + user codes\n * - \"poll\" → check authorization status\n * - \"verify\" → user authorizes a device code\n */\nexport async function handleDevice(\n ctx: EnrichedActionCtx,\n provider: DeviceProviderConfig,\n args: {\n params?: Record<string, any>;\n },\n): Promise<\n | {\n kind: \"deviceCode\";\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresIn: number;\n interval: number;\n }\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n> {\n const flow = args.params?.flow;\n\n // Default flow: create device + user codes\n if (!flow) {\n return handleCreate(ctx, provider);\n }\n\n switch (flow) {\n case \"poll\":\n return handlePoll(ctx, provider, args.params ?? {});\n case \"verify\":\n return handleVerify(ctx, provider, args.params ?? {});\n default:\n throwAuthError(\n \"DEVICE_UNKNOWN_FLOW\",\n `Unknown device flow: ${flow}. Expected one of: poll, verify`,\n );\n }\n}\n"],"mappings":"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"}