@robelest/convex-auth 0.0.4-preview.28 → 0.0.4-preview.29

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 (50) hide show
  1. package/dist/bin.js +4 -1
  2. package/dist/component/_generated/component.d.ts +344 -0
  3. package/dist/component/convex.config.d.ts +2 -2
  4. package/dist/component/model.d.ts +25 -25
  5. package/dist/component/model.js +1 -0
  6. package/dist/component/public/factors/totp.js +12 -0
  7. package/dist/component/public/groups/core.js +89 -1
  8. package/dist/component/public/groups/members.js +39 -1
  9. package/dist/component/public/identity/accounts.js +22 -3
  10. package/dist/component/public/identity/users.js +79 -5
  11. package/dist/component/public/sso/audit.js +5 -2
  12. package/dist/component/public/sso/core.js +3 -3
  13. package/dist/component/public/sso/domains.js +7 -3
  14. package/dist/component/public/sso/scim.js +36 -1
  15. package/dist/component/public.js +5 -5
  16. package/dist/component/schema.d.ts +293 -289
  17. package/dist/component/schema.js +2 -1
  18. package/dist/core/index.d.ts +63 -27
  19. package/dist/core/index.js +1 -0
  20. package/dist/providers/credentials.d.ts +12 -0
  21. package/dist/providers/password.js +28 -7
  22. package/dist/server/auth-context.d.ts +17 -0
  23. package/dist/server/auth-context.js +1 -1
  24. package/dist/server/auth.d.ts +18 -6
  25. package/dist/server/auth.js +1 -0
  26. package/dist/server/context.js +11 -5
  27. package/dist/server/contract.js +44 -12
  28. package/dist/server/core.js +146 -149
  29. package/dist/server/ctxCache.js +94 -0
  30. package/dist/server/limits.js +39 -9
  31. package/dist/server/mounts.d.ts +85 -85
  32. package/dist/server/mutations/credentialsSignIn.js +114 -0
  33. package/dist/server/mutations/index.js +2 -1
  34. package/dist/server/mutations/refresh.js +25 -12
  35. package/dist/server/mutations/retrieve.js +2 -1
  36. package/dist/server/mutations/signin.js +27 -9
  37. package/dist/server/mutations/store.js +5 -0
  38. package/dist/server/mutations/verify.js +32 -8
  39. package/dist/server/runtime.d.ts +81 -47
  40. package/dist/server/services/group.js +23 -16
  41. package/dist/server/sessions.d.ts +21 -0
  42. package/dist/server/sessions.js +37 -27
  43. package/dist/server/signin.js +32 -9
  44. package/dist/server/sso/domain.js +1 -2
  45. package/dist/server/sso/oidc.js +1 -1
  46. package/dist/server/tokens.js +19 -3
  47. package/dist/server/users.js +3 -2
  48. package/dist/server/utils/span.js +18 -0
  49. package/package.json +1 -1
  50. package/README.md +0 -161
