@robelest/convex-auth 0.0.4-preview.32 → 0.0.4-preview.34

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 (89) hide show
  1. package/dist/component/_generated/component.d.ts +1611 -2039
  2. package/dist/component/account.js +3 -0
  3. package/dist/component/convex.config.d.ts +2 -2
  4. package/dist/component/factor/device.js +3 -0
  5. package/dist/component/factor/passkey.js +3 -0
  6. package/dist/component/factor/totp.js +3 -0
  7. package/dist/component/group/invite.js +3 -0
  8. package/dist/component/group/member.js +3 -0
  9. package/dist/component/group.js +3 -0
  10. package/dist/component/model.d.ts +342 -30
  11. package/dist/component/model.js +22 -4
  12. package/dist/component/modules.js +24 -21
  13. package/dist/component/public/factors/devices.js +37 -106
  14. package/dist/component/public/factors/passkeys.js +29 -149
  15. package/dist/component/public/factors/totp.js +32 -159
  16. package/dist/component/public/groups/core.js +19 -82
  17. package/dist/component/public/groups/invites.js +15 -104
  18. package/dist/component/public/groups/members.js +26 -149
  19. package/dist/component/public/identity/accounts.js +12 -94
  20. package/dist/component/public/identity/codes.js +13 -73
  21. package/dist/component/public/identity/sessions.js +5 -107
  22. package/dist/component/public/identity/tokens.js +13 -103
  23. package/dist/component/public/identity/users.js +188 -185
  24. package/dist/component/public/identity/verifiers.js +17 -80
  25. package/dist/component/public/security/keys.js +13 -120
  26. package/dist/component/public/security/limits.js +0 -43
  27. package/dist/component/public/sso/audit.js +0 -28
  28. package/dist/component/public/sso/core.js +31 -104
  29. package/dist/component/public/sso/domains.js +0 -71
  30. package/dist/component/public/sso/scim.js +63 -239
  31. package/dist/component/public/sso/secrets.js +0 -30
  32. package/dist/component/public/sso/webhooks.js +23 -128
  33. package/dist/component/rateLimit.js +3 -0
  34. package/dist/component/schema.d.ts +378 -342
  35. package/dist/component/schema.js +11 -1
  36. package/dist/component/session.js +3 -0
  37. package/dist/component/sso/audit.js +3 -0
  38. package/dist/component/sso/connection/domain/verification.js +3 -0
  39. package/dist/component/sso/connection/domain.js +3 -0
  40. package/dist/component/sso/connection/scim/config.js +3 -0
  41. package/dist/component/sso/connection/scim/identity.js +3 -0
  42. package/dist/component/sso/connection/secret.js +3 -0
  43. package/dist/component/sso/connection.js +3 -0
  44. package/dist/component/sso/webhook/delivery.js +3 -0
  45. package/dist/component/sso/webhook/endpoint.js +3 -0
  46. package/dist/component/token/pkce.js +3 -0
  47. package/dist/component/token/refresh.js +3 -0
  48. package/dist/component/token/verification.js +3 -0
  49. package/dist/component/user/email.js +3 -0
  50. package/dist/component/user/key.js +3 -0
  51. package/dist/component/user.js +62 -0
  52. package/dist/core/index.d.ts +131 -28
  53. package/dist/core/index.js +2 -0
  54. package/dist/model.js +391 -0
  55. package/dist/providers/credentials.d.ts +1 -1
  56. package/dist/providers/github.js +6 -0
  57. package/dist/providers/password.js +1 -2
  58. package/dist/server/auth.d.ts +73 -7
  59. package/dist/server/auth.js +4 -1
  60. package/dist/server/context.js +30 -3
  61. package/dist/server/contract.js +42 -42
  62. package/dist/server/core.js +224 -86
  63. package/dist/server/db.js +45 -37
  64. package/dist/server/facade.d.ts +39 -0
  65. package/dist/server/facade.js +16 -0
  66. package/dist/server/index.d.ts +5 -3
  67. package/dist/server/index.js +3 -1
  68. package/dist/server/mounts.d.ts +101 -101
  69. package/dist/server/mutations/credentials/signin.js +3 -7
  70. package/dist/server/mutations/oauth.js +9 -6
  71. package/dist/server/runtime.d.ts +147 -46
  72. package/dist/server/runtime.js +10 -8
  73. package/dist/server/services/group.js +9 -9
  74. package/dist/server/sso/domain.d.ts +1 -1
  75. package/dist/server/sso/domain.js +40 -40
  76. package/dist/server/sso/http.js +18 -18
  77. package/dist/server/sso/oidc.js +1 -1
  78. package/dist/server/sso/policies.js +3 -3
  79. package/dist/server/sso/policy.js +12 -4
  80. package/dist/server/sso/provision.js +9 -9
  81. package/dist/server/sso/validators.js +2 -2
  82. package/dist/server/sso/webhook.js +8 -8
  83. package/dist/server/types.d.ts +185 -124
  84. package/dist/server/types.js +29 -24
  85. package/dist/server/users.js +49 -2
  86. package/dist/server/validators.d.ts +745 -0
  87. package/dist/server/validators.js +60 -0
  88. package/package.json +1 -1
  89. package/dist/component/public.js +0 -22
