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

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 (310) hide show
  1. package/dist/authorization/index.d.ts +1 -1
  2. package/dist/authorization/index.js +1 -1
  3. package/dist/authorization/index.js.map +1 -1
  4. package/dist/client/index.d.ts +1 -2
  5. package/dist/client/index.d.ts.map +1 -1
  6. package/dist/client/index.js +36 -39
  7. package/dist/client/index.js.map +1 -1
  8. package/dist/component/client/index.d.ts +1 -2
  9. package/dist/component/convex.config.d.ts +2 -2
  10. package/dist/component/convex.config.d.ts.map +1 -1
  11. package/dist/component/model.d.ts +5 -5
  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 +39 -39
  53. package/dist/component/server/auth.d.ts +95 -52
  54. package/dist/component/server/auth.d.ts.map +1 -1
  55. package/dist/component/server/auth.js +63 -43
  56. package/dist/component/server/auth.js.map +1 -1
  57. package/dist/component/server/core.js +116 -235
  58. package/dist/component/server/core.js.map +1 -1
  59. package/dist/component/server/crypto.js +25 -7
  60. package/dist/component/server/crypto.js.map +1 -1
  61. package/dist/component/server/device.js +58 -15
  62. package/dist/component/server/device.js.map +1 -1
  63. package/dist/component/server/enterprise/domain.js +148 -59
  64. package/dist/component/server/enterprise/domain.js.map +1 -1
  65. package/dist/component/server/enterprise/http.js +36 -15
  66. package/dist/component/server/enterprise/http.js.map +1 -1
  67. package/dist/component/server/enterprise/oidc.js +1 -1
  68. package/dist/component/server/http.js +26 -21
  69. package/dist/component/server/http.js.map +1 -1
  70. package/dist/component/server/identity.js +5 -2
  71. package/dist/component/server/identity.js.map +1 -1
  72. package/dist/component/server/limits.js +21 -30
  73. package/dist/component/server/limits.js.map +1 -1
  74. package/dist/component/server/mutations/account.js +12 -10
  75. package/dist/component/server/mutations/account.js.map +1 -1
  76. package/dist/component/server/mutations/code.js +5 -2
  77. package/dist/component/server/mutations/code.js.map +1 -1
  78. package/dist/component/server/mutations/invalidate.js +1 -1
  79. package/dist/component/server/mutations/invalidate.js.map +1 -1
  80. package/dist/component/server/mutations/oauth.js +10 -4
  81. package/dist/component/server/mutations/oauth.js.map +1 -1
  82. package/dist/component/server/mutations/refresh.js +2 -2
  83. package/dist/component/server/mutations/refresh.js.map +1 -1
  84. package/dist/component/server/mutations/register.js +46 -42
  85. package/dist/component/server/mutations/register.js.map +1 -1
  86. package/dist/component/server/mutations/retrieve.js +21 -25
  87. package/dist/component/server/mutations/retrieve.js.map +1 -1
  88. package/dist/component/server/mutations/signature.js +10 -4
  89. package/dist/component/server/mutations/signature.js.map +1 -1
  90. package/dist/component/server/mutations/signout.js.map +1 -1
  91. package/dist/component/server/mutations/store.js +9 -24
  92. package/dist/component/server/mutations/store.js.map +1 -1
  93. package/dist/component/server/mutations/verifier.js.map +1 -1
  94. package/dist/component/server/mutations/verify.js +1 -1
  95. package/dist/component/server/mutations/verify.js.map +1 -1
  96. package/dist/component/server/oauth.js +53 -16
  97. package/dist/component/server/oauth.js.map +1 -1
  98. package/dist/component/server/passkey.js +115 -31
  99. package/dist/component/server/passkey.js.map +1 -1
  100. package/dist/component/server/redirects.js +9 -3
  101. package/dist/component/server/redirects.js.map +1 -1
  102. package/dist/component/server/refresh.js +10 -7
  103. package/dist/component/server/refresh.js.map +1 -1
  104. package/dist/component/server/runtime.d.ts +3 -3
  105. package/dist/component/server/runtime.d.ts.map +1 -1
  106. package/dist/component/server/runtime.js +62 -20
  107. package/dist/component/server/runtime.js.map +1 -1
  108. package/dist/component/server/signin.js +34 -10
  109. package/dist/component/server/signin.js.map +1 -1
  110. package/dist/component/server/totp.js +79 -19
  111. package/dist/component/server/totp.js.map +1 -1
  112. package/dist/component/server/types.d.ts +12 -20
  113. package/dist/component/server/types.d.ts.map +1 -1
  114. package/dist/component/server/types.js.map +1 -1
  115. package/dist/component/server/users.js +6 -3
  116. package/dist/component/server/users.js.map +1 -1
  117. package/dist/component/server/utils.js +10 -4
  118. package/dist/component/server/utils.js.map +1 -1
  119. package/dist/core/types.d.ts +14 -22
  120. package/dist/core/types.d.ts.map +1 -1
  121. package/dist/factors/device.js +8 -9
  122. package/dist/factors/device.js.map +1 -1
  123. package/dist/factors/passkey.js +18 -21
  124. package/dist/factors/passkey.js.map +1 -1
  125. package/dist/providers/password.js +66 -81
  126. package/dist/providers/password.js.map +1 -1
  127. package/dist/runtime/invite.js +2 -8
  128. package/dist/runtime/invite.js.map +1 -1
  129. package/dist/server/auth.d.ts +95 -52
  130. package/dist/server/auth.d.ts.map +1 -1
  131. package/dist/server/auth.js +63 -43
  132. package/dist/server/auth.js.map +1 -1
  133. package/dist/server/core.d.ts +71 -159
  134. package/dist/server/core.d.ts.map +1 -1
  135. package/dist/server/core.js +116 -235
  136. package/dist/server/core.js.map +1 -1
  137. package/dist/server/crypto.d.ts.map +1 -1
  138. package/dist/server/crypto.js +25 -7
  139. package/dist/server/crypto.js.map +1 -1
  140. package/dist/server/device.js +58 -15
  141. package/dist/server/device.js.map +1 -1
  142. package/dist/server/enterprise/domain.d.ts +0 -8
  143. package/dist/server/enterprise/domain.d.ts.map +1 -1
  144. package/dist/server/enterprise/domain.js +148 -59
  145. package/dist/server/enterprise/domain.js.map +1 -1
  146. package/dist/server/enterprise/http.d.ts.map +1 -1
  147. package/dist/server/enterprise/http.js +35 -14
  148. package/dist/server/enterprise/http.js.map +1 -1
  149. package/dist/server/http.d.ts +2 -2
  150. package/dist/server/http.d.ts.map +1 -1
  151. package/dist/server/http.js +25 -20
  152. package/dist/server/http.js.map +1 -1
  153. package/dist/server/identity.js +5 -2
  154. package/dist/server/identity.js.map +1 -1
  155. package/dist/server/index.d.ts +2 -2
  156. package/dist/server/limits.js +21 -30
  157. package/dist/server/limits.js.map +1 -1
  158. package/dist/server/mounts.d.ts +26 -64
  159. package/dist/server/mounts.d.ts.map +1 -1
  160. package/dist/server/mounts.js +45 -106
  161. package/dist/server/mounts.js.map +1 -1
  162. package/dist/server/mutations/account.d.ts +8 -9
  163. package/dist/server/mutations/account.d.ts.map +1 -1
  164. package/dist/server/mutations/account.js +11 -9
  165. package/dist/server/mutations/account.js.map +1 -1
  166. package/dist/server/mutations/code.d.ts +13 -13
  167. package/dist/server/mutations/code.d.ts.map +1 -1
  168. package/dist/server/mutations/code.js +5 -2
  169. package/dist/server/mutations/code.js.map +1 -1
  170. package/dist/server/mutations/invalidate.d.ts +4 -4
  171. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  172. package/dist/server/mutations/invalidate.js.map +1 -1
  173. package/dist/server/mutations/oauth.d.ts +12 -10
  174. package/dist/server/mutations/oauth.d.ts.map +1 -1
  175. package/dist/server/mutations/oauth.js +9 -3
  176. package/dist/server/mutations/oauth.js.map +1 -1
  177. package/dist/server/mutations/refresh.d.ts +3 -3
  178. package/dist/server/mutations/refresh.d.ts.map +1 -1
  179. package/dist/server/mutations/refresh.js +1 -1
  180. package/dist/server/mutations/refresh.js.map +1 -1
  181. package/dist/server/mutations/register.d.ts +11 -11
  182. package/dist/server/mutations/register.d.ts.map +1 -1
  183. package/dist/server/mutations/register.js +45 -41
  184. package/dist/server/mutations/register.js.map +1 -1
  185. package/dist/server/mutations/retrieve.d.ts +6 -6
  186. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  187. package/dist/server/mutations/retrieve.js +20 -24
  188. package/dist/server/mutations/retrieve.js.map +1 -1
  189. package/dist/server/mutations/signature.d.ts +6 -7
  190. package/dist/server/mutations/signature.d.ts.map +1 -1
  191. package/dist/server/mutations/signature.js +9 -3
  192. package/dist/server/mutations/signature.js.map +1 -1
  193. package/dist/server/mutations/signin.d.ts +5 -5
  194. package/dist/server/mutations/signin.d.ts.map +1 -1
  195. package/dist/server/mutations/signout.js.map +1 -1
  196. package/dist/server/mutations/store.d.ts +97 -97
  197. package/dist/server/mutations/store.d.ts.map +1 -1
  198. package/dist/server/mutations/store.js +8 -23
  199. package/dist/server/mutations/store.js.map +1 -1
  200. package/dist/server/mutations/verifier.js.map +1 -1
  201. package/dist/server/mutations/verify.d.ts +10 -10
  202. package/dist/server/mutations/verify.d.ts.map +1 -1
  203. package/dist/server/mutations/verify.js.map +1 -1
  204. package/dist/server/oauth.js +53 -16
  205. package/dist/server/oauth.js.map +1 -1
  206. package/dist/server/passkey.d.ts +2 -2
  207. package/dist/server/passkey.d.ts.map +1 -1
  208. package/dist/server/passkey.js +114 -30
  209. package/dist/server/passkey.js.map +1 -1
  210. package/dist/server/redirects.js +9 -3
  211. package/dist/server/redirects.js.map +1 -1
  212. package/dist/server/refresh.js +10 -7
  213. package/dist/server/refresh.js.map +1 -1
  214. package/dist/server/runtime.d.ts +14 -14
  215. package/dist/server/runtime.d.ts.map +1 -1
  216. package/dist/server/runtime.js +61 -19
  217. package/dist/server/runtime.js.map +1 -1
  218. package/dist/server/signin.js +34 -10
  219. package/dist/server/signin.js.map +1 -1
  220. package/dist/server/ssr.d.ts.map +1 -1
  221. package/dist/server/ssr.js +175 -184
  222. package/dist/server/ssr.js.map +1 -1
  223. package/dist/server/totp.js +78 -18
  224. package/dist/server/totp.js.map +1 -1
  225. package/dist/server/types.d.ts +13 -21
  226. package/dist/server/types.d.ts.map +1 -1
  227. package/dist/server/types.js.map +1 -1
  228. package/dist/server/users.js +6 -3
  229. package/dist/server/users.js.map +1 -1
  230. package/dist/server/utils.js +10 -4
  231. package/dist/server/utils.js.map +1 -1
  232. package/package.json +2 -6
  233. package/src/authorization/index.ts +1 -1
  234. package/src/cli/index.ts +1 -1
  235. package/src/client/core/types.ts +14 -14
  236. package/src/client/factors/device.ts +10 -12
  237. package/src/client/factors/passkey.ts +23 -26
  238. package/src/client/index.ts +54 -64
  239. package/src/client/runtime/invite.ts +5 -7
  240. package/src/component/index.ts +1 -0
  241. package/src/component/public/enterprise/audit.ts +6 -1
  242. package/src/component/public/enterprise/core.ts +1 -0
  243. package/src/component/public/enterprise/domains.ts +5 -1
  244. package/src/component/public/enterprise/scim.ts +1 -0
  245. package/src/component/public/enterprise/secrets.ts +1 -0
  246. package/src/component/public/enterprise/webhooks.ts +1 -0
  247. package/src/component/public/factors/devices.ts +1 -0
  248. package/src/component/public/factors/passkeys.ts +1 -0
  249. package/src/component/public/factors/totp.ts +1 -0
  250. package/src/component/public/groups/core.ts +1 -1
  251. package/src/component/public/groups/invites.ts +7 -1
  252. package/src/component/public/groups/members.ts +1 -0
  253. package/src/component/public/identity/accounts.ts +1 -0
  254. package/src/component/public/identity/codes.ts +1 -0
  255. package/src/component/public/identity/sessions.ts +1 -0
  256. package/src/component/public/identity/tokens.ts +1 -0
  257. package/src/component/public/identity/users.ts +1 -0
  258. package/src/component/public/identity/verifiers.ts +1 -0
  259. package/src/component/public/security/keys.ts +1 -0
  260. package/src/component/public/security/limits.ts +1 -0
  261. package/src/providers/password.ts +89 -110
  262. package/src/server/auth.ts +177 -111
  263. package/src/server/core.ts +197 -233
  264. package/src/server/crypto.ts +31 -29
  265. package/src/server/device.ts +65 -32
  266. package/src/server/enterprise/domain.ts +158 -170
  267. package/src/server/enterprise/http.ts +46 -39
  268. package/src/server/http.ts +36 -30
  269. package/src/server/identity.ts +5 -5
  270. package/src/server/index.ts +2 -0
  271. package/src/server/limits.ts +53 -80
  272. package/src/server/mounts.ts +47 -74
  273. package/src/server/mutations/account.ts +22 -36
  274. package/src/server/mutations/code.ts +6 -6
  275. package/src/server/mutations/invalidate.ts +1 -1
  276. package/src/server/mutations/oauth.ts +14 -8
  277. package/src/server/mutations/refresh.ts +5 -4
  278. package/src/server/mutations/register.ts +87 -132
  279. package/src/server/mutations/retrieve.ts +44 -44
  280. package/src/server/mutations/signature.ts +13 -6
  281. package/src/server/mutations/signout.ts +1 -1
  282. package/src/server/mutations/store.ts +16 -31
  283. package/src/server/mutations/verifier.ts +1 -1
  284. package/src/server/mutations/verify.ts +3 -5
  285. package/src/server/oauth.ts +60 -69
  286. package/src/server/passkey.ts +567 -517
  287. package/src/server/redirects.ts +10 -6
  288. package/src/server/refresh.ts +14 -18
  289. package/src/server/runtime.ts +70 -55
  290. package/src/server/signin.ts +44 -37
  291. package/src/server/ssr.ts +390 -407
  292. package/src/server/totp.ts +85 -35
  293. package/src/server/types.ts +19 -22
  294. package/src/server/users.ts +7 -6
  295. package/src/server/utils.ts +10 -12
  296. package/dist/component/server/authError.js +0 -34
  297. package/dist/component/server/authError.js.map +0 -1
  298. package/dist/component/server/errors.d.ts +0 -1
  299. package/dist/component/server/errors.js +0 -137
  300. package/dist/component/server/errors.js.map +0 -1
  301. package/dist/server/authError.d.ts +0 -46
  302. package/dist/server/authError.d.ts.map +0 -1
  303. package/dist/server/authError.js +0 -34
  304. package/dist/server/authError.js.map +0 -1
  305. package/dist/server/errors.d.ts +0 -177
  306. package/dist/server/errors.d.ts.map +0 -1
  307. package/dist/server/errors.js +0 -212
  308. package/dist/server/errors.js.map +0 -1
  309. package/src/server/authError.ts +0 -44
  310. package/src/server/errors.ts +0 -290
