@robelest/convex-auth 0.0.4-preview.22 → 0.0.4-preview.24

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 (314) hide show
  1. package/README.md +10 -11
  2. package/dist/authorization/index.d.ts +1 -1
  3. package/dist/authorization/index.js +1 -1
  4. package/dist/authorization/index.js.map +1 -1
  5. package/dist/client/index.d.ts +1 -2
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +36 -39
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/component/client/index.d.ts +1 -2
  10. package/dist/component/index.js +2 -2
  11. package/dist/component/model.d.ts +9 -9
  12. package/dist/component/model.d.ts.map +1 -1
  13. package/dist/component/public/enterprise/audit.d.ts.map +1 -1
  14. package/dist/component/public/enterprise/audit.js.map +1 -1
  15. package/dist/component/public/enterprise/core.d.ts.map +1 -1
  16. package/dist/component/public/enterprise/core.js.map +1 -1
  17. package/dist/component/public/enterprise/domains.d.ts.map +1 -1
  18. package/dist/component/public/enterprise/domains.js.map +1 -1
  19. package/dist/component/public/enterprise/scim.d.ts.map +1 -1
  20. package/dist/component/public/enterprise/scim.js.map +1 -1
  21. package/dist/component/public/enterprise/secrets.d.ts.map +1 -1
  22. package/dist/component/public/enterprise/secrets.js.map +1 -1
  23. package/dist/component/public/enterprise/webhooks.d.ts.map +1 -1
  24. package/dist/component/public/enterprise/webhooks.js.map +1 -1
  25. package/dist/component/public/factors/devices.d.ts.map +1 -1
  26. package/dist/component/public/factors/devices.js.map +1 -1
  27. package/dist/component/public/factors/passkeys.d.ts.map +1 -1
  28. package/dist/component/public/factors/passkeys.js.map +1 -1
  29. package/dist/component/public/factors/totp.d.ts.map +1 -1
  30. package/dist/component/public/factors/totp.js.map +1 -1
  31. package/dist/component/public/groups/core.js.map +1 -1
  32. package/dist/component/public/groups/invites.d.ts.map +1 -1
  33. package/dist/component/public/groups/invites.js.map +1 -1
  34. package/dist/component/public/groups/members.d.ts.map +1 -1
  35. package/dist/component/public/groups/members.js.map +1 -1
  36. package/dist/component/public/identity/accounts.d.ts.map +1 -1
  37. package/dist/component/public/identity/accounts.js.map +1 -1
  38. package/dist/component/public/identity/codes.d.ts.map +1 -1
  39. package/dist/component/public/identity/codes.js.map +1 -1
  40. package/dist/component/public/identity/sessions.d.ts.map +1 -1
  41. package/dist/component/public/identity/sessions.js.map +1 -1
  42. package/dist/component/public/identity/tokens.d.ts.map +1 -1
  43. package/dist/component/public/identity/tokens.js.map +1 -1
  44. package/dist/component/public/identity/users.d.ts.map +1 -1
  45. package/dist/component/public/identity/users.js.map +1 -1
  46. package/dist/component/public/identity/verifiers.d.ts.map +1 -1
  47. package/dist/component/public/identity/verifiers.js.map +1 -1
  48. package/dist/component/public/security/keys.d.ts.map +1 -1
  49. package/dist/component/public/security/keys.js.map +1 -1
  50. package/dist/component/public/security/limits.d.ts.map +1 -1
  51. package/dist/component/public/security/limits.js.map +1 -1
  52. package/dist/component/schema.d.ts +41 -41
  53. package/dist/component/server/auth.d.ts +127 -130
  54. package/dist/component/server/auth.d.ts.map +1 -1
  55. package/dist/component/server/auth.js +100 -64
  56. package/dist/component/server/auth.js.map +1 -1
  57. package/dist/component/server/context.js +53 -0
  58. package/dist/component/server/context.js.map +1 -0
  59. package/dist/component/server/core.js +113 -250
  60. package/dist/component/server/core.js.map +1 -1
  61. package/dist/component/server/crypto.js +25 -7
  62. package/dist/component/server/crypto.js.map +1 -1
  63. package/dist/component/server/device.js +59 -16
  64. package/dist/component/server/device.js.map +1 -1
  65. package/dist/component/server/enterprise/domain.js +148 -59
  66. package/dist/component/server/enterprise/domain.js.map +1 -1
  67. package/dist/component/server/enterprise/http.js +36 -15
  68. package/dist/component/server/enterprise/http.js.map +1 -1
  69. package/dist/component/server/enterprise/oidc.js +1 -1
  70. package/dist/component/server/http.d.ts +85 -0
  71. package/dist/component/server/http.d.ts.map +1 -0
  72. package/dist/component/server/http.js +85 -22
  73. package/dist/component/server/http.js.map +1 -1
  74. package/dist/component/server/identity.js +5 -2
  75. package/dist/component/server/identity.js.map +1 -1
  76. package/dist/component/server/limits.js +21 -30
  77. package/dist/component/server/limits.js.map +1 -1
  78. package/dist/component/server/mutations/account.js +12 -10
  79. package/dist/component/server/mutations/account.js.map +1 -1
  80. package/dist/component/server/mutations/code.js +5 -2
  81. package/dist/component/server/mutations/code.js.map +1 -1
  82. package/dist/component/server/mutations/invalidate.js +1 -1
  83. package/dist/component/server/mutations/invalidate.js.map +1 -1
  84. package/dist/component/server/mutations/oauth.js +10 -4
  85. package/dist/component/server/mutations/oauth.js.map +1 -1
  86. package/dist/component/server/mutations/refresh.js +2 -2
  87. package/dist/component/server/mutations/refresh.js.map +1 -1
  88. package/dist/component/server/mutations/register.js +46 -42
  89. package/dist/component/server/mutations/register.js.map +1 -1
  90. package/dist/component/server/mutations/retrieve.js +21 -25
  91. package/dist/component/server/mutations/retrieve.js.map +1 -1
  92. package/dist/component/server/mutations/signature.js +10 -4
  93. package/dist/component/server/mutations/signature.js.map +1 -1
  94. package/dist/component/server/mutations/signout.js.map +1 -1
  95. package/dist/component/server/mutations/store.js +9 -24
  96. package/dist/component/server/mutations/store.js.map +1 -1
  97. package/dist/component/server/mutations/verifier.js.map +1 -1
  98. package/dist/component/server/mutations/verify.js +1 -1
  99. package/dist/component/server/mutations/verify.js.map +1 -1
  100. package/dist/component/server/oauth.js +53 -16
  101. package/dist/component/server/oauth.js.map +1 -1
  102. package/dist/component/server/passkey.js +115 -31
  103. package/dist/component/server/passkey.js.map +1 -1
  104. package/dist/component/server/redirects.js +9 -3
  105. package/dist/component/server/redirects.js.map +1 -1
  106. package/dist/component/server/refresh.js +10 -7
  107. package/dist/component/server/refresh.js.map +1 -1
  108. package/dist/component/server/runtime.d.ts +5 -5
  109. package/dist/component/server/runtime.js +156 -113
  110. package/dist/component/server/runtime.js.map +1 -1
  111. package/dist/component/server/signin.js +34 -10
  112. package/dist/component/server/signin.js.map +1 -1
  113. package/dist/component/server/totp.js +79 -19
  114. package/dist/component/server/totp.js.map +1 -1
  115. package/dist/component/server/types.d.ts +12 -20
  116. package/dist/component/server/types.d.ts.map +1 -1
  117. package/dist/component/server/types.js.map +1 -1
  118. package/dist/component/server/users.js +6 -3
  119. package/dist/component/server/users.js.map +1 -1
  120. package/dist/component/server/utils.js +10 -4
  121. package/dist/component/server/utils.js.map +1 -1
  122. package/dist/core/types.d.ts +14 -22
  123. package/dist/core/types.d.ts.map +1 -1
  124. package/dist/factors/device.js +8 -9
  125. package/dist/factors/device.js.map +1 -1
  126. package/dist/factors/passkey.js +18 -21
  127. package/dist/factors/passkey.js.map +1 -1
  128. package/dist/providers/password.js +66 -81
  129. package/dist/providers/password.js.map +1 -1
  130. package/dist/runtime/invite.js +2 -8
  131. package/dist/runtime/invite.js.map +1 -1
  132. package/dist/server/auth.d.ts +127 -130
  133. package/dist/server/auth.d.ts.map +1 -1
  134. package/dist/server/auth.js +100 -64
  135. package/dist/server/auth.js.map +1 -1
  136. package/dist/server/context.d.ts +1 -0
  137. package/dist/server/context.js +53 -0
  138. package/dist/server/context.js.map +1 -0
  139. package/dist/server/core.d.ts +74 -195
  140. package/dist/server/core.d.ts.map +1 -1
  141. package/dist/server/core.js +113 -250
  142. package/dist/server/core.js.map +1 -1
  143. package/dist/server/crypto.d.ts.map +1 -1
  144. package/dist/server/crypto.js +25 -7
  145. package/dist/server/crypto.js.map +1 -1
  146. package/dist/server/device.js +59 -16
  147. package/dist/server/device.js.map +1 -1
  148. package/dist/server/enterprise/domain.d.ts +0 -8
  149. package/dist/server/enterprise/domain.d.ts.map +1 -1
  150. package/dist/server/enterprise/domain.js +148 -59
  151. package/dist/server/enterprise/domain.js.map +1 -1
  152. package/dist/server/enterprise/http.d.ts.map +1 -1
  153. package/dist/server/enterprise/http.js +35 -14
  154. package/dist/server/enterprise/http.js.map +1 -1
  155. package/dist/server/http.d.ts +81 -3
  156. package/dist/server/http.d.ts.map +1 -1
  157. package/dist/server/http.js +84 -21
  158. package/dist/server/http.js.map +1 -1
  159. package/dist/server/identity.js +5 -2
  160. package/dist/server/identity.js.map +1 -1
  161. package/dist/server/index.d.ts +3 -2
  162. package/dist/server/index.js +2 -2
  163. package/dist/server/limits.js +21 -30
  164. package/dist/server/limits.js.map +1 -1
  165. package/dist/server/mounts.d.ts +25 -63
  166. package/dist/server/mounts.d.ts.map +1 -1
  167. package/dist/server/mounts.js +46 -107
  168. package/dist/server/mounts.js.map +1 -1
  169. package/dist/server/mutations/account.d.ts +8 -9
  170. package/dist/server/mutations/account.d.ts.map +1 -1
  171. package/dist/server/mutations/account.js +11 -9
  172. package/dist/server/mutations/account.js.map +1 -1
  173. package/dist/server/mutations/code.d.ts +12 -12
  174. package/dist/server/mutations/code.d.ts.map +1 -1
  175. package/dist/server/mutations/code.js +5 -2
  176. package/dist/server/mutations/code.js.map +1 -1
  177. package/dist/server/mutations/invalidate.d.ts +4 -4
  178. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  179. package/dist/server/mutations/invalidate.js.map +1 -1
  180. package/dist/server/mutations/oauth.d.ts +14 -12
  181. package/dist/server/mutations/oauth.d.ts.map +1 -1
  182. package/dist/server/mutations/oauth.js +9 -3
  183. package/dist/server/mutations/oauth.js.map +1 -1
  184. package/dist/server/mutations/refresh.d.ts +3 -3
  185. package/dist/server/mutations/refresh.d.ts.map +1 -1
  186. package/dist/server/mutations/refresh.js +1 -1
  187. package/dist/server/mutations/refresh.js.map +1 -1
  188. package/dist/server/mutations/register.d.ts +11 -11
  189. package/dist/server/mutations/register.d.ts.map +1 -1
  190. package/dist/server/mutations/register.js +45 -41
  191. package/dist/server/mutations/register.js.map +1 -1
  192. package/dist/server/mutations/retrieve.d.ts +6 -6
  193. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  194. package/dist/server/mutations/retrieve.js +20 -24
  195. package/dist/server/mutations/retrieve.js.map +1 -1
  196. package/dist/server/mutations/signature.d.ts +6 -7
  197. package/dist/server/mutations/signature.d.ts.map +1 -1
  198. package/dist/server/mutations/signature.js +9 -3
  199. package/dist/server/mutations/signature.js.map +1 -1
  200. package/dist/server/mutations/signin.d.ts +5 -5
  201. package/dist/server/mutations/signout.js.map +1 -1
  202. package/dist/server/mutations/store.d.ts +83 -83
  203. package/dist/server/mutations/store.js +8 -23
  204. package/dist/server/mutations/store.js.map +1 -1
  205. package/dist/server/mutations/verifier.js.map +1 -1
  206. package/dist/server/mutations/verify.d.ts +7 -7
  207. package/dist/server/mutations/verify.d.ts.map +1 -1
  208. package/dist/server/mutations/verify.js.map +1 -1
  209. package/dist/server/oauth.js +53 -16
  210. package/dist/server/oauth.js.map +1 -1
  211. package/dist/server/passkey.d.ts +2 -2
  212. package/dist/server/passkey.d.ts.map +1 -1
  213. package/dist/server/passkey.js +114 -30
  214. package/dist/server/passkey.js.map +1 -1
  215. package/dist/server/redirects.js +9 -3
  216. package/dist/server/redirects.js.map +1 -1
  217. package/dist/server/refresh.js +10 -7
  218. package/dist/server/refresh.js.map +1 -1
  219. package/dist/server/runtime.d.ts +11 -11
  220. package/dist/server/runtime.js +155 -112
  221. package/dist/server/runtime.js.map +1 -1
  222. package/dist/server/signin.js +34 -10
  223. package/dist/server/signin.js.map +1 -1
  224. package/dist/server/ssr.d.ts.map +1 -1
  225. package/dist/server/ssr.js +175 -184
  226. package/dist/server/ssr.js.map +1 -1
  227. package/dist/server/totp.js +78 -18
  228. package/dist/server/totp.js.map +1 -1
  229. package/dist/server/types.d.ts +13 -21
  230. package/dist/server/types.d.ts.map +1 -1
  231. package/dist/server/types.js.map +1 -1
  232. package/dist/server/users.js +6 -3
  233. package/dist/server/users.js.map +1 -1
  234. package/dist/server/utils.js +10 -4
  235. package/dist/server/utils.js.map +1 -1
  236. package/package.json +1 -5
  237. package/src/authorization/index.ts +1 -1
  238. package/src/client/core/types.ts +14 -14
  239. package/src/client/factors/device.ts +10 -12
  240. package/src/client/factors/passkey.ts +23 -26
  241. package/src/client/index.ts +54 -64
  242. package/src/client/runtime/invite.ts +5 -7
  243. package/src/component/index.ts +9 -3
  244. package/src/component/public/enterprise/audit.ts +6 -1
  245. package/src/component/public/enterprise/core.ts +1 -0
  246. package/src/component/public/enterprise/domains.ts +5 -1
  247. package/src/component/public/enterprise/scim.ts +1 -0
  248. package/src/component/public/enterprise/secrets.ts +1 -0
  249. package/src/component/public/enterprise/webhooks.ts +1 -0
  250. package/src/component/public/factors/devices.ts +1 -0
  251. package/src/component/public/factors/passkeys.ts +1 -0
  252. package/src/component/public/factors/totp.ts +1 -0
  253. package/src/component/public/groups/core.ts +1 -1
  254. package/src/component/public/groups/invites.ts +7 -1
  255. package/src/component/public/groups/members.ts +1 -0
  256. package/src/component/public/identity/accounts.ts +1 -0
  257. package/src/component/public/identity/codes.ts +1 -0
  258. package/src/component/public/identity/sessions.ts +1 -0
  259. package/src/component/public/identity/tokens.ts +1 -0
  260. package/src/component/public/identity/users.ts +1 -0
  261. package/src/component/public/identity/verifiers.ts +1 -0
  262. package/src/component/public/security/keys.ts +1 -0
  263. package/src/component/public/security/limits.ts +1 -0
  264. package/src/providers/password.ts +89 -110
  265. package/src/server/auth.ts +240 -182
  266. package/src/server/context.ts +90 -0
  267. package/src/server/core.ts +195 -286
  268. package/src/server/crypto.ts +31 -29
  269. package/src/server/device.ts +65 -32
  270. package/src/server/enterprise/domain.ts +158 -170
  271. package/src/server/enterprise/http.ts +46 -39
  272. package/src/server/http.ts +289 -30
  273. package/src/server/identity.ts +5 -5
  274. package/src/server/index.ts +9 -3
  275. package/src/server/limits.ts +53 -80
  276. package/src/server/mounts.ts +56 -80
  277. package/src/server/mutations/account.ts +22 -36
  278. package/src/server/mutations/code.ts +6 -6
  279. package/src/server/mutations/invalidate.ts +1 -1
  280. package/src/server/mutations/oauth.ts +14 -8
  281. package/src/server/mutations/refresh.ts +5 -4
  282. package/src/server/mutations/register.ts +87 -132
  283. package/src/server/mutations/retrieve.ts +44 -44
  284. package/src/server/mutations/signature.ts +13 -6
  285. package/src/server/mutations/signout.ts +1 -1
  286. package/src/server/mutations/store.ts +16 -31
  287. package/src/server/mutations/verifier.ts +1 -1
  288. package/src/server/mutations/verify.ts +3 -5
  289. package/src/server/oauth.ts +60 -69
  290. package/src/server/passkey.ts +567 -517
  291. package/src/server/redirects.ts +10 -6
  292. package/src/server/refresh.ts +14 -18
  293. package/src/server/runtime.ts +340 -302
  294. package/src/server/signin.ts +44 -37
  295. package/src/server/ssr.ts +390 -407
  296. package/src/server/totp.ts +85 -35
  297. package/src/server/types.ts +19 -22
  298. package/src/server/users.ts +7 -6
  299. package/src/server/utils.ts +10 -12
  300. package/dist/component/server/authError.js +0 -34
  301. package/dist/component/server/authError.js.map +0 -1
  302. package/dist/component/server/errors.d.ts +0 -1
  303. package/dist/component/server/errors.js +0 -137
  304. package/dist/component/server/errors.js.map +0 -1
  305. package/dist/server/authError.d.ts +0 -46
  306. package/dist/server/authError.d.ts.map +0 -1
  307. package/dist/server/authError.js +0 -34
  308. package/dist/server/authError.js.map +0 -1
  309. package/dist/server/errors.d.ts +0 -177
  310. package/dist/server/errors.d.ts.map +0 -1
  311. package/dist/server/errors.js +0 -212
  312. package/dist/server/errors.js.map +0 -1
  313. package/src/server/authError.ts +0 -44
  314. package/src/server/errors.ts +0 -290