@@ -74,18 +74,18 @@ function createGroupConnectionDomain(deps) {
74
74
  connection: {
75
75
  create: async (ctx, data) => {
76
76
  return {
77
- connectionId: await createGroupConnection(ctx, config.component.public, data),
77
+ connectionId: await createGroupConnection(ctx, config.component.sso, data),
78
78
  groupId: data.groupId
79
79
  };
80
80
  },
81
81
  get: async (ctx, connectionId) => {
82
- return await getGroupConnection(ctx, config.component.public, connectionId);
82
+ return await getGroupConnection(ctx, config.component.sso, connectionId);
83
83
  },
84
84
  getByDomain: async (ctx, domain) => {
85
- return await getGroupConnectionByDomain(ctx, config.component.public, normalizeDomain(domain));
85
+ return await getGroupConnectionByDomain(ctx, config.component.sso, normalizeDomain(domain));
86
86
  },
87
87
  list: async (ctx, opts) => {
88
- return await listGroupConnections(ctx, config.component.public, {
88
+ return await listGroupConnections(ctx, config.component.sso, {
89
89
  where: opts?.where,
90
90
  limit: opts?.limit,
91
91
  cursor: opts?.cursor,
@@ -94,18 +94,18 @@ function createGroupConnectionDomain(deps) {
94
94
  });
95
95
  },
96
96
  update: async (ctx, connectionId, data) => {
97
- await updateGroupConnection(ctx, config.component.public, {
97
+ await updateGroupConnection(ctx, config.component.sso, {
98
98
  connectionId,
99
99
  data
100
100
  });
101
101
  return { connectionId };
102
102
  },
103
103
  delete: async (ctx, connectionId) => {
104
- await deleteGroupConnection(ctx, config.component.public, connectionId);
104
+ await deleteGroupConnection(ctx, config.component.sso, connectionId);
105
105
  return { connectionId };
106
106
  },
107
107
  status: async (ctx, connectionId) => {
108
- const connection = await getGroupConnection(ctx, config.component.public, connectionId);
108
+ const connection = await getGroupConnection(ctx, config.component.sso, connectionId);
109
109
  if (!connection) throw convexError({
110
110
  code: "INVALID_PARAMETERS",
111
111
  message: connectionNotFoundError
@@ -114,8 +114,8 @@ function createGroupConnectionDomain(deps) {
114
114
  const oidcConfig = getOidcConfig(connection.config);
115
115
  const oidcSecret = await getGroupConnectionSecret(ctx, connection._id, GROUP_CONNECTION_OIDC_CLIENT_SECRET_KIND);
116
116
  const samlConfig = getSamlConfig(connection.config);
117
- const scimConfig = await getScimConfigByConnection(ctx, config.component.public, connectionId);
118
- const domains = await listConnectionDomains(ctx, config.component.public, connectionId);
117
+ const scimConfig = await getScimConfigByConnection(ctx, config.component.sso, connectionId);
118
+ const domains = await listConnectionDomains(ctx, config.component.sso, connectionId);
119
119
  const oidcReady = oidcConfig?.enabled === true && typeof oidcConfig?.client?.id === "string" && oidcConfig.client.id.length > 0 && oidcSecret !== null && (typeof oidcConfig?.discovery?.issuer === "string" || typeof oidcConfig?.discovery?.discoveryUrl === "string");
120
120
  const samlReady = samlConfig?.enabled === true && typeof samlConfig?.idp?.entityId === "string";
121
121
  const scimReady = scimConfig?.status === "active";
@@ -149,21 +149,21 @@ function createGroupConnectionDomain(deps) {
149
149
  },
150
150
  domain: {
151
151
  add: async (ctx, data) => {
152
- return await addConnectionDomain(ctx, config.component.public, {
152
+ return await addConnectionDomain(ctx, config.component.sso, {
153
153
  ...data,
154
154
  domain: normalizeDomain(data.domain)
155
155
  });
156
156
  },
157
157
  list: async (ctx, connectionId) => {
158
- return await listConnectionDomains(ctx, config.component.public, connectionId);
158
+ return await listConnectionDomains(ctx, config.component.sso, connectionId);
159
159
  },
160
160
  validate: async (ctx, connectionId) => {
161
- const connection = await getGroupConnection(ctx, config.component.public, connectionId);
161
+ const connection = await getGroupConnection(ctx, config.component.sso, connectionId);
162
162
  if (connection === null) throw convexError({
163
163
  code: "INVALID_PARAMETERS",
164
164
  message: connectionNotFoundError
165
165
  });
166
- const domains = await listConnectionDomains(ctx, config.component.public, connectionId);
166
+ const domains = await listConnectionDomains(ctx, config.component.sso, connectionId);
167
167
  const primaryDomains = domains.filter((domain) => domain.isPrimary);
168
168
  const verifiedDomains = domains.filter((domain) => domain.verifiedAt !== void 0);
169
169
  const warnings = [];
@@ -184,7 +184,7 @@ function createGroupConnectionDomain(deps) {
184
184
  };
185
185
  },
186
186
  status: async (ctx, connectionId) => {
187
- const [connection, domains] = await Promise.all([getGroupConnection(ctx, config.component.public, connectionId), listConnectionDomains(ctx, config.component.public, connectionId)]);
187
+ const [connection, domains] = await Promise.all([getGroupConnection(ctx, config.component.sso, connectionId), listConnectionDomains(ctx, config.component.sso, connectionId)]);
188
188
  if (connection === null) throw convexError({
189
189
  code: "INVALID_PARAMETERS",
190
190
  message: connectionNotFoundError
@@ -192,7 +192,7 @@ function createGroupConnectionDomain(deps) {
192
192
  const primaryDomain = domains.find((domain) => domain.isPrimary) ?? null;
193
193
  const verifiedDomains = domains.filter((domain) => domain.verifiedAt !== void 0);
194
194
  const pendingChallenges = (await Promise.all(domains.map(async (domain) => {
195
- const verification = await getConnectionDomainVerification(ctx, config.component.public, domain._id);
195
+ const verification = await getConnectionDomainVerification(ctx, config.component.sso, domain._id);
196
196
  if (!verification || verification.expiresAt < Date.now()) return null;
197
197
  return {
198
198
  domain: domain.domain,
@@ -245,13 +245,13 @@ function createGroupConnectionDomain(deps) {
245
245
  };
246
246
  },
247
247
  remove: async (ctx, domainId) => {
248
- await deleteConnectionDomain(ctx, config.component.public, domainId);
248
+ await deleteConnectionDomain(ctx, config.component.sso, domainId);
249
249
  },
250
250
  verification: {
251
251
  request: async (ctx, args) => {
252
252
  const connection = await loadConnectionOrThrow(ctx, args.connectionId);
253
253
  const normalizedDomain = normalizeDomain(args.domain);
254
- const domain = (await listConnectionDomains(ctx, config.component.public, connection._id)).find((entry) => entry.domain === normalizedDomain);
254
+ const domain = (await listConnectionDomains(ctx, config.component.sso, connection._id)).find((entry) => entry.domain === normalizedDomain);
255
255
  if (!domain) throw convexError({
256
256
  code: "INVALID_PARAMETERS",
257
257
  message: "Domain is not attached to this connection."
@@ -261,7 +261,7 @@ function createGroupConnectionDomain(deps) {
261
261
  const token = generateRandomString(32, INVITE_TOKEN_ALPHABET);
262
262
  const tokenHash = await sha256(token);
263
263
  const recordName = getDomainVerificationRecordName(normalizedDomain);
264
- await upsertConnectionDomainVerification(ctx, config.component.public, {
264
+ await upsertConnectionDomainVerification(ctx, config.component.sso, {
265
265
  connectionId: connection._id,
266
266
  groupId: connection.groupId,
267
267
  domainId: domain._id,
@@ -301,7 +301,7 @@ function createGroupConnectionDomain(deps) {
301
301
  confirm: async (ctx, args) => {
302
302
  const connection = await loadConnectionOrThrow(ctx, args.connectionId);
303
303
  const normalizedDomain = normalizeDomain(args.domain);
304
- const domain = (await listConnectionDomains(ctx, config.component.public, connection._id)).find((entry) => entry.domain === normalizedDomain);
304
+ const domain = (await listConnectionDomains(ctx, config.component.sso, connection._id)).find((entry) => entry.domain === normalizedDomain);
305
305
  if (!domain) throw convexError({
306
306
  code: "INVALID_PARAMETERS",
307
307
  message: "Domain is not attached to this connection."
@@ -316,7 +316,7 @@ function createGroupConnectionDomain(deps) {
316
316
  message: "Domain is already verified."
317
317
  }]
318
318
  };
319
- const verification = await getConnectionDomainVerification(ctx, config.component.public, domain._id);
319
+ const verification = await getConnectionDomainVerification(ctx, config.component.sso, domain._id);
320
320
  const checks = [];
321
321
  if (!verification) {
322
322
  checks.push({
@@ -335,7 +335,7 @@ function createGroupConnectionDomain(deps) {
335
335
  ok: true
336
336
  });
337
337
  if (verification.expiresAt < Date.now()) {
338
- await deleteConnectionDomainVerification(ctx, config.component.public, domain._id);
338
+ await deleteConnectionDomainVerification(ctx, config.component.sso, domain._id);
339
339
  checks.push({
340
340
  name: "challenge_active",
341
341
  ok: false,
@@ -377,7 +377,7 @@ function createGroupConnectionDomain(deps) {
377
377
  checks
378
378
  };
379
379
  const verifiedAt = Date.now();
380
- await verifyConnectionDomain(ctx, config.component.public, {
380
+ await verifyConnectionDomain(ctx, config.component.sso, {
381
381
  domainId: domain._id,
382
382
  verifiedAt
383
383
  });
@@ -407,7 +407,7 @@ function createGroupConnectionDomain(deps) {
407
407
  configure: async (ctx, data) => {
408
408
  let connection;
409
409
  try {
410
- connection = await getGroupConnection(ctx, config.component.public, data.connectionId);
410
+ connection = await getGroupConnection(ctx, config.component.sso, data.connectionId);
411
411
  } catch {
412
412
  throw convexError({
413
413
  code: "INTERNAL_ERROR",
@@ -493,7 +493,7 @@ function createGroupConnectionDomain(deps) {
493
493
  hasMetadataXml: typeof nextSamlConfig?.idp?.metadataXml === "string"
494
494
  });
495
495
  try {
496
- await updateGroupConnection(ctx, config.component.public, {
496
+ await updateGroupConnection(ctx, config.component.sso, {
497
497
  connectionId: connection._id,
498
498
  data: {
499
499
  status: "active",
@@ -507,7 +507,7 @@ function createGroupConnectionDomain(deps) {
507
507
  });
508
508
  }
509
509
  if (normalizedDomains) for (const [index, domain] of normalizedDomains.entries()) try {
510
- await addConnectionDomain(ctx, config.component.public, {
510
+ await addConnectionDomain(ctx, config.component.sso, {
511
511
  connectionId: connection._id,
512
512
  groupId: connection.groupId,
513
513
  domain,
@@ -547,7 +547,7 @@ function createGroupConnectionDomain(deps) {
547
547
  refresh: async (ctx, data) => {
548
548
  let connection;
549
549
  try {
550
- connection = await getGroupConnection(ctx, config.component.public, data.connectionId);
550
+ connection = await getGroupConnection(ctx, config.component.sso, data.connectionId);
551
551
  } catch {
552
552
  throw convexError({
553
553
  code: "INTERNAL_ERROR",
@@ -606,7 +606,7 @@ function createGroupConnectionDomain(deps) {
606
606
  security: samlConfig.security
607
607
  });
608
608
  try {
609
- await updateGroupConnection(ctx, config.component.public, {
609
+ await updateGroupConnection(ctx, config.component.sso, {
610
610
  connectionId: connection._id,
611
611
  data: {
612
612
  status: connection.status,
@@ -644,7 +644,7 @@ function createGroupConnectionDomain(deps) {
644
644
  get: async (ctx, connectionId) => {
645
645
  let connection;
646
646
  try {
647
- connection = await getGroupConnection(ctx, config.component.public, connectionId);
647
+ connection = await getGroupConnection(ctx, config.component.sso, connectionId);
648
648
  } catch {
649
649
  throw convexError({
650
650
  code: "INTERNAL_ERROR",
@@ -658,7 +658,7 @@ function createGroupConnectionDomain(deps) {
658
658
  return getSamlConfig(connection.config);
659
659
  },
660
660
  status: (ctx, connectionId) => {
661
- return getGroupConnection(ctx, config.component.public, connectionId).then((connection) => {
661
+ return getGroupConnection(ctx, config.component.sso, connectionId).then((connection) => {
662
662
  if (!connection) throw convexError({
663
663
  code: "INVALID_PARAMETERS",
664
664
  message: connectionNotFoundError
@@ -679,7 +679,7 @@ function createGroupConnectionDomain(deps) {
679
679
  });
680
680
  },
681
681
  metadata: async (ctx, opts) => {
682
- const connection = await getGroupConnection(ctx, config.component.public, opts.connectionId);
682
+ const connection = await getGroupConnection(ctx, config.component.sso, opts.connectionId);
683
683
  if (!connection) throw convexError({
684
684
  code: "INVALID_PARAMETERS",
685
685
  message: "Connection not found."
@@ -700,7 +700,7 @@ function createGroupConnectionDomain(deps) {
700
700
  },
701
701
  validate: async (ctx, connectionId) => {
702
702
  const checks = [];
703
- const connection = await getGroupConnection(ctx, config.component.public, connectionId);
703
+ const connection = await getGroupConnection(ctx, config.component.sso, connectionId);
704
704
  if (!connection) return {
705
705
  ok: false,
706
706
  connectionId,
@@ -804,7 +804,7 @@ function createGroupConnectionDomain(deps) {
804
804
  });
805
805
  let connection;
806
806
  try {
807
- connection = await getGroupConnection(ctx, config.component.public, data.connectionId);
807
+ connection = await getGroupConnection(ctx, config.component.sso, data.connectionId);
808
808
  } catch {
809
809
  throw convexError({
810
810
  code: "INTERNAL_ERROR",
@@ -850,7 +850,7 @@ function createGroupConnectionDomain(deps) {
850
850
  }
851
851
  });
852
852
  try {
853
- await updateGroupConnection(ctx, config.component.public, {
853
+ await updateGroupConnection(ctx, config.component.sso, {
854
854
  connectionId: data.connectionId,
855
855
  data: { config: nextConfig }
856
856
  });
@@ -871,7 +871,7 @@ function createGroupConnectionDomain(deps) {
871
871
  });
872
872
  }
873
873
  try {
874
- await upsertGroupConnectionSecret(ctx, config.component.public, {
874
+ await upsertGroupConnectionSecret(ctx, config.component.sso, {
875
875
  connectionId: data.connectionId,
876
876
  groupId: connection.groupId,
877
877
  kind: GROUP_CONNECTION_OIDC_CLIENT_SECRET_KIND,
@@ -922,7 +922,7 @@ function createGroupConnectionDomain(deps) {
922
922
  get: async (ctx, connectionId) => {
923
923
  let connection;
924
924
  try {
925
- connection = await getGroupConnection(ctx, config.component.public, connectionId);
925
+ connection = await getGroupConnection(ctx, config.component.sso, connectionId);
926
926
  } catch {
927
927
  throw convexError({
928
928
  code: "INTERNAL_ERROR",
@@ -945,7 +945,7 @@ function createGroupConnectionDomain(deps) {
945
945
  return withOidcSecretState(getPublicOidcConfig(connection.config), secret !== null);
946
946
  },
947
947
  status: (ctx, connectionId) => {
948
- return Promise.all([getGroupConnection(ctx, config.component.public, connectionId), getGroupConnectionSecret(ctx, connectionId, GROUP_CONNECTION_OIDC_CLIENT_SECRET_KIND)]).then(([connection, secret]) => {
948
+ return Promise.all([getGroupConnection(ctx, config.component.sso, connectionId), getGroupConnectionSecret(ctx, connectionId, GROUP_CONNECTION_OIDC_CLIENT_SECRET_KIND)]).then(([connection, secret]) => {
949
949
  if (!connection) throw convexError({
950
950
  code: "INVALID_PARAMETERS",
951
951
  message: connectionNotFoundError
@@ -980,7 +980,7 @@ function createGroupConnectionDomain(deps) {
980
980
  let connection;
981
981
  if (data.connectionId !== void 0) {
982
982
  try {
983
- connection = await getGroupConnection(ctx, config.component.public, data.connectionId);
983
+ connection = await getGroupConnection(ctx, config.component.sso, data.connectionId);
984
984
  } catch {
985
985
  throw convexError({
986
986
  code: "INTERNAL_ERROR",
@@ -994,7 +994,7 @@ function createGroupConnectionDomain(deps) {
994
994
  } else if (data.domain !== void 0 || data.email !== void 0) {
995
995
  let result;
996
996
  try {
997
- result = await getGroupConnectionByDomain(ctx, config.component.public, normalizeDomain(data.domain ?? String(data.email).split("@").pop() ?? ""));
997
+ result = await getGroupConnectionByDomain(ctx, config.component.sso, normalizeDomain(data.domain ?? String(data.email).split("@").pop() ?? ""));
998
998
  } catch {
999
999
  throw convexError({
1000
1000
  code: "INTERNAL_ERROR",
@@ -1066,7 +1066,7 @@ function createGroupConnectionDomain(deps) {
1066
1066
  },
1067
1067
  validate: async (ctx, connectionId) => {
1068
1068
  const checks = [];
1069
- const connection = await getGroupConnection(ctx, config.component.public, connectionId);
1069
+ const connection = await getGroupConnection(ctx, config.component.sso, connectionId);
1070
1070
  if (!connection) return {
1071
1071
  ok: false,
1072
1072
  connectionId,
@@ -1162,7 +1162,7 @@ function createGroupConnectionDomain(deps) {
1162
1162
  return await recordGroupAuditEvent(ctx, data);
1163
1163
  },
1164
1164
  list: async (ctx, data) => {
1165
- return await listAuditEvents(ctx, config.component.public, data);
1165
+ return await listAuditEvents(ctx, config.component.sso, data);
1166
1166
  }
1167
1167
  },
1168
1168
  webhook
@@ -349,7 +349,7 @@ function addGroupHttpRuntime(deps) {
349
349
  where: { groupId: state$1.connection.groupId },
350
350
  limit: 100
351
351
  });
352
- const identities = await listScimIdentitiesByConnection(state$1.ctx, config.component.public, state$1.connection._id);
352
+ const identities = await listScimIdentitiesByConnection(state$1.ctx, config.component.sso, state$1.connection._id);
353
353
  const identityByUserId = new Map(identities.filter((identity) => typeof identity.userId === "string").map((identity) => [identity.userId, identity]));
354
354
  const users = (await Promise.all(members.items.map(async (member) => {
355
355
  const user = await auth.user.get(state$1.ctx, member.userId);
@@ -414,7 +414,7 @@ function addGroupHttpRuntime(deps) {
414
414
  profile: extracted
415
415
  }) ?? extracted;
416
416
  const externalId = provisionProfile.externalId;
417
- const existingIdentity = externalId ? await getScimIdentity(state$1.ctx, config.component.public, {
417
+ const existingIdentity = externalId ? await getScimIdentity(state$1.ctx, config.component.sso, {
418
418
  connectionId: state$1.connection._id,
419
419
  resourceType: "user",
420
420
  externalId
@@ -426,7 +426,7 @@ function addGroupHttpRuntime(deps) {
426
426
  groups: provisionProfile.groups,
427
427
  roles: provisionProfile.roles
428
428
  });
429
- const userId = existingUser?._id ? existingUser._id : await insertUser(state$1.ctx, config.component.public, {
429
+ const userId = existingUser?._id ? existingUser._id : await insertUser(state$1.ctx, config.component.user, {
430
430
  name: provisionProfile.name,
431
431
  ...typeof provisionProfile.firstName === "string" ? { firstName: provisionProfile.firstName } : {},
432
432
  ...typeof provisionProfile.lastName === "string" ? { lastName: provisionProfile.lastName } : {},
@@ -438,7 +438,7 @@ function addGroupHttpRuntime(deps) {
438
438
  });
439
439
  if (created && externalId) {
440
440
  const providerId = state$1.connection.protocol === "oidc" ? groupOidcProviderId(state$1.connection._id) : groupSamlProviderId(state$1.connection._id);
441
- await insertAccount(state$1.ctx, config.component.public, {
441
+ await insertAccount(state$1.ctx, config.component.account, {
442
442
  userId,
443
443
  provider: providerId,
444
444
  providerAccountId: externalId
@@ -461,7 +461,7 @@ function addGroupHttpRuntime(deps) {
461
461
  policy: state$1.policy.provisioning.user,
462
462
  source: "scim"
463
463
  });
464
- if (Object.keys(patchData).length > 0) await patchUser(state$1.ctx, config.component.public, {
464
+ if (Object.keys(patchData).length > 0) await patchUser(state$1.ctx, config.component.user, {
465
465
  userId,
466
466
  data: patchData
467
467
  });
@@ -477,7 +477,7 @@ function addGroupHttpRuntime(deps) {
477
477
  roleIds: provisionedRoleIds,
478
478
  status: provisionProfile.active === false ? "inactive" : "active"
479
479
  });
480
- if (externalId) await upsertScimIdentity(state$1.ctx, config.component.public, {
480
+ if (externalId) await upsertScimIdentity(state$1.ctx, config.component.sso, {
481
481
  connectionId: state$1.connection._id,
482
482
  groupId: state$1.connection.groupId,
483
483
  resourceType: "user",
@@ -510,7 +510,7 @@ function addGroupHttpRuntime(deps) {
510
510
  const userId = state$1.parsedPath.resourceId;
511
511
  const existingUser = await auth.user.get(state$1.ctx, userId);
512
512
  if (!existingUser) return scimError(404, "notFound", "User not found.");
513
- const existingIdentity = await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.public, {
513
+ const existingIdentity = await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.sso, {
514
514
  connectionId: state$1.connection._id,
515
515
  userId
516
516
  });
@@ -593,7 +593,7 @@ function addGroupHttpRuntime(deps) {
593
593
  policy: state$1.policy.provisioning.user,
594
594
  source: "scim"
595
595
  });
596
- if (Object.keys(nextPatchData).length > 0) await patchUser(state$1.ctx, config.component.public, {
596
+ if (Object.keys(nextPatchData).length > 0) await patchUser(state$1.ctx, config.component.user, {
597
597
  userId,
598
598
  data: nextPatchData
599
599
  });
@@ -606,7 +606,7 @@ function addGroupHttpRuntime(deps) {
606
606
  }),
607
607
  status: provisionProfile.active === false || nextActive === false ? "inactive" : "active"
608
608
  });
609
- await upsertScimIdentity(state$1.ctx, config.component.public, {
609
+ await upsertScimIdentity(state$1.ctx, config.component.sso, {
610
610
  connectionId: state$1.connection._id,
611
611
  groupId: state$1.connection.groupId,
612
612
  resourceType: "user",
@@ -637,7 +637,7 @@ function addGroupHttpRuntime(deps) {
637
637
  const missing = requireScimResourceId(state$1.parsedPath.resourceId, "User");
638
638
  if (missing) return missing;
639
639
  const userId = state$1.parsedPath.resourceId;
640
- const identity = await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.public, {
640
+ const identity = await getScimIdentityByConnectionAndUser(state$1.ctx, config.component.sso, {
641
641
  connectionId: state$1.connection._id,
642
642
  userId
643
643
  });
@@ -647,8 +647,8 @@ function addGroupHttpRuntime(deps) {
647
647
  userId
648
648
  });
649
649
  if (resolution.membership) await auth.member.delete(state$1.ctx, resolution.membership._id);
650
- if (state$1.policy.provisioning.deprovision.mode === "hard") await deleteScimIdentity(state$1.ctx, config.component.public, identity._id);
651
- else await upsertScimIdentity(state$1.ctx, config.component.public, {
650
+ if (state$1.policy.provisioning.deprovision.mode === "hard") await deleteScimIdentity(state$1.ctx, config.component.sso, identity._id);
651
+ else await upsertScimIdentity(state$1.ctx, config.component.sso, {
652
652
  connectionId: identity.connectionId,
653
653
  groupId: identity.groupId,
654
654
  resourceType: identity.resourceType,
@@ -667,7 +667,7 @@ function addGroupHttpRuntime(deps) {
667
667
  where: { parentGroupId: state$1.connection.groupId },
668
668
  limit: 100
669
669
  });
670
- const identities = await listScimIdentitiesByConnection(state$1.ctx, config.component.public, state$1.connection._id);
670
+ const identities = await listScimIdentitiesByConnection(state$1.ctx, config.component.sso, state$1.connection._id);
671
671
  const identityByGroupId = new Map(identities.filter((identity) => typeof identity.mappedGroupId === "string").map((identity) => [identity.mappedGroupId, identity]));
672
672
  const groups = await Promise.all(groupsList.items.map(async (group) => {
673
673
  const typedGroup = group;
@@ -727,7 +727,7 @@ function addGroupHttpRuntime(deps) {
727
727
  const handleGroupsPost = async (state$1) => {
728
728
  const body = await readScimJson(state$1.request);
729
729
  const externalId = typeof body.externalId === "string" ? body.externalId : void 0;
730
- const existingIdentity = externalId ? await getScimIdentity(state$1.ctx, config.component.public, {
730
+ const existingIdentity = externalId ? await getScimIdentity(state$1.ctx, config.component.sso, {
731
731
  connectionId: state$1.connection._id,
732
732
  resourceType: "group",
733
733
  externalId
@@ -760,7 +760,7 @@ function addGroupHttpRuntime(deps) {
760
760
  })).items.map((member) => ({ value: member.userId }))
761
761
  }), 200, { Location: location$1 });
762
762
  }
763
- await upsertScimIdentity(state$1.ctx, config.component.public, {
763
+ await upsertScimIdentity(state$1.ctx, config.component.sso, {
764
764
  connectionId: state$1.connection._id,
765
765
  groupId: state$1.connection.groupId,
766
766
  resourceType: "group",
@@ -810,7 +810,7 @@ function addGroupHttpRuntime(deps) {
810
810
  const missing = requireScimResourceId(state$1.parsedPath.resourceId, "Group");
811
811
  if (missing) return missing;
812
812
  const groupId = state$1.parsedPath.resourceId;
813
- const identity = await getScimIdentityByMappedGroup(state$1.ctx, config.component.public, groupId);
813
+ const identity = await getScimIdentityByMappedGroup(state$1.ctx, config.component.sso, groupId);
814
814
  if (!identity || identity.connectionId !== state$1.connection._id) return scimError(404, "notFound", "Group not found.");
815
815
  const body = await readScimJson(state$1.request);
816
816
  const operations = Array.isArray(body.Operations) ? body.Operations : unsupportedScimPatch();
@@ -906,10 +906,10 @@ function addGroupHttpRuntime(deps) {
906
906
  const missing = requireScimResourceId(state$1.parsedPath.resourceId, "Group");
907
907
  if (missing) return missing;
908
908
  const groupId = state$1.parsedPath.resourceId;
909
- const identity = await getScimIdentityByMappedGroup(state$1.ctx, config.component.public, groupId);
909
+ const identity = await getScimIdentityByMappedGroup(state$1.ctx, config.component.sso, groupId);
910
910
  if (!identity || identity.connectionId !== state$1.connection._id) return scimError(404, "notFound", "Group not found.");
911
911
  await auth.group.delete(state$1.ctx, groupId);
912
- await deleteScimIdentity(state$1.ctx, config.component.public, identity._id);
912
+ await deleteScimIdentity(state$1.ctx, config.component.sso, identity._id);
913
913
  await state$1.recordScimEvent("group.sso.scim.group.deleted", true, "group", groupId);
914
914
  return new Response(null, { status: 204 });
915
915
  };
@@ -313,7 +313,7 @@ function createSyntheticOAuthMaterializedConfig(providerId, options) {
313
313
  type: "oauth",
314
314
  provider: null,
315
315
  scopes: [],
316
- accountLinking: options?.accountLinking ?? "verifiedEmail"
316
+ accountLinking: options?.accountLinking ?? "sameConnection"
317
317
  };
318
318
  }
319
319
  /** @internal */
@@ -11,13 +11,13 @@ function createGroupPolicyDomain(deps) {
11
11
  return await loadGroupPolicyOrThrow(ctx, groupId);
12
12
  },
13
13
  update: async (ctx, groupId, patch) => {
14
- const group = await getGroup(ctx, config.component.public, groupId);
14
+ const group = await getGroup(ctx, config.component.group, groupId);
15
15
  if (!group) throw convexError({
16
16
  code: "INVALID_PARAMETERS",
17
17
  message: "Group not found."
18
18
  });
19
19
  const policy = patchGroupConnectionPolicy(group.policy, patch);
20
- await ctx.runMutation(config.component.public.groupUpdate, {
20
+ await ctx.runMutation(config.component.group.update, {
21
21
  groupId,
22
22
  data: { policy }
23
23
  });
@@ -33,7 +33,7 @@ function createGroupPolicyDomain(deps) {
33
33
  return policy;
34
34
  },
35
35
  validate: async (ctx, groupId) => {
36
- if (!await getGroup(ctx, config.component.public, groupId)) return {
36
+ if (!await getGroup(ctx, config.component.group, groupId)) return {
37
37
  ok: false,
38
38
  groupId,
39
39
  checks: [{
@@ -4,8 +4,8 @@ import { asRecord } from "./shared.js";
4
4
  const DEFAULT_GROUP_CONNECTION_POLICY = {
5
5
  version: 1,
6
6
  identity: { accountLinking: {
7
- oidc: "verifiedEmail",
8
- saml: "verifiedEmail"
7
+ oidc: "sameConnection",
8
+ saml: "sameConnection"
9
9
  } },
10
10
  provisioning: {
11
11
  user: {
@@ -56,8 +56,16 @@ function normalizeGroupConnectionPolicy(policy) {
56
56
  return {
57
57
  version: 1,
58
58
  identity: { accountLinking: {
59
- oidc: oneOf(accountLinking.oidc, ["none"], d.identity.accountLinking.oidc),
60
- saml: oneOf(accountLinking.saml, ["none"], d.identity.accountLinking.saml)
59
+ oidc: oneOf(accountLinking.oidc, [
60
+ "none",
61
+ "verifiedEmail",
62
+ "sameConnection"
63
+ ], d.identity.accountLinking.oidc),
64
+ saml: oneOf(accountLinking.saml, [
65
+ "none",
66
+ "verifiedEmail",
67
+ "sameConnection"
68
+ ], d.identity.accountLinking.saml)
61
69
  } },
62
70
  provisioning: {
63
71
  user: {
@@ -11,7 +11,7 @@ function createGroupScimDomain(deps) {
11
11
  const getScimBasePath = (connectionId) => `${requireEnv("CONVEX_SITE_URL")}/connections/${connectionId}/scim/v2`;
12
12
  const validateScim = async (ctx, connectionId) => {
13
13
  const checks = [];
14
- const connection = await getGroupConnection(ctx, config.component.public, connectionId);
14
+ const connection = await getGroupConnection(ctx, config.component.sso, connectionId);
15
15
  if (!connection) return {
16
16
  ok: false,
17
17
  connectionId,
@@ -22,7 +22,7 @@ function createGroupScimDomain(deps) {
22
22
  }]
23
23
  };
24
24
  const policy = await loadGroupPolicyOrThrow(ctx, connection.groupId);
25
- const scimConfig = await getScimConfigByConnection(ctx, config.component.public, connectionId);
25
+ const scimConfig = await getScimConfigByConnection(ctx, config.component.sso, connectionId);
26
26
  const hasConfig = scimConfig !== null && scimConfig !== void 0;
27
27
  checks.push({
28
28
  name: "scim_config_exists",
@@ -87,7 +87,7 @@ function createGroupScimDomain(deps) {
87
87
  };
88
88
  return {
89
89
  configure: async (ctx, data) => {
90
- const connection = await getGroupConnection(ctx, config.component.public, data.connectionId);
90
+ const connection = await getGroupConnection(ctx, config.component.sso, data.connectionId);
91
91
  if (connection === null) throw convexError({
92
92
  code: "INVALID_PARAMETERS",
93
93
  message: "Connection not found."
@@ -95,7 +95,7 @@ function createGroupScimDomain(deps) {
95
95
  const rawToken = generateRandomString(48, INVITE_TOKEN_ALPHABET);
96
96
  const tokenHash = await sha256(rawToken);
97
97
  const basePath = getScimBasePath(connection._id);
98
- const configId = await upsertScimConfig(ctx, config.component.public, {
98
+ const configId = await upsertScimConfig(ctx, config.component.sso, {
99
99
  connectionId: connection._id,
100
100
  groupId: connection.groupId,
101
101
  status: data.status ?? "active",
@@ -133,7 +133,7 @@ function createGroupScimDomain(deps) {
133
133
  };
134
134
  },
135
135
  get: async (ctx, connectionId) => {
136
- const scimConfig = await getScimConfigByConnection(ctx, config.component.public, connectionId);
136
+ const scimConfig = await getScimConfigByConnection(ctx, config.component.sso, connectionId);
137
137
  if (!scimConfig) return null;
138
138
  const shape = getScimConfigShape(scimConfig);
139
139
  return {
@@ -143,7 +143,7 @@ function createGroupScimDomain(deps) {
143
143
  };
144
144
  },
145
145
  status: async (ctx, connectionId) => {
146
- const currentConfig = await getScimConfigByConnection(ctx, config.component.public, connectionId);
146
+ const currentConfig = await getScimConfigByConnection(ctx, config.component.sso, connectionId);
147
147
  const result = await validateScim(ctx, connectionId);
148
148
  return {
149
149
  connectionId,
@@ -155,17 +155,17 @@ function createGroupScimDomain(deps) {
155
155
  };
156
156
  },
157
157
  getConfigByToken: async (ctx, token) => {
158
- return await getScimConfigByTokenHash(ctx, config.component.public, await sha256(token));
158
+ return await getScimConfigByTokenHash(ctx, config.component.sso, await sha256(token));
159
159
  },
160
160
  validate: async (ctx, connectionId) => {
161
161
  return await validateScim(ctx, connectionId);
162
162
  },
163
163
  identity: {
164
164
  get: async (ctx, data) => {
165
- return await getScimIdentity(ctx, config.component.public, data);
165
+ return await getScimIdentity(ctx, config.component.sso, data);
166
166
  },
167
167
  upsert: async (ctx, data) => {
168
- return await upsertScimIdentity(ctx, config.component.public, {
168
+ return await upsertScimIdentity(ctx, config.component.sso, {
169
169
  ...data,
170
170
  lastProvisionedAt: Date.now()
171
171
  });
@@ -6,8 +6,8 @@ const groupConnectionStatusValidator = v.union(v.literal("draft"), v.literal("ac
6
6
  /** @internal Structured validator for mounted group policy patch payloads. */
7
7
  const groupPolicyPatchValidator = v.object({
8
8
  identity: v.optional(v.object({ accountLinking: v.optional(v.object({
9
- oidc: v.optional(v.union(v.literal("verifiedEmail"), v.literal("none"))),
10
- saml: v.optional(v.union(v.literal("verifiedEmail"), v.literal("none")))
9
+ oidc: v.optional(v.union(v.literal("verifiedEmail"), v.literal("none"), v.literal("sameConnection"))),
10
+ saml: v.optional(v.union(v.literal("verifiedEmail"), v.literal("none"), v.literal("sameConnection")))
11
11
  })) })),
12
12
  provisioning: v.optional(v.object({
13
13
  user: v.optional(v.object({