@@ -1,11 +1,10 @@
1
+ import { Fx } from "@robelest/fx";
2
+ import { Cv } from "@robelest/fx/convex";
1
3
  import type { GenericActionCtx, HttpRouter } from "convex/server";
4
+ import { ConvexError } from "convex/values";
2
5
  import { serialize as serializeCookie } from "cookie";
3
6
 
4
7
  import { redirectToParamCookie, useRedirectToParam } from "../cookies";
5
- import { isAuthError } from "../errors";
6
- import { Fx } from "@robelest/fx";
7
-
8
- import { AuthError } from "../authError";
9
8
  import { addSSORoutes, convertErrorsToResponse, getCookies } from "../http";
10
9
  import type { SSORuntimeRoute } from "../http";
11
10
  import { createOAuthAuthorizationURL, handleOAuthCallback } from "../oauth";
@@ -207,12 +206,10 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
207
206
  runtimeRoute.protocol !== "saml" ||
208
207
  runtimeRoute.rest.length !== 1 ||
209
208
  runtimeRoute.rest[0] !== "acs",
210
- Fx.fail(
211
- new AuthError(
212
- "INVALID_PARAMETERS",
213
- "Invalid enterprise runtime path.",
214
- ).toConvexError(),
215
- ),
209
+ Cv.fail({
210
+ code: "INVALID_PARAMETERS",
211
+ message: "Invalid enterprise runtime path.",
212
+ }),
216
213
  );