@@ -0,0 +1,114 @@
1
+ import { LOG_LEVELS } from "../../shared/log.js";
2
+ import { verify } from "../crypto.js";
3
+ import { authDb } from "../db.js";
4
+ import { log, maybeRedact } from "../log.js";
5
+ import { AUTH_STORE_REF } from "./store/refs.js";
6
+ import { withSpan } from "../utils/span.js";
7
+ import { issueSession } from "../sessions.js";
8
+ import { getSignInRateLimitState, isStateRateLimited, recordFailedSignIn, resetSignInRateLimit } from "../limits.js";
9
+ import { v } from "convex/values";
10
+
11
+ //#region src/server/mutations/credentialsSignIn.ts
12
+ const credentialsSignInArgs = v.object({
13
+ provider: v.string(),
14
+ account: v.object({
15
+ id: v.string(),
16
+ secret: v.string()
17
+ }),
18
+ generateTokens: v.boolean(),
19
+ requireVerifiedEmail: v.boolean(),
20
+ enforceTotp: v.boolean()
21
+ });
22
+ async function credentialsSignInImpl(ctx, args, getProviderOrThrow, config) {
23
+ return withSpan("convex-auth.mutations.credentialsSignIn", {
24
+ provider: args.provider,
25
+ generateTokens: args.generateTokens
26
+ }, () => credentialsSignInInner(ctx, args, getProviderOrThrow, config));
27
+ }
28
+ async function credentialsSignInInner(ctx, args, getProviderOrThrow, config) {
29
+ const { provider: providerId, account, generateTokens, requireVerifiedEmail, enforceTotp } = args;
30
+ const db = authDb(ctx, config);
31
+ log(LOG_LEVELS.DEBUG, "credentialsSignInImpl args:", {
32
+ provider: providerId,
33
+ account: {
34
+ id: account.id,
35
+ secret: maybeRedact(account.secret)
36
+ },
37
+ generateTokens,
38
+ requireVerifiedEmail,
39
+ enforceTotp
40
+ });
41
+ const existingAccount = await db.accounts.get(providerId, account.id);
42
+ if (existingAccount === null) return { kind: "invalidAccount" };
43
+ const [user, rateLimitState] = await Promise.all([db.users.getById(existingAccount.userId), getSignInRateLimitState(ctx, existingAccount._id, config)]);
44
+ if (user === null) {
45
+ log(LOG_LEVELS.ERROR, `Account ${existingAccount._id} links to missing user ${existingAccount.userId}`);
46
+ return { kind: "invalidAccount" };
47
+ }
48
+ if (isStateRateLimited(rateLimitState)) return { kind: "tooManyAttempts" };
49
+ if (!await withSpan("convex-auth.credentials.verify", { providerId }, () => verify(getProviderOrThrow(providerId), account.secret, existingAccount.secret ?? ""))) {
50
+ await recordFailedSignIn(ctx, existingAccount._id, config, rateLimitState);
51
+ return { kind: "invalidSecret" };
52
+ }
53
+ if (requireVerifiedEmail && !existingAccount.emailVerified) {
54
+ await resetSignInRateLimit(ctx, existingAccount._id, config, rateLimitState);
55
+ return {
56
+ kind: "emailVerificationRequired",
57
+ account: {
58
+ _id: existingAccount._id,
59
+ emailVerified: existingAccount.emailVerified
60
+ },
61
+ user: {
62
+ _id: user._id,
63
+ email: user.email
64
+ }
65
+ };
66
+ }
67
+ let hasTotp = user.hasTotp;
68
+ if (enforceTotp && hasTotp === void 0) {
69
+ const memberResolveRef = config.component.public["totpGetVerifiedByUserId"];
70
+ hasTotp = await ctx.runQuery(memberResolveRef, { userId: existingAccount.userId }) !== null;
71
+ await db.users.patch(existingAccount.userId, { hasTotp });
72
+ }
73
+ const totpRequired = enforceTotp && hasTotp === true;
74
+ const [issuance] = await Promise.all([issueSession(ctx, config, {
75
+ userId: existingAccount.userId,
76
+ generateTokens: generateTokens && !totpRequired
77
+ }), resetSignInRateLimit(ctx, existingAccount._id, config, rateLimitState)]);
78
+ if (totpRequired) return {
79
+ kind: "totpRequired",
80
+ issuance,
81
+ account: {
82
+ _id: existingAccount._id,
83
+ emailVerified: existingAccount.emailVerified
84
+ },
85
+ user: {
86
+ _id: user._id,
87
+ email: user.email
88
+ }
89
+ };
90
+ return {
91
+ kind: "signedIn",
92
+ issuance,
93
+ account: {
94
+ _id: existingAccount._id,
95
+ emailVerified: existingAccount.emailVerified
96
+ },
97
+ user: {
98
+ _id: user._id,
99
+ email: user.email,
100
+ hasTotp
101
+ }
102
+ };
103
+ }
104
+ /** @internal */
105
+ const callCredentialsSignIn = async (ctx, args) => {
106
+ return await ctx.runMutation(AUTH_STORE_REF, { args: {
107
+ type: "credentialsSignIn",
108
+ ...args
109
+ } });
110
+ };
111
+
112
+ //#endregion
113
+ export { callCredentialsSignIn, credentialsSignInArgs, credentialsSignInImpl };
114
+ //# sourceMappingURL=credentialsSignIn.js.map
@@ -1,5 +1,6 @@
1
1
  import { callModifyAccount } from "./account.js";
2
2
  import { callCreateVerificationCode } from "./code.js";
3
+ import { callCredentialsSignIn } from "./credentialsSignIn.js";
3
4
  import { callInvalidateSessions } from "./invalidate.js";
4
5
  import { callUserOAuth } from "./oauth.js";
5
6
  import { callRefreshSession } from "./refresh.js";
@@ -12,4 +13,4 @@ import { callVerifier } from "./verifier.js";
12
13
  import { callVerifyCodeAndSignIn } from "./verify.js";
13
14
  import { storeArgs, storeImpl } from "./store.js";
14
15
 
15
- export { callCreateAccountFromCredentials, callCreateVerificationCode, callInvalidateSessions, callModifyAccount, callRefreshSession, callRetrieveAccountWithCredentials, callSignIn, callSignOut, callUserOAuth, callVerifier, callVerifierSignature, callVerifyCodeAndSignIn, storeArgs, storeImpl };
16
+ export { callCreateAccountFromCredentials, callCreateVerificationCode, callCredentialsSignIn, callInvalidateSessions, callModifyAccount, callRefreshSession, callRetrieveAccountWithCredentials, callSignIn, callSignOut, callUserOAuth, callVerifier, callVerifierSignature, callVerifyCodeAndSignIn, storeArgs, storeImpl };
@@ -1,13 +1,21 @@
1
1
  import { authDb } from "../db.js";