@@ -1,4 +1,3 @@
1
- import { AuthError } from "./authError.js";
2
1
  import { generateRandomString, requireEnv } from "./utils.js";
3
2
  import { callCreateVerificationCode } from "./mutations/code.js";
4
3
  import { callRefreshSession } from "./mutations/refresh.js";
@@ -11,6 +10,7 @@ import { handleDevice } from "./device.js";
11
10
  import { handlePasskeyFx } from "./passkey.js";
12
11
  import { redirectAbsoluteUrl, setURLSearchParam } from "./redirects.js";
13
12
  import { handleTotp } from "./totp.js";
13
+ import { Cv } from "@robelest/fx/convex";
14
14
  import { Fx } from "@robelest/fx";
15
15
 
16
16
  //#region src/server/signin.ts
@@ -18,7 +18,7 @@ const DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S = 3600 * 24;
18
18
  /** @internal */
19
19
  async function signInImpl(ctx, provider, args, options) {
20
20
  const fx = signInFx(ctx, provider, args, options);
21
- return Fx.run(fx.pipe(Fx.recover((e) => Fx.fatal(e.toConvexError()))));
21
+ return Fx.run(fx.pipe(Fx.recover((e) => Fx.fatal(e))));
22
22
  }
23
23
  /**
24
24
  * Core sign-in pipeline as an Fx generator.
@@ -48,7 +48,10 @@ function signInFx(ctx, provider, args, options) {
48
48
  allowExtraProviders: options.allowExtraProviders
49
49
  }))
50
50
  };
51
- const resolvedProvider = yield* provider != null ? Fx.succeed(provider) : Fx.fail(new AuthError("SIGN_IN_MISSING_PARAMS"));
51
+ const resolvedProvider = yield* provider != null ? Fx.succeed(provider) : Cv.fail({
52
+ code: "SIGN_IN_MISSING_PARAMS",
53
+ message: "Cannot sign in: missing provider, code, or refresh token."
54
+ });
52
55
  return yield* Fx.match(resolvedProvider).on("type", {
53
56
  email: (p) => handleEmailAndPhoneProviderFx(ctx, p, args, options),
54
57
  phone: (p) => handleEmailAndPhoneProviderFx(ctx, p, args, options),
@@ -72,12 +75,18 @@ function handleEmailAndPhoneProviderFx(ctx, provider, args, options) {
72
75
  }));
73
76
  return {
74
77
  kind: "signedIn",
75
- signedIn: yield* result != null ? Fx.succeed(result) : Fx.fail(new AuthError("INVALID_VERIFICATION_CODE"))
78
+ signedIn: yield* result != null ? Fx.succeed(result) : Cv.fail({
79
+ code: "INVALID_VERIFICATION_CODE",
80
+ message: "Invalid or expired verification code."
81
+ })
76
82
  };
77
83
  }
78
84
  const code = provider.generateVerificationToken ? yield* Fx.from({
79
85
  ok: async () => provider.generateVerificationToken(),
80
- err: () => new AuthError("INTERNAL_ERROR", "Failed to generate verification token")
86
+ err: () => Cv.error({
87
+ code: "INTERNAL_ERROR",
88
+ message: "Failed to generate verification token"
89
+ })
81
90
  }) : generateRandomString(32, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
82
91
  const expirationTime = Date.now() + (provider.maxAge ?? DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S) * 1e3;
83
92
  const verificationArgs = {
@@ -101,14 +110,20 @@ function handleEmailAndPhoneProviderFx(ctx, provider, args, options) {
101
110
  provider: p,
102
111
  request: new Request("http://localhost")
103
112
  }, ctx),
104
- err: () => new AuthError("INTERNAL_ERROR", "Failed to send email code")
113
+ err: () => Cv.error({
114
+ code: "INTERNAL_ERROR",
115
+ message: "Failed to send email code"
116
+ })
105
117
  }),
106
118
  phone: (p) => Fx.from({
107
119
  ok: async () => p.sendVerificationRequest({
108
120
  ...verificationArgs,
109
121
  provider: p
110
122
  }, ctx),
111
- err: () => new AuthError("INTERNAL_ERROR", "Failed to send phone code")
123
+ err: () => Cv.error({
124
+ code: "INTERNAL_ERROR",
125
+ message: "Failed to send phone code"
126
+ })
112
127
  })
113
128
  });
114
129
  return {
@@ -167,7 +182,10 @@ function handleOAuthProviderFx(ctx, provider, args, options) {
167
182
  const verifier = yield* Fx.promise(() => callVerifier(ctx));
168
183
  redirect.searchParams.set("code", verifier);
169
184
  if (args.params?.redirectTo !== void 0) {
170
- yield* Fx.guard(typeof args.params.redirectTo !== "string", Fx.fail(new AuthError("INVALID_REDIRECT", `Expected \`redirectTo\` to be a string, got ${args.params.redirectTo}`)));
185
+ yield* Fx.guard(typeof args.params.redirectTo !== "string", Cv.fail({
186
+ code: "INVALID_REDIRECT",
187
+ message: `Expected \`redirectTo\` to be a string, got ${args.params.redirectTo}`
188
+ }));
171
189
  redirect.searchParams.set("redirectTo", args.params.redirectTo);
172
190
  }
173
191
  return {
@@ -180,9 +198,15 @@ function handleOAuthProviderFx(ctx, provider, args, options) {
180
198
  function handleSsoProviderFx(ctx, args) {
181
199
  return Fx.gen(function* () {
182
200
  const enterpriseId = args.params?.enterpriseId;
183
- if (!enterpriseId || typeof enterpriseId !== "string") return yield* Fx.fail(new AuthError("SIGN_IN_MISSING_PARAMS", "enterpriseId is required for SSO sign-in."));
201
+ if (!enterpriseId || typeof enterpriseId !== "string") return yield* Cv.fail({
202
+ code: "SIGN_IN_MISSING_PARAMS",
203
+ message: "enterpriseId is required for SSO sign-in."
204
+ });
184
205
  const protocol = args.params?.protocol ?? "oidc";
185
- if (protocol !== "oidc" && protocol !== "saml") return yield* Fx.fail(new AuthError("SIGN_IN_MISSING_PARAMS", `Invalid SSO protocol: ${protocol}. Expected "oidc" or "saml".`));
206
+ if (protocol !== "oidc" && protocol !== "saml") return yield* Cv.fail({
207
+ code: "SIGN_IN_MISSING_PARAMS",
208
+ message: `Invalid SSO protocol: ${protocol}. Expected "oidc" or "saml".`
209
+ });
186
210
  const verifier = yield* Fx.promise(() => callVerifier(ctx));
187
211
  const siteUrl = process.env.CUSTOM_AUTH_SITE_URL ?? requireEnv("CONVEX_SITE_URL");
188
212
  const redirect = new URL(`${siteUrl}/api/auth/sso/${enterpriseId}/${protocol}/signin`);
@@ -1 +1 @@
1
- {"version":3,"file":"signin.js","names":[],"sources":["../../../src/server/signin.ts"],"sourcesContent":["import type { Fx as FxType } from \"@robelest/fx\";\nimport { GenericId } from \"convex/values\";\n\nimport { handleDevice } from \"./device\";\nimport { Fx } from \"@robelest/fx\";\n\nimport { AuthError } from \"./authError\";\nimport {\n callCreateVerificationCode,\n callRefreshSession,\n callSignIn,\n callVerifier,\n callVerifierSignature,\n callVerifyCodeAndSignIn,\n} from \"./mutations/index\";\nimport { handlePasskeyFx } from \"./passkey\";\nimport { redirectAbsoluteUrl, setURLSearchParam } from \"./redirects\";\nimport { handleTotp } from \"./totp\";\nimport {\n AuthProviderMaterializedConfig,\n ConvexCredentialsConfig,\n EmailConfig,\n GenericActionCtxWithAuthConfig,\n PhoneConfig,\n} from \"./types\";\nimport {\n AuthDataModel,\n SessionInfo,\n SessionInfoWithTokens,\n Tokens,\n queryTotpVerifiedByUserId,\n} from \"./types\";\nimport type { OAuthMaterializedConfig } from \"./types\";\nimport { generateRandomString } from \"./utils\";\nimport { requireEnv } from \"./utils\";\n\nconst DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S = 60 * 60 * 24; // 24 hours\n\ntype EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;\n\ntype SignInResult =\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n | { kind: \"refreshTokens\"; signedIn: { tokens: Tokens } }\n | { kind: \"started\"; started: true }\n | { kind: \"redirect\"; redirect: string; verifier: string }\n | { kind: \"passkeyOptions\"; options: Record<string, any>; verifier: string }\n | { kind: \"totpRequired\"; verifier: string }\n | {\n kind: \"totpSetup\";\n uri: string;\n secret: string;\n verifier: string;\n totpId: string;\n }\n | {\n kind: \"deviceCode\";\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresIn: number;\n interval: number;\n };\n\n/** @internal */\nexport async function signInImpl(\n ctx: EnrichedActionCtx,\n provider: AuthProviderMaterializedConfig | null,\n args: {\n accountId?: GenericId<\"Account\">;\n params?: Record<string, any>;\n verifier?: string;\n refreshToken?: string;\n calledBy?: string;\n },\n options: {\n generateTokens: boolean;\n allowExtraProviders: boolean;\n },\n): Promise<SignInResult> {\n const fx = signInFx(ctx, provider, args, options);\n return Fx.run(\n fx.pipe(Fx.recover((e) => Fx.fatal((e as AuthError).toConvexError()))),\n );\n}\n\n/**\n * Core sign-in pipeline as an Fx generator.\n *\n * Handles: refresh tokens, verification codes, then dispatches by\n * provider type using a dispatch map (no if-chain).\n */\nfunction signInFx(\n ctx: EnrichedActionCtx,\n provider: AuthProviderMaterializedConfig | null,\n args: {\n accountId?: GenericId<\"Account\">;\n params?: Record<string, any>;\n verifier?: string;\n refreshToken?: string;\n calledBy?: string;\n },\n options: {\n generateTokens: boolean;\n allowExtraProviders: boolean;\n },\n): FxType<SignInResult, AuthError> {\n return Fx.gen(function* () {\n // --- Refresh token (no provider) ---\n if (provider === null && args.refreshToken) {\n const tokens = yield* Fx.promise(() =>\n callRefreshSession(ctx, { refreshToken: args.refreshToken! }),\n );\n if (tokens === null) {\n return { kind: \"signedIn\" as const, signedIn: null };\n }\n return { kind: \"refreshTokens\" as const, signedIn: { tokens } };\n }\n\n // --- Verify code (no provider, code present) ---\n if (provider === null && args.params?.code !== undefined) {\n const result = yield* Fx.promise(() =>\n callVerifyCodeAndSignIn(ctx, {\n params: args.params,\n verifier: args.verifier,\n generateTokens: true,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n return { kind: \"signedIn\" as const, signedIn: result };\n }\n\n // --- Provider is required past this point ---\n const resolvedProvider = yield* provider != null\n ? Fx.succeed(provider)\n : Fx.fail(new AuthError(\"SIGN_IN_MISSING_PARAMS\"));\n\n // --- Dispatch by provider type ---\n return yield* Fx.match(resolvedProvider).on(\"type\", {\n email: (p) => handleEmailAndPhoneProviderFx(ctx, p, args, options),\n phone: (p) => handleEmailAndPhoneProviderFx(ctx, p, args, options),\n credentials: (p) => handleCredentialsFx(ctx, p, args, options),\n oauth: (p) => handleOAuthProviderFx(ctx, p, args, options),\n passkey: (p) => handlePasskeyFx(ctx, p, args),\n totp: (p) => handleTotp(ctx, p, args),\n device: (p) => handleDevice(ctx, p, args),\n sso: (_p) => handleSsoProviderFx(ctx, args),\n });\n });\n}\n\n// ============================================================================\n// Email / Phone\n// ============================================================================\n\nfunction handleEmailAndPhoneProviderFx(\n ctx: EnrichedActionCtx,\n provider: EmailConfig | PhoneConfig,\n args: {\n params?: Record<string, any>;\n accountId?: GenericId<\"Account\">;\n },\n options: {\n generateTokens: boolean;\n allowExtraProviders: boolean;\n },\n): FxType<\n | { kind: \"started\"; started: true }\n | { kind: \"signedIn\"; signedIn: SessionInfoWithTokens },\n AuthError\n> {\n return Fx.gen(function* () {\n // --- Code verification path ---\n if (args.params?.code !== undefined) {\n const result = yield* Fx.promise(() =>\n callVerifyCodeAndSignIn(ctx, {\n params: args.params,\n provider: provider.id,\n generateTokens: options.generateTokens,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n const verified = yield* result != null\n ? Fx.succeed(result)\n : Fx.fail(new AuthError(\"INVALID_VERIFICATION_CODE\"));\n return {\n kind: \"signedIn\" as const,\n signedIn: verified as SessionInfoWithTokens,\n };\n }\n\n // --- Send verification code path ---\n const alphabet =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n const code = provider.generateVerificationToken\n ? yield* Fx.from({\n ok: async () => provider.generateVerificationToken!(),\n err: () =>\n new AuthError(\n \"INTERNAL_ERROR\",\n \"Failed to generate verification token\",\n ),\n })\n : generateRandomString(32, alphabet);\n const expirationTime =\n Date.now() +\n (provider.maxAge ?? DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S) * 1000;\n\n const identifier = yield* Fx.promise(() =>\n callCreateVerificationCode(ctx, {\n provider: provider.id,\n accountId: args.accountId,\n email: args.params?.email,\n phone: args.params?.phone,\n code,\n expirationTime,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n const destination = yield* Fx.promise(() =>\n redirectAbsoluteUrl(\n ctx.auth.config,\n (args.params ?? {}) as { redirectTo: unknown },\n ),\n );\n const verificationArgs = {\n identifier,\n url: setURLSearchParam(destination, \"code\", code),\n token: code,\n expires: new Date(expirationTime),\n };\n yield* Fx.match(provider).on(\"type\", {\n email: (p) =>\n Fx.from({\n ok: async () =>\n p.sendVerificationRequest(\n {\n ...verificationArgs,\n provider: p,\n request: new Request(\"http://localhost\"),\n },\n ctx,\n ),\n err: () =>\n new AuthError(\"INTERNAL_ERROR\", \"Failed to send email code\"),\n }),\n phone: (p) =>\n Fx.from({\n ok: async () =>\n p.sendVerificationRequest(\n { ...verificationArgs, provider: p },\n ctx,\n ),\n err: () =>\n new AuthError(\"INTERNAL_ERROR\", \"Failed to send phone code\"),\n }),\n });\n return { kind: \"started\" as const, started: true as const };\n });\n}\n\n// ============================================================================\n// Credentials\n// ============================================================================\n\nfunction handleCredentialsFx(\n ctx: EnrichedActionCtx,\n provider: ConvexCredentialsConfig,\n args: {\n params?: Record<string, any>;\n },\n options: {\n generateTokens: boolean;\n },\n): FxType<\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n | { kind: \"totpRequired\"; verifier: string },\n AuthError\n> {\n return Fx.gen(function* () {\n const result = yield* Fx.promise(() =>\n provider.authorize(args.params ?? {}, ctx),\n );\n if (result === null) {\n return { kind: \"signedIn\" as const, signedIn: null };\n }\n\n // Check if user has TOTP 2FA enrolled before issuing tokens\n const hasTotpEnrolled = yield* Fx.promise(async () => {\n const totpDoc = await queryTotpVerifiedByUserId(ctx, result.userId);\n return totpDoc !== null;\n });\n if (hasTotpEnrolled) {\n // Create session but withhold tokens — TOTP verification needed\n yield* Fx.promise(() =>\n callSignIn(ctx, {\n userId: result.userId,\n sessionId: result.sessionId,\n generateTokens: false,\n }),\n );\n // Store userId in verifier so the TOTP verify flow can complete sign-in\n const verifier = yield* Fx.promise(() => callVerifier(ctx));\n yield* Fx.promise(() =>\n callVerifierSignature(ctx, {\n verifier,\n signature: JSON.stringify({ userId: result.userId }),\n }),\n );\n return { kind: \"totpRequired\" as const, verifier };\n }\n\n const idsAndTokens = yield* Fx.promise(() =>\n callSignIn(ctx, {\n userId: result.userId,\n sessionId: result.sessionId,\n generateTokens: options.generateTokens,\n }),\n );\n return { kind: \"signedIn\" as const, signedIn: idsAndTokens };\n });\n}\n\n// ============================================================================\n// OAuth\n// ============================================================================\n\nfunction handleOAuthProviderFx(\n ctx: EnrichedActionCtx,\n provider: OAuthMaterializedConfig,\n args: {\n params?: Record<string, any>;\n verifier?: string;\n },\n options: {\n allowExtraProviders: boolean;\n },\n): FxType<\n | { kind: \"signedIn\"; signedIn: SessionInfoWithTokens | null }\n | { kind: \"redirect\"; redirect: string; verifier: string },\n AuthError\n> {\n return Fx.gen(function* () {\n // --- Code verification path ---\n if (args.params?.code !== undefined) {\n const result = yield* Fx.promise(() =>\n callVerifyCodeAndSignIn(ctx, {\n params: args.params,\n verifier: args.verifier,\n generateTokens: true,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n return {\n kind: \"signedIn\" as const,\n signedIn: result as SessionInfoWithTokens | null,\n };\n }\n\n // --- Build redirect URL ---\n const redirect = new URL(\n (process.env.CUSTOM_AUTH_SITE_URL ?? requireEnv(\"CONVEX_SITE_URL\")) +\n `/api/auth/signin/${provider.id}`,\n );\n const verifier = yield* Fx.promise(() => callVerifier(ctx));\n redirect.searchParams.set(\"code\", verifier);\n\n if (args.params?.redirectTo !== undefined) {\n yield* Fx.guard(\n typeof args.params.redirectTo !== \"string\",\n Fx.fail(\n new AuthError(\n \"INVALID_REDIRECT\",\n `Expected \\`redirectTo\\` to be a string, got ${args.params.redirectTo}`,\n ),\n ),\n );\n redirect.searchParams.set(\"redirectTo\", args.params.redirectTo);\n }\n\n return {\n kind: \"redirect\" as const,\n redirect: redirect.toString(),\n verifier,\n };\n });\n}\n\n// ============================================================================\n// SSO (Enterprise OIDC / SAML)\n// ============================================================================\n\nfunction handleSsoProviderFx(\n ctx: EnrichedActionCtx,\n args: {\n params?: Record<string, any>;\n },\n): FxType<{ kind: \"redirect\"; redirect: string; verifier: string }, AuthError> {\n return Fx.gen(function* () {\n const enterpriseId = args.params?.enterpriseId;\n if (!enterpriseId || typeof enterpriseId !== \"string\") {\n return yield* Fx.fail(\n new AuthError(\n \"SIGN_IN_MISSING_PARAMS\",\n \"enterpriseId is required for SSO sign-in.\",\n ),\n );\n }\n\n const protocol: \"oidc\" | \"saml\" = args.params?.protocol ?? \"oidc\";\n if (protocol !== \"oidc\" && protocol !== \"saml\") {\n return yield* Fx.fail(\n new AuthError(\n \"SIGN_IN_MISSING_PARAMS\",\n `Invalid SSO protocol: ${protocol as string}. Expected \"oidc\" or \"saml\".`,\n ),\n );\n }\n\n const verifier = yield* Fx.promise(() => callVerifier(ctx));\n const siteUrl =\n process.env.CUSTOM_AUTH_SITE_URL ?? requireEnv(\"CONVEX_SITE_URL\");\n const redirect = new URL(\n `${siteUrl}/api/auth/sso/${enterpriseId}/${protocol}/signin`,\n );\n redirect.searchParams.set(\"code\", verifier);\n\n if (typeof args.params?.redirectTo === \"string\") {\n redirect.searchParams.set(\"redirectTo\", args.params.redirectTo);\n }\n\n return {\n kind: \"redirect\" as const,\n redirect: redirect.toString(),\n verifier,\n };\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"signin.js","names":[],"sources":["../../../src/server/signin.ts"],"sourcesContent":["import type { Fx as FxType } from \"@robelest/fx\";\nimport { Fx } from \"@robelest/fx\";\nimport { Cv } from \"@robelest/fx/convex\";\nimport { GenericId } from \"convex/values\";\nimport { ConvexError } from \"convex/values\";\n\nimport { handleDevice } from \"./device\";\nimport {\n callCreateVerificationCode,\n callRefreshSession,\n callSignIn,\n callVerifier,\n callVerifierSignature,\n callVerifyCodeAndSignIn,\n} from \"./mutations/index\";\nimport { handlePasskeyFx } from \"./passkey\";\nimport { redirectAbsoluteUrl, setURLSearchParam } from \"./redirects\";\nimport { handleTotp } from \"./totp\";\nimport {\n AuthProviderMaterializedConfig,\n ConvexCredentialsConfig,\n EmailConfig,\n GenericActionCtxWithAuthConfig,\n PhoneConfig,\n} from \"./types\";\nimport {\n AuthDataModel,\n SessionInfo,\n SessionInfoWithTokens,\n Tokens,\n queryTotpVerifiedByUserId,\n} from \"./types\";\nimport type { OAuthMaterializedConfig } from \"./types\";\nimport { generateRandomString } from \"./utils\";\nimport { requireEnv } from \"./utils\";\n\nconst DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S = 60 * 60 * 24; // 24 hours\n\ntype EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;\n\ntype SignInResult =\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n | { kind: \"refreshTokens\"; signedIn: { tokens: Tokens } }\n | { kind: \"started\"; started: true }\n | { kind: \"redirect\"; redirect: string; verifier: string }\n | { kind: \"passkeyOptions\"; options: Record<string, any>; verifier: string }\n | { kind: \"totpRequired\"; verifier: string }\n | {\n kind: \"totpSetup\";\n uri: string;\n secret: string;\n verifier: string;\n totpId: string;\n }\n | {\n kind: \"deviceCode\";\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresIn: number;\n interval: number;\n };\n\n/** @internal */\nexport async function signInImpl(\n ctx: EnrichedActionCtx,\n provider: AuthProviderMaterializedConfig | null,\n args: {\n accountId?: GenericId<\"Account\">;\n params?: Record<string, any>;\n verifier?: string;\n refreshToken?: string;\n calledBy?: string;\n },\n options: {\n generateTokens: boolean;\n allowExtraProviders: boolean;\n },\n): Promise<SignInResult> {\n const fx = signInFx(ctx, provider, args, options);\n return Fx.run(fx.pipe(Fx.recover((e) => Fx.fatal(e))));\n}\n\n/**\n * Core sign-in pipeline as an Fx generator.\n *\n * Handles: refresh tokens, verification codes, then dispatches by\n * provider type using a dispatch map (no if-chain).\n */\nfunction signInFx(\n ctx: EnrichedActionCtx,\n provider: AuthProviderMaterializedConfig | null,\n args: {\n accountId?: GenericId<\"Account\">;\n params?: Record<string, any>;\n verifier?: string;\n refreshToken?: string;\n calledBy?: string;\n },\n options: {\n generateTokens: boolean;\n allowExtraProviders: boolean;\n },\n): FxType<SignInResult, ConvexError<any>> {\n return Fx.gen(function* () {\n // --- Refresh token (no provider) ---\n if (provider === null && args.refreshToken) {\n const tokens = yield* Fx.promise(() =>\n callRefreshSession(ctx, { refreshToken: args.refreshToken! }),\n );\n if (tokens === null) {\n return { kind: \"signedIn\" as const, signedIn: null };\n }\n return { kind: \"refreshTokens\" as const, signedIn: { tokens } };\n }\n\n // --- Verify code (no provider, code present) ---\n if (provider === null && args.params?.code !== undefined) {\n const result = yield* Fx.promise(() =>\n callVerifyCodeAndSignIn(ctx, {\n params: args.params,\n verifier: args.verifier,\n generateTokens: true,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n return { kind: \"signedIn\" as const, signedIn: result };\n }\n\n // --- Provider is required past this point ---\n const resolvedProvider = yield* provider != null\n ? Fx.succeed(provider)\n : Cv.fail({\n code: \"SIGN_IN_MISSING_PARAMS\",\n message: \"Cannot sign in: missing provider, code, or refresh token.\",\n });\n\n // --- Dispatch by provider type ---\n return yield* Fx.match(resolvedProvider).on(\"type\", {\n email: (p) => handleEmailAndPhoneProviderFx(ctx, p, args, options),\n phone: (p) => handleEmailAndPhoneProviderFx(ctx, p, args, options),\n credentials: (p) => handleCredentialsFx(ctx, p, args, options),\n oauth: (p) => handleOAuthProviderFx(ctx, p, args, options),\n passkey: (p) => handlePasskeyFx(ctx, p, args),\n totp: (p) => handleTotp(ctx, p, args),\n device: (p) => handleDevice(ctx, p, args),\n sso: (_p) => handleSsoProviderFx(ctx, args),\n });\n });\n}\n\n// ============================================================================\n// Email / Phone\n// ============================================================================\n\nfunction handleEmailAndPhoneProviderFx(\n ctx: EnrichedActionCtx,\n provider: EmailConfig | PhoneConfig,\n args: {\n params?: Record<string, any>;\n accountId?: GenericId<\"Account\">;\n },\n options: {\n generateTokens: boolean;\n allowExtraProviders: boolean;\n },\n): FxType<\n | { kind: \"started\"; started: true }\n | { kind: \"signedIn\"; signedIn: SessionInfoWithTokens },\n ConvexError<any>\n> {\n return Fx.gen(function* () {\n // --- Code verification path ---\n if (args.params?.code !== undefined) {\n const result = yield* Fx.promise(() =>\n callVerifyCodeAndSignIn(ctx, {\n params: args.params,\n provider: provider.id,\n generateTokens: options.generateTokens,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n const verified = yield* result != null\n ? Fx.succeed(result)\n : Cv.fail({\n code: \"INVALID_VERIFICATION_CODE\",\n message: \"Invalid or expired verification code.\",\n });\n return {\n kind: \"signedIn\" as const,\n signedIn: verified as SessionInfoWithTokens,\n };\n }\n\n // --- Send verification code path ---\n const alphabet =\n \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n const code = provider.generateVerificationToken\n ? yield* Fx.from({\n ok: async () => provider.generateVerificationToken!(),\n err: () =>\n Cv.error({\n code: \"INTERNAL_ERROR\",\n message: \"Failed to generate verification token\",\n }),\n })\n : generateRandomString(32, alphabet);\n const expirationTime =\n Date.now() +\n (provider.maxAge ?? DEFAULT_EMAIL_VERIFICATION_CODE_DURATION_S) * 1000;\n\n const identifier = yield* Fx.promise(() =>\n callCreateVerificationCode(ctx, {\n provider: provider.id,\n accountId: args.accountId,\n email: args.params?.email,\n phone: args.params?.phone,\n code,\n expirationTime,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n const destination = yield* Fx.promise(() =>\n redirectAbsoluteUrl(\n ctx.auth.config,\n (args.params ?? {}) as { redirectTo: unknown },\n ),\n );\n const verificationArgs = {\n identifier,\n url: setURLSearchParam(destination, \"code\", code),\n token: code,\n expires: new Date(expirationTime),\n };\n yield* Fx.match(provider).on(\"type\", {\n email: (p) =>\n Fx.from({\n ok: async () =>\n p.sendVerificationRequest(\n {\n ...verificationArgs,\n provider: p,\n request: new Request(\"http://localhost\"),\n },\n ctx,\n ),\n err: () =>\n Cv.error({\n code: \"INTERNAL_ERROR\",\n message: \"Failed to send email code\",\n }),\n }),\n phone: (p) =>\n Fx.from({\n ok: async () =>\n p.sendVerificationRequest(\n { ...verificationArgs, provider: p },\n ctx,\n ),\n err: () =>\n Cv.error({\n code: \"INTERNAL_ERROR\",\n message: \"Failed to send phone code\",\n }),\n }),\n });\n return { kind: \"started\" as const, started: true as const };\n });\n}\n\n// ============================================================================\n// Credentials\n// ============================================================================\n\nfunction handleCredentialsFx(\n ctx: EnrichedActionCtx,\n provider: ConvexCredentialsConfig,\n args: {\n params?: Record<string, any>;\n },\n options: {\n generateTokens: boolean;\n },\n): FxType<\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n | { kind: \"totpRequired\"; verifier: string },\n ConvexError<any>\n> {\n return Fx.gen(function* () {\n const result = yield* Fx.promise(() =>\n provider.authorize(args.params ?? {}, ctx),\n );\n if (result === null) {\n return { kind: \"signedIn\" as const, signedIn: null };\n }\n\n // Check if user has TOTP 2FA enrolled before issuing tokens\n const hasTotpEnrolled = yield* Fx.promise(async () => {\n const totpDoc = await queryTotpVerifiedByUserId(ctx, result.userId);\n return totpDoc !== null;\n });\n if (hasTotpEnrolled) {\n // Create session but withhold tokens — TOTP verification needed\n yield* Fx.promise(() =>\n callSignIn(ctx, {\n userId: result.userId,\n sessionId: result.sessionId,\n generateTokens: false,\n }),\n );\n // Store userId in verifier so the TOTP verify flow can complete sign-in\n const verifier = yield* Fx.promise(() => callVerifier(ctx));\n yield* Fx.promise(() =>\n callVerifierSignature(ctx, {\n verifier,\n signature: JSON.stringify({ userId: result.userId }),\n }),\n );\n return { kind: \"totpRequired\" as const, verifier };\n }\n\n const idsAndTokens = yield* Fx.promise(() =>\n callSignIn(ctx, {\n userId: result.userId,\n sessionId: result.sessionId,\n generateTokens: options.generateTokens,\n }),\n );\n return { kind: \"signedIn\" as const, signedIn: idsAndTokens };\n });\n}\n\n// ============================================================================\n// OAuth\n// ============================================================================\n\nfunction handleOAuthProviderFx(\n ctx: EnrichedActionCtx,\n provider: OAuthMaterializedConfig,\n args: {\n params?: Record<string, any>;\n verifier?: string;\n },\n options: {\n allowExtraProviders: boolean;\n },\n): FxType<\n | { kind: \"signedIn\"; signedIn: SessionInfoWithTokens | null }\n | { kind: \"redirect\"; redirect: string; verifier: string },\n ConvexError<any>\n> {\n return Fx.gen(function* () {\n // --- Code verification path ---\n if (args.params?.code !== undefined) {\n const result = yield* Fx.promise(() =>\n callVerifyCodeAndSignIn(ctx, {\n params: args.params,\n verifier: args.verifier,\n generateTokens: true,\n allowExtraProviders: options.allowExtraProviders,\n }),\n );\n return {\n kind: \"signedIn\" as const,\n signedIn: result as SessionInfoWithTokens | null,\n };\n }\n\n // --- Build redirect URL ---\n const redirect = new URL(\n (process.env.CUSTOM_AUTH_SITE_URL ?? requireEnv(\"CONVEX_SITE_URL\")) +\n `/api/auth/signin/${provider.id}`,\n );\n const verifier = yield* Fx.promise(() => callVerifier(ctx));\n redirect.searchParams.set(\"code\", verifier);\n\n if (args.params?.redirectTo !== undefined) {\n yield* Fx.guard(\n typeof args.params.redirectTo !== \"string\",\n Cv.fail({\n code: \"INVALID_REDIRECT\",\n message: `Expected \\`redirectTo\\` to be a string, got ${args.params.redirectTo}`,\n }),\n );\n redirect.searchParams.set(\"redirectTo\", args.params.redirectTo);\n }\n\n return {\n kind: \"redirect\" as const,\n redirect: redirect.toString(),\n verifier,\n };\n });\n}\n\n// ============================================================================\n// SSO (Enterprise OIDC / SAML)\n// ============================================================================\n\nfunction handleSsoProviderFx(\n ctx: EnrichedActionCtx,\n args: {\n params?: Record<string, any>;\n },\n): FxType<\n { kind: \"redirect\"; redirect: string; verifier: string },\n ConvexError<any>\n> {\n return Fx.gen(function* () {\n const enterpriseId = args.params?.enterpriseId;\n if (!enterpriseId || typeof enterpriseId !== \"string\") {\n return yield* Cv.fail({\n code: \"SIGN_IN_MISSING_PARAMS\",\n message: \"enterpriseId is required for SSO sign-in.\",\n });\n }\n\n const protocol: \"oidc\" | \"saml\" = args.params?.protocol ?? \"oidc\";\n if (protocol !== \"oidc\" && protocol !== \"saml\") {\n return yield* Cv.fail({\n code: \"SIGN_IN_MISSING_PARAMS\",\n message: `Invalid SSO protocol: ${protocol as string}. Expected \"oidc\" or \"saml\".`,\n });\n }\n\n const verifier = yield* Fx.promise(() => callVerifier(ctx));\n const siteUrl =\n process.env.CUSTOM_AUTH_SITE_URL ?? requireEnv(\"CONVEX_SITE_URL\");\n const redirect = new URL(\n `${siteUrl}/api/auth/sso/${enterpriseId}/${protocol}/signin`,\n );\n redirect.searchParams.set(\"code\", verifier);\n\n if (typeof args.params?.redirectTo === \"string\") {\n redirect.searchParams.set(\"redirectTo\", args.params.redirectTo);\n }\n\n return {\n kind: \"redirect\" as const,\n redirect: redirect.toString(),\n verifier,\n };\n });\n}\n"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import { AuthError } from "./authError.js";
2
1
  import { userIdFromIdentitySubject } from "./identity.js";
3
2
  import { callVerifierSignature } from "./mutations/signature.js";
4
3
  import { callSignIn } from "./mutations/signin.js";
5
4
  import { callVerifier } from "./mutations/verifier.js";
6
5
  import { mutateTotpInsert, mutateTotpMarkVerified, mutateTotpUpdateLastUsed, mutateVerifierDelete, queryTotpById, queryTotpVerifiedByUserId, queryUserById, queryVerifierById } from "./types.js";
7
- import { encodeBase32LowerCaseNoPadding } from "@oslojs/encoding";
6
+ import { Cv } from "@robelest/fx/convex";
8
7
  import { Fx } from "@robelest/fx";
8
+ import { encodeBase32LowerCaseNoPadding } from "@oslojs/encoding";
9
9
  import { createTOTPKeyURI, verifyTOTPWithGracePeriod } from "@oslojs/otp";
10
10
 
11
11
  //#region src/server/totp.ts
@@ -24,11 +24,23 @@ const TOTP_FLOWS = [
24
24
  ];
25
25
  const resolveTotpFlowFx = (params) => {
26
26
  const flow = params.flow;
27
- return typeof flow === "string" && TOTP_FLOWS.includes(flow) ? Fx.succeed(flow) : Fx.fail(new AuthError("TOTP_MISSING_FLOW", "Missing `flow` parameter. Expected one of: setup, confirm, verify"));
27
+ return typeof flow === "string" && TOTP_FLOWS.includes(flow) ? Fx.succeed(flow) : Cv.fail({
28
+ code: "TOTP_MISSING_FLOW",
29
+ message: "Missing `flow` parameter. Expected one of: setup, confirm, verify"
30
+ });
28
31
  };
29
- const requireTotpVerifierFx = (verifier) => verifier != null ? Fx.succeed(verifier) : Fx.fail(new AuthError("TOTP_MISSING_VERIFIER"));
30
- const requireTotpCodeFx = (params) => typeof params.code === "string" ? Fx.succeed(params.code) : Fx.fail(new AuthError("TOTP_MISSING_CODE"));
31
- const requireTotpIdFx = (params) => typeof params.totpId === "string" ? Fx.succeed(params.totpId) : Fx.fail(new AuthError("TOTP_MISSING_ID"));
32
+ const requireTotpVerifierFx = (verifier) => verifier != null ? Fx.succeed(verifier) : Cv.fail({
33
+ code: "TOTP_MISSING_VERIFIER",
34
+ message: "Missing verifier for TOTP operation."
35
+ });
36
+ const requireTotpCodeFx = (params) => typeof params.code === "string" ? Fx.succeed(params.code) : Cv.fail({
37
+ code: "TOTP_MISSING_CODE",
38
+ message: "Missing TOTP code."
39
+ });
40
+ const requireTotpIdFx = (params) => typeof params.totpId === "string" ? Fx.succeed(params.totpId) : Cv.fail({
41
+ code: "TOTP_MISSING_ID",
42
+ message: "Missing TOTP enrollment ID."
43
+ });
32
44
  const resolveTotpDispatchFx = (params, verifier) => resolveTotpFlowFx(params).pipe(Fx.chain((flow) => Fx.match({ flow }).on("flow", {
33
45
  setup: () => Fx.succeed({
34
46
  flow: "setup",
@@ -57,8 +69,14 @@ const handleTotp = (ctx, provider, args) => {
57
69
  return resolveTotpDispatchFx(args.params ?? {}, args.verifier).pipe(Fx.chain((dispatch) => Fx.match(dispatch).on("flow", {
58
70
  setup: ({ params }) => Fx.from({
59
71
  ok: () => ctx.auth.getUserIdentity(),
60
- err: (e) => new AuthError("INTERNAL_ERROR", String(e))
61
- }).pipe(Fx.chain((identity) => identity === null ? Fx.fail(new AuthError("TOTP_AUTH_REQUIRED")) : Fx.succeed(userIdFromIdentitySubject(identity.subject))), Fx.chain((userId) => Fx.from({
72
+ err: (e) => Cv.error({
73
+ code: "INTERNAL_ERROR",
74
+ message: String(e)
75
+ })
76
+ }).pipe(Fx.chain((identity) => identity === null ? Cv.fail({
77
+ code: "TOTP_AUTH_REQUIRED",
78
+ message: "Sign in first, then set up two-factor authentication."
79
+ }) : Fx.succeed(userIdFromIdentitySubject(identity.subject))), Fx.chain((userId) => Fx.from({
62
80
  ok: async () => {
63
81
  const secret = new Uint8Array(20);
64
82
  crypto.getRandomValues(secret);
@@ -92,15 +110,36 @@ const handleTotp = (ctx, provider, args) => {
92
110
  })
93
111
  };
94
112
  },
95
- err: (e) => new AuthError("INTERNAL_ERROR", `TOTP setup failed: ${String(e)}`)
113
+ err: (e) => Cv.error({
114
+ code: "INTERNAL_ERROR",
115
+ message: `TOTP setup failed: ${String(e)}`
116
+ })
96
117
  }))),
97
118
  confirm: ({ code, totpId, verifier }) => Fx.from({
98
119
  ok: () => ctx.auth.getUserIdentity(),
99
- err: (e) => new AuthError("INTERNAL_ERROR", String(e))
100
- }).pipe(Fx.chain((identity) => identity === null ? Fx.fail(new AuthError("TOTP_AUTH_REQUIRED")) : Fx.succeed(userIdFromIdentitySubject(identity.subject))), Fx.chain((userId) => Fx.from({
120
+ err: (e) => Cv.error({
121
+ code: "INTERNAL_ERROR",
122
+ message: String(e)
123
+ })
124
+ }).pipe(Fx.chain((identity) => identity === null ? Cv.fail({
125
+ code: "TOTP_AUTH_REQUIRED",
126
+ message: "Sign in first, then set up two-factor authentication."
127
+ }) : Fx.succeed(userIdFromIdentitySubject(identity.subject))), Fx.chain((userId) => Fx.from({
101
128
  ok: () => queryTotpById(ctx, totpId),
102
- err: () => new AuthError("TOTP_NOT_FOUND")
103
- }).pipe(Fx.chain((doc) => doc === null ? Fx.fail(new AuthError("TOTP_NOT_FOUND")) : Fx.succeed(doc)), Fx.chain((totpDoc) => totpDoc.verified ? Fx.fail(new AuthError("TOTP_ALREADY_VERIFIED")) : Fx.succeed(totpDoc))).pipe(Fx.chain((totpDoc) => verifyTOTPWithGracePeriod(new Uint8Array(totpDoc.secret), provider.options.period, provider.options.digits, code, 30) ? Fx.succeed(totpDoc) : Fx.fail(new AuthError("TOTP_INVALID_CODE")))).pipe(Fx.chain((_totpDoc) => Fx.from({
129
+ err: () => Cv.error({
130
+ code: "TOTP_NOT_FOUND",
131
+ message: "TOTP enrollment not found."
132
+ })
133
+ }).pipe(Fx.chain((doc) => doc === null ? Cv.fail({
134
+ code: "TOTP_NOT_FOUND",
135
+ message: "TOTP enrollment not found."
136
+ }) : Fx.succeed(doc)), Fx.chain((totpDoc) => totpDoc.verified ? Cv.fail({
137
+ code: "TOTP_ALREADY_VERIFIED",
138
+ message: "TOTP enrollment is already verified."
139
+ }) : Fx.succeed(totpDoc))).pipe(Fx.chain((totpDoc) => verifyTOTPWithGracePeriod(new Uint8Array(totpDoc.secret), provider.options.period, provider.options.digits, code, 30) ? Fx.succeed(totpDoc) : Cv.fail({
140
+ code: "TOTP_INVALID_CODE",
141
+ message: "Invalid TOTP code."
142
+ }))).pipe(Fx.chain((_totpDoc) => Fx.from({
104
143
  ok: async () => {
105
144
  await mutateTotpMarkVerified(ctx, totpId, Date.now());
106
145
  await mutateVerifierDelete(ctx, verifier);
@@ -109,15 +148,24 @@ const handleTotp = (ctx, provider, args) => {
109
148
  generateTokens: true
110
149
  });
111
150
  },
112
- err: (e) => new AuthError("INTERNAL_ERROR", String(e))
151
+ err: (e) => Cv.error({
152
+ code: "INTERNAL_ERROR",
153
+ message: String(e)
154
+ })
113
155
  }))).pipe(Fx.map((signInResult) => ({
114
156
  kind: "signedIn",
115
157
  signedIn: signInResult
116
158
  }))))),
117
159
  verify: ({ code, verifier }) => Fx.from({
118
160
  ok: () => queryVerifierById(ctx, verifier),
119
- err: () => new AuthError("TOTP_INVALID_VERIFIER")
120
- }).pipe(Fx.chain((doc) => doc === null ? Fx.fail(new AuthError("TOTP_INVALID_VERIFIER")) : Fx.succeed(doc)), Fx.map((doc) => {
161
+ err: () => Cv.error({
162
+ code: "TOTP_INVALID_VERIFIER",
163
+ message: "Invalid or expired TOTP verifier."
164
+ })
165
+ }).pipe(Fx.chain((doc) => doc === null ? Cv.fail({
166
+ code: "TOTP_INVALID_VERIFIER",
167
+ message: "Invalid or expired TOTP verifier."
168
+ }) : Fx.succeed(doc)), Fx.map((doc) => {
121
169
  return {
122
170
  userId: JSON.parse(doc.signature).userId,
123
171
  code,
@@ -125,8 +173,17 @@ const handleTotp = (ctx, provider, args) => {
125
173
  };
126
174
  }), Fx.chain(({ userId, code: code$1, verifier: verifier$1 }) => Fx.from({
127
175
  ok: () => queryTotpVerifiedByUserId(ctx, userId),
128
- err: () => new AuthError("TOTP_NO_ENROLLMENT")
129
- }).pipe(Fx.chain((totpDoc) => totpDoc === null ? Fx.fail(new AuthError("TOTP_NO_ENROLLMENT")) : Fx.succeed(totpDoc)), Fx.chain((totpDoc) => verifyTOTPWithGracePeriod(new Uint8Array(totpDoc.secret), totpDoc.period, totpDoc.digits, code$1, 30) ? Fx.succeed(totpDoc) : Fx.fail(new AuthError("TOTP_INVALID_CODE"))), Fx.chain((totpDoc) => Fx.from({
176
+ err: () => Cv.error({
177
+ code: "TOTP_NO_ENROLLMENT",
178
+ message: "No verified TOTP enrollment found."
179
+ })
180
+ }).pipe(Fx.chain((totpDoc) => totpDoc === null ? Cv.fail({
181
+ code: "TOTP_NO_ENROLLMENT",
182
+ message: "No verified TOTP enrollment found."
183
+ }) : Fx.succeed(totpDoc)), Fx.chain((totpDoc) => verifyTOTPWithGracePeriod(new Uint8Array(totpDoc.secret), totpDoc.period, totpDoc.digits, code$1, 30) ? Fx.succeed(totpDoc) : Cv.fail({
184
+ code: "TOTP_INVALID_CODE",
185
+ message: "Invalid TOTP code."
186
+ })), Fx.chain((totpDoc) => Fx.from({
130
187
  ok: async () => {
131
188
  await mutateTotpUpdateLastUsed(ctx, totpDoc._id, Date.now());
132
189
  await mutateVerifierDelete(ctx, verifier$1);
@@ -135,7 +192,10 @@ const handleTotp = (ctx, provider, args) => {
135
192
  generateTokens: true
136
193
  });
137
194
  },
138
- err: (e) => new AuthError("INTERNAL_ERROR", String(e))
195
+ err: (e) => Cv.error({
196
+ code: "INTERNAL_ERROR",
197
+ message: String(e)
198
+ })
139
199
  })), Fx.map((signInResult) => ({
140
200
  kind: "signedIn",
141
201
  signedIn: signInResult
@@ -1 +1 @@
1
- {"version":3,"file":"totp.js","names":["code","verifier"],"sources":["../../../src/server/totp.ts"],"sourcesContent":["/**\n * Server-side TOTP ceremony logic for two-factor authentication.\n *\n * Handles the three phases of the TOTP flow:\n * 1. setup — generate a TOTP secret and `otpauth://` URI for enrollment\n * 2. confirm — verify the first code from the authenticator app\n * 3. verify — verify a TOTP code during sign-in (2FA challenge)\n */\n\nimport { encodeBase32LowerCaseNoPadding } from \"@oslojs/encoding\";\nimport { verifyTOTPWithGracePeriod, createTOTPKeyURI } from \"@oslojs/otp\";\nimport type { Fx as FxType } from \"@robelest/fx\";\n\nimport { Fx } from \"@robelest/fx\";\n\nimport { AuthError } from \"./authError\";\nimport { userIdFromIdentitySubject } from \"./identity\";\nimport { callSignIn, callVerifier } from \"./mutations/index\";\nimport { callVerifierSignature } from \"./mutations/signature\";\nimport { TotpProviderConfig, GenericActionCtxWithAuthConfig } from \"./types\";\nimport {\n AuthDataModel,\n SessionInfo,\n queryUserById,\n queryTotpById,\n queryTotpVerifiedByUserId,\n queryVerifierById,\n mutateTotpInsert,\n mutateTotpMarkVerified,\n mutateTotpUpdateLastUsed,\n mutateVerifierDelete,\n} from \"./types\";\n\ntype EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;\n\n// ============================================================================\n// Setup flow\n// ============================================================================\n\n// ============================================================================\n// Confirm flow\n// ============================================================================\n\n// ============================================================================\n// Verify flow (2FA during sign-in)\n// ============================================================================\n\n// ============================================================================\n// Main dispatch\n// ============================================================================\n\ntype TotpResult =\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n | {\n kind: \"totpSetup\";\n uri: string;\n secret: string;\n verifier: string;\n totpId: string;\n };\n\nconst TOTP_FLOWS = [\"setup\", \"confirm\", \"verify\"] as const;\n\ntype TotpFlow = (typeof TOTP_FLOWS)[number];\n\ntype TotpDispatch =\n | { flow: \"setup\"; params: Record<string, unknown> }\n | { flow: \"confirm\"; code: string; totpId: string; verifier: string }\n | { flow: \"verify\"; code: string; verifier: string };\n\nconst resolveTotpFlowFx = (\n params: Record<string, unknown>,\n): FxType<TotpFlow, AuthError> => {\n const flow = params.flow;\n return typeof flow === \"string\" && TOTP_FLOWS.includes(flow as never)\n ? Fx.succeed(flow as TotpFlow)\n : Fx.fail(\n new AuthError(\n \"TOTP_MISSING_FLOW\",\n \"Missing `flow` parameter. Expected one of: setup, confirm, verify\",\n ),\n );\n};\n\nconst requireTotpVerifierFx = (\n verifier: string | undefined,\n): FxType<string, AuthError> =>\n verifier != null\n ? Fx.succeed(verifier)\n : Fx.fail(new AuthError(\"TOTP_MISSING_VERIFIER\"));\n\nconst requireTotpCodeFx = (\n params: Record<string, unknown>,\n): FxType<string, AuthError> =>\n typeof params.code === \"string\"\n ? Fx.succeed(params.code)\n : Fx.fail(new AuthError(\"TOTP_MISSING_CODE\"));\n\nconst requireTotpIdFx = (\n params: Record<string, unknown>,\n): FxType<string, AuthError> =>\n typeof params.totpId === \"string\"\n ? Fx.succeed(params.totpId)\n : Fx.fail(new AuthError(\"TOTP_MISSING_ID\"));\n\nconst resolveTotpDispatchFx = (\n params: Record<string, unknown>,\n verifier: string | undefined,\n): FxType<TotpDispatch, AuthError> =>\n resolveTotpFlowFx(params).pipe(\n Fx.chain((flow) =>\n Fx.match({ flow }).on(\"flow\", {\n setup: () => Fx.succeed({ flow: \"setup\" as const, params }),\n confirm: () =>\n Fx.gen(function* () {\n const resolvedVerifier = yield* requireTotpVerifierFx(verifier);\n const code = yield* requireTotpCodeFx(params);\n const totpId = yield* requireTotpIdFx(params);\n return {\n flow: \"confirm\" as const,\n code,\n totpId,\n verifier: resolvedVerifier,\n };\n }),\n verify: () =>\n Fx.gen(function* () {\n const resolvedVerifier = yield* requireTotpVerifierFx(verifier);\n const code = yield* requireTotpCodeFx(params);\n return {\n flow: \"verify\" as const,\n code,\n verifier: resolvedVerifier,\n };\n }),\n }),\n ),\n );\n\n/** @internal */\nexport const handleTotp = (\n ctx: EnrichedActionCtx,\n provider: TotpProviderConfig,\n args: { params?: Record<string, any>; verifier?: string },\n): FxType<TotpResult, AuthError> => {\n const params = (args.params ?? {}) as Record<string, unknown>;\n\n return resolveTotpDispatchFx(params, args.verifier).pipe(\n Fx.chain((dispatch) =>\n Fx.match(dispatch).on(\"flow\", {\n setup: ({ params }) =>\n Fx.from({\n ok: () => ctx.auth.getUserIdentity(),\n err: (e) => new AuthError(\"INTERNAL_ERROR\", String(e)),\n }).pipe(\n Fx.chain((identity) =>\n identity === null\n ? Fx.fail(new AuthError(\"TOTP_AUTH_REQUIRED\"))\n : Fx.succeed(userIdFromIdentitySubject(identity.subject)),\n ),\n Fx.chain((userId) =>\n Fx.from({\n ok: async () => {\n const secret = new Uint8Array(20);\n crypto.getRandomValues(secret);\n\n let accountName: string = params.accountName as string;\n if (!accountName) {\n const user = await queryUserById(ctx, userId);\n accountName = user?.email ?? \"user\";\n }\n\n const uri = createTOTPKeyURI(\n provider.options.issuer,\n accountName,\n secret,\n provider.options.period,\n provider.options.digits,\n );\n const base32Secret = encodeBase32LowerCaseNoPadding(secret);\n\n const verifier = await callVerifier(ctx);\n await callVerifierSignature(ctx, {\n verifier,\n signature: JSON.stringify({\n secret: Array.from(secret),\n userId,\n digits: provider.options.digits,\n period: provider.options.period,\n }),\n });\n\n const totpId = await mutateTotpInsert(ctx, {\n userId,\n secret: secret.buffer.slice(\n secret.byteOffset,\n secret.byteOffset + secret.byteLength,\n ),\n digits: provider.options.digits,\n period: provider.options.period,\n verified: false,\n name:\n typeof params.name === \"string\" ? params.name : undefined,\n createdAt: Date.now(),\n });\n\n return {\n kind: \"totpSetup\" as const,\n uri,\n secret: base32Secret,\n verifier,\n totpId,\n };\n },\n err: (e) =>\n new AuthError(\n \"INTERNAL_ERROR\",\n `TOTP setup failed: ${String(e)}`,\n ),\n }),\n ),\n ),\n confirm: ({ code, totpId, verifier }) =>\n Fx.from({\n ok: () => ctx.auth.getUserIdentity(),\n err: (e) => new AuthError(\"INTERNAL_ERROR\", String(e)),\n }).pipe(\n Fx.chain((identity) =>\n identity === null\n ? Fx.fail(new AuthError(\"TOTP_AUTH_REQUIRED\"))\n : Fx.succeed(userIdFromIdentitySubject(identity.subject)),\n ),\n Fx.chain((userId) =>\n Fx.from({\n ok: () => queryTotpById(ctx, totpId),\n err: () => new AuthError(\"TOTP_NOT_FOUND\"),\n })\n .pipe(\n Fx.chain((doc) =>\n doc === null\n ? Fx.fail(new AuthError(\"TOTP_NOT_FOUND\"))\n : Fx.succeed(doc),\n ),\n Fx.chain((totpDoc) =>\n totpDoc.verified\n ? Fx.fail(new AuthError(\"TOTP_ALREADY_VERIFIED\"))\n : Fx.succeed(totpDoc),\n ),\n )\n .pipe(\n Fx.chain((totpDoc) =>\n verifyTOTPWithGracePeriod(\n new Uint8Array(totpDoc.secret),\n provider.options.period,\n provider.options.digits,\n code,\n 30,\n )\n ? Fx.succeed(totpDoc)\n : Fx.fail(new AuthError(\"TOTP_INVALID_CODE\")),\n ),\n )\n .pipe(\n Fx.chain((_totpDoc) =>\n Fx.from({\n ok: async () => {\n await mutateTotpMarkVerified(ctx, totpId, Date.now());\n await mutateVerifierDelete(ctx, verifier);\n return callSignIn(ctx, {\n userId,\n generateTokens: true,\n });\n },\n err: (e) => new AuthError(\"INTERNAL_ERROR\", String(e)),\n }),\n ),\n )\n .pipe(\n Fx.map((signInResult) => ({\n kind: \"signedIn\" as const,\n signedIn: signInResult,\n })),\n ),\n ),\n ),\n verify: ({ code, verifier }) =>\n Fx.from({\n ok: () => queryVerifierById(ctx, verifier),\n err: () => new AuthError(\"TOTP_INVALID_VERIFIER\"),\n }).pipe(\n Fx.chain((doc) =>\n doc === null\n ? Fx.fail(new AuthError(\"TOTP_INVALID_VERIFIER\"))\n : Fx.succeed(doc),\n ),\n Fx.map((doc) => {\n const data = JSON.parse(doc.signature!);\n return { userId: data.userId as string, code, verifier };\n }),\n Fx.chain(({ userId, code, verifier }) =>\n Fx.from({\n ok: () => queryTotpVerifiedByUserId(ctx, userId),\n err: () => new AuthError(\"TOTP_NO_ENROLLMENT\"),\n }).pipe(\n Fx.chain((totpDoc) =>\n totpDoc === null\n ? Fx.fail(new AuthError(\"TOTP_NO_ENROLLMENT\"))\n : Fx.succeed(totpDoc),\n ),\n Fx.chain((totpDoc) =>\n verifyTOTPWithGracePeriod(\n new Uint8Array(totpDoc.secret),\n totpDoc.period,\n totpDoc.digits,\n code,\n 30,\n )\n ? Fx.succeed(totpDoc)\n : Fx.fail(new AuthError(\"TOTP_INVALID_CODE\")),\n ),\n Fx.chain((totpDoc) =>\n Fx.from({\n ok: async () => {\n await mutateTotpUpdateLastUsed(\n ctx,\n totpDoc._id,\n Date.now(),\n );\n await mutateVerifierDelete(ctx, verifier);\n return callSignIn(ctx, { userId, generateTokens: true });\n },\n err: (e) => new AuthError(\"INTERNAL_ERROR\", String(e)),\n }),\n ),\n Fx.map((signInResult) => ({\n kind: \"signedIn\" as const,\n signedIn: signInResult,\n })),\n ),\n ),\n ),\n }),\n ),\n );\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n"],"mappings":"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"}
1
+ {"version":3,"file":"totp.js","names":["code","verifier"],"sources":["../../../src/server/totp.ts"],"sourcesContent":["/**\n * Server-side TOTP ceremony logic for two-factor authentication.\n *\n * Handles the three phases of the TOTP flow:\n * 1. setup — generate a TOTP secret and `otpauth://` URI for enrollment\n * 2. confirm — verify the first code from the authenticator app\n * 3. verify — verify a TOTP code during sign-in (2FA challenge)\n */\n\nimport { encodeBase32LowerCaseNoPadding } from \"@oslojs/encoding\";\nimport { verifyTOTPWithGracePeriod, createTOTPKeyURI } from \"@oslojs/otp\";\nimport type { Fx as FxType } from \"@robelest/fx\";\nimport { Fx } from \"@robelest/fx\";\nimport { Cv } from \"@robelest/fx/convex\";\nimport type { ConvexError } from \"convex/values\";\n\nimport { userIdFromIdentitySubject } from \"./identity\";\nimport { callSignIn, callVerifier } from \"./mutations/index\";\nimport { callVerifierSignature } from \"./mutations/signature\";\nimport { TotpProviderConfig, GenericActionCtxWithAuthConfig } from \"./types\";\nimport {\n AuthDataModel,\n SessionInfo,\n queryUserById,\n queryTotpById,\n queryTotpVerifiedByUserId,\n queryVerifierById,\n mutateTotpInsert,\n mutateTotpMarkVerified,\n mutateTotpUpdateLastUsed,\n mutateVerifierDelete,\n} from \"./types\";\n\ntype EnrichedActionCtx = GenericActionCtxWithAuthConfig<AuthDataModel>;\n\n// ============================================================================\n// Setup flow\n// ============================================================================\n\n// ============================================================================\n// Confirm flow\n// ============================================================================\n\n// ============================================================================\n// Verify flow (2FA during sign-in)\n// ============================================================================\n\n// ============================================================================\n// Main dispatch\n// ============================================================================\n\ntype TotpResult =\n | { kind: \"signedIn\"; signedIn: SessionInfo | null }\n | {\n kind: \"totpSetup\";\n uri: string;\n secret: string;\n verifier: string;\n totpId: string;\n };\n\nconst TOTP_FLOWS = [\"setup\", \"confirm\", \"verify\"] as const;\n\ntype TotpFlow = (typeof TOTP_FLOWS)[number];\n\ntype TotpDispatch =\n | { flow: \"setup\"; params: Record<string, unknown> }\n | { flow: \"confirm\"; code: string; totpId: string; verifier: string }\n | { flow: \"verify\"; code: string; verifier: string };\n\nconst resolveTotpFlowFx = (\n params: Record<string, unknown>,\n): FxType<TotpFlow, ConvexError<any>> => {\n const flow = params.flow;\n return typeof flow === \"string\" && TOTP_FLOWS.includes(flow as never)\n ? Fx.succeed(flow as TotpFlow)\n : Cv.fail({\n code: \"TOTP_MISSING_FLOW\",\n message:\n \"Missing `flow` parameter. Expected one of: setup, confirm, verify\",\n });\n};\n\nconst requireTotpVerifierFx = (\n verifier: string | undefined,\n): FxType<string, ConvexError<any>> =>\n verifier != null\n ? Fx.succeed(verifier)\n : Cv.fail({\n code: \"TOTP_MISSING_VERIFIER\",\n message: \"Missing verifier for TOTP operation.\",\n });\n\nconst requireTotpCodeFx = (\n params: Record<string, unknown>,\n): FxType<string, ConvexError<any>> =>\n typeof params.code === \"string\"\n ? Fx.succeed(params.code)\n : Cv.fail({ code: \"TOTP_MISSING_CODE\", message: \"Missing TOTP code.\" });\n\nconst requireTotpIdFx = (\n params: Record<string, unknown>,\n): FxType<string, ConvexError<any>> =>\n typeof params.totpId === \"string\"\n ? Fx.succeed(params.totpId)\n : Cv.fail({\n code: \"TOTP_MISSING_ID\",\n message: \"Missing TOTP enrollment ID.\",\n });\n\nconst resolveTotpDispatchFx = (\n params: Record<string, unknown>,\n verifier: string | undefined,\n): FxType<TotpDispatch, ConvexError<any>> =>\n resolveTotpFlowFx(params).pipe(\n Fx.chain((flow) =>\n Fx.match({ flow }).on(\"flow\", {\n setup: () => Fx.succeed({ flow: \"setup\" as const, params }),\n confirm: () =>\n Fx.gen(function* () {\n const resolvedVerifier = yield* requireTotpVerifierFx(verifier);\n const code = yield* requireTotpCodeFx(params);\n const totpId = yield* requireTotpIdFx(params);\n return {\n flow: \"confirm\" as const,\n code,\n totpId,\n verifier: resolvedVerifier,\n };\n }),\n verify: () =>\n Fx.gen(function* () {\n const resolvedVerifier = yield* requireTotpVerifierFx(verifier);\n const code = yield* requireTotpCodeFx(params);\n return {\n flow: \"verify\" as const,\n code,\n verifier: resolvedVerifier,\n };\n }),\n }),\n ),\n );\n\n/** @internal */\nexport const handleTotp = (\n ctx: EnrichedActionCtx,\n provider: TotpProviderConfig,\n args: { params?: Record<string, any>; verifier?: string },\n): FxType<TotpResult, ConvexError<any>> => {\n const params = (args.params ?? {}) as Record<string, unknown>;\n\n return resolveTotpDispatchFx(params, args.verifier).pipe(\n Fx.chain((dispatch) =>\n Fx.match(dispatch).on(\"flow\", {\n setup: ({ params }) =>\n Fx.from({\n ok: () => ctx.auth.getUserIdentity(),\n err: (e) =>\n Cv.error({ code: \"INTERNAL_ERROR\", message: String(e) }),\n }).pipe(\n Fx.chain((identity) =>\n identity === null\n ? Cv.fail({\n code: \"TOTP_AUTH_REQUIRED\",\n message:\n \"Sign in first, then set up two-factor authentication.\",\n })\n : Fx.succeed(userIdFromIdentitySubject(identity.subject)),\n ),\n Fx.chain((userId) =>\n Fx.from({\n ok: async () => {\n const secret = new Uint8Array(20);\n crypto.getRandomValues(secret);\n\n let accountName: string = params.accountName as string;\n if (!accountName) {\n const user = await queryUserById(ctx, userId);\n accountName = user?.email ?? \"user\";\n }\n\n const uri = createTOTPKeyURI(\n provider.options.issuer,\n accountName,\n secret,\n provider.options.period,\n provider.options.digits,\n );\n const base32Secret = encodeBase32LowerCaseNoPadding(secret);\n\n const verifier = await callVerifier(ctx);\n await callVerifierSignature(ctx, {\n verifier,\n signature: JSON.stringify({\n secret: Array.from(secret),\n userId,\n digits: provider.options.digits,\n period: provider.options.period,\n }),\n });\n\n const totpId = await mutateTotpInsert(ctx, {\n userId,\n secret: secret.buffer.slice(\n secret.byteOffset,\n secret.byteOffset + secret.byteLength,\n ),\n digits: provider.options.digits,\n period: provider.options.period,\n verified: false,\n name:\n typeof params.name === \"string\" ? params.name : undefined,\n createdAt: Date.now(),\n });\n\n return {\n kind: \"totpSetup\" as const,\n uri,\n secret: base32Secret,\n verifier,\n totpId,\n };\n },\n err: (e) =>\n Cv.error({\n code: \"INTERNAL_ERROR\",\n message: `TOTP setup failed: ${String(e)}`,\n }),\n }),\n ),\n ),\n confirm: ({ code, totpId, verifier }) =>\n Fx.from({\n ok: () => ctx.auth.getUserIdentity(),\n err: (e) =>\n Cv.error({ code: \"INTERNAL_ERROR\", message: String(e) }),\n }).pipe(\n Fx.chain((identity) =>\n identity === null\n ? Cv.fail({\n code: \"TOTP_AUTH_REQUIRED\",\n message:\n \"Sign in first, then set up two-factor authentication.\",\n })\n : Fx.succeed(userIdFromIdentitySubject(identity.subject)),\n ),\n Fx.chain((userId) =>\n Fx.from({\n ok: () => queryTotpById(ctx, totpId),\n err: () =>\n Cv.error({\n code: \"TOTP_NOT_FOUND\",\n message: \"TOTP enrollment not found.\",\n }),\n })\n .pipe(\n Fx.chain((doc) =>\n doc === null\n ? Cv.fail({\n code: \"TOTP_NOT_FOUND\",\n message: \"TOTP enrollment not found.\",\n })\n : Fx.succeed(doc),\n ),\n Fx.chain((totpDoc) =>\n totpDoc.verified\n ? Cv.fail({\n code: \"TOTP_ALREADY_VERIFIED\",\n message: \"TOTP enrollment is already verified.\",\n })\n : Fx.succeed(totpDoc),\n ),\n )\n .pipe(\n Fx.chain((totpDoc) =>\n verifyTOTPWithGracePeriod(\n new Uint8Array(totpDoc.secret),\n provider.options.period,\n provider.options.digits,\n code,\n 30,\n )\n ? Fx.succeed(totpDoc)\n : Cv.fail({\n code: \"TOTP_INVALID_CODE\",\n message: \"Invalid TOTP code.\",\n }),\n ),\n )\n .pipe(\n Fx.chain((_totpDoc) =>\n Fx.from({\n ok: async () => {\n await mutateTotpMarkVerified(ctx, totpId, Date.now());\n await mutateVerifierDelete(ctx, verifier);\n return callSignIn(ctx, {\n userId,\n generateTokens: true,\n });\n },\n err: (e) =>\n Cv.error({\n code: \"INTERNAL_ERROR\",\n message: String(e),\n }),\n }),\n ),\n )\n .pipe(\n Fx.map((signInResult) => ({\n kind: \"signedIn\" as const,\n signedIn: signInResult,\n })),\n ),\n ),\n ),\n verify: ({ code, verifier }) =>\n Fx.from({\n ok: () => queryVerifierById(ctx, verifier),\n err: () =>\n Cv.error({\n code: \"TOTP_INVALID_VERIFIER\",\n message: \"Invalid or expired TOTP verifier.\",\n }),\n }).pipe(\n Fx.chain((doc) =>\n doc === null\n ? Cv.fail({\n code: \"TOTP_INVALID_VERIFIER\",\n message: \"Invalid or expired TOTP verifier.\",\n })\n : Fx.succeed(doc),\n ),\n Fx.map((doc) => {\n const data = JSON.parse(doc.signature!);\n return { userId: data.userId as string, code, verifier };\n }),\n Fx.chain(({ userId, code, verifier }) =>\n Fx.from({\n ok: () => queryTotpVerifiedByUserId(ctx, userId),\n err: () =>\n Cv.error({\n code: \"TOTP_NO_ENROLLMENT\",\n message: \"No verified TOTP enrollment found.\",\n }),\n }).pipe(\n Fx.chain((totpDoc) =>\n totpDoc === null\n ? Cv.fail({\n code: \"TOTP_NO_ENROLLMENT\",\n message: \"No verified TOTP enrollment found.\",\n })\n : Fx.succeed(totpDoc),\n ),\n Fx.chain((totpDoc) =>\n verifyTOTPWithGracePeriod(\n new Uint8Array(totpDoc.secret),\n totpDoc.period,\n totpDoc.digits,\n code,\n 30,\n )\n ? Fx.succeed(totpDoc)\n : Cv.fail({\n code: \"TOTP_INVALID_CODE\",\n message: \"Invalid TOTP code.\",\n }),\n ),\n Fx.chain((totpDoc) =>\n Fx.from({\n ok: async () => {\n await mutateTotpUpdateLastUsed(\n ctx,\n totpDoc._id,\n Date.now(),\n );\n await mutateVerifierDelete(ctx, verifier);\n return callSignIn(ctx, { userId, generateTokens: true });\n },\n err: (e) =>\n Cv.error({ code: \"INTERNAL_ERROR\", message: String(e) }),\n }),\n ),\n Fx.map((signInResult) => ({\n kind: \"signedIn\" as const,\n signedIn: signInResult,\n })),\n ),\n ),\n ),\n }),\n ),\n );\n};\n\n// ============================================================================\n// Helpers\n// ============================================================================\n"],"mappings":"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"}
@@ -665,29 +665,23 @@ type AuthProviderSignInResult = {
665
665
  userId: GenericId<"User">;
666
666
  sessionId: GenericId<"Session">;
667
667
  } | null;
668
- /** Arguments for `auth.member.resolve()`. */
669
- type AuthMemberResolveArgs = {
668
+ /** Arguments for `auth.member.inspect()`. */
669
+ type AuthMemberInspectArgs = {
670
670
  userId: GenericId<"User">;
671
671
  groupId: GenericId<"Group">;
672
672
  ancestry?: boolean;
673
- roleIds?: string[];
674
- grants?: string[];
675
673
  maxDepth?: number;
676
674
  };
677
- /** Result of `auth.member.resolve()` — membership check with role and grant details. */
678
- type AuthMemberResolveResult = {
679
- ok: boolean;
675
+ /** Result of `auth.member.inspect()` — membership state and derived access details. */
676
+ type AuthMemberInspectResult = {
680
677
  membership: GenericDoc<GenericDataModel, "GroupMember"> | null;
681
- matchedGroupId: GenericId<"Group"> | null;
682
678
  roleIds: string[];
683
679
  grants: string[];
684
- missingGrants: string[];
685
- depth: number | null;
686
- isDirect: boolean;
687
- isInherited: boolean;
688
- traversedGroupIds: GenericId<"Group">[];
689
- code?: "INVALID_ROLE_IDS";
690
- invalidRoleIds?: string[];
680
+ };
681
+ /** Arguments for `auth.member.require()`. */
682
+ type AuthMemberRequireArgs = AuthMemberInspectArgs & {
683
+ roleIds?: string[];
684
+ grants?: string[];
691
685
  };
692
686
  /**
693
687
  * Server-side auth helper methods injected into `ctx.auth` within provider actions.
@@ -710,7 +704,6 @@ type AuthMemberResolveResult = {
710
704
  type AuthServerHelpers = {
711
705
  /** Account management: create, retrieve, and update provider-linked accounts. */account: {
712
706
  create: (ctx: GenericActionCtx<any>, args: AuthCreateAccountArgs) => Promise<{
713
- ok: true;
714
707
  account: GenericDoc<GenericDataModel, "Account">;
715
708
  user: GenericDoc<GenericDataModel, "User">;
716
709
  }>;
@@ -719,7 +712,6 @@ type AuthServerHelpers = {
719
712
  user: GenericDoc<GenericDataModel, "User">;
720
713
  }>;
721
714
  update: (ctx: GenericActionCtx<any>, args: AuthUpdateAccountArgs) => Promise<{
722
- ok: true;
723
715
  accountId: GenericId<"Account">;
724
716
  }>;
725
717
  };
@@ -728,13 +720,13 @@ type AuthServerHelpers = {
728
720
  auth: GenericActionCtx<GenericDataModel>["auth"];
729
721
  }) => Promise<GenericId<"Session"> | null>;
730
722
  invalidate: (ctx: GenericActionCtx<any>, args: AuthInvalidateSessionsArgs) => Promise<{
731
- ok: true;
732
723
  userId: GenericId<"User">;
733
724
  except: GenericId<"Session">[];
734
725
  }>;
735
726
  };
736
727
  member: {
737
- resolve: (ctx: GenericActionCtx<any>, args: AuthMemberResolveArgs) => Promise<AuthMemberResolveResult>;
728
+ inspect: (ctx: GenericActionCtx<any>, args: AuthMemberInspectArgs) => Promise<AuthMemberInspectResult>;
729
+ require: (ctx: GenericActionCtx<any>, args: AuthMemberRequireArgs) => Promise<AuthMemberInspectResult>;
738
730
  };
739
731
  provider: {
740
732
  signIn: (ctx: GenericActionCtx<any>, provider: AuthProviderConfig, args: AuthProviderSignInArgs) => Promise<AuthProviderSignInResult>;
@@ -764,7 +756,7 @@ type ConvexAuthMaterializedConfig = {
764
756
  * Materialized OAuth provider config (Arctic-based).
765
757
  *
766
758
  * Carries the Arctic provider instance along with scopes and profile config.
767
- * Produced by materializing an `OAuthProviderInstance` during `configDefaults`.
759
+ * Produced by materializing an `OAuthProviderInstance` during `configDefaults`.
768
760
  */
769
761
  interface OAuthMaterializedConfig {
770
762
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/server/types.ts"],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/server/types.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;KAqCY,SAAA,MAAe,CAAA,GAAI,WAAA,CAAY,CAAA;;;;;;AAA3C;;;KAUY,kBAAA;EAV+B,+DAYzC,EAAA,WAZwC;EAcxC,KAAA,WAdoB;EAgBpB,MAAA;AAAA;;;;AANF;;;;;KAiBY,uBAAA;EACV,KAAA,EAAO,MAAA,SAAe,kBAAA;AAAA;;AADxB;;;;;;;;;KAcY,UAAA,wBACa,uBAAA,gBACrB,cAAA;EAAyB,KAAA,uBAA4B,MAAA;AAAA,UAC/C,MAAA;;;;;;;;;;;KAaE,SAAA,wBACa,uBAAA,gBACrB,cAAA;EACF,KAAA,uBAA4B,MAAA;IAAiB,MAAA;EAAA;AAAA,IAE3C,MAAA,OAAa,MAAA;AALjB;;;AAAA,KAWY,gBAAA;EATR;;;;;;EAgBF,SAAA,EAAW,kBAAA;EAjBY;;;;;;EAwBvB,SAAA,EAAW,gBAAA;EApBI;;;EAwBf,OAAA;IAlB0B;;;;;;;IA0BxB,eAAA;IAqHc;;;;;;;IA7Gd,kBAAA;EAAA;EA4Ka;;;EAvKf,GAAA;IAwLe;;;;;;;IAhLb,UAAA;EAAA;EAAA;;;EAKF,MAAA;IAyDE;;;;;;;;;IA/CA,wBAAA;EAAA;EAiFI;;;;;;;EAxEN,SAAA;IAyFM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiFR;;;;;;IApII,QAAA,IAAY,MAAA;MAwIoB;;;MApI9B,UAAA;IAAA,MACI,OAAA;IAyIN;;;;;;;;;;;IA7HA,kBAAA,IACE,GAAA,EAAK,kBAAA,CAAmB,YAAA,GACxB,IAAA;MAuIiB;;;;MAlIf,cAAA,EAAgB,SAAA;MAmIH;;;;MA9Hb,IAAA;MA8Ha;;;;MAzHb,QAAA,EAAU,8BAAA;MA8GT;;;;;;;MAtGD,OAAA,EAAS,MAAA;QACP,KAAA;QACA,KAAA;QACA,aAAA;QACA,aAAA;MAAA;MA0Ga;;;MArGf,UAAA;IAAA,MAEC,OAAA,CAAQ,SAAA;IAsGI;;AAMrB;;;;;AAWA;;;;;AAQA;;IAhHI,yBAAA,IACE,GAAA,EAAK,kBAAA,CAAmB,YAAA,GACxB,IAAA;MA8GmC;;AASzC;MAnHQ,MAAA,EAAQ,SAAA;MAmHyB;;;AAWzC;MAzHQ,cAAA,EAAgB,SAAA;MAyHa;;;AAUrC;MA9HQ,IAAA;MA8HyB;;;;MAzHzB,QAAA,EAAU,8BAAA;MA0IN;;;;;;;MAlIJ,OAAA,EAAS,MAAA;QACP,KAAA;QACA,KAAA;QACA,aAAA;QACA,aAAA;MAAA;MAuHJ;;;MAlHE,UAAA;IAAA,MAEC,OAAA;EAAA;EAsHL;;;EAjHF,aAAA;IACE,KAAA,EAAO,MAAA;MAGH,KAAA;MACA,MAAA;IAAA;EAAA;AAAA;;;;;;;;;KAcI,kBAAA,GAAkB,qBAAA,GACwB,QAAA,GACV,OAAA,GACF,IAAA,GACN,SAAA,GACU,MAAA,GACN,GAAA,GACN,KAAA,GACI,KAAA,GAElC,uBAAA,GACA,uBAAA,QACK,IAAA,UAAc,uBAAA,IACnB,WAAA,QACK,IAAA,UAAc,WAAA,IACnB,WAAA,QACK,IAAA,UAAc,WAAA,IACnB,qBAAA,QACK,IAAA,UAAc,qBAAA,IACnB,kBAAA,QACK,IAAA,UAAc,kBAAA,IACnB,oBAAA,QACK,IAAA,UAAc,oBAAA,IACnB,iBAAA;;;;;UAMa,iBAAA;EACf,EAAA;EACA,IAAA;AAAA;;;;;;;KASU,8BAAA;;;;;;AA8FZ;KAtFY,6BAAA;;;;;;;;KASA,6BAAA;;;;;;;KAWA,yBAAA;;;;;;;;;UAUK,gBAAA;EACf,OAAA;EACA,QAAA;IACE,cAAA;MACE,IAAA,EAAM,8BAAA;MACN,IAAA,EAAM,8BAAA;IAAA;EAAA;EAGV,YAAA;IACE,SAAA;MACE,IAAA,EAAM,6BAAA;IAAA;IAER,GAAA;MACE,IAAA,EAAM,6BAAA;MACN,cAAA;IAAA;IAEF,WAAA;MACE,IAAA,EAAM,yBAAA;IAAA;EAAA;EAGV,MAAA,GAAS,MAAA;AAAA;;;;;;;UASM,qBAAA;EACf,QAAA;IACE,cAAA;MACE,IAAA,GAAO,8BAAA;MACP,IAAA,GAAO,8BAAA;IAAA;EAAA;EAGX,YAAA;IACE,SAAA;MACE,IAAA,GAAO,6BAAA;IAAA;IAET,GAAA;MACE,IAAA,GAAO,6BAAA;MACP,cAAA;IAAA;IAEF,WAAA;MACE,IAAA,GAAO,yBAAA;IAAA;EAAA;EAGX,MAAA,GAAS,MAAA;AAAA;;;;;;UAQM,WAAA,mBACG,gBAAA,GAAmB,gBAAA;EAuED;EApEpC,EAAA;EA4E0B;EA1E1B,IAAA;EA2EkB;EAzElB,IAAA;EAwFa;EAtFb,IAAA;EA0FsC;;;;;EApFtC,MAAA;EAqHsB;;;;;;EA9GtB,uBAAA,GACE,MAAA;IACE,UAAA;IACA,GAAA;IACA,OAAA,EAAS,IAAA;IACT,QAAA,EAAU,WAAA;IACV,KAAA;IACA,OAAA,EAAS,OAAA;EAAA,GAEX,GAAA,GAAM,gBAAA,CAAiB,YAAA,MACpB,SAAA;EA6DD;;;;;EAvDJ,yBAAA,SAAkC,SAAA;EA2D9B;;;;EAtDJ,mBAAA,IAAuB,UAAA;EAyDlB;;;;;;;EAjDL,SAAA;EAgFyB;;;EA5EvB,MAAA,EAAQ,MAAA,SAAe,KAAA,eACvB,OAAA,EAAS,UAAA,CAAW,SAAA,iBACjB,OAAA;EA2EH;EAzEF,OAAA,EAAS,eAAA,CAAgB,SAAA;AAAA;;;;;AAqF3B;;;KA3EY,eAAA,mBACQ,gBAAA,GAAmB,gBAAA,IACnC,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,SAAA;;;;;;;UAQZ,WAAA,mBACG,gBAAA,GAAmB,gBAAA;EAErC,EAAA;EACA,IAAA;EA8DqC;;;EA1DrC,MAAA;EA2D2B;;;EAvD3B,uBAAA,GACE,MAAA;IACE,UAAA;IACA,GAAA;IACA,OAAA,EAAS,IAAA;IACT,QAAA,EAAU,WAAA;IACV,KAAA;EAAA,GAEF,GAAA,EAAK,8BAAA,CAA+B,SAAA,MACjC,OAAA;EAqDH;;AAMJ;EAvDE,MAAA;;;;;;;;;EASA,yBAAA,SAAkC,OAAA;EAmEhC;;;;;EA7DF,mBAAA,IAAuB,UAAA;EAiFA;AAOzB;;;;;;EAhFE,SAAA;EAqFE;;;EAjFA,MAAA,EAAQ,MAAA,SAAe,KAAA,eACvB,OAAA,EAAS,UAAA,CAAW,SAAA,iBACjB,OAAA;EACL,OAAA,EAAS,eAAA,CAAgB,SAAA;AAAA;;;;;;;;KAUf,eAAA,mBACQ,gBAAA,GAAmB,gBAAA,IACnC,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,SAAA;;;AAoH7B;KA/GY,uBAAA,GAA0B,iBAAA;EACpC,IAAA;EACA,EAAA;AAAA;AAqHF;;;AAAA,UA/GiB,qBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;IA+GA,iEA7GE,MAAA,WA8GA;IA5GA,IAAA,WA8GA;IA5GA,MAAA;IA+GF;;;;AAKF;IA9GI,WAAA;IAgHO;;;;;IA1GP,gBAAA;IA0G6B;AAIjC;;;;IAxGI,WAAA,6CA0GF;IAxGE,uBAAA;IA0GA;;;AAKJ;;IAzGI,UAAA;IA2GgB;;;;;IArGhB,qBAAA;EAAA;AAAA;;;;UAOa,kBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;IAgGA,+DA9FE,MAAA;IA+FF;;;;;IAzFE,MAAA;IA6FgC;;;;;IAvFhC,MAAA;EAAA;AAAA;;AA6FJ;;;;UAhFiB,YAAA;EACf,EAAA;EACA,IAAA;EACA,KAAA;EACA,KAAA;EAgFA;EAAA,CA9EC,GAAA;AAAA;AAkFH;AAAA,KA/DY,sBAAA;mEAEV,EAAA,UA8DA;EA5DA,MAAA;AAAA;;KAIU,qBAAA;EACV,QAAA;EACA,OAAA,EAAS,sBAAA;EACT,OAAA,EAAS,MAAA;IACP,KAAA;IACA,KAAA;IACA,aAAA;IACA,aAAA;EAAA;EAEF,kBAAA;EACA,kBAAA;AAAA;AA2EF;AAAA,KAvEY,uBAAA;EACV,QAAA;EACA,OAAA,EAAS,sBAAA;AAAA;;KAIC,qBAAA;EACV,QAAA;EACA,OAAA;IACE,EAAA;IACA,MAAA;EAAA;AAAA;;KAKQ,0BAAA;EACV,MAAA,EAAQ,SAAA;EACR,MAAA,GAAS,SAAA;AAAA;;KAIC,sBAAA;EACV,SAAA,GAAY,SAAA;EACZ,MAAA,GAAS,MAAA,SAAe,KAAA;AAAA;;KAId,wBAAA;EACV,MAAA,EAAQ,SAAA;EACR,SAAA,EAAW,SAAA;AAAA;;KAID,qBAAA;EACV,MAAA,EAAQ,SAAA;EACR,OAAA,EAAS,SAAA;EACT,QAAA;EACA,QAAA;AAAA;;KAIU,uBAAA;EACV,UAAA,EAAY,UAAA,CAAW,gBAAA;EACvB,OAAA;EACA,MAAA;AAAA;;KAIU,qBAAA,GAAwB,qBAAA;EAClC,OAAA;EACA,MAAA;AAAA;;;;;;;;;;;;;;;;;;;KAqBU,iBAAA;EAcG,iFAZb,OAAA;IACE,MAAA,GACE,GAAA,EAAK,gBAAA,OACL,IAAA,EAAM,qBAAA,KACH,OAAA;MACH,OAAA,EAAS,UAAA,CAAW,gBAAA;MACpB,IAAA,EAAM,UAAA,CAAW,gBAAA;IAAA;IAEnB,GAAA,GACE,GAAA,EAAK,gBAAA,OACL,IAAA,EAAM,uBAAA,KACH,OAAA;MACH,OAAA,EAAS,UAAA,CAAW,gBAAA;MACpB,IAAA,EAAM,UAAA,CAAW,gBAAA;IAAA;IAEnB,MAAA,GACE,GAAA,EAAK,gBAAA,OACL,IAAA,EAAM,qBAAA,KACH,OAAA;MAAU,SAAA,EAAW,SAAA;IAAA;EAAA;EAE5B,OAAA;IACE,OAAA,GAAU,GAAA;MACR,IAAA,EAAM,gBAAA,CAAiB,gBAAA;IAAA,MACnB,OAAA,CAAQ,SAAA;IACd,UAAA,GACE,GAAA,EAAK,gBAAA,OACL,IAAA,EAAM,0BAAA,KACH,OAAA;MACH,MAAA,EAAQ,SAAA;MACR,MAAA,EAAQ,SAAA;IAAA;EAAA;EAGZ,MAAA;IACE,OAAA,GACE,GAAA,EAAK,gBAAA,OACL,IAAA,EAAM,qBAAA,KACH,OAAA,CAAQ,uBAAA;IACb,OAAA,GACE,GAAA,EAAK,gBAAA,OACL,IAAA,EAAM,qBAAA,KACH,OAAA,CAAQ,uBAAA;EAAA;EAEf,QAAA;IACE,MAAA,GACE,GAAA,EAAK,gBAAA,OACL,QAAA,EAAU,kBAAA,EACV,IAAA,EAAM,sBAAA,KACH,OAAA,CAAQ,wBAAA;EAAA;AAAA;;;;;;;KAUL,8BAAA,mBAAiD,gBAAA,IAC3D,gBAAA,CAAiB,SAAA;EACf,IAAA,EAAM,gBAAA,CAAiB,SAAA;IACrB,MAAA,EAAQ,4BAAA;EAAA,IACN,iBAAA;AAAA;;;;;;;KASI,4BAAA;EACV,SAAA,EAAW,8BAAA;AAAA,IACT,IAAA,CACF,gBAAA;;;;;;;UA6Be,uBAAA;EA3CU;;;;EAAA,SAgDhB,EAAA;EA9Cc;AASzB;;;EATyB,SAmDd,IAAA;EAvCT;;;;EAAA,SA4CS,QAAA;EA9CE;;;;EAAA,SAmDF,MAAA;EApBM;;;;EAAA,SAyBN,OAAA,IACP,MAAA,EA1BoC,OAAA,CA0BX,YAAA,KACtB,OAAA,CAAQ,YAAA;EAAR;;;;EAAA,SAKI,cAAA;AAAA;;;;;;;UASM,oBAAA;EACf,EAAA;EACA,IAAA;EAFe;EAIf,OAAA;;EAEA,cAAA;EALA;EAOA,SAAA;EAJA;EAMA,QAAA;EAFA;;;;;AAeF;EANE,eAAA;AAAA;;;;KAMU,8BAAA,GACR,uBAAA,GACA,WAAA,GACA,WAAA,GACA,uBAAA,GACA,qBAAA,GACA,kBAAA,GACA,oBAAA,GACA,iBAAA;;;;;;;KAQQ,MAAA,WAAiB,kBAAA,MAAkB,GAAA,SACN,CAAA;;;;;;;AADzC;;UAwBiB,QAAA;EACf,QAAA;EACA,OAAA;AAAA;;;;;;;;;AAFF;;;UAgBiB,YAAA;EAdR;EAgBP,GAAA,CAAI,QAAA,UAAkB,MAAA;EAFK;EAI3B,MAAA,EAAQ,QAAA;AAAA;;;;;UAOO,SAAA;EAPC;EAShB,GAAA;EAFe;EAIf,MAAA;;EAEA,MAAA;EAJA;EAMA,IAAA;EAFA;EAIA,MAAA,EAAQ,QAAA;EAAR;EAEA,SAAA;IAAc,WAAA;IAAqB,QAAA;EAAA;EAEnC;EAAA,SAAA;EAIA;EAFA,UAAA;EAMA;EAJA,SAAA;EAIiB;EAFjB,OAAA;EAuKe;EArKf,QAAA,GAAW,MAAA;AAAA;;;;;;;;;;;;;;;;;;UAqKI,cAAA;EACf,GAAA;sDAEE,MAAA;IAEA,KAAA;IAEA,MAAA,EAAQ,YAAA;EAAA;AAAA;;;;UAOK,UAAA;;EAEf,MAAA;;EAEA,OAAA;;EAEA,OAAA;AAAA;;;;KA8OU,UAAA,mBACQ,gBAAA,oBACA,qBAAA,CAAsB,SAAA,KACtC,cAAA,CAAe,SAAA,EAAW,SAAA;EAC5B,GAAA,EAAK,SAAA,CAAU,SAAA;EACf,aAAA;AAAA;;KAwCU,aAAA,GAAgB,6BAAA,QAAqC,QAAA;;KAYrD,GAAA,WAAc,qBAAA,CAAsB,aAAA,KAAkB,UAAA,CAChE,aAAA,EACA,CAAA;;KAIU,MAAA;EAAW,KAAA;EAAe,YAAA;AAAA;;KAG1B,WAAA;EACV,MAAA,EAAQ,SAAA;EACR,SAAA,EAAW,SAAA;EACX,MAAA,EAAQ,MAAA;AAAA"}