217
214
 
218
215
  const enterpriseId = runtimeRoute.enterpriseId;
@@ -230,10 +227,10 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
230
227
  config: loaded.config,
231
228
  }),
232
229
  err: (e) =>
233
- new AuthError(
234
- "OAUTH_PROVIDER_ERROR",
235
- `SAML response parse failed: ${e instanceof Error ? e.message : String(e)}`,
236
- ).toConvexError(),
230
+ Cv.error({
231
+ code: "OAUTH_PROVIDER_ERROR",
232
+ message: `SAML response parse failed: ${e instanceof Error ? e.message : String(e)}`,
233
+ }),
237
234
  });
238
235
 
239
236
  yield* Fx.from({
@@ -247,10 +244,11 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
247
244
  return Promise.resolve();
248
245
  },
249
246
  err: () =>
250
- new AuthError(
251
- "OAUTH_INVALID_STATE",
252
- "SAML RelayState did not match the pending login request.",
253
- ).toConvexError(),
247
+ Cv.error({
248
+ code: "OAUTH_INVALID_STATE",
249
+ message:
250
+ "SAML RelayState did not match the pending login request.",
251
+ }),
254
252
  });
255
253
 
256
254
  const { samlAttributes, samlSessionIndex, ...userProfile } =
@@ -331,10 +329,10 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
331
329
  runtimeRoute.rest.length !== 1 ||