2
2
  import { log, maybeRedact } from "../log.js";
3
3
  import { AUTH_STORE_REF } from "./store/refs.js";
4
- import { REFRESH_TOKEN_REUSE_WINDOW_MS, parseRefreshToken, refreshTokenExpirationTime } from "../refresh.js";
5
- import { generateTokensForSession } from "../sessions.js";
4
+ import { REFRESH_TOKEN_DIVIDER, REFRESH_TOKEN_REUSE_WINDOW_MS, parseRefreshToken, refreshTokenExpirationTime } from "../refresh.js";
6
5
  import { withSpan } from "../utils/span.js";
6
+ import { finalizeSessionIssuance } from "../sessions.js";
7
7
  import { v } from "convex/values";
8
8
 
9
9
  //#region src/server/mutations/refresh.ts
10
10
  const refreshSessionArgs = v.object({ refreshToken: v.string() });
11
+ /**
12
+ * Exchange a refresh token and mint the next pair of session IDs + refresh
13
+ * token string. The RSA-2048 JWT signing used to live here; it has been
14
+ * moved to the action wrapper ({@link callRefreshSession}) so the mutation
15
+ * can commit without paying 5–30ms of CPU per refresh.
16
+ *
17
+ * @internal
18
+ */
11
19
  async function refreshSessionImpl(ctx, args, config) {
12
20
  const db = authDb(ctx, config);
13
21
  return withSpan("convex-auth.refresh.session", { hasRefreshToken: true }, async () => {
@@ -33,15 +41,11 @@ async function refreshSessionImpl(ctx, args, config) {
33
41
  throw new RefreshFailure("Failed to exchange refresh token");
34
42
  }
35
43
  if (exchanged === null) return null;
36
- try {
37
- return await generateTokensForSession(config, {
38
- userId: exchanged.userId,
39
- sessionId: exchanged.sessionId,
40
- refreshTokenId: exchanged.refreshTokenId
41
- });
42
- } catch {
43
- throw new RefreshFailure("Failed to generate refresh-session tokens");
44
- }
44
+ return {
45
+ userId: exchanged.userId,
46
+ sessionId: exchanged.sessionId,
47
+ refreshToken: `${exchanged.refreshTokenId}${REFRESH_TOKEN_DIVIDER}${exchanged.sessionId}`
48
+ };
45
49
  } catch (e) {
46
50
  if (e instanceof RefreshFailure) {
47
51
  log("DEBUG", e.reason);
@@ -57,11 +61,20 @@ var RefreshFailure = class extends Error {
57
61
  this.reason = reason;
58
62
  }
59
63
  };
64
+ /**
65
+ * Action-side wrapper: exchange the refresh token via the mutation, then
66
+ * sign the next JWT outside the mutation transaction. See
67
+ * {@link refreshSessionImpl} for the rationale.
68
+ *
69
+ * @internal
70
+ */
60
71
  const callRefreshSession = async (ctx, args) => {
61
- return ctx.runMutation(AUTH_STORE_REF, { args: {
72
+ const issuance = await ctx.runMutation(AUTH_STORE_REF, { args: {
62
73
  type: "refreshSession",
63
74
  ...args
64
75
  } });
76
+ if (issuance === null || issuance.refreshToken === null) return null;
77
+ return (await finalizeSessionIssuance(ctx.auth.config, issuance)).tokens;
65
78
  };
66
79
 
67
80
  //#endregion
@@ -3,6 +3,7 @@ import { verify } from "../crypto.js";
3
3
  import { authDb } from "../db.js";
4
4
  import { log, maybeRedact } from "../log.js";
5
5
  import { AUTH_STORE_REF } from "./store/refs.js";
6
+ import { withSpan } from "../utils/span.js";
6
7
  import { isSignInRateLimited, recordFailedSignIn, resetSignInRateLimit } from "../limits.js";
7
8
  import { v } from "convex/values";
8
9
 
@@ -30,7 +31,7 @@ async function retrieveAccountWithCredentialsImpl(ctx, args, getProviderOrThrow,
30
31
  if (account.secret !== void 0) {
31
32
  const accountSecret = account.secret;
32
33
  if (await isSignInRateLimited(ctx, existingAccount._id, config)) return "TooManyFailedAttempts";
33
- if (!await verify(getProviderOrThrow(providerId), accountSecret, existingAccount.secret ?? "")) {
34
+ if (!await withSpan("convex-auth.credentials.verify", { providerId }, () => verify(getProviderOrThrow(providerId), accountSecret, existingAccount.secret ?? ""))) {
34
35
  await recordFailedSignIn(ctx, existingAccount._id, config);
35
36
  return "InvalidSecret";
36
37
  }
@@ -1,7 +1,8 @@
1
1
  import { LOG_LEVELS } from "../../shared/log.js";
2
2
  import { log } from "../log.js";
3
3
  import { AUTH_STORE_REF } from "./store/refs.js";
4
- import { getAuthSessionId, issueSession } from "../sessions.js";
4
+ import { withSpan } from "../utils/span.js";
5
+ import { finalizeSessionIssuance, getAuthSessionId, issueSession } from "../sessions.js";
5
6
  import { v } from "convex/values";
6
7
 
7
8
  //#region src/server/mutations/signin.ts
@@ -11,20 +12,37 @@ const signInArgs = v.object({
11
12
  generateTokens: v.boolean()
12
13
  });
13
14
  async function signInImpl(ctx, args, config) {
14
- log(LOG_LEVELS.DEBUG, "signInImpl args:", args);
15
- const { userId, sessionId: existingSessionId, generateTokens } = args;
16
- return await issueSession(ctx, config, {
17
- userId,
18
- existingSessionId,
19
- replaceSessionId: existingSessionId === void 0 ? await getAuthSessionId(ctx) ?? void 0 : void 0,
20
- generateTokens
15
+ return withSpan("convex-auth.mutations.signIn", {
16
+ hasExistingSession: args.sessionId !== void 0,
17
+ generateTokens: args.generateTokens
18
+ }, async () => {
19
+ log(LOG_LEVELS.DEBUG, "signInImpl args:", args);
20
+ const { userId, sessionId: existingSessionId, generateTokens } = args;
21
+ return await issueSession(ctx, config, {
22
+ userId,
23
+ existingSessionId,
24
+ replaceSessionId: existingSessionId === void 0 ? await getAuthSessionId(ctx) ?? void 0 : void 0,
25
+ generateTokens
26
+ });
21
27
  });
22
28
  }
29
+ /**
30
+ * Run the sign-in mutation, then sign the JWT on the action side.
31
+ *
32
+ * Splitting the work like this keeps the 5–30ms of RSA-2048 CPU out of the
33
+ * mutation transaction so the mutation can commit quickly even on a cold
34
+ * worker. The refresh-token string itself is cheap to compute and stays
35
+ * inside the mutation (returned on the {@link SessionIssuance}); only the
36
+ * JWT signing moves here.
37
+ *
38
+ * @internal
39
+ */
23
40
  const callSignIn = async (ctx, args) => {
24
- return ctx.runMutation(AUTH_STORE_REF, { args: {
41
+ const issuance = await ctx.runMutation(AUTH_STORE_REF, { args: {
25
42
  type: "signIn",
26
43
  ...args
27
44
  } });
45
+ return await finalizeSessionIssuance(ctx.auth.config, issuance);
28
46
  };
29
47
 
30
48
  //#endregion
@@ -2,6 +2,7 @@ import { LOG_LEVELS } from "../../shared/log.js";
2
2
  import { log } from "../log.js";
3
3
  import { modifyAccountArgs, modifyAccountImpl } from "./account.js";
4
4
  import { createVerificationCodeArgs, createVerificationCodeImpl } from "./code.js";
5
+ import { credentialsSignInArgs, credentialsSignInImpl } from "./credentialsSignIn.js";
5
6
  import { invalidateSessionsArgs, invalidateSessionsImpl } from "./invalidate.js";
6
7
  import { userOAuthArgs, userOAuthImpl } from "./oauth.js";
7
8
  import { refreshSessionArgs } from "./refresh.js";
@@ -42,6 +43,9 @@ const storeArgs = v.object({ args: v.union(v.object({
42
43
  }), v.object({
43
44
  type: v.literal("retrieveAccountWithCredentials"),
44
45
  ...retrieveAccountWithCredentialsArgs.fields
46
+ }), v.object({
47
+ type: v.literal("credentialsSignIn"),
48
+ ...credentialsSignInArgs.fields
45
49
  }), v.object({
46
50
  type: v.literal("modifyAccount"),
47
51
  ...modifyAccountArgs.fields
@@ -65,6 +69,7 @@ const storeImpl = async (ctx, fnArgs, services) => {
65
69
  createVerificationCode: (a) => createVerificationCodeImpl(ctx, a, getProviderOrThrow, config),
66
70
  createAccountFromCredentials: (a) => createAccountFromCredentialsImpl(ctx, a, getProviderOrThrow, config),
67
71
  retrieveAccountWithCredentials: (a) => retrieveAccountWithCredentialsImpl(ctx, a, getProviderOrThrow, config),
72
+ credentialsSignIn: (a) => credentialsSignInImpl(ctx, a, getProviderOrThrow, config),
68
73
  modifyAccount: (a) => modifyAccountImpl(ctx, a, getProviderOrThrow, config),
69
74
  invalidateSessions: (a) => invalidateSessionsImpl(ctx, a, config)
70
75
  }[args.type];
@@ -4,12 +4,13 @@ import { authDb } from "../db.js";
4
4
  import { requireEnv } from "../env.js";
5
5
  import { log } from "../log.js";
6
6
  import { AUTH_STORE_REF } from "./store/refs.js";
7
- import { getAuthSessionId, issueSession } from "../sessions.js";
7
+ import { withSpan } from "../utils/span.js";
8
+ import { finalizeSessionIssuance, getAuthSessionId, issueSession } from "../sessions.js";
8
9
  import { upsertUserAndAccount } from "../users.js";
10
+ import { getSignInRateLimitState, isStateRateLimited, recordFailedSignIn, resetSignInRateLimit } from "../limits.js";
9
11
  import { payloadRecordValidator } from "../payloads.js";
10
12
  import { isGroupProviderId } from "../sso/shared.js";
11
13
  import { createSyntheticOAuthMaterializedConfig } from "../sso/oidc.js";
12
- import { isSignInRateLimited, recordFailedSignIn, resetSignInRateLimit } from "../limits.js";
13
14
  import { v } from "convex/values";
14
15
 
15
16
  //#region src/server/mutations/verify.ts
@@ -21,9 +22,17 @@ const verifyCodeAndSignInArgs = v.object({
21
22
  allowExtraProviders: v.boolean()
22
23
  });
23
24
  async function verifyCodeAndSignInImpl(ctx, args, getProviderOrThrow, config) {
25
+ return withSpan("convex-auth.mutations.verifyCodeAndSignIn", {
26
+ provider: args.provider ?? "",
27
+ generateTokens: args.generateTokens
28
+ }, () => verifyCodeAndSignInImplInner(ctx, args, getProviderOrThrow, config));
29
+ }
30
+ async function verifyCodeAndSignInImplInner(ctx, args, getProviderOrThrow, config) {
24
31
  const params = args.params;
25
32
  const { generateTokens, provider, allowExtraProviders } = args;
26
33
  const identifier = typeof params.email === "string" ? params.email : typeof params.phone === "string" ? params.phone : void 0;
34
+ let rateLimitState = null;
35
+ let rateLimitLoaded = false;
27
36
  try {
28
37
  log(LOG_LEVELS.DEBUG, "verifyCodeAndSignInImpl args:", {
29
38
  params: {
@@ -41,7 +50,9 @@ async function verifyCodeAndSignInImpl(ctx, args, getProviderOrThrow, config) {
41
50
  requireEnv("CONVEX_SITE_URL");
42
51
  }
43
52
  if (identifier !== void 0) {
44
- if (await isSignInRateLimited(ctx, identifier, config)) throw new VerifyFailure("Too many failed attempts to verify code for this email");
53
+ rateLimitState = await getSignInRateLimitState(ctx, identifier, config);
54
+ rateLimitLoaded = true;
55
+ if (isStateRateLimited(rateLimitState)) throw new VerifyFailure("Too many failed attempts to verify code for this email");
45
56
  }
46
57
  const db = authDb(ctx, config);
47
58
  const verifier = args.verifier;
@@ -50,7 +61,6 @@ async function verifyCodeAndSignInImpl(ctx, args, getProviderOrThrow, config) {
50
61
  const hash = await sha256(codeValue);
51
62
  const code = await db.verificationCodes.getByCode(hash);
52
63
  if (code === null) throw new VerifyFailure("Invalid verification code");
53
- await db.verificationCodes.delete(code._id);
54
64
  if (code.verifier !== verifier) throw new VerifyFailure("Invalid verifier");
55
65
  if (code.expirationTime < Date.now()) throw new VerifyFailure("Expired verification code");
56
66
  if (provider !== void 0 && code.provider !== provider) throw new VerifyFailure(`Invalid provider "${provider}" for given \`code\``);
@@ -73,16 +83,20 @@ async function verifyCodeAndSignInImpl(ctx, args, getProviderOrThrow, config) {
73
83
  } : {}
74
84
  }
75
85
  }, config)).userId;
76
- if (identifier !== void 0) await resetSignInRateLimit(ctx, identifier, config);
86
+ const [, , replaceSessionId] = await Promise.all([
87
+ db.verificationCodes.delete(code._id),
88
+ identifier !== void 0 ? resetSignInRateLimit(ctx, identifier, config, rateLimitState) : Promise.resolve(),
89
+ getAuthSessionId(ctx)
90
+ ]);
77
91
  return await issueSession(ctx, config, {
78
92
  userId,
79
- replaceSessionId: await getAuthSessionId(ctx) ?? void 0,
93
+ replaceSessionId: replaceSessionId ?? void 0,
80
94
  generateTokens
81
95
  });
82
96
  } catch (error) {
83
97
  if (error instanceof VerifyFailure) {
84
98
  log(LOG_LEVELS.ERROR, error.reason);
85
- if (identifier !== void 0) await recordFailedSignIn(ctx, identifier, config);
99
+ if (identifier !== void 0) await recordFailedSignIn(ctx, identifier, config, rateLimitLoaded ? rateLimitState : void 0);
86
100
  return null;
87
101
  }
88
102
  throw error;
@@ -98,11 +112,21 @@ var VerifyFailure = class extends Error {
98
112
  this.name = "VerifyFailure";
99
113
  }
100
114
  };
115
+ /**
116
+ * Run the verify-code-and-sign-in mutation, then sign the JWT on the action
117
+ * side. See {@link callSignIn} for the rationale — the mutation returns
118
+ * `SessionIssuance` (cheap string-encoded refresh token + IDs), and this
119
+ * wrapper does the RSA-2048 work outside the mutation transaction.
120
+ *
121
+ * @internal
122
+ */
101
123
  const callVerifyCodeAndSignIn = async (ctx, args) => {
102
- return ctx.runMutation(AUTH_STORE_REF, { args: {
124
+ const issuance = await ctx.runMutation(AUTH_STORE_REF, { args: {
103
125
  type: "verifyCodeAndSignIn",
104
126
  ...args
105
127
  } });
128
+ if (issuance === null) return null;
129
+ return await finalizeSessionIssuance(ctx.auth.config, issuance);
106
130
  };
107
131
 
108
132
  //#endregion
@@ -1,10 +1,10 @@
1
1
  import { ComponentCtx, ComponentReadCtx } from "./componentContext.js";
2
- import { AuthProviderConfig, ConvexAuthConfig, CorsConfig, HttpKeyContext, KeyDoc, KeyScope, ScopeChecker, UserOrderBy, UserWhere } from "./types.js";
2
+ import { AuthProviderConfig, ConvexAuthConfig, CorsConfig, Doc, HttpKeyContext, KeyDoc, KeyScope, ScopeChecker, UserOrderBy, UserWhere } from "./types.js";
3
3
  import { AuthProfile, SignInParams } from "./payloads.js";
4
4
  import { HttpAuthContext, HttpAuthContextConfig, OptionalHttpAuthContext } from "./http.js";
5
5
  import { createGroupConnectionDomain } from "./sso/domain.js";
6
- import * as convex_values1133 from "convex/values";
7
- import * as convex_server106 from "convex/server";
6
+ import * as convex_values1137 from "convex/values";
7
+ import * as convex_server108 from "convex/server";
8
8
  import { GenericActionCtx, GenericDataModel, HttpRouter } from "convex/server";
9
9
 
10
10
  //#region src/server/runtime.d.ts
@@ -32,7 +32,10 @@ declare function Auth(config_: ConvexAuthConfig): {
32
32
  */
33
33
  auth: {
34
34
  user: {
35
- get: (ctx: ComponentReadCtx, userId: string) => Promise<any>;
35
+ get: {
36
+ (ctx: ComponentReadCtx, userId: string): Promise<Doc<"User"> | null>;
37
+ (ctx: ComponentReadCtx, userIds: readonly string[]): Promise<Array<Doc<"User"> | null>>;
38
+ };
36
39
  list: (ctx: ComponentReadCtx, opts?: {
37
40
  where?: UserWhere;
38
41
  limit?: number;
@@ -41,8 +44,8 @@ declare function Auth(config_: ConvexAuthConfig): {
41
44
  order?: "asc" | "desc";
42
45
  }) => Promise<any>;
43
46
  viewer: (ctx: ComponentReadCtx & {
44
- auth: convex_server106.Auth;
45
- }) => Promise<any>;
47
+ auth: convex_server108.Auth;
48
+ }) => Promise<Doc<"User"> | null>;
46
49
  update: (ctx: ComponentCtx, userId: string, data: Record<string, unknown>) => Promise<{
47
50
  userId: string;
48
51
  }>;
@@ -67,14 +70,17 @@ declare function Auth(config_: ConvexAuthConfig): {
67
70
  };
68
71
  session: {
69
72
  current: (ctx: {
70
- auth: convex_server106.Auth;
71
- }) => Promise<convex_values1133.GenericId<"Session"> | null>;
73
+ auth: convex_server108.Auth;
74
+ }) => Promise<convex_values1137.GenericId<"Session"> | null>;
75
+ userId: (ctx: {
76
+ auth: convex_server108.Auth;
77
+ }) => Promise<convex_values1137.GenericId<"User"> | null>;
72
78
  invalidate: <DataModel extends GenericDataModel>(ctx: GenericActionCtx<DataModel>, args: {
73
- userId: convex_values1133.GenericId<"User">;
74
- except?: convex_values1133.GenericId<"Session">[];
79
+ userId: convex_values1137.GenericId<"User">;
80
+ except?: convex_values1137.GenericId<"Session">[];
75
81
  }) => Promise<{
76
- userId: convex_values1133.GenericId<"User">;
77
- except: convex_values1133.GenericId<"Session">[];
82
+ userId: convex_values1137.GenericId<"User">;
83
+ except: convex_values1137.GenericId<"Session">[];
78
84
  }>;
79
85
  get: (ctx: ComponentReadCtx, sessionId: string) => Promise<any>;
80
86
  list: (ctx: ComponentReadCtx, opts: {
@@ -143,7 +149,7 @@ declare function Auth(config_: ConvexAuthConfig): {
143
149
  };
144
150
  provider: {
145
151
  signIn: (<DataModel extends GenericDataModel>(ctx: GenericActionCtx<DataModel>, providerConfig: AuthProviderConfig, args: {
146
- accountId?: convex_values1133.GenericId<"Account">;
152
+ accountId?: convex_values1137.GenericId<"Account">;
147
153
  params?: SignInParams;
148
154
  }) => Promise<{
149
155
  userId: string;
@@ -164,7 +170,10 @@ declare function Auth(config_: ConvexAuthConfig): {
164
170
  }) => Promise<{
165
171
  groupId: string;
166
172
  }>;
167
- get: (ctx: ComponentReadCtx, groupId: string) => Promise<any>;
173
+ get: {
174
+ (ctx: ComponentReadCtx, groupId: string): Promise<Doc<"Group"> | null>;
175
+ (ctx: ComponentReadCtx, groupIds: readonly string[]): Promise<Array<Doc<"Group"> | null>>;
176
+ };
168
177
  list: (ctx: ComponentReadCtx, opts?: {
169
178
  where?: {
170
179
  slug?: string;
@@ -197,7 +206,7 @@ declare function Auth(config_: ConvexAuthConfig): {
197
206
  maxDepth?: number;
198
207
  includeSelf?: boolean;
199
208
  }) => Promise<{
200
- ancestors: Record<string, unknown>[];
209
+ ancestors: Array<Exclude<Doc<"Group"> | null, null>>;
201
210
  cycleDetected: boolean;
202
211
  maxDepthReached: boolean;
203
212
  }>;
@@ -231,29 +240,44 @@ declare function Auth(config_: ConvexAuthConfig): {
231
240
  update: (ctx: ComponentCtx, memberId: string, data: Record<string, unknown>) => Promise<{
232
241
  memberId: string;
233
242
  }>;
234
- inspect: (ctx: ComponentReadCtx, opts: {
235
- userId: string;
236
- groupId: string;
237
- ancestry?: boolean;
238
- maxDepth?: number;
239
- }) => Promise<{
240
- membership: null;
241
- roleIds: string[];
242
- grants: string[];
243
- } | {
244
- membership: {
245
- _id: string;
246
- _creationTime: number;
243
+ inspect: {
244
+ (ctx: ComponentReadCtx, opts: {
245
+ userId: string;
247
246
  groupId: string;
247
+ ancestry?: boolean;
248
+ maxDepth?: number;
249
+ }): Promise<{
250
+ membership: {
251
+ _id: string;
252
+ _creationTime: number;
253
+ groupId: string;
254
+ userId: string;
255
+ role?: string;
256
+ roleIds?: string[];
257
+ status?: string;
258
+ extend?: Record<string, unknown>;
259
+ } | null;
260
+ roleIds: string[];
261
+ grants: string[];
262
+ }>;
263
+ (ctx: ComponentReadCtx, opts: {
248
264
  userId: string;
249
- role?: string;
250
- roleIds?: string[];
251
- status?: string;
252
- extend?: Record<string, unknown>;
253
- };
254
- roleIds: string[];
255
- grants: string[];
256
- }>;
265
+ groupIds: readonly string[];
266
+ }): Promise<Array<{
267
+ membership: {
268
+ _id: string;
269
+ _creationTime: number;
270
+ groupId: string;
271
+ userId: string;
272
+ role?: string;
273
+ roleIds?: string[];
274
+ status?: string;
275
+ extend?: Record<string, unknown>;
276
+ } | null;
277
+ roleIds: string[];
278
+ grants: string[];
279
+ }>>;
280
+ };
257
281
  require: (ctx: ComponentReadCtx, opts: {
258
282
  userId: string;
259
283
  groupId: string;
@@ -271,7 +295,7 @@ declare function Auth(config_: ConvexAuthConfig): {
271
295
  roleIds?: string[];
272
296
  status?: string;
273
297
  extend?: Record<string, unknown>;
274
- };
298
+ } | null;
275
299
  roleIds: string[];
276
300
  grants: string[];
277
301
  }>;
@@ -433,22 +457,22 @@ declare function Auth(config_: ConvexAuthConfig): {
433
457
  context: {
434
458
  <TResolve extends Record<string, unknown> = Record<string, never>, TCtx extends {
435
459
  auth: {
436
- getUserIdentity: () => Promise<convex_server106.UserIdentity | null>;
460
+ getUserIdentity: () => Promise<convex_server108.UserIdentity | null>;
437
461
  };
438
462
  } & ComponentReadCtx = {
439
463
  auth: {
440
- getUserIdentity: () => Promise<convex_server106.UserIdentity | null>;
464
+ getUserIdentity: () => Promise<convex_server108.UserIdentity | null>;
441
465
  };
442
466
  } & ComponentReadCtx>(ctx: TCtx, request: Request, config: HttpAuthContextConfig<TResolve, TCtx> & {
443
467
  optional: true;
444
468
  }): Promise<OptionalHttpAuthContext & TResolve>;
445
469
  <TResolve extends Record<string, unknown> = Record<string, never>, TCtx extends {
446
470
  auth: {
447
- getUserIdentity: () => Promise<convex_server106.UserIdentity | null>;
471
+ getUserIdentity: () => Promise<convex_server108.UserIdentity | null>;
448
472
  };
449
473
  } & ComponentReadCtx = {
450
474
  auth: {
451
- getUserIdentity: () => Promise<convex_server106.UserIdentity | null>;
475
+ getUserIdentity: () => Promise<convex_server108.UserIdentity | null>;
452
476
  };
453
477
  } & ComponentReadCtx>(ctx: TCtx, request: Request, config?: HttpAuthContextConfig<TResolve, TCtx>): Promise<HttpAuthContext & TResolve>;
454
478
  };
@@ -482,7 +506,7 @@ declare function Auth(config_: ConvexAuthConfig): {
482
506
  action: string;
483
507
  };
484
508
  cors?: CorsConfig;
485
- }) => convex_server106.PublicHttpAction;
509
+ }) => convex_server108.PublicHttpAction;
486
510
  /**
487
511
  * Register a Bearer-authenticated route **and** its OPTIONS preflight
488
512
  * in a single call.
@@ -528,7 +552,7 @@ declare function Auth(config_: ConvexAuthConfig): {
528
552
  *
529
553
  * Also used for refreshing the session.
530
554
  */
531
- signIn: convex_server106.RegisteredAction<"public", {
555
+ signIn: convex_server108.RegisteredAction<"public", {
532
556
  provider?: string | undefined;
533
557
  verifier?: string | undefined;
534
558
  params?: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null> | undefined;
@@ -538,12 +562,12 @@ declare function Auth(config_: ConvexAuthConfig): {
538
562
  /**
539
563
  * Action called by the client to invalidate the current session.
540
564
  */
541
- signOut: convex_server106.RegisteredAction<"public", {}, Promise<void>>;
565
+ signOut: convex_server108.RegisteredAction<"public", {}, Promise<void>>;
542
566
  /**
543
567
  * Internal mutation used by the library to read and write
544
568
  * to the database during signin and signout.
545
569
  */
546
- store: convex_server106.RegisteredMutation<"internal", {
570
+ store: convex_server108.RegisteredMutation<"internal", {
547
571
  args: {
548
572
  sessionId?: string | undefined;
549
573
  type: "signIn";
@@ -586,11 +610,11 @@ declare function Auth(config_: ConvexAuthConfig): {
586
610
  sessionIndex?: string | undefined;
587
611
  } | undefined;
588
612
  } | undefined;
589
- profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
590
613
  type: "userOAuth";
591
614
  provider: string;
592
615
  providerAccountId: string;
593
616
  signature: string;
617
+ profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
594
618
  } | {
595
619
  email?: string | undefined;
596
620
  phone?: string | undefined;
@@ -603,9 +627,9 @@ declare function Auth(config_: ConvexAuthConfig): {
603
627
  } | {
604
628
  shouldLinkViaEmail?: boolean | undefined;
605
629
  shouldLinkViaPhone?: boolean | undefined;
606
- profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
607
630
  type: "createAccountFromCredentials";
608
631
  provider: string;
632
+ profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
609
633
  account: {
610
634
  secret?: string | undefined;
611
635
  id: string;
@@ -617,6 +641,16 @@ declare function Auth(config_: ConvexAuthConfig): {
617
641
  secret?: string | undefined;
618
642
  id: string;
619
643
  };
644
+ } | {
645
+ type: "credentialsSignIn";
646
+ provider: string;
647
+ generateTokens: boolean;
648
+ account: {
649
+ id: string;
650
+ secret: string;
651
+ };
652
+ requireVerifiedEmail: boolean;
653
+ enforceTotp: boolean;
620
654
  } | {
621
655
  type: "modifyAccount";
622
656
  provider: string;