@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
|
@@ -27,20 +27,6 @@ import { ConvexError, v } from "convex/values";
|
|
|
27
27
|
* @param metadata - Optional arbitrary metadata to attach to the key record.
|
|
28
28
|
* @returns The `_id` of the newly created `ApiKey` document.
|
|
29
29
|
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* const keyId = await ctx.runMutation(
|
|
33
|
-
* components.auth.security.keys.keyInsert,
|
|
34
|
-
* {
|
|
35
|
-
* userId: user._id,
|
|
36
|
-
* prefix: "sk_live_",
|
|
37
|
-
* hashedKey: await sha256(rawKey),
|
|
38
|
-
* name: "Production Backend",
|
|
39
|
-
* scopes: [{ resource: "messages", actions: ["read", "write"] }],
|
|
40
|
-
* expiresAt: Date.now() + 90 * 24 * 60 * 60 * 1000,
|
|
41
|
-
* },
|
|
42
|
-
* );
|
|
43
|
-
* ```
|
|
44
30
|
*/
|
|
45
31
|
const keyInsert = mutation({
|
|
46
32
|
args: {
|
|
@@ -66,35 +52,20 @@ const keyInsert = mutation({
|
|
|
66
52
|
}
|
|
67
53
|
});
|
|
68
54
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* primary lookup path during Bearer token verification: the incoming
|
|
73
|
-
* token is hashed and matched against stored hashes in constant time.
|
|
74
|
-
* Returns the full key record including scopes, rate limit state, and
|
|
75
|
-
* revocation status so the caller can perform authorization checks.
|
|
76
|
-
*
|
|
77
|
-
* @param hashedKey - SHA-256 hash of the API key string extracted from
|
|
78
|
-
* the `Authorization: Bearer <token>` header.
|
|
79
|
-
* @returns The matching `ApiKey` document (including rate limit state),
|
|
80
|
-
* or `null` if no key matches the given hash.
|
|
81
|
-
*
|
|
82
|
-
* @example
|
|
83
|
-
* ```ts
|
|
84
|
-
* const apiKey = await ctx.runQuery(
|
|
85
|
-
* components.auth.security.keys.keyGetByHashedKey,
|
|
86
|
-
* { hashedKey: await sha256(bearerToken) },
|
|
87
|
-
* );
|
|
88
|
-
* if (apiKey === null || apiKey.revoked) {
|
|
89
|
-
* throw new Error("Invalid or revoked API key");
|
|
90
|
-
* }
|
|
91
|
-
* ```
|
|
55
|
+
* Read an API key by identity — one function, all-optional args, unioned
|
|
56
|
+
* return: `{ id }` (point lookup) or `{ hashedKey }` (Bearer-verify
|
|
57
|
+
* index).
|
|
92
58
|
*/
|
|
93
|
-
const
|
|
94
|
-
args: {
|
|
59
|
+
const keyGet = query({
|
|
60
|
+
args: {
|
|
61
|
+
id: v.optional(v.id("ApiKey")),
|
|
62
|
+
hashedKey: v.optional(v.string())
|
|
63
|
+
},
|
|
95
64
|
returns: v.union(vApiKeyDoc, v.null()),
|
|
96
|
-
handler: async (ctx,
|
|
97
|
-
return await ctx.db.query("ApiKey").withIndex("hashed_key", (q) => q.eq("hashedKey", hashedKey)).first();
|
|
65
|
+
handler: async (ctx, args) => {
|
|
66
|
+
if (args.hashedKey !== void 0) return await ctx.db.query("ApiKey").withIndex("hashed_key", (q) => q.eq("hashedKey", args.hashedKey)).first();
|
|
67
|
+
if (args.id === void 0) return null;
|
|
68
|
+
return await ctx.db.get("ApiKey", args.id);
|
|
98
69
|
}
|
|
99
70
|
});
|
|
100
71
|
/**
|
|
@@ -123,25 +94,6 @@ const keyGetByHashedKey = query({
|
|
|
123
94
|
* @returns An object with `items` (array of `ApiKey` documents) and
|
|
124
95
|
* `nextCursor` (string ID of the last item, or `null` if no more pages).
|
|
125
96
|
*
|
|
126
|
-
* @example
|
|
127
|
-
* ```ts
|
|
128
|
-
* // Fetch the first page of active keys for a user
|
|
129
|
-
* const page = await ctx.runQuery(
|
|
130
|
-
* components.auth.security.keys.keyList,
|
|
131
|
-
* {
|
|
132
|
-
* where: { userId: user._id, revoked: false },
|
|
133
|
-
* limit: 20,
|
|
134
|
-
* order: "desc",
|
|
135
|
-
* },
|
|
136
|
-
* );
|
|
137
|
-
* // Fetch the next page
|
|
138
|
-
* if (page.nextCursor) {
|
|
139
|
-
* const page2 = await ctx.runQuery(
|
|
140
|
-
* components.auth.security.keys.keyList,
|
|
141
|
-
* { where: { userId: user._id, revoked: false }, cursor: page.nextCursor },
|
|
142
|
-
* );
|
|
143
|
-
* }
|
|
144
|
-
* ```
|
|
145
97
|
*/
|
|
146
98
|
const keyList = query({
|
|
147
99
|
args: {
|
|
@@ -184,35 +136,6 @@ const keyList = query({
|
|
|
184
136
|
}
|
|
185
137
|
});
|
|
186
138
|
/**
|
|
187
|
-
* Get a single API key by its document ID.
|
|
188
|
-
*
|
|
189
|
-
* Performs a direct document lookup on the `ApiKey` table. Useful when
|
|
190
|
-
* you already have the key's `_id` (e.g. from a list query or a stored
|
|
191
|
-
* reference) and need to retrieve its full details.
|
|
192
|
-
*
|
|
193
|
-
* @param keyId - The `_id` of the `ApiKey` document to retrieve.
|
|
194
|
-
* @returns The `ApiKey` document, or `null` if no key exists with the
|
|
195
|
-
* given ID.
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* ```ts
|
|
199
|
-
* const apiKey = await ctx.runQuery(
|
|
200
|
-
* components.auth.security.keys.keyGetById,
|
|
201
|
-
* { keyId: storedKeyId },
|
|
202
|
-
* );
|
|
203
|
-
* if (apiKey !== null) {
|
|
204
|
-
* console.log(apiKey.name, apiKey.scopes);
|
|
205
|
-
* }
|
|
206
|
-
* ```
|
|
207
|
-
*/
|
|
208
|
-
const keyGetById = query({
|
|
209
|
-
args: { keyId: v.id("ApiKey") },
|
|
210
|
-
returns: v.union(vApiKeyDoc, v.null()),
|
|
211
|
-
handler: async (ctx, { keyId }) => {
|
|
212
|
-
return await ctx.db.get("ApiKey", keyId);
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
|
-
/**
|
|
216
139
|
* Patch an API key record with partial updates.
|
|
217
140
|
*
|
|
218
141
|
* Performs a partial update on the `ApiKey` document. Supports modifying
|
|
@@ -234,29 +157,6 @@ const keyGetById = query({
|
|
|
234
157
|
* recent API call using this key.
|
|
235
158
|
* @returns `null` on success.
|
|
236
159
|
*
|
|
237
|
-
* @example
|
|
238
|
-
* ```ts
|
|
239
|
-
* // Revoke an API key
|
|
240
|
-
* await ctx.runMutation(
|
|
241
|
-
* components.auth.security.keys.keyPatch,
|
|
242
|
-
* {
|
|
243
|
-
* keyId: apiKey._id,
|
|
244
|
-
* data: { revoked: true },
|
|
245
|
-
* },
|
|
246
|
-
* );
|
|
247
|
-
*
|
|
248
|
-
* // Rename and update scopes
|
|
249
|
-
* await ctx.runMutation(
|
|
250
|
-
* components.auth.security.keys.keyPatch,
|
|
251
|
-
* {
|
|
252
|
-
* keyId: apiKey._id,
|
|
253
|
-
* data: {
|
|
254
|
-
* name: "Read-Only Key",
|
|
255
|
-
* scopes: [{ resource: "messages", actions: ["read"] }],
|
|
256
|
-
* },
|
|
257
|
-
* },
|
|
258
|
-
* );
|
|
259
|
-
* ```
|
|
260
160
|
*/
|
|
261
161
|
const keyPatch = mutation({
|
|
262
162
|
args: {
|
|
@@ -292,13 +192,6 @@ const keyPatch = mutation({
|
|
|
292
192
|
* @param keyId - The `_id` of the `ApiKey` document to delete.
|
|
293
193
|
* @returns `null` on success.
|
|
294
194
|
*
|
|
295
|
-
* @example
|
|
296
|
-
* ```ts
|
|
297
|
-
* await ctx.runMutation(
|
|
298
|
-
* components.auth.security.keys.keyDelete,
|
|
299
|
-
* { keyId: apiKey._id },
|
|
300
|
-
* );
|
|
301
|
-
* ```
|
|
302
195
|
*/
|
|
303
196
|
const keyDelete = mutation({
|
|
304
197
|
args: { keyId: v.id("ApiKey") },
|
|
@@ -315,5 +208,5 @@ const keyDelete = mutation({
|
|
|
315
208
|
});
|
|
316
209
|
|
|
317
210
|
//#endregion
|
|
318
|
-
export { keyDelete,
|
|
211
|
+
export { keyDelete, keyGet, keyInsert, keyList, keyPatch };
|
|
319
212
|
//# sourceMappingURL=keys.js.map
|
|
@@ -16,16 +16,6 @@ import { v } from "convex/values";
|
|
|
16
16
|
* @returns The rate limit state object (including `attemptsLeft` and
|
|
17
17
|
* `lastAttemptTime`), or `null` if no entry exists for the identifier.
|
|
18
18
|
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* const limit = await ctx.runQuery(
|
|
22
|
-
* components.auth.security.limits.rateLimitGet,
|
|
23
|
-
* { identifier: `login:${email}` },
|
|
24
|
-
* );
|
|
25
|
-
* if (limit !== null && limit.attemptsLeft <= 0) {
|
|
26
|
-
* throw new Error("Too many login attempts. Please try again later.");
|
|
27
|
-
* }
|
|
28
|
-
* ```
|
|
29
19
|
*/
|
|
30
20
|
const rateLimitGet = query({
|
|
31
21
|
args: { identifier: v.string() },
|
|
@@ -57,17 +47,6 @@ const rateLimitGet = query({
|
|
|
57
47
|
* initial attempt.
|
|
58
48
|
* @returns The `_id` of the newly created `RateLimit` document.
|
|
59
49
|
*
|
|
60
|
-
* @example
|
|
61
|
-
* ```ts
|
|
62
|
-
* const rateLimitId = await ctx.runMutation(
|
|
63
|
-
* components.auth.security.limits.rateLimitCreate,
|
|
64
|
-
* {
|
|
65
|
-
* identifier: `login:${email}`,
|
|
66
|
-
* attemptsLeft: 4, // 5 max minus this attempt
|
|
67
|
-
* lastAttemptTime: Date.now(),
|
|
68
|
-
* },
|
|
69
|
-
* );
|
|
70
|
-
* ```
|
|
71
50
|
*/
|
|
72
51
|
const rateLimitCreate = mutation({
|
|
73
52
|
args: {
|
|
@@ -100,20 +79,6 @@ const rateLimitCreate = mutation({
|
|
|
100
79
|
* - `lastAttemptTime` -- Updated timestamp of the most recent attempt.
|
|
101
80
|
* @returns `null` on success.
|
|
102
81
|
*
|
|
103
|
-
* @example
|
|
104
|
-
* ```ts
|
|
105
|
-
* // Decrement attempts after a failed login
|
|
106
|
-
* await ctx.runMutation(
|
|
107
|
-
* components.auth.security.limits.rateLimitPatch,
|
|
108
|
-
* {
|
|
109
|
-
* rateLimitId: limit._id,
|
|
110
|
-
* data: {
|
|
111
|
-
* attemptsLeft: limit.attemptsLeft - 1,
|
|
112
|
-
* lastAttemptTime: Date.now(),
|
|
113
|
-
* },
|
|
114
|
-
* },
|
|
115
|
-
* );
|
|
116
|
-
* ```
|
|
117
82
|
*/
|
|
118
83
|
const rateLimitPatch = mutation({
|
|
119
84
|
args: {
|
|
@@ -146,14 +111,6 @@ const rateLimitPatch = mutation({
|
|
|
146
111
|
* @param rateLimitId - The `_id` of the `RateLimit` document to delete.
|
|
147
112
|
* @returns `null` on success.
|
|
148
113
|
*
|
|
149
|
-
* @example
|
|
150
|
-
* ```ts
|
|
151
|
-
* // Admin resets a user's login rate limit
|
|
152
|
-
* await ctx.runMutation(
|
|
153
|
-
* components.auth.security.limits.rateLimitDelete,
|
|
154
|
-
* { rateLimitId: limit._id },
|
|
155
|
-
* );
|
|
156
|
-
* ```
|
|
157
114
|
*/
|
|
158
115
|
const rateLimitDelete = mutation({
|
|
159
116
|
args: { rateLimitId: v.id("RateLimit") },
|
|
@@ -24,24 +24,6 @@ import { ConvexError, v } from "convex/values";
|
|
|
24
24
|
* @param args.metadata - An optional arbitrary object with additional event details.
|
|
25
25
|
* @returns The ID of the newly created `GroupAuditEvent` document.
|
|
26
26
|
*
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* const eventId = await ctx.runMutation(
|
|
30
|
-
* components.auth.group.sso.groupAuditEventCreate,
|
|
31
|
-
* {
|
|
32
|
-
* connectionId,
|
|
33
|
-
* groupId: orgGroupId,
|
|
34
|
-
* eventType: "user.login",
|
|
35
|
-
* actorType: "user",
|
|
36
|
-
* actorId: userId,
|
|
37
|
-
* subjectType: "session",
|
|
38
|
-
* subjectId: sessionId,
|
|
39
|
-
* status: "success",
|
|
40
|
-
* occurredAt: Date.now(),
|
|
41
|
-
* ip: "203.0.113.42",
|
|
42
|
-
* },
|
|
43
|
-
* );
|
|
44
|
-
* ```
|
|
45
27
|
*/
|
|
46
28
|
const groupAuditEventCreate = mutation({
|
|
47
29
|
args: {
|
|
@@ -77,16 +59,6 @@ const groupAuditEventCreate = mutation({
|
|
|
77
59
|
* @param args.limit - Maximum number of events to return (clamped between 1 and 100, defaults to 50).
|
|
78
60
|
* @returns An array of audit event documents, most recent first.
|
|
79
61
|
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```ts
|
|
82
|
-
* const events = await ctx.runQuery(
|
|
83
|
-
* components.auth.group.sso.groupAuditEventList,
|
|
84
|
-
* { connectionId, limit: 20 },
|
|
85
|
-
* );
|
|
86
|
-
* for (const event of events) {
|
|
87
|
-
* console.log(event.eventType, event.actorType, event.status);
|
|
88
|
-
* }
|
|
89
|
-
* ```
|
|
90
62
|
*/
|
|
91
63
|
const groupAuditEventList = query({
|
|
92
64
|
args: {
|
|
@@ -18,18 +18,6 @@ import { v } from "convex/values";
|
|
|
18
18
|
* @param args.extend - An optional arbitrary extension object for custom fields.
|
|
19
19
|
* @returns The ID of the newly created `Group Connection` document.
|
|
20
20
|
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* const connectionId = await ctx.runMutation(
|
|
24
|
-
* components.auth.group.sso.groupConnectionCreate,
|
|
25
|
-
* {
|
|
26
|
-
* groupId: orgGroupId,
|
|
27
|
-
* slug: "acme-corp",
|
|
28
|
-
* name: "Acme Corporation",
|
|
29
|
-
* status: "active",
|
|
30
|
-
* },
|
|
31
|
-
* );
|
|
32
|
-
* ```
|
|
33
21
|
*/
|
|
34
22
|
const groupConnectionCreate = mutation({
|
|
35
23
|
args: {
|
|
@@ -50,69 +38,44 @@ const groupConnectionCreate = mutation({
|
|
|
50
38
|
}
|
|
51
39
|
});
|
|
52
40
|
/**
|
|
53
|
-
*
|
|
41
|
+
* Read a group connection by identity.
|
|
54
42
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
43
|
+
* Accepts exactly one selector:
|
|
44
|
+
* - `connectionId` — direct document lookup, returning the
|
|
45
|
+
* `GroupConnection` document or `null`.
|
|
46
|
+
* - `domain` — resolve the connection that owns a linked domain. Looks
|
|
47
|
+
* up the `GroupConnectionDomain` row, then its parent connection, and
|
|
48
|
+
* returns `{ connection, domain }` (or `null` if the domain is not
|
|
49
|
+
* registered or its connection no longer exists).
|
|
57
50
|
*
|
|
58
|
-
* @param
|
|
59
|
-
* @
|
|
51
|
+
* @param connectionId - Optional `_id` of the `GroupConnection`.
|
|
52
|
+
* @param domain - Optional domain name to resolve (e.g. `"acme.com"`).
|
|
53
|
+
* @returns For `connectionId`: the connection document or `null`. For
|
|
54
|
+
* `domain`: `{ connection, domain }` or `null`.
|
|
60
55
|
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```ts
|
|
63
|
-
* const connection = await ctx.runQuery(
|
|
64
|
-
* components.auth.group.sso.groupConnectionGet,
|
|
65
|
-
* { connectionId },
|
|
66
|
-
* );
|
|
67
|
-
* if (connection) {
|
|
68
|
-
* console.log(group.sso.name, group.sso.status);
|
|
69
|
-
* }
|
|
70
|
-
* ```
|
|
71
56
|
*/
|
|
72
57
|
const groupConnectionGet = query({
|
|
73
|
-
args: {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
/**
|
|
80
|
-
* Retrieve an group connection record by one of its linked domain names.
|
|
81
|
-
*
|
|
82
|
-
* Looks up a `GroupConnectionDomain` row matching the given domain string, then
|
|
83
|
-
* resolves the parent group.sso. Returns both the group connection and the matched
|
|
84
|
-
* domain document, or `null` if the domain is not registered or its group connection
|
|
85
|
-
* no longer exists.
|
|
86
|
-
*
|
|
87
|
-
* @param args.domain - The domain name to search for (e.g. `"acme.com"`).
|
|
88
|
-
* @returns An object containing the `group connection` and `domain` documents, or `null` if not found.
|
|
89
|
-
*
|
|
90
|
-
* @example
|
|
91
|
-
* ```ts
|
|
92
|
-
* const result = await ctx.runQuery(
|
|
93
|
-
* components.auth.group.sso.groupConnectionGetByDomain,
|
|
94
|
-
* { domain: "acme.com" },
|
|
95
|
-
* );
|
|
96
|
-
* if (result) {
|
|
97
|
-
* console.log(result.connection.name, result.domain.verifiedAt);
|
|
98
|
-
* }
|
|
99
|
-
* ```
|
|
100
|
-
*/
|
|
101
|
-
const groupConnectionGetByDomain = query({
|
|
102
|
-
args: { domain: v.string() },
|
|
103
|
-
returns: v.union(v.object({
|
|
58
|
+
args: {
|
|
59
|
+
connectionId: v.optional(v.id("GroupConnection")),
|
|
60
|
+
domain: v.optional(v.string())
|
|
61
|
+
},
|
|
62
|
+
returns: v.union(vGroupConnectionDoc, v.object({
|
|
104
63
|
connection: vGroupConnectionDoc,
|
|
105
64
|
domain: vGroupConnectionDomainDoc
|
|
106
65
|
}), v.null()),
|
|
107
|
-
handler: async (ctx,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
66
|
+
handler: async (ctx, args) => {
|
|
67
|
+
if (args.domain !== void 0) {
|
|
68
|
+
const domainRow = await ctx.db.query("GroupConnectionDomain").withIndex("domain", (idx) => idx.eq("domain", args.domain)).first();
|
|
69
|
+
if (!domainRow) return null;
|
|
70
|
+
const connection = await ctx.db.get("GroupConnection", domainRow.connectionId);
|
|
71
|
+
if (!connection) return null;
|
|
72
|
+
return {
|
|
73
|
+
connection,
|
|
74
|
+
domain: domainRow
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (args.connectionId === void 0) return null;
|
|
78
|
+
return await ctx.db.get("GroupConnection", args.connectionId);
|
|
116
79
|
}
|
|
117
80
|
});
|
|
118
81
|
/**
|
|
@@ -130,25 +93,6 @@ const groupConnectionGetByDomain = query({
|
|
|
130
93
|
* @param args.order - Sort direction: `"asc"` or `"desc"` (defaults to `"desc"`).
|
|
131
94
|
* @returns A paginated result containing `items` (array of group connection documents) and `nextCursor` (`string | null`).
|
|
132
95
|
*
|
|
133
|
-
* @example
|
|
134
|
-
* ```ts
|
|
135
|
-
* const page = await ctx.runQuery(
|
|
136
|
-
* components.auth.group.sso.groupConnectionList,
|
|
137
|
-
* {
|
|
138
|
-
* where: { status: "active" },
|
|
139
|
-
* limit: 25,
|
|
140
|
-
* order: "asc",
|
|
141
|
-
* },
|
|
142
|
-
* );
|
|
143
|
-
* for (const ent of page.items) {
|
|
144
|
-
* console.log(ent.name);
|
|
145
|
-
* }
|
|
146
|
-
* // Fetch next page:
|
|
147
|
-
* const nextPage = await ctx.runQuery(
|
|
148
|
-
* components.auth.group.sso.groupConnectionList,
|
|
149
|
-
* { where: { status: "active" }, cursor: page.nextCursor },
|
|
150
|
-
* );
|
|
151
|
-
* ```
|
|
152
96
|
*/
|
|
153
97
|
const groupConnectionList = query({
|
|
154
98
|
args: {
|
|
@@ -200,16 +144,6 @@ const groupConnectionList = query({
|
|
|
200
144
|
* @param args.data - An object containing the fields to update (e.g. `{ name, status, policy }`).
|
|
201
145
|
* @returns `null` on success.
|
|
202
146
|
*
|
|
203
|
-
* @example
|
|
204
|
-
* ```ts
|
|
205
|
-
* await ctx.runMutation(
|
|
206
|
-
* components.auth.group.sso.groupConnectionUpdate,
|
|
207
|
-
* {
|
|
208
|
-
* connectionId,
|
|
209
|
-
* data: { status: "active", name: "Acme Corp (Renamed)" },
|
|
210
|
-
* },
|
|
211
|
-
* );
|
|
212
|
-
* ```
|
|
213
147
|
*/
|
|
214
148
|
const groupConnectionUpdate = mutation({
|
|
215
149
|
args: {
|
|
@@ -233,13 +167,6 @@ const groupConnectionUpdate = mutation({
|
|
|
233
167
|
* @param args.connectionId - The document ID of the group connection to delete.
|
|
234
168
|
* @returns `null` on success.
|
|
235
169
|
*
|
|
236
|
-
* @example
|
|
237
|
-
* ```ts
|
|
238
|
-
* await ctx.runMutation(
|
|
239
|
-
* components.auth.group.sso.groupConnectionDelete,
|
|
240
|
-
* { connectionId },
|
|
241
|
-
* );
|
|
242
|
-
* ```
|
|
243
170
|
*/
|
|
244
171
|
const groupConnectionDelete = mutation({
|
|
245
172
|
args: { connectionId: v.id("GroupConnection") },
|
|
@@ -259,5 +186,5 @@ const groupConnectionDelete = mutation({
|
|
|
259
186
|
});
|
|
260
187
|
|
|
261
188
|
//#endregion
|
|
262
|
-
export { groupConnectionCreate, groupConnectionDelete, groupConnectionGet,
|
|
189
|
+
export { groupConnectionCreate, groupConnectionDelete, groupConnectionGet, groupConnectionList, groupConnectionUpdate };
|
|
263
190
|
//# sourceMappingURL=core.js.map
|
|
@@ -18,18 +18,6 @@ import { ConvexError, v } from "convex/values";
|
|
|
18
18
|
* @param args.isPrimary - Whether this domain should be set as the primary domain for the connection. Defaults to `true` for the first domain.
|
|
19
19
|
* @returns The ID of the created or updated `GroupConnectionDomain` document.
|
|
20
20
|
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```ts
|
|
23
|
-
* const domainId = await ctx.runMutation(
|
|
24
|
-
* components.auth.connection.groupConnectionDomainAdd,
|
|
25
|
-
* {
|
|
26
|
-
* connectionId,
|
|
27
|
-
* groupId: orgGroupId,
|
|
28
|
-
* domain: "acme.com",
|
|
29
|
-
* isPrimary: true,
|
|
30
|
-
* },
|
|
31
|
-
* );
|
|
32
|
-
* ```
|
|
33
21
|
*/
|
|
34
22
|
const groupConnectionDomainAdd = mutation({
|
|
35
23
|
args: {
|
|
@@ -71,16 +59,6 @@ const groupConnectionDomainAdd = mutation({
|
|
|
71
59
|
* @param args.connectionId - The ID of the connection whose domains to list.
|
|
72
60
|
* @returns An array of connection domain documents.
|
|
73
61
|
*
|
|
74
|
-
* @example
|
|
75
|
-
* ```ts
|
|
76
|
-
* const domains = await ctx.runQuery(
|
|
77
|
-
* components.auth.connection.groupConnectionDomainList,
|
|
78
|
-
* { connectionId },
|
|
79
|
-
* );
|
|
80
|
-
* for (const d of domains) {
|
|
81
|
-
* console.log(d.domain, d.isPrimary, d.verifiedAt);
|
|
82
|
-
* }
|
|
83
|
-
* ```
|
|
84
62
|
*/
|
|
85
63
|
const groupConnectionDomainList = query({
|
|
86
64
|
args: {
|
|
@@ -102,13 +80,6 @@ const groupConnectionDomainList = query({
|
|
|
102
80
|
* @param args.domainId - The document ID of the connection domain to remove.
|
|
103
81
|
* @returns `null` on success.
|
|
104
82
|
*
|
|
105
|
-
* @example
|
|
106
|
-
* ```ts
|
|
107
|
-
* await ctx.runMutation(
|
|
108
|
-
* components.auth.connection.groupConnectionDomainDelete,
|
|
109
|
-
* { domainId },
|
|
110
|
-
* );
|
|
111
|
-
* ```
|
|
112
83
|
*/
|
|
113
84
|
const groupConnectionDomainDelete = mutation({
|
|
114
85
|
args: { domainId: v.id("GroupConnectionDomain") },
|
|
@@ -129,16 +100,6 @@ const groupConnectionDomainDelete = mutation({
|
|
|
129
100
|
* @param args.domainId - The document ID of the connection domain whose verification to retrieve.
|
|
130
101
|
* @returns The domain verification document, or `null` if none exists.
|
|
131
102
|
*
|
|
132
|
-
* @example
|
|
133
|
-
* ```ts
|
|
134
|
-
* const verification = await ctx.runQuery(
|
|
135
|
-
* components.auth.connection.groupConnectionDomainVerificationGet,
|
|
136
|
-
* { domainId },
|
|
137
|
-
* );
|
|
138
|
-
* if (verification) {
|
|
139
|
-
* console.log(verification.recordName, verification.expiresAt);
|
|
140
|
-
* }
|
|
141
|
-
* ```
|
|
142
103
|
*/
|
|
143
104
|
const groupConnectionDomainVerificationGet = query({
|
|
144
105
|
args: { domainId: v.id("GroupConnectionDomain") },
|
|
@@ -166,23 +127,6 @@ const groupConnectionDomainVerificationGet = query({
|
|
|
166
127
|
* @param args.expiresAt - Epoch timestamp (ms) after which the challenge expires.
|
|
167
128
|
* @returns The ID of the created or updated `GroupConnectionDomainVerification` document.
|
|
168
129
|
*
|
|
169
|
-
* @example
|
|
170
|
-
* ```ts
|
|
171
|
-
* const verificationId = await ctx.runMutation(
|
|
172
|
-
* components.auth.connection.groupConnectionDomainVerificationUpsert,
|
|
173
|
-
* {
|
|
174
|
-
* connectionId,
|
|
175
|
-
* groupId: orgGroupId,
|
|
176
|
-
* domainId,
|
|
177
|
-
* domain: "acme.com",
|
|
178
|
-
* recordName: "_convex-verify.acme.com",
|
|
179
|
-
* token: "abc123",
|
|
180
|
-
* tokenHash: "sha256:...",
|
|
181
|
-
* requestedAt: Date.now(),
|
|
182
|
-
* expiresAt: Date.now() + 7 * 24 * 60 * 60 * 1000,
|
|
183
|
-
* },
|
|
184
|
-
* );
|
|
185
|
-
* ```
|
|
186
130
|
*/
|
|
187
131
|
const groupConnectionDomainVerificationUpsert = mutation({
|
|
188
132
|
args: {
|
|
@@ -223,13 +167,6 @@ const groupConnectionDomainVerificationUpsert = mutation({
|
|
|
223
167
|
* @param args.domainId - The document ID of the connection domain whose verification to delete.
|
|
224
168
|
* @returns `null` on success.
|
|
225
169
|
*
|
|
226
|
-
* @example
|
|
227
|
-
* ```ts
|
|
228
|
-
* await ctx.runMutation(
|
|
229
|
-
* components.auth.connection.groupConnectionDomainVerificationDelete,
|
|
230
|
-
* { domainId },
|
|
231
|
-
* );
|
|
232
|
-
* ```
|
|
233
170
|
*/
|
|
234
171
|
const groupConnectionDomainVerificationDelete = mutation({
|
|
235
172
|
args: { domainId: v.id("GroupConnectionDomain") },
|
|
@@ -251,14 +188,6 @@ const groupConnectionDomainVerificationDelete = mutation({
|
|
|
251
188
|
* @param args.verifiedAt - Epoch timestamp (ms) at which the domain was verified.
|
|
252
189
|
* @returns The updated connection domain document with the `verifiedAt` field set.
|
|
253
190
|
*
|
|
254
|
-
* @example
|
|
255
|
-
* ```ts
|
|
256
|
-
* const verifiedDomain = await ctx.runMutation(
|
|
257
|
-
* components.auth.connection.groupConnectionDomainVerify,
|
|
258
|
-
* { domainId, verifiedAt: Date.now() },
|
|
259
|
-
* );
|
|
260
|
-
* console.log("Domain verified:", verifiedDomain.domain);
|
|
261
|
-
* ```
|
|
262
191
|
*/
|
|
263
192
|
const groupConnectionDomainVerify = mutation({
|
|
264
193
|
args: {
|