332
330
  runtimeRoute.rest[0] !== "slo"
333
331
  ) {
334
- throw new AuthError(
335
- "INVALID_PARAMETERS",
336
- "Invalid enterprise runtime path.",
337
- ).toConvexError();
332
+ throw Cv.error({
333
+ code: "INVALID_PARAMETERS",
334
+ message: "Invalid enterprise runtime path.",
335
+ });
338
336
  }
339
337
  const { loaded, enterprise } = await loadActiveEnterpriseSamlOrThrow(
340
338
  ctx,
@@ -371,10 +369,10 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
371
369
  if (parsedMessage.hasSamlResponse) {
372
370
  return new Response(null, { status: 204 });
373
371
  }
374
- throw new AuthError(
375
- "INVALID_PARAMETERS",
376
- "Missing SAML logout payload.",
377
- ).toConvexError();
372
+ throw Cv.error({
373
+ code: "INVALID_PARAMETERS",
374
+ message: "Missing SAML logout payload.",
375
+ });
378
376
  };
379
377
 
380
378
  const handleScimRequest = async (
@@ -645,7 +643,7 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
645
643
  userId,
646
644
  data: patchData,
647
645
  });
648
- const resolution = await auth.member.resolve(state.ctx, {
646
+ const resolution = await auth.member.inspect(state.ctx, {
649
647
  groupId: state.enterprise.groupId,
650
648
  userId,
651
649
  });
@@ -711,7 +709,7 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
711
709
  );
712
710
  if (missing) return missing;
713
711
  const userId = state.parsedPath.resourceId!;
714
- const resolution = await auth.member.resolve(state.ctx, {
712
+ const resolution = await auth.member.inspect(state.ctx, {
715
713
  groupId: state.enterprise.groupId,
716
714
  userId,
717
715
  });
@@ -961,15 +959,12 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
961
959
  );
962
960
  const userId = match?.[1];
963
961
  if (userId) {
964
- const resolution = await auth.member.resolve(
965
- state.ctx,
966
- { groupId, userId },
967
- );
962
+ const resolution = await auth.member.inspect(state.ctx, {
963
+ groupId,
964
+ userId,
965
+ });
968
966
  if (resolution.membership) {
969
- await auth.member.delete(
970
- state.ctx,
971
- resolution.membership._id,
972
- );
967
+ await auth.member.delete(state.ctx, resolution.membership._id);
973
968
  }
974
969
  }
975
970
  }
@@ -1105,7 +1100,13 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
1105
1100
  ) {
1106
1101
  return scimError(400, "invalidFilter", error.message);
1107
1102
  }
