@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.
- package/dist/component/_generated/component.d.ts +1611 -2039
- package/dist/component/account.js +3 -0
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/factor/device.js +3 -0
- package/dist/component/factor/passkey.js +3 -0
- package/dist/component/factor/totp.js +3 -0
- package/dist/component/group/invite.js +3 -0
- package/dist/component/group/member.js +3 -0
- package/dist/component/group.js +3 -0
- package/dist/component/model.d.ts +342 -30
- package/dist/component/model.js +22 -4
- package/dist/component/modules.js +24 -21
- package/dist/component/public/factors/devices.js +37 -106
- package/dist/component/public/factors/passkeys.js +29 -149
- package/dist/component/public/factors/totp.js +32 -159
- package/dist/component/public/groups/core.js +19 -82
- package/dist/component/public/groups/invites.js +15 -104
- package/dist/component/public/groups/members.js +26 -149
- package/dist/component/public/identity/accounts.js +12 -94
- package/dist/component/public/identity/codes.js +13 -73
- package/dist/component/public/identity/sessions.js +5 -107
- package/dist/component/public/identity/tokens.js +13 -103
- package/dist/component/public/identity/users.js +188 -185
- package/dist/component/public/identity/verifiers.js +17 -80
- package/dist/component/public/security/keys.js +13 -120
- package/dist/component/public/security/limits.js +0 -43
- package/dist/component/public/sso/audit.js +0 -28
- package/dist/component/public/sso/core.js +31 -104
- package/dist/component/public/sso/domains.js +0 -71
- package/dist/component/public/sso/scim.js +63 -239
- package/dist/component/public/sso/secrets.js +0 -30
- package/dist/component/public/sso/webhooks.js +23 -128
- package/dist/component/rateLimit.js +3 -0
- package/dist/component/schema.d.ts +378 -342
- package/dist/component/schema.js +11 -1
- package/dist/component/session.js +3 -0
- package/dist/component/sso/audit.js +3 -0
- package/dist/component/sso/connection/domain/verification.js +3 -0
- package/dist/component/sso/connection/domain.js +3 -0
- package/dist/component/sso/connection/scim/config.js +3 -0
- package/dist/component/sso/connection/scim/identity.js +3 -0
- package/dist/component/sso/connection/secret.js +3 -0
- package/dist/component/sso/connection.js +3 -0
- package/dist/component/sso/webhook/delivery.js +3 -0
- package/dist/component/sso/webhook/endpoint.js +3 -0
- package/dist/component/token/pkce.js +3 -0
- package/dist/component/token/refresh.js +3 -0
- package/dist/component/token/verification.js +3 -0
- package/dist/component/user/email.js +3 -0
- package/dist/component/user/key.js +3 -0
- package/dist/component/user.js +62 -0
- package/dist/core/index.d.ts +131 -28
- package/dist/core/index.js +2 -0
- package/dist/model.js +391 -0
- package/dist/providers/credentials.d.ts +1 -1
- package/dist/providers/github.js +6 -0
- package/dist/providers/password.js +1 -2
- package/dist/server/auth.d.ts +73 -7
- package/dist/server/auth.js +4 -1
- package/dist/server/context.js +30 -3
- package/dist/server/contract.js +42 -42
- package/dist/server/core.js +224 -86
- package/dist/server/db.js +45 -37
- package/dist/server/facade.d.ts +39 -0
- package/dist/server/facade.js +16 -0
- package/dist/server/index.d.ts +5 -3
- package/dist/server/index.js +3 -1
- package/dist/server/mounts.d.ts +101 -101
- package/dist/server/mutations/credentials/signin.js +3 -7
- package/dist/server/mutations/oauth.js +9 -6
- package/dist/server/runtime.d.ts +147 -46
- package/dist/server/runtime.js +10 -8
- package/dist/server/services/group.js +9 -9
- package/dist/server/sso/domain.d.ts +1 -1
- package/dist/server/sso/domain.js +40 -40
- package/dist/server/sso/http.js +18 -18
- package/dist/server/sso/oidc.js +1 -1
- package/dist/server/sso/policies.js +3 -3
- package/dist/server/sso/policy.js +12 -4
- package/dist/server/sso/provision.js +9 -9
- package/dist/server/sso/validators.js +2 -2
- package/dist/server/sso/webhook.js +8 -8
- package/dist/server/types.d.ts +185 -124
- package/dist/server/types.js +29 -24
- package/dist/server/users.js +49 -2
- package/dist/server/validators.d.ts +745 -0
- package/dist/server/validators.js +60 -0
- package/package.json +1 -1
- package/dist/component/public.js +0 -22
|
@@ -8,7 +8,7 @@ function createGroupWebhookDomain(deps) {
|
|
|
8
8
|
return {
|
|
9
9
|
endpoint: {
|
|
10
10
|
get: async (ctx, endpointId) => {
|
|
11
|
-
return await getWebhookEndpoint(ctx, config.component.
|
|
11
|
+
return await getWebhookEndpoint(ctx, config.component.sso, endpointId);
|
|
12
12
|
},
|
|
13
13
|
create: async (ctx, data) => {
|
|
14
14
|
const connection = await loadConnectionOrThrow(ctx, data.connectionId);
|
|
@@ -17,7 +17,7 @@ function createGroupWebhookDomain(deps) {
|
|
|
17
17
|
message: "Connection not found."
|
|
18
18
|
});
|
|
19
19
|
const secretHash = await sha256(data.secret);
|
|
20
|
-
const endpointId = await createWebhookEndpoint(ctx, config.component.
|
|
20
|
+
const endpointId = await createWebhookEndpoint(ctx, config.component.sso, {
|
|
21
21
|
connectionId: connection._id,
|
|
22
22
|
groupId: connection.groupId,
|
|
23
23
|
url: data.url,
|
|
@@ -38,10 +38,10 @@ function createGroupWebhookDomain(deps) {
|
|
|
38
38
|
return { endpointId };
|
|
39
39
|
},
|
|
40
40
|
list: async (ctx, connectionId) => {
|
|
41
|
-
return await listWebhookEndpoints(ctx, config.component.
|
|
41
|
+
return await listWebhookEndpoints(ctx, config.component.sso, connectionId);
|
|
42
42
|
},
|
|
43
43
|
disable: async (ctx, endpointId) => {
|
|
44
|
-
await updateWebhookEndpoint(ctx, config.component.
|
|
44
|
+
await updateWebhookEndpoint(ctx, config.component.sso, {
|
|
45
45
|
endpointId,
|
|
46
46
|
data: { status: "disabled" }
|
|
47
47
|
});
|
|
@@ -53,16 +53,16 @@ function createGroupWebhookDomain(deps) {
|
|
|
53
53
|
},
|
|
54
54
|
delivery: {
|
|
55
55
|
list: async (ctx, data) => {
|
|
56
|
-
return await listWebhookDeliveries(ctx, config.component.
|
|
56
|
+
return await listWebhookDeliveries(ctx, config.component.sso, data);
|
|
57
57
|
},
|
|
58
58
|
listReady: async (ctx, limit) => {
|
|
59
|
-
return await listReadyWebhookDeliveries(ctx, config.component.
|
|
59
|
+
return await listReadyWebhookDeliveries(ctx, config.component.sso, {
|
|
60
60
|
now: Date.now(),
|
|
61
61
|
limit
|
|
62
62
|
});
|
|
63
63
|
},
|
|
64
64
|
markDelivered: async (ctx, deliveryId, responseStatus) => {
|
|
65
|
-
await patchWebhookDelivery(ctx, config.component.
|
|
65
|
+
await patchWebhookDelivery(ctx, config.component.sso, {
|
|
66
66
|
deliveryId,
|
|
67
67
|
data: {
|
|
68
68
|
status: "delivered",
|
|
@@ -73,7 +73,7 @@ function createGroupWebhookDomain(deps) {
|
|
|
73
73
|
});
|
|
74
74
|
},
|
|
75
75
|
markFailed: async (ctx, deliveryId, data) => {
|
|
76
|
-
await patchWebhookDelivery(ctx, config.component.
|
|
76
|
+
await patchWebhookDelivery(ctx, config.component.sso, {
|
|
77
77
|
deliveryId,
|
|
78
78
|
data: {
|
|
79
79
|
status: data.retryAt ? "pending" : "failed",
|
package/dist/server/types.d.ts
CHANGED
|
@@ -407,10 +407,15 @@ interface SSOProviderConfig {
|
|
|
407
407
|
/**
|
|
408
408
|
* Account linking strategy for group SSO sign-in.
|
|
409
409
|
*
|
|
410
|
-
* - `"
|
|
410
|
+
* - `"sameConnection"` (default) — only link to a user already associated
|
|
411
|
+
* with **this** connection (via its account/externalId). Never link across
|
|
412
|
+
* IdPs by email. This prevents cross-IdP/tenant account takeover.
|
|
413
|
+
* - `"verifiedEmail"` — link accounts when the IdP-provided email matches a
|
|
414
|
+
* verified email on an existing user. Opt-in; only safe when every
|
|
415
|
+
* connection that can assert this email is mutually trusted.
|
|
411
416
|
* - `"none"` — never auto-link; always create a new account.
|
|
412
417
|
*/
|
|
413
|
-
type GroupConnectionAccountLinkingPolicy = "verifiedEmail" | "none";
|
|
418
|
+
type GroupConnectionAccountLinkingPolicy = "verifiedEmail" | "none" | "sameConnection";
|
|
414
419
|
/**
|
|
415
420
|
* Policy for reusing existing users during SCIM provisioning.
|
|
416
421
|
*
|
|
@@ -743,10 +748,21 @@ interface TotpProviderConfig {
|
|
|
743
748
|
*
|
|
744
749
|
* `id` is the provider-specific account identifier (e.g. GitHub user ID).
|
|
745
750
|
*/
|
|
751
|
+
interface ProfileEmail {
|
|
752
|
+
email: string;
|
|
753
|
+
primary?: boolean;
|
|
754
|
+
verified?: boolean;
|
|
755
|
+
}
|
|
746
756
|
interface OAuthProfile {
|
|
747
757
|
id: string;
|
|
748
758
|
name?: string;
|
|
749
759
|
email?: string;
|
|
760
|
+
/**
|
|
761
|
+
* All emails the provider reported (e.g. GitHub `/user/emails`). When
|
|
762
|
+
* present, every entry is recorded; `email` remains the primary for
|
|
763
|
+
* back-compat. Single-email providers omit this.
|
|
764
|
+
*/
|
|
765
|
+
emails?: ProfileEmail[];
|
|
750
766
|
image?: string;
|
|
751
767
|
/** Additional claims from the ID token or userinfo endpoint. */
|
|
752
768
|
[key: string]: unknown;
|
|
@@ -914,8 +930,7 @@ type AuthServerHelpers = {
|
|
|
914
930
|
totp: {
|
|
915
931
|
/**
|
|
916
932
|
* Delete a TOTP factor by ID and fire the `totpRemoved` lifecycle
|
|
917
|
-
* event.
|
|
918
|
-
* `User.hasTotp` flag is cleared as part of the same mutation.
|
|
933
|
+
* event.
|
|
919
934
|
*/
|
|
920
935
|
delete: (ctx: GenericActionCtx<GenericDataModel>, args: AuthDeleteTotpArgs) => Promise<{
|
|
921
936
|
totpId: GenericId<"TotpFactor">;
|
|
@@ -1013,7 +1028,7 @@ interface OAuthMaterializedConfig {
|
|
|
1013
1028
|
* Account-linking policy for OAuth identities. Defaults to verified email linking.
|
|
1014
1029
|
* @readonly
|
|
1015
1030
|
*/
|
|
1016
|
-
readonly accountLinking?: "verifiedEmail" | "none";
|
|
1031
|
+
readonly accountLinking?: "verifiedEmail" | "none" | "sameConnection";
|
|
1017
1032
|
}
|
|
1018
1033
|
/**
|
|
1019
1034
|
* Device authorization provider config (RFC 8628).
|
|
@@ -1142,124 +1157,170 @@ interface CorsConfig {
|
|
|
1142
1157
|
* Component function references required by core auth runtime.
|
|
1143
1158
|
*/
|
|
1144
1159
|
type AuthComponentApi = {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1160
|
+
user: {
|
|
1161
|
+
get: FunctionReference<"query", "internal">;
|
|
1162
|
+
list: FunctionReference<"query", "internal">;
|
|
1163
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1164
|
+
upsert: FunctionReference<"mutation", "internal">;
|
|
1165
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1166
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1167
|
+
email: {
|
|
1168
|
+
list: FunctionReference<"query", "internal">;
|
|
1169
|
+
owner: FunctionReference<"query", "internal">;
|
|
1170
|
+
upsert: FunctionReference<"mutation", "internal">;
|
|
1171
|
+
setPrimary: FunctionReference<"mutation", "internal">;
|
|
1172
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1173
|
+
};
|
|
1174
|
+
key: {
|
|
1175
|
+
get: FunctionReference<"query", "internal">;
|
|
1176
|
+
list: FunctionReference<"query", "internal">;
|
|
1177
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1178
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1179
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1180
|
+
};
|
|
1181
|
+
};
|
|
1182
|
+
account: {
|
|
1183
|
+
get: FunctionReference<"query", "internal">;
|
|
1184
|
+
list: FunctionReference<"query", "internal">;
|
|
1185
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1186
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1187
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1188
|
+
};
|
|
1189
|
+
session: {
|
|
1190
|
+
get: FunctionReference<"query", "internal">;
|
|
1191
|
+
list: FunctionReference<"query", "internal">;
|
|
1192
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1193
|
+
issue: FunctionReference<"mutation", "internal">;
|
|
1194
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1195
|
+
};
|
|
1196
|
+
token: {
|
|
1197
|
+
refresh: {
|
|
1198
|
+
get: FunctionReference<"query", "internal">;
|
|
1199
|
+
list: FunctionReference<"query", "internal">;
|
|
1200
|
+
listChildren: FunctionReference<"query", "internal">;
|
|
1201
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1202
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1203
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1204
|
+
exchange: FunctionReference<"mutation", "internal">;
|
|
1205
|
+
};
|
|
1206
|
+
verification: {
|
|
1207
|
+
get: FunctionReference<"query", "internal">;
|
|
1208
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1209
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1210
|
+
};
|
|
1211
|
+
pkce: {
|
|
1212
|
+
get: FunctionReference<"query", "internal">;
|
|
1213
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1214
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1215
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1216
|
+
};
|
|
1217
|
+
};
|
|
1218
|
+
rateLimit: {
|
|
1219
|
+
get: FunctionReference<"query", "internal">;
|
|
1220
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1221
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1222
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1223
|
+
};
|
|
1224
|
+
group: {
|
|
1225
|
+
get: FunctionReference<"query", "internal">;
|
|
1226
|
+
ancestors: FunctionReference<"query", "internal">;
|
|
1227
|
+
list: FunctionReference<"query", "internal">;
|
|
1228
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1229
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1230
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1231
|
+
member: {
|
|
1232
|
+
get: FunctionReference<"query", "internal">;
|
|
1233
|
+
list: FunctionReference<"query", "internal">;
|
|
1234
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1235
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1236
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1237
|
+
resolve: FunctionReference<"query", "internal">;
|
|
1238
|
+
};
|
|
1239
|
+
invite: {
|
|
1240
|
+
get: FunctionReference<"query", "internal">;
|
|
1241
|
+
list: FunctionReference<"query", "internal">;
|
|
1242
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1243
|
+
accept: FunctionReference<"mutation", "internal">;
|
|
1244
|
+
redeem: FunctionReference<"mutation", "internal">;
|
|
1245
|
+
revoke: FunctionReference<"mutation", "internal">;
|
|
1246
|
+
};
|
|
1247
|
+
};
|
|
1248
|
+
factor: {
|
|
1249
|
+
passkey: {
|
|
1250
|
+
get: FunctionReference<"query", "internal">;
|
|
1251
|
+
list: FunctionReference<"query", "internal">;
|
|
1252
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1253
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1254
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1255
|
+
};
|
|
1256
|
+
totp: {
|
|
1257
|
+
get: FunctionReference<"query", "internal">;
|
|
1258
|
+
list: FunctionReference<"query", "internal">;
|
|
1259
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1260
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1261
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1262
|
+
};
|
|
1263
|
+
device: {
|
|
1264
|
+
get: FunctionReference<"query", "internal">;
|
|
1265
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1266
|
+
authorize: FunctionReference<"mutation", "internal">;
|
|
1267
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1268
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1269
|
+
};
|
|
1270
|
+
};
|
|
1271
|
+
sso: {
|
|
1272
|
+
connection: {
|
|
1273
|
+
get: FunctionReference<"query", "internal">;
|
|
1274
|
+
list: FunctionReference<"query", "internal">;
|
|
1275
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1276
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1277
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1278
|
+
domain: {
|
|
1279
|
+
list: FunctionReference<"query", "internal">;
|
|
1280
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1281
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1282
|
+
verify: FunctionReference<"mutation", "internal">;
|
|
1283
|
+
verification: {
|
|
1284
|
+
get: FunctionReference<"query", "internal">;
|
|
1285
|
+
upsert: FunctionReference<"mutation", "internal">;
|
|
1286
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1287
|
+
};
|
|
1288
|
+
};
|
|
1289
|
+
secret: {
|
|
1290
|
+
get: FunctionReference<"query", "internal">;
|
|
1291
|
+
upsert: FunctionReference<"mutation", "internal">;
|
|
1292
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1293
|
+
};
|
|
1294
|
+
scim: {
|
|
1295
|
+
config: {
|
|
1296
|
+
get: FunctionReference<"query", "internal">;
|
|
1297
|
+
upsert: FunctionReference<"mutation", "internal">;
|
|
1298
|
+
};
|
|
1299
|
+
identity: {
|
|
1300
|
+
get: FunctionReference<"query", "internal">;
|
|
1301
|
+
list: FunctionReference<"query", "internal">;
|
|
1302
|
+
upsert: FunctionReference<"mutation", "internal">;
|
|
1303
|
+
delete: FunctionReference<"mutation", "internal">;
|
|
1304
|
+
};
|
|
1305
|
+
};
|
|
1306
|
+
};
|
|
1307
|
+
audit: {
|
|
1308
|
+
list: FunctionReference<"query", "internal">;
|
|
1309
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1310
|
+
};
|
|
1311
|
+
webhook: {
|
|
1312
|
+
endpoint: {
|
|
1313
|
+
get: FunctionReference<"query", "internal">;
|
|
1314
|
+
list: FunctionReference<"query", "internal">;
|
|
1315
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1316
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1317
|
+
};
|
|
1318
|
+
delivery: {
|
|
1319
|
+
list: FunctionReference<"query", "internal">;
|
|
1320
|
+
create: FunctionReference<"mutation", "internal">;
|
|
1321
|
+
update: FunctionReference<"mutation", "internal">;
|
|
1322
|
+
};
|
|
1323
|
+
};
|
|
1263
1324
|
};
|
|
1264
1325
|
};
|
|
1265
1326
|
/**
|
|
@@ -1286,5 +1347,5 @@ type SessionTokenIdentityClaims = {
|
|
|
1286
1347
|
};
|
|
1287
1348
|
type KeyDoc = Infer<typeof vApiKeyDoc>;
|
|
1288
1349
|
//#endregion
|
|
1289
|
-
export { AfterCtx, AuthAuthorizationConfig, AuthCallbackContext, AuthCallbackProfile, AuthCallbacks, AuthEvent, AuthGrant, AuthProviderConfig, AuthRoleId, BeforeCtx, BeforeEvent, BeforeResult, ConvexAuthConfig, ConvexAuthMaterializedConfig, ConvexCredentialsConfig, CorsConfig, DeviceProviderConfig, Doc, EmailConfig, EmailUserConfig, GenericActionCtxWithAuthConfig, GenericDoc, GroupConnectionPolicy, GroupConnectionPolicyPatch, HasDeviceProvider, HasPasskeyProvider, HasSSO, HasTotpProvider, HttpKeyContext, KeyDoc, KeyScope, OAuthMaterializedConfig, OAuthProfile, OAuthTokens, OIDCClaimMapping, PasskeyProviderConfig, PhoneConfig, PhoneUserConfig, SSOProviderConfig, ScopeChecker, SessionTokenIdentityClaims, TotpProviderConfig, UserOrderBy, UserWhere };
|
|
1350
|
+
export { AfterCtx, AuthAuthorizationConfig, AuthCallbackContext, AuthCallbackProfile, AuthCallbacks, AuthDataModel, AuthEvent, AuthGrant, AuthProviderConfig, AuthRoleId, BeforeCtx, BeforeEvent, BeforeResult, ConvexAuthConfig, ConvexAuthMaterializedConfig, ConvexCredentialsConfig, CorsConfig, DeviceProviderConfig, Doc, EmailConfig, EmailUserConfig, GenericActionCtxWithAuthConfig, GenericDoc, GroupConnectionPolicy, GroupConnectionPolicyPatch, HasDeviceProvider, HasPasskeyProvider, HasSSO, HasTotpProvider, HttpKeyContext, KeyDoc, KeyScope, OAuthMaterializedConfig, OAuthProfile, OAuthTokens, OIDCClaimMapping, PasskeyProviderConfig, PhoneConfig, PhoneUserConfig, SSOProviderConfig, ScopeChecker, SessionTokenIdentityClaims, TotpProviderConfig, UserOrderBy, UserWhere };
|
|
1290
1351
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/server/types.js
CHANGED
|
@@ -1,77 +1,82 @@
|
|
|
1
1
|
//#region src/server/types.ts
|
|
2
2
|
async function queryUserById(ctx, userId) {
|
|
3
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
3
|
+
return await ctx.runQuery(ctx.auth.config.component.user.get, { id: userId });
|
|
4
4
|
}
|
|
5
5
|
async function queryUserByVerifiedEmail(ctx, email) {
|
|
6
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
6
|
+
return await ctx.runQuery(ctx.auth.config.component.user.get, { verifiedEmail: email });
|
|
7
7
|
}
|
|
8
8
|
async function queryVerifierById(ctx, verifierId) {
|
|
9
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
9
|
+
return await ctx.runQuery(ctx.auth.config.component.token.pkce.get, { id: verifierId });
|
|
10
10
|
}
|
|
11
11
|
async function mutateVerifierDelete(ctx, verifierId) {
|
|
12
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
12
|
+
await ctx.runMutation(ctx.auth.config.component.token.pkce.delete, { verifierId });
|
|
13
13
|
}
|
|
14
14
|
async function queryTotpById(ctx, totpId) {
|
|
15
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
15
|
+
return await ctx.runQuery(ctx.auth.config.component.factor.totp.get, { id: totpId });
|
|
16
16
|
}
|
|
17
17
|
async function queryTotpVerifiedByUserId(ctx, userId) {
|
|
18
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
18
|
+
return await ctx.runQuery(ctx.auth.config.component.factor.totp.get, { verifiedForUserId: userId });
|
|
19
19
|
}
|
|
20
20
|
async function mutateTotpInsert(ctx, args) {
|
|
21
|
-
return await ctx.runMutation(ctx.auth.config.component.
|
|
21
|
+
return await ctx.runMutation(ctx.auth.config.component.factor.totp.create, args);
|
|
22
22
|
}
|
|
23
23
|
async function mutateTotpMarkVerified(ctx, totpId, lastUsedAt) {
|
|
24
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
24
|
+
await ctx.runMutation(ctx.auth.config.component.factor.totp.update, {
|
|
25
25
|
totpId,
|
|
26
|
-
|
|
26
|
+
data: {
|
|
27
|
+
verified: true,
|
|
28
|
+
lastUsedAt
|
|
29
|
+
}
|
|
27
30
|
});
|
|
28
31
|
}
|
|
29
32
|
async function mutateTotpUpdateLastUsed(ctx, totpId, lastUsedAt) {
|
|
30
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
33
|
+
await ctx.runMutation(ctx.auth.config.component.factor.totp.update, {
|
|
31
34
|
totpId,
|
|
32
|
-
lastUsedAt
|
|
35
|
+
data: { lastUsedAt }
|
|
33
36
|
});
|
|
34
37
|
}
|
|
35
38
|
async function queryPasskeysByUserId(ctx, userId) {
|
|
36
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
39
|
+
return await ctx.runQuery(ctx.auth.config.component.factor.passkey.list, { userId });
|
|
37
40
|
}
|
|
38
41
|
async function queryPasskeyByCredentialId(ctx, credentialId) {
|
|
39
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
42
|
+
return await ctx.runQuery(ctx.auth.config.component.factor.passkey.get, { credentialId });
|
|
40
43
|
}
|
|
41
44
|
async function mutatePasskeyInsert(ctx, args) {
|
|
42
|
-
return await ctx.runMutation(ctx.auth.config.component.
|
|
45
|
+
return await ctx.runMutation(ctx.auth.config.component.factor.passkey.create, args);
|
|
43
46
|
}
|
|
44
47
|
async function mutatePasskeyUpdateCounter(ctx, passkeyId, counter, lastUsedAt) {
|
|
45
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
48
|
+
await ctx.runMutation(ctx.auth.config.component.factor.passkey.update, {
|
|
46
49
|
passkeyId,
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
data: {
|
|
51
|
+
counter,
|
|
52
|
+
lastUsedAt
|
|
53
|
+
}
|
|
49
54
|
});
|
|
50
55
|
}
|
|
51
56
|
async function mutateDeviceInsert(ctx, args) {
|
|
52
|
-
return await ctx.runMutation(ctx.auth.config.component.
|
|
57
|
+
return await ctx.runMutation(ctx.auth.config.component.factor.device.create, args);
|
|
53
58
|
}
|
|
54
59
|
async function queryDeviceByCodeHash(ctx, deviceCodeHash) {
|
|
55
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
60
|
+
return await ctx.runQuery(ctx.auth.config.component.factor.device.get, { deviceCodeHash });
|
|
56
61
|
}
|
|
57
62
|
async function queryDeviceByUserCode(ctx, userCode) {
|
|
58
|
-
return await ctx.runQuery(ctx.auth.config.component.
|
|
63
|
+
return await ctx.runQuery(ctx.auth.config.component.factor.device.get, { userCode });
|
|
59
64
|
}
|
|
60
65
|
async function mutateDeviceAuthorize(ctx, deviceId, userId, sessionId) {
|
|
61
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
66
|
+
await ctx.runMutation(ctx.auth.config.component.factor.device.authorize, {
|
|
62
67
|
deviceId,
|
|
63
68
|
userId,
|
|
64
69
|
sessionId
|
|
65
70
|
});
|
|
66
71
|
}
|
|
67
72
|
async function mutateDeviceUpdateLastPolled(ctx, deviceId, lastPolledAt) {
|
|
68
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
73
|
+
await ctx.runMutation(ctx.auth.config.component.factor.device.update, {
|
|
69
74
|
deviceId,
|
|
70
|
-
lastPolledAt
|
|
75
|
+
data: { lastPolledAt }
|
|
71
76
|
});
|
|
72
77
|
}
|
|
73
78
|
async function mutateDeviceDelete(ctx, deviceId) {
|
|
74
|
-
await ctx.runMutation(ctx.auth.config.component.
|
|
79
|
+
await ctx.runMutation(ctx.auth.config.component.factor.device.delete, { deviceId });
|
|
75
80
|
}
|
|
76
81
|
|
|
77
82
|
//#endregion
|
package/dist/server/users.js
CHANGED
|
@@ -67,6 +67,51 @@ async function checkAllowLink(args, config, userId) {
|
|
|
67
67
|
userId
|
|
68
68
|
}) !== false;
|
|
69
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Persist the emails this sign-in asserts onto the resolved user.
|
|
72
|
+
*
|
|
73
|
+
* The profile's primary email is recorded as the primary `UserEmail`
|
|
74
|
+
* row; any provider-reported secondaries (e.g. GitHub `/user/emails`)
|
|
75
|
+
* are recorded non-primary, each keeping its own verified state.
|
|
76
|
+
* Provenance (`source`, `provider`, `connectionId`) is captured so SSO
|
|
77
|
+
* linking can stay connection-scoped.
|
|
78
|
+
*
|
|
79
|
+
* @param db - The component-backed auth DB facade.
|
|
80
|
+
* @param userId - The resolved (created or linked) user.
|
|
81
|
+
* @param args - The create-or-update args (provider, accountExtend, emails).
|
|
82
|
+
* @param profile - The provisioned profile (already destructured).
|
|
83
|
+
* @param emailVerified - Whether the primary email is verified.
|
|
84
|
+
*/
|
|
85
|
+
async function recordOwnedEmails(db, userId, args, profile, emailVerified) {
|
|
86
|
+
const identity = args.accountExtend?.identity;
|
|
87
|
+
const protocol = typeof identity?.protocol === "string" ? identity.protocol : void 0;
|
|
88
|
+
const source = protocol === "saml" ? "saml" : protocol === "oidc" ? "oidc" : args.provider.type === "oauth" ? "oauth" : "password";
|
|
89
|
+
const provider = typeof args.provider.id === "string" ? args.provider.id : void 0;
|
|
90
|
+
const connectionId = typeof identity?.connectionId === "string" ? identity.connectionId : void 0;
|
|
91
|
+
const primaryEmail = typeof profile.email === "string" ? profile.email.toLowerCase() : null;
|
|
92
|
+
if (primaryEmail !== null) await db.emails.upsert({
|
|
93
|
+
userId,
|
|
94
|
+
email: primaryEmail,
|
|
95
|
+
verified: emailVerified,
|
|
96
|
+
isPrimary: true,
|
|
97
|
+
source,
|
|
98
|
+
provider,
|
|
99
|
+
connectionId
|
|
100
|
+
});
|
|
101
|
+
for (const entry of args.emails ?? []) {
|
|
102
|
+
const addr = entry.email.toLowerCase();
|
|
103
|
+
if (addr === primaryEmail) continue;
|
|
104
|
+
await db.emails.upsert({
|
|
105
|
+
userId,
|
|
106
|
+
email: addr,
|
|
107
|
+
verified: entry.verified === true,
|
|
108
|
+
isPrimary: false,
|
|
109
|
+
source,
|
|
110
|
+
provider,
|
|
111
|
+
connectionId
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
70
115
|
async function updateExistingUser(db, userId, userData, source, provisioningUser) {
|
|
71
116
|
const currentUser = await db.users.getById(userId);
|
|
72
117
|
const mode = effectiveUserUpdateMode(source, provisioningUser);
|
|
@@ -109,8 +154,9 @@ async function defaultCreateOrUpdateUser(ctx, existingSessionId, existingAccount
|
|
|
109
154
|
const { provider, profile: { id: _profileId, emailVerified: profileEmailVerified, phoneVerified: profilePhoneVerified, ...profile } } = args;
|
|
110
155
|
const emailVerified = profileEmailVerified ?? (provider.type === "oauth" && provider.accountLinking !== "none");
|
|
111
156
|
const phoneVerified = profilePhoneVerified ?? false;
|
|
112
|
-
const
|
|
113
|
-
const
|
|
157
|
+
const connectionScopedLinking = provider.type === "oauth" && provider.accountLinking === "sameConnection";
|
|
158
|
+
const shouldLinkViaEmail = !connectionScopedLinking && (args.shouldLinkViaEmail || emailVerified || provider.type === "email");
|
|
159
|
+
const shouldLinkViaPhone = !connectionScopedLinking && (args.shouldLinkViaPhone || phoneVerified || provider.type === "phone");
|
|
114
160
|
let userId = existingUserId ?? existingUserIdOverride;
|
|
115
161
|
if (existingUserId === null) {
|
|
116
162
|
userId = await resolveUserIdByLinking(ctx, args, profile, shouldLinkViaEmail, shouldLinkViaPhone, existingUserIdOverride, config);
|
|
@@ -130,6 +176,7 @@ async function defaultCreateOrUpdateUser(ctx, existingSessionId, existingAccount
|
|
|
130
176
|
});
|
|
131
177
|
userId = await db.users.insert(userData);
|
|
132
178
|
}
|
|
179
|
+
await recordOwnedEmails(db, userId, args, profile, emailVerified === true);
|
|
133
180
|
const after = config.callbacks?.after;
|
|
134
181
|
if (after !== void 0) {
|
|
135
182
|
log(LOG_LEVELS.DEBUG, "Calling `after` callback for user lifecycle event");
|