1108
- if (isAuthError(error)) {
1103
+ if (
1104
+ error instanceof ConvexError &&
1105
+ typeof error.data === "object" &&
1106
+ error.data !== null &&
1107
+ "code" in error.data &&
1108
+ "message" in error.data
1109
+ ) {
1109
1110
  const code = error.data.code as string;
1110
1111
  const status =
1111
1112
  code === "MISSING_BEARER_TOKEN" || code === "INVALID_API_KEY"
@@ -1141,7 +1142,10 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
1141
1142
  const url = new URL(request.url);
1142
1143
  const verifier = url.searchParams.get("code");
1143
1144
  if (!verifier) {
1144
- throw new AuthError("OAUTH_MISSING_VERIFIER").toConvexError();
1145
+ throw Cv.error({
1146
+ code: "OAUTH_MISSING_VERIFIER",
1147
+ message: "Missing sign-in verifier.",
1148
+ });
1145
1149
  }
1146
1150
  const { loaded, enterprise } = await loadActiveEnterpriseSamlOrThrow(
1147
1151
  ctx,
@@ -1204,7 +1208,10 @@ export function addEnterpriseHttpRuntime(deps: EnterpriseHttpRuntimeDeps) {
1204
1208
  const url = new URL(request.url);
1205
1209
  const verifier = url.searchParams.get("code");
1206
1210
  if (!verifier) {
1207
- throw new AuthError("OAUTH_MISSING_VERIFIER").toConvexError();
1211
+ throw Cv.error({
1212
+ code: "OAUTH_MISSING_VERIFIER",
1213
+ message: "Missing sign-in verifier.",
1214
+ });
1208
1215
  }
1209
1216
  const { enterprise, oidc } = await loadEnterpriseOidcOrThrow(
1210
1217
  ctx,
@@ -1,3 +1,5 @@
1
+ import { Fx } from "@robelest/fx";
2
+ import { Cv } from "@robelest/fx/convex";
1
3
  import {
2
4
  GenericActionCtx,
3
5
  GenericDataModel,
@@ -7,10 +9,6 @@ import {
7
9
  import { ConvexError } from "convex/values";
8
10
  import { parse as parseCookies } from "cookie";
9
11
 
10
- import { isAuthError } from "./errors";
11
- import { Fx } from "@robelest/fx";
12
-
13
- import { AuthError } from "./authError";
14
12
  import type { CorsConfig, HttpKeyContext } from "./types";
15
13
  import { logError } from "./utils";
16
14
 
@@ -59,19 +57,21 @@ export function createHttpAction(auth: {
59
57
  const rawKey = authHeader.slice(7);
60
58
 
61
59
  const keyResult = await Fx.run(
62
- Fx.from({
63
- ok: () => auth.key.verify(genericCtx, rawKey),
64
- err: (error) => error,
65
- }).pipe(
66
- Fx.fold({
67
- ok: (result) => ({ ok: true, value: result }) as const,
68
- err: (error) => ({ ok: false, error }) as const,
69
- }),
60
+ Fx.attempt(
61
+ () => auth.key.verify(genericCtx, rawKey),
62
+ (result) => ({ ok: true, value: result }) as const,
63
+ (error) => ({ ok: false, error }) as const,
70
64
  ),
71
65
  );
72
66
 
73
67
  if (!keyResult.ok) {
74
- if (isAuthError(keyResult.error)) {
68
+ if (
69
+ keyResult.error instanceof ConvexError &&
70
+ typeof keyResult.error.data === "object" &&
71
+ keyResult.error.data !== null &&
72
+ "code" in keyResult.error.data &&
73
+ "message" in keyResult.error.data
74
+ ) {
75
75
  const { code, message } = keyResult.error.data as {
76
76
  code: string;
77
77
  message: string;
@@ -219,7 +219,13 @@ export function convertErrorsToResponse(
219
219
  err: (error) => error,
220
220
  }).pipe(
221
221
  Fx.recover((error) => {
222
- if (isAuthError(error)) {
222
+ if (
223
+ error instanceof ConvexError &&
224
+ typeof error.data === "object" &&
225
+ error.data !== null &&
226
+ "code" in error.data &&
227
+ "message" in error.data
228
+ ) {
223
229
  return Fx.succeed(
224
230
  new Response(
225
231
  JSON.stringify({
@@ -426,10 +432,10 @@ export function addSSORoutes(
426
432
  deps.routeBase,
427
433
  );
428
434
  if (!route) {
429
- throw new AuthError(
430
- "INVALID_PARAMETERS",
431
- "Invalid enterprise runtime path.",
432
- ).toConvexError();
435
+ throw Cv.error({
436
+ code: "INVALID_PARAMETERS",
437
+ message: "Invalid enterprise runtime path.",
438
+ });
433
439
  }
434
440
  if (route.protocol === "saml" && route.rest.length === 1) {
435
441
  if (route.rest[0] === "metadata") {
@@ -456,10 +462,10 @@ export function addSSORoutes(
456
462
  if (route.protocol === "scim" && route.rest[0] === "v2") {
457
463
  return await deps.handleScimRequest(ctx, request);
458
464
  }
459
- throw new AuthError(
460
- "INVALID_PARAMETERS",
461
- "Invalid enterprise runtime path.",
462
- ).toConvexError();
465
+ throw Cv.error({
466
+ code: "INVALID_PARAMETERS",
467
+ message: "Invalid enterprise runtime path.",
468
+ });
463
469
  }),
464
470
  ),
465
471
  });
@@ -484,10 +490,10 @@ export function addSSORoutes(
484
490
  if (route?.protocol === "scim" && route.rest[0] === "v2") {
485
491
  return await deps.handleScimRequest(ctx, request);
486
492
  }
487
- throw new AuthError(
488
- "INVALID_PARAMETERS",
489
- "Invalid enterprise runtime path.",
490
- ).toConvexError();
493
+ throw Cv.error({
494
+ code: "INVALID_PARAMETERS",
495
+ message: "Invalid enterprise runtime path.",
496
+ });
491
497
  }),
492
498
  ),
493
499
  });
@@ -504,10 +510,10 @@ export function addSSORoutes(
504
510
  if (route?.protocol === "scim" && route.rest[0] === "v2") {
505
511
  return await deps.handleScimRequest(ctx, request);
506
512
  }
507
- throw new AuthError(
508
- "INVALID_PARAMETERS",
509
- "Invalid enterprise runtime path.",
510
- ).toConvexError();
513
+ throw Cv.error({
514
+ code: "INVALID_PARAMETERS",
515
+ message: "Invalid enterprise runtime path.",
516
+ });
511
517
  }),
512
518
  ),
513
519
  });
@@ -1,4 +1,4 @@
1
- import { AuthError } from "./authError";
1
+ import { Cv } from "@robelest/fx/convex";
2
2
 
3
3
  /** @internal */
4
4
  export function userIdFromIdentitySubject(subject: string): string {
@@ -9,10 +9,10 @@ export function userIdFromIdentitySubject(subject: string): string {
9
9
  rest.length === 0 ||
10
10
  rest.some((segment) => segment.length === 0)
11
11
  ) {
12
- throw new AuthError(
13
- "INTERNAL_ERROR",
14
- "Authenticated identity subject is malformed.",
15
- );
12
+ throw Cv.error({
13
+ code: "INTERNAL_ERROR",
14
+ message: "Authenticated identity subject is malformed.",
15
+ });
16
16
  }
17
17
  return userId;
18
18
  }
@@ -2,7 +2,9 @@ export { AuthCtx, createAuth } from "./auth";
2
2
  export type {
3
3
  AuthApi,
4
4
  AuthApiBase,
5
+ AuthContext,
5
6
  AuthConfig,
7
+ AuthCtxConfig,
6
8
  ConvexAuthResult,
7
9
  InferAuth,
8
10
  InferClientApi,
@@ -1,10 +1,9 @@
1
1
  import { Fx } from "@robelest/fx";
2
+ import { ConvexError } from "convex/values";
2
3
 
3
4
  import { authDb } from "./db";
4
- import { AuthError } from "./authError";
5
5
  import { Doc, MutationCtx } from "./types";
6
6
  import { ConvexAuthConfig } from "./types";
7
- import { errorMessage } from "./utils";
8
7
 
9
8
  const DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR = 10;
10
9
 
@@ -16,7 +15,7 @@ export const isSignInRateLimited = (
16
15
  ctx: MutationCtx,
17
16
  identifier: string,
18
17
  config: ConvexAuthConfig,
19
- ): Fx<boolean, AuthError> =>
18
+ ): Fx<boolean, ConvexError<any>> =>
20
19
  getRateLimitState(ctx, identifier, config).pipe(
21
20
  Fx.map((state) => state !== null && state.attemptsLeft < 1),
22
21
  );
@@ -31,40 +30,28 @@ export const recordFailedSignIn = (
31
30
  ctx: MutationCtx,
32
31
  identifier: string,
33
32
  config: ConvexAuthConfig,
34
- ): Fx<void, AuthError> =>
35
- getRateLimitState(ctx, identifier, config).pipe(
36
- Fx.chain((state) =>
37
- state !== null
38
- ? Fx.from({
39
- ok: () =>
40
- authDb(ctx, config).rateLimits.patch(state.limit._id, {
41
- attemptsLeft: state.attemptsLeft - 1,
42
- lastAttemptTime: Date.now(),
43
- }),
44
- err: (e) =>
45
- new AuthError(
46
- "INTERNAL_ERROR",
47
- `Failed to patch rate limit: ${errorMessage(e)}`,
48
- ),
49
- })
50
- : Fx.from({
51
- ok: () =>
52
- authDb(ctx, config).rateLimits.create({
53
- identifier,
54
- attemptsLeft:
55
- (config.signIn?.maxFailedAttemptsPerHour ??
56
- DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR) - 1,
57
- lastAttemptTime: Date.now(),
58
- }),
59
- err: (e) =>
60
- new AuthError(
61
- "INTERNAL_ERROR",
62
- `Failed to create rate limit: ${errorMessage(e)}`,
63
- ),
64
- }),
65
- ),
66
- Fx.map(() => undefined),
67
- );
33
+ ): Fx<void, ConvexError<any>> =>
34
+ Fx.gen(function* () {
35
+ const state = yield* getRateLimitState(ctx, identifier, config);
36
+ if (state !== null) {
37
+ yield* Fx.promise(() =>
38
+ authDb(ctx, config).rateLimits.patch(state.limit._id, {
39
+ attemptsLeft: state.attemptsLeft - 1,
40
+ lastAttemptTime: Date.now(),
41
+ }),
42
+ );
43
+ } else {
44
+ yield* Fx.promise(() =>
45
+ authDb(ctx, config).rateLimits.create({
46
+ identifier,
47
+ attemptsLeft:
48
+ (config.signIn?.maxFailedAttemptsPerHour ??
49
+ DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR) - 1,
50
+ lastAttemptTime: Date.now(),
51
+ }),
52
+ );
53
+ }
54
+ });
68
55
 
69
56
  /**
70
57
  * Reset the rate limit for the given identifier (e.g. after successful sign-in).
@@ -74,21 +61,15 @@ export const resetSignInRateLimit = (
74
61
  ctx: MutationCtx,
75
62
  identifier: string,
76
63
  config: ConvexAuthConfig,
77
- ): Fx<void, AuthError> =>
78
- getRateLimitState(ctx, identifier, config).pipe(
79
- Fx.chain((state) =>
80
- state !== null
81
- ? Fx.from({
82
- ok: () => authDb(ctx, config).rateLimits.delete(state.limit._id),
83
- err: (e) =>
84
- new AuthError(
85
- "INTERNAL_ERROR",
86
- `Failed to delete rate limit: ${errorMessage(e)}`,
87
- ),
88
- })
89
- : Fx.unit,
90
- ),
91
- );
64
+ ): Fx<void, ConvexError<any>> =>
65
+ Fx.gen(function* () {
66
+ const state = yield* getRateLimitState(ctx, identifier, config);
67
+ if (state !== null) {
68
+ yield* Fx.promise(() =>
69
+ authDb(ctx, config).rateLimits.delete(state.limit._id),
70
+ );
71
+ }
72
+ });
92
73
 
93
74
  // ---------------------------------------------------------------------------
94
75
  // Internal
@@ -103,32 +84,24 @@ const getRateLimitState = (
103
84
  ctx: MutationCtx,
104
85
  identifier: string,
105
86
  config: ConvexAuthConfig,
106
- ): Fx<RateLimitState, AuthError> => {
107
- const now = Date.now();
108
- const maxAttemptsPerHour =
109
- config.signIn?.maxFailedAttemptsPerHour ??
110
- DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR;
87
+ ): Fx<RateLimitState, ConvexError<any>> =>
88
+ Fx.gen(function* () {
89
+ const now = Date.now();
90
+ const maxAttemptsPerHour =
91
+ config.signIn?.maxFailedAttemptsPerHour ??
92
+ DEFAULT_MAX_SIGN_IN_ATTEMPTS_PER_HOUR;
111
93
 
112
- return Fx.from({
113
- ok: () => authDb(ctx, config).rateLimits.get(identifier),
114
- err: (e) =>
115
- new AuthError(
116
- "INTERNAL_ERROR",
117
- `Failed to get rate limit: ${errorMessage(e)}`,
118
- ),
119
- }).pipe(
120
- Fx.map((raw) => {
121
- const limit = raw as
122
- | (Doc<"RateLimit"> & { attemptsLeft: number; lastAttemptTime: number })
123
- | null;
124
- if (limit === null) return null;
125
- const elapsed = now - limit.lastAttemptTime;
126
- const maxAttemptsPerMs = maxAttemptsPerHour / (60 * 60 * 1000);
127
- const attemptsLeft = Math.min(
128
- maxAttemptsPerHour,
129
- limit.attemptsLeft + elapsed * maxAttemptsPerMs,
130
- );
131
- return { limit, attemptsLeft };
132
- }),
133
- );
134
- };
94
+ const limit = (yield* Fx.promise(() =>
95
+ authDb(ctx, config).rateLimits.get(identifier),
96
+ )) as
97
+ | (Doc<"RateLimit"> & { attemptsLeft: number; lastAttemptTime: number })
98
+ | null;
99
+ if (limit === null) return null;
100
+ const elapsed = now - limit.lastAttemptTime;
101
+ const maxAttemptsPerMs = maxAttemptsPerHour / (60 * 60 * 1000);
102
+ const attemptsLeft = Math.min(
103
+ maxAttemptsPerHour,
104
+ limit.attemptsLeft + elapsed * maxAttemptsPerMs,
105
+ );
106
+ return { limit, attemptsLeft };
107
+ });