@robelest/convex-auth 0.0.4-preview.13 → 0.0.4-preview.15
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/README.md +140 -9
- package/dist/bin.cjs +5957 -5478
- package/dist/client/index.d.ts +3 -7
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +27 -26
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +14 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +1513 -3
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/model.d.ts +153 -0
- package/dist/component/model.d.ts.map +1 -0
- package/dist/component/model.js +327 -0
- package/dist/component/model.js.map +1 -0
- package/dist/component/providers/sso.d.ts +1 -1
- package/dist/component/public/enterprise.d.ts +49 -0
- package/dist/component/public/enterprise.d.ts.map +1 -0
- package/dist/component/public/enterprise.js +450 -0
- package/dist/component/public/enterprise.js.map +1 -0
- package/dist/component/public/factors.d.ts +52 -0
- package/dist/component/public/factors.d.ts.map +1 -0
- package/dist/component/public/factors.js +285 -0
- package/dist/component/public/factors.js.map +1 -0
- package/dist/component/public/groups.d.ts +118 -0
- package/dist/component/public/groups.d.ts.map +1 -0
- package/dist/component/public/groups.js +599 -0
- package/dist/component/public/groups.js.map +1 -0
- package/dist/component/public/identity.d.ts +93 -0
- package/dist/component/public/identity.d.ts.map +1 -0
- package/dist/component/public/identity.js +426 -0
- package/dist/component/public/identity.js.map +1 -0
- package/dist/component/public/keys.d.ts +41 -0
- package/dist/component/public/keys.d.ts.map +1 -0
- package/dist/component/public/keys.js +157 -0
- package/dist/component/public/keys.js.map +1 -0
- package/dist/component/public/shared.d.ts +26 -0
- package/dist/component/public/shared.d.ts.map +1 -0
- package/dist/component/public/shared.js +32 -0
- package/dist/component/public/shared.js.map +1 -0
- package/dist/component/public.d.ts +9 -321
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +6 -2145
- package/dist/component/schema.d.ts +368 -258
- package/dist/component/schema.js +23 -27
- package/dist/component/schema.js.map +1 -1
- package/dist/component/server/auth.d.ts +42 -7
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +70 -6
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/cookies.js +3 -0
- package/dist/component/server/cookies.js.map +1 -1
- package/dist/component/server/db.js +1 -0
- package/dist/component/server/db.js.map +1 -1
- package/dist/component/server/device.js +3 -1
- package/dist/component/server/device.js.map +1 -1
- package/dist/component/server/domains/core.js +466 -0
- package/dist/component/server/domains/core.js.map +1 -0
- package/dist/component/server/domains/sso.js +689 -0
- package/dist/component/server/domains/sso.js.map +1 -0
- package/dist/component/server/factory.d.ts +136 -0
- package/dist/component/server/factory.d.ts.map +1 -0
- package/dist/component/server/factory.js +1128 -0
- package/dist/component/server/factory.js.map +1 -0
- package/dist/component/server/fx.js +2 -1
- package/dist/component/server/fx.js.map +1 -1
- package/dist/component/server/http.js +287 -0
- package/dist/component/server/http.js.map +1 -0
- package/dist/component/server/identity.js +13 -0
- package/dist/component/server/identity.js.map +1 -0
- package/dist/component/server/keys.js +4 -0
- package/dist/component/server/keys.js.map +1 -1
- package/dist/component/server/mutations/account.js +1 -1
- package/dist/component/server/mutations/index.js +2 -2
- package/dist/component/server/mutations/index.js.map +1 -1
- package/dist/component/server/mutations/invalidate.js +1 -1
- package/dist/component/server/mutations/oauth.js +10 -7
- package/dist/component/server/mutations/oauth.js.map +1 -1
- package/dist/component/server/mutations/refresh.js +1 -1
- package/dist/component/server/mutations/register.js +1 -1
- package/dist/component/server/mutations/retrieve.js +1 -1
- package/dist/component/server/mutations/signature.js +1 -1
- package/dist/component/server/mutations/store.js +6 -3
- package/dist/component/server/mutations/store.js.map +1 -1
- package/dist/component/server/mutations/verify.js +1 -1
- package/dist/component/server/oauth.js +3 -0
- package/dist/component/server/oauth.js.map +1 -1
- package/dist/component/server/passkey.js +3 -2
- package/dist/component/server/passkey.js.map +1 -1
- package/dist/component/server/provider.js +2 -0
- package/dist/component/server/provider.js.map +1 -1
- package/dist/component/server/providers.js +3 -0
- package/dist/component/server/providers.js.map +1 -1
- package/dist/component/server/ratelimit.js +3 -0
- package/dist/component/server/ratelimit.js.map +1 -1
- package/dist/component/server/redirects.js +2 -0
- package/dist/component/server/redirects.js.map +1 -1
- package/dist/component/server/refresh.js +5 -0
- package/dist/component/server/refresh.js.map +1 -1
- package/dist/component/server/sessions.js +5 -0
- package/dist/component/server/sessions.js.map +1 -1
- package/dist/component/server/signin.js +2 -1
- package/dist/component/server/signin.js.map +1 -1
- package/dist/component/server/sso.js +166 -19
- package/dist/component/server/sso.js.map +1 -1
- package/dist/component/server/tokens.js +1 -0
- package/dist/component/server/tokens.js.map +1 -1
- package/dist/component/server/totp.js +4 -2
- package/dist/component/server/totp.js.map +1 -1
- package/dist/component/server/types.d.ts +50 -35
- package/dist/component/server/types.d.ts.map +1 -1
- package/dist/component/server/types.js.map +1 -1
- package/dist/component/server/users.js +1 -0
- package/dist/component/server/users.js.map +1 -1
- package/dist/component/server/utils.js +44 -2
- package/dist/component/server/utils.js.map +1 -1
- package/dist/providers/anonymous.d.ts +1 -1
- package/dist/providers/credentials.d.ts +1 -1
- package/dist/providers/password.d.ts +1 -1
- package/dist/providers/sso.d.ts +1 -1
- package/dist/providers/sso.js.map +1 -1
- package/dist/server/auth.d.ts +44 -9
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +70 -6
- package/dist/server/auth.js.map +1 -1
- package/dist/server/cookies.d.ts +1 -38
- package/dist/server/cookies.js +3 -0
- package/dist/server/cookies.js.map +1 -1
- package/dist/server/db.d.ts +1 -125
- package/dist/server/db.js +1 -0
- package/dist/server/db.js.map +1 -1
- package/dist/server/device.d.ts +1 -24
- package/dist/server/device.js +3 -1
- package/dist/server/device.js.map +1 -1
- package/dist/server/domains/core.d.ts +320 -0
- package/dist/server/domains/core.d.ts.map +1 -0
- package/dist/server/domains/core.js +466 -0
- package/dist/server/domains/core.js.map +1 -0
- package/dist/server/domains/sso.d.ts +340 -0
- package/dist/server/domains/sso.d.ts.map +1 -0
- package/dist/server/domains/sso.js +689 -0
- package/dist/server/domains/sso.js.map +1 -0
- package/dist/server/enterpriseValidators.d.ts +1 -0
- package/dist/server/enterpriseValidators.js +56 -0
- package/dist/server/enterpriseValidators.js.map +1 -0
- package/dist/server/factory.d.ts +136 -0
- package/dist/server/factory.d.ts.map +1 -0
- package/dist/server/factory.js +1128 -0
- package/dist/server/factory.js.map +1 -0
- package/dist/server/fx.d.ts +1 -16
- package/dist/server/fx.d.ts.map +1 -1
- package/dist/server/fx.js +1 -0
- package/dist/server/fx.js.map +1 -1
- package/dist/server/http.d.ts +59 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +287 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/identity.d.ts +1 -0
- package/dist/server/identity.js +13 -0
- package/dist/server/identity.js.map +1 -0
- package/dist/server/index.d.ts +432 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +486 -36
- package/dist/server/index.js.map +1 -1
- package/dist/server/keys.d.ts +1 -57
- package/dist/server/keys.js +4 -0
- package/dist/server/keys.js.map +1 -1
- package/dist/server/mutations/account.d.ts +7 -7
- package/dist/server/mutations/account.d.ts.map +1 -1
- package/dist/server/mutations/code.d.ts +13 -13
- package/dist/server/mutations/index.d.ts +107 -107
- package/dist/server/mutations/index.d.ts.map +1 -1
- package/dist/server/mutations/index.js +1 -1
- package/dist/server/mutations/index.js.map +1 -1
- package/dist/server/mutations/invalidate.d.ts +5 -5
- package/dist/server/mutations/oauth.d.ts +10 -10
- package/dist/server/mutations/oauth.d.ts.map +1 -1
- package/dist/server/mutations/oauth.js +9 -6
- package/dist/server/mutations/oauth.js.map +1 -1
- package/dist/server/mutations/refresh.d.ts +4 -4
- package/dist/server/mutations/register.d.ts +12 -12
- package/dist/server/mutations/register.d.ts.map +1 -1
- package/dist/server/mutations/retrieve.d.ts +1 -1
- package/dist/server/mutations/signature.d.ts +5 -5
- package/dist/server/mutations/signature.d.ts.map +1 -1
- package/dist/server/mutations/signin.d.ts +1 -1
- package/dist/server/mutations/signout.d.ts +1 -1
- package/dist/server/mutations/store.d.ts +3 -2
- package/dist/server/mutations/store.d.ts.map +1 -1
- package/dist/server/mutations/store.js +6 -3
- package/dist/server/mutations/store.js.map +1 -1
- package/dist/server/mutations/verifier.d.ts +1 -1
- package/dist/server/mutations/verify.d.ts +4 -4
- package/dist/server/oauth.d.ts +1 -59
- package/dist/server/oauth.js +3 -0
- package/dist/server/oauth.js.map +1 -1
- package/dist/server/passkey.d.ts.map +1 -1
- package/dist/server/passkey.js +3 -2
- package/dist/server/passkey.js.map +1 -1
- package/dist/server/provider.d.ts +1 -14
- package/dist/server/provider.d.ts.map +1 -1
- package/dist/server/provider.js +2 -0
- package/dist/server/provider.js.map +1 -1
- package/dist/server/providers.js +3 -0
- package/dist/server/providers.js.map +1 -1
- package/dist/server/ratelimit.d.ts +1 -22
- package/dist/server/ratelimit.js +3 -0
- package/dist/server/ratelimit.js.map +1 -1
- package/dist/server/redirects.d.ts +1 -10
- package/dist/server/redirects.js +2 -0
- package/dist/server/redirects.js.map +1 -1
- package/dist/server/refresh.d.ts +1 -37
- package/dist/server/refresh.js +5 -0
- package/dist/server/refresh.js.map +1 -1
- package/dist/server/sessions.d.ts +1 -28
- package/dist/server/sessions.js +5 -0
- package/dist/server/sessions.js.map +1 -1
- package/dist/server/signin.d.ts +1 -55
- package/dist/server/signin.js +2 -1
- package/dist/server/signin.js.map +1 -1
- package/dist/server/sso.d.ts +1 -348
- package/dist/server/sso.js +165 -18
- package/dist/server/sso.js.map +1 -1
- package/dist/server/templates.d.ts +1 -21
- package/dist/server/templates.js +1 -0
- package/dist/server/templates.js.map +1 -1
- package/dist/server/tokens.d.ts +1 -11
- package/dist/server/tokens.js +1 -0
- package/dist/server/tokens.js.map +1 -1
- package/dist/server/totp.d.ts +1 -23
- package/dist/server/totp.js +4 -2
- package/dist/server/totp.js.map +1 -1
- package/dist/server/types.d.ts +55 -71
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js.map +1 -1
- package/dist/server/users.d.ts +1 -31
- package/dist/server/users.js +1 -0
- package/dist/server/users.js.map +1 -1
- package/dist/server/utils.d.ts +1 -27
- package/dist/server/utils.js +44 -2
- package/dist/server/utils.js.map +1 -1
- package/dist/server/version.d.ts +1 -1
- package/dist/server/version.js +1 -1
- package/dist/server/version.js.map +1 -1
- package/package.json +4 -5
- package/src/cli/bin.ts +5 -0
- package/src/cli/index.ts +22 -9
- package/src/cli/keys.ts +3 -0
- package/src/client/index.ts +36 -37
- package/src/component/_generated/api.ts +14 -0
- package/src/component/_generated/component.ts +1920 -3
- package/src/component/index.ts +2 -0
- package/src/component/model.ts +424 -0
- package/src/component/public/enterprise.ts +654 -0
- package/src/component/public/factors.ts +332 -0
- package/src/component/public/groups.ts +951 -0
- package/src/component/public/identity.ts +566 -0
- package/src/component/public/keys.ts +209 -0
- package/src/component/public/shared.ts +117 -0
- package/src/component/public.ts +5 -2965
- package/src/component/schema.ts +47 -57
- package/src/providers/sso.ts +1 -1
- package/src/server/auth.ts +192 -9
- package/src/server/cookies.ts +3 -0
- package/src/server/db.ts +3 -0
- package/src/server/device.ts +3 -1
- package/src/server/domains/core.ts +916 -0
- package/src/server/domains/sso.ts +1462 -0
- package/src/server/enterpriseValidators.ts +88 -0
- package/src/server/factory.ts +2168 -0
- package/src/server/fx.ts +1 -0
- package/src/server/http.ts +529 -0
- package/src/server/identity.ts +18 -0
- package/src/server/index.ts +712 -40
- package/src/server/keys.ts +4 -0
- package/src/server/mutations/index.ts +1 -1
- package/src/server/mutations/oauth.ts +36 -8
- package/src/server/mutations/store.ts +6 -3
- package/src/server/oauth.ts +6 -0
- package/src/server/passkey.ts +3 -2
- package/src/server/provider.ts +2 -0
- package/src/server/providers.ts +3 -0
- package/src/server/ratelimit.ts +3 -0
- package/src/server/redirects.ts +2 -0
- package/src/server/refresh.ts +5 -0
- package/src/server/sessions.ts +5 -0
- package/src/server/signin.ts +1 -0
- package/src/server/sso.ts +251 -17
- package/src/server/templates.ts +1 -0
- package/src/server/tokens.ts +1 -0
- package/src/server/totp.ts +4 -2
- package/src/server/types.ts +85 -77
- package/src/server/users.ts +1 -0
- package/src/server/utils.ts +71 -1
- package/src/server/version.ts +1 -1
- package/dist/component/public.js.map +0 -1
- package/dist/component/server/implementation.d.ts +0 -1264
- package/dist/component/server/implementation.d.ts.map +0 -1
- package/dist/component/server/implementation.js +0 -2365
- package/dist/component/server/implementation.js.map +0 -1
- package/dist/server/cookies.d.ts.map +0 -1
- package/dist/server/db.d.ts.map +0 -1
- package/dist/server/device.d.ts.map +0 -1
- package/dist/server/implementation.d.ts +0 -1264
- package/dist/server/implementation.d.ts.map +0 -1
- package/dist/server/implementation.js +0 -2365
- package/dist/server/implementation.js.map +0 -1
- package/dist/server/keys.d.ts.map +0 -1
- package/dist/server/oauth.d.ts.map +0 -1
- package/dist/server/ratelimit.d.ts.map +0 -1
- package/dist/server/redirects.d.ts.map +0 -1
- package/dist/server/refresh.d.ts.map +0 -1
- package/dist/server/sessions.d.ts.map +0 -1
- package/dist/server/signin.d.ts.map +0 -1
- package/dist/server/sso.d.ts.map +0 -1
- package/dist/server/templates.d.ts.map +0 -1
- package/dist/server/tokens.d.ts.map +0 -1
- package/dist/server/totp.d.ts.map +0 -1
- package/dist/server/users.d.ts.map +0 -1
- package/dist/server/utils.d.ts.map +0 -1
- package/src/server/implementation.ts +0 -5336
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { mutation, query } from "../functions.js";
|
|
2
|
+
import { vDeviceCodeDoc, vDeviceStatus, vPasskeyDoc, vRateLimitResult, vTotpFactorDoc } from "../model.js";
|
|
3
|
+
import { v } from "./shared.js";
|
|
4
|
+
|
|
5
|
+
//#region src/component/public/factors.ts
|
|
6
|
+
/** Store a new passkey credential for a user. */
|
|
7
|
+
const passkeyInsert = mutation({
|
|
8
|
+
args: {
|
|
9
|
+
userId: v.id("User"),
|
|
10
|
+
credentialId: v.string(),
|
|
11
|
+
publicKey: v.bytes(),
|
|
12
|
+
algorithm: v.number(),
|
|
13
|
+
counter: v.number(),
|
|
14
|
+
transports: v.optional(v.array(v.string())),
|
|
15
|
+
deviceType: v.string(),
|
|
16
|
+
backedUp: v.boolean(),
|
|
17
|
+
name: v.optional(v.string()),
|
|
18
|
+
createdAt: v.number()
|
|
19
|
+
},
|
|
20
|
+
returns: v.id("Passkey"),
|
|
21
|
+
handler: async (ctx, args) => {
|
|
22
|
+
return await ctx.db.insert("Passkey", args);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
/** Look up a passkey by its credential ID. */
|
|
26
|
+
const passkeyGetByCredentialId = query({
|
|
27
|
+
args: { credentialId: v.string() },
|
|
28
|
+
returns: v.union(vPasskeyDoc, v.null()),
|
|
29
|
+
handler: async (ctx, { credentialId }) => {
|
|
30
|
+
return await ctx.db.query("Passkey").withIndex("credential_id", (q) => q.eq("credentialId", credentialId)).unique();
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
/** List all passkeys for a user. */
|
|
34
|
+
const passkeyListByUserId = query({
|
|
35
|
+
args: { userId: v.id("User") },
|
|
36
|
+
returns: v.array(vPasskeyDoc),
|
|
37
|
+
handler: async (ctx, { userId }) => {
|
|
38
|
+
return await ctx.db.query("Passkey").withIndex("user_id", (q) => q.eq("userId", userId)).collect();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
/** Update a passkey's counter and last used timestamp after authentication. */
|
|
42
|
+
const passkeyUpdateCounter = mutation({
|
|
43
|
+
args: {
|
|
44
|
+
passkeyId: v.id("Passkey"),
|
|
45
|
+
counter: v.number(),
|
|
46
|
+
lastUsedAt: v.number()
|
|
47
|
+
},
|
|
48
|
+
returns: v.null(),
|
|
49
|
+
handler: async (ctx, { passkeyId, counter, lastUsedAt }) => {
|
|
50
|
+
await ctx.db.patch("Passkey", passkeyId, {
|
|
51
|
+
counter,
|
|
52
|
+
lastUsedAt
|
|
53
|
+
});
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
/** Update a passkey's metadata (name). */
|
|
58
|
+
const passkeyUpdateMeta = mutation({
|
|
59
|
+
args: {
|
|
60
|
+
passkeyId: v.id("Passkey"),
|
|
61
|
+
data: v.any()
|
|
62
|
+
},
|
|
63
|
+
returns: v.null(),
|
|
64
|
+
handler: async (ctx, { passkeyId, data }) => {
|
|
65
|
+
await ctx.db.patch("Passkey", passkeyId, data);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
/** Delete a passkey credential. */
|
|
70
|
+
const passkeyDelete = mutation({
|
|
71
|
+
args: { passkeyId: v.id("Passkey") },
|
|
72
|
+
returns: v.null(),
|
|
73
|
+
handler: async (ctx, { passkeyId }) => {
|
|
74
|
+
await ctx.db.delete("Passkey", passkeyId);
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
/** Store a new TOTP enrollment for a user. */
|
|
79
|
+
const totpInsert = mutation({
|
|
80
|
+
args: {
|
|
81
|
+
userId: v.id("User"),
|
|
82
|
+
secret: v.bytes(),
|
|
83
|
+
digits: v.number(),
|
|
84
|
+
period: v.number(),
|
|
85
|
+
verified: v.boolean(),
|
|
86
|
+
name: v.optional(v.string()),
|
|
87
|
+
createdAt: v.number()
|
|
88
|
+
},
|
|
89
|
+
returns: v.id("TotpFactor"),
|
|
90
|
+
handler: async (ctx, args) => {
|
|
91
|
+
return await ctx.db.insert("TotpFactor", args);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
/** Get a verified TOTP enrollment for a user (returns first match). */
|
|
95
|
+
const totpGetVerifiedByUserId = query({
|
|
96
|
+
args: { userId: v.id("User") },
|
|
97
|
+
returns: v.union(vTotpFactorDoc, v.null()),
|
|
98
|
+
handler: async (ctx, { userId }) => {
|
|
99
|
+
return await ctx.db.query("TotpFactor").withIndex("user_id", (q) => q.eq("userId", userId)).filter((q) => q.eq(q.field("verified"), true)).first();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
/** List all TOTP enrollments for a user. */
|
|
103
|
+
const totpListByUserId = query({
|
|
104
|
+
args: { userId: v.id("User") },
|
|
105
|
+
returns: v.array(vTotpFactorDoc),
|
|
106
|
+
handler: async (ctx, { userId }) => {
|
|
107
|
+
return await ctx.db.query("TotpFactor").withIndex("user_id", (q) => q.eq("userId", userId)).collect();
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
/** Get a TOTP enrollment by its ID. */
|
|
111
|
+
const totpGetById = query({
|
|
112
|
+
args: { totpId: v.id("TotpFactor") },
|
|
113
|
+
returns: v.union(vTotpFactorDoc, v.null()),
|
|
114
|
+
handler: async (ctx, { totpId }) => {
|
|
115
|
+
return await ctx.db.get("TotpFactor", totpId);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
/** Mark a TOTP enrollment as verified (setup complete). */
|
|
119
|
+
const totpMarkVerified = mutation({
|
|
120
|
+
args: {
|
|
121
|
+
totpId: v.id("TotpFactor"),
|
|
122
|
+
lastUsedAt: v.number()
|
|
123
|
+
},
|
|
124
|
+
returns: v.null(),
|
|
125
|
+
handler: async (ctx, { totpId, lastUsedAt }) => {
|
|
126
|
+
await ctx.db.patch("TotpFactor", totpId, {
|
|
127
|
+
verified: true,
|
|
128
|
+
lastUsedAt
|
|
129
|
+
});
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
/** Update a TOTP enrollment's last used timestamp. */
|
|
134
|
+
const totpUpdateLastUsed = mutation({
|
|
135
|
+
args: {
|
|
136
|
+
totpId: v.id("TotpFactor"),
|
|
137
|
+
lastUsedAt: v.number()
|
|
138
|
+
},
|
|
139
|
+
returns: v.null(),
|
|
140
|
+
handler: async (ctx, { totpId, lastUsedAt }) => {
|
|
141
|
+
await ctx.db.patch("TotpFactor", totpId, { lastUsedAt });
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
/** Delete a TOTP enrollment. */
|
|
146
|
+
const totpDelete = mutation({
|
|
147
|
+
args: { totpId: v.id("TotpFactor") },
|
|
148
|
+
returns: v.null(),
|
|
149
|
+
handler: async (ctx, { totpId }) => {
|
|
150
|
+
await ctx.db.delete("TotpFactor", totpId);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
/** Look up a rate limit entry by its identifier. */
|
|
155
|
+
const rateLimitGet = query({
|
|
156
|
+
args: { identifier: v.string() },
|
|
157
|
+
returns: v.union(vRateLimitResult, v.null()),
|
|
158
|
+
handler: async (ctx, { identifier }) => {
|
|
159
|
+
const row = await ctx.db.query("RateLimit").withIndex("by_identifier", (q) => q.eq("identifier", identifier)).unique();
|
|
160
|
+
if (row === null) return null;
|
|
161
|
+
return {
|
|
162
|
+
...row,
|
|
163
|
+
attemptsLeft: row.attempts_left,
|
|
164
|
+
lastAttemptTime: row.last_attempt_time
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
/** Create a new rate limit entry. */
|
|
169
|
+
const rateLimitCreate = mutation({
|
|
170
|
+
args: {
|
|
171
|
+
identifier: v.string(),
|
|
172
|
+
attemptsLeft: v.number(),
|
|
173
|
+
lastAttemptTime: v.number()
|
|
174
|
+
},
|
|
175
|
+
returns: v.id("RateLimit"),
|
|
176
|
+
handler: async (ctx, { identifier, attemptsLeft, lastAttemptTime }) => {
|
|
177
|
+
return await ctx.db.insert("RateLimit", {
|
|
178
|
+
identifier,
|
|
179
|
+
attempts_left: attemptsLeft,
|
|
180
|
+
last_attempt_time: lastAttemptTime
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
/** Patch a rate limit entry with partial data. */
|
|
185
|
+
const rateLimitPatch = mutation({
|
|
186
|
+
args: {
|
|
187
|
+
rateLimitId: v.id("RateLimit"),
|
|
188
|
+
data: v.any()
|
|
189
|
+
},
|
|
190
|
+
returns: v.null(),
|
|
191
|
+
handler: async (ctx, { rateLimitId, data }) => {
|
|
192
|
+
const nextData = { ...data };
|
|
193
|
+
if (nextData.attemptsLeft !== void 0) {
|
|
194
|
+
nextData.attempts_left = nextData.attemptsLeft;
|
|
195
|
+
delete nextData.attemptsLeft;
|
|
196
|
+
}
|
|
197
|
+
if (nextData.lastAttemptTime !== void 0) {
|
|
198
|
+
nextData.last_attempt_time = nextData.lastAttemptTime;
|
|
199
|
+
delete nextData.lastAttemptTime;
|
|
200
|
+
}
|
|
201
|
+
await ctx.db.patch("RateLimit", rateLimitId, nextData);
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
/** Delete a rate limit entry. */
|
|
206
|
+
const rateLimitDelete = mutation({
|
|
207
|
+
args: { rateLimitId: v.id("RateLimit") },
|
|
208
|
+
returns: v.null(),
|
|
209
|
+
handler: async (ctx, { rateLimitId }) => {
|
|
210
|
+
await ctx.db.delete("RateLimit", rateLimitId);
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
/** Insert a new device authorization record. */
|
|
215
|
+
const deviceInsert = mutation({
|
|
216
|
+
args: {
|
|
217
|
+
deviceCodeHash: v.string(),
|
|
218
|
+
userCode: v.string(),
|
|
219
|
+
expiresAt: v.number(),
|
|
220
|
+
interval: v.number(),
|
|
221
|
+
status: vDeviceStatus
|
|
222
|
+
},
|
|
223
|
+
returns: v.id("DeviceCode"),
|
|
224
|
+
handler: async (ctx, args) => {
|
|
225
|
+
return await ctx.db.insert("DeviceCode", args);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
/** Look up a device authorization by its hashed device code. */
|
|
229
|
+
const deviceGetByCodeHash = query({
|
|
230
|
+
args: { deviceCodeHash: v.string() },
|
|
231
|
+
returns: v.union(vDeviceCodeDoc, v.null()),
|
|
232
|
+
handler: async (ctx, { deviceCodeHash }) => {
|
|
233
|
+
return await ctx.db.query("DeviceCode").withIndex("device_code_hash", (q) => q.eq("deviceCodeHash", deviceCodeHash)).first();
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
/** Look up a pending device authorization by its user code. */
|
|
237
|
+
const deviceGetByUserCode = query({
|
|
238
|
+
args: { userCode: v.string() },
|
|
239
|
+
returns: v.union(vDeviceCodeDoc, v.null()),
|
|
240
|
+
handler: async (ctx, { userCode }) => {
|
|
241
|
+
return await ctx.db.query("DeviceCode").withIndex("user_code_status", (q) => q.eq("userCode", userCode).eq("status", "pending")).first();
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
/** Authorize a device code — link it to a user and session. */
|
|
245
|
+
const deviceAuthorize = mutation({
|
|
246
|
+
args: {
|
|
247
|
+
deviceId: v.id("DeviceCode"),
|
|
248
|
+
userId: v.id("User"),
|
|
249
|
+
sessionId: v.id("Session")
|
|
250
|
+
},
|
|
251
|
+
returns: v.null(),
|
|
252
|
+
handler: async (ctx, { deviceId, userId, sessionId }) => {
|
|
253
|
+
await ctx.db.patch("DeviceCode", deviceId, {
|
|
254
|
+
status: "authorized",
|
|
255
|
+
userId,
|
|
256
|
+
sessionId
|
|
257
|
+
});
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
/** Update the last-polled timestamp on a device authorization record. */
|
|
262
|
+
const deviceUpdateLastPolled = mutation({
|
|
263
|
+
args: {
|
|
264
|
+
deviceId: v.id("DeviceCode"),
|
|
265
|
+
lastPolledAt: v.number()
|
|
266
|
+
},
|
|
267
|
+
returns: v.null(),
|
|
268
|
+
handler: async (ctx, { deviceId, lastPolledAt }) => {
|
|
269
|
+
await ctx.db.patch("DeviceCode", deviceId, { lastPolledAt });
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
/** Delete a device authorization record (cleanup after use or expiry). */
|
|
274
|
+
const deviceDelete = mutation({
|
|
275
|
+
args: { deviceId: v.id("DeviceCode") },
|
|
276
|
+
returns: v.null(),
|
|
277
|
+
handler: async (ctx, { deviceId }) => {
|
|
278
|
+
await ctx.db.delete("DeviceCode", deviceId);
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
//#endregion
|
|
284
|
+
export { deviceAuthorize, deviceDelete, deviceGetByCodeHash, deviceGetByUserCode, deviceInsert, deviceUpdateLastPolled, passkeyDelete, passkeyGetByCredentialId, passkeyInsert, passkeyListByUserId, passkeyUpdateCounter, passkeyUpdateMeta, rateLimitCreate, rateLimitDelete, rateLimitGet, rateLimitPatch, totpDelete, totpGetById, totpGetVerifiedByUserId, totpInsert, totpListByUserId, totpMarkVerified, totpUpdateLastUsed };
|
|
285
|
+
//# sourceMappingURL=factors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factors.js","names":[],"sources":["../../../src/component/public/factors.ts"],"sourcesContent":["import {\n mutation,\n query,\n v,\n vDeviceCodeDoc,\n vDeviceStatus,\n vPasskeyDoc,\n vRateLimitResult,\n vTotpFactorDoc,\n} from \"./shared\";\n\n// ============================================================================\n// Passkeys\n// ============================================================================\n\n/** Store a new passkey credential for a user. */\nexport const passkeyInsert = mutation({\n args: {\n userId: v.id(\"User\"),\n credentialId: v.string(),\n publicKey: v.bytes(),\n algorithm: v.number(),\n counter: v.number(),\n transports: v.optional(v.array(v.string())),\n deviceType: v.string(),\n backedUp: v.boolean(),\n name: v.optional(v.string()),\n createdAt: v.number(),\n },\n returns: v.id(\"Passkey\"),\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"Passkey\", args);\n },\n});\n\n/** Look up a passkey by its credential ID. */\nexport const passkeyGetByCredentialId = query({\n args: { credentialId: v.string() },\n returns: v.union(vPasskeyDoc, v.null()),\n handler: async (ctx, { credentialId }) => {\n return await ctx.db\n .query(\"Passkey\")\n .withIndex(\"credential_id\", (q) => q.eq(\"credentialId\", credentialId))\n .unique();\n },\n});\n\n/** List all passkeys for a user. */\nexport const passkeyListByUserId = query({\n args: { userId: v.id(\"User\") },\n returns: v.array(vPasskeyDoc),\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"Passkey\")\n .withIndex(\"user_id\", (q) => q.eq(\"userId\", userId))\n .collect();\n },\n});\n\n/** Update a passkey's counter and last used timestamp after authentication. */\nexport const passkeyUpdateCounter = mutation({\n args: {\n passkeyId: v.id(\"Passkey\"),\n counter: v.number(),\n lastUsedAt: v.number(),\n },\n returns: v.null(),\n handler: async (ctx, { passkeyId, counter, lastUsedAt }) => {\n await ctx.db.patch(\"Passkey\", passkeyId, { counter, lastUsedAt });\n return null;\n },\n});\n\n/** Update a passkey's metadata (name). */\nexport const passkeyUpdateMeta = mutation({\n args: { passkeyId: v.id(\"Passkey\"), data: v.any() },\n returns: v.null(),\n handler: async (ctx, { passkeyId, data }) => {\n await ctx.db.patch(\"Passkey\", passkeyId, data);\n return null;\n },\n});\n\n/** Delete a passkey credential. */\nexport const passkeyDelete = mutation({\n args: { passkeyId: v.id(\"Passkey\") },\n returns: v.null(),\n handler: async (ctx, { passkeyId }) => {\n await ctx.db.delete(\"Passkey\", passkeyId);\n return null;\n },\n});\n\n// ============================================================================\n// TOTP Two-Factor Authentication\n// ============================================================================\n\n/** Store a new TOTP enrollment for a user. */\nexport const totpInsert = mutation({\n args: {\n userId: v.id(\"User\"),\n secret: v.bytes(),\n digits: v.number(),\n period: v.number(),\n verified: v.boolean(),\n name: v.optional(v.string()),\n createdAt: v.number(),\n },\n returns: v.id(\"TotpFactor\"),\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"TotpFactor\", args);\n },\n});\n\n/** Get a verified TOTP enrollment for a user (returns first match). */\nexport const totpGetVerifiedByUserId = query({\n args: { userId: v.id(\"User\") },\n returns: v.union(vTotpFactorDoc, v.null()),\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"TotpFactor\")\n .withIndex(\"user_id\", (q) => q.eq(\"userId\", userId))\n .filter((q) => q.eq(q.field(\"verified\"), true))\n .first();\n },\n});\n\n/** List all TOTP enrollments for a user. */\nexport const totpListByUserId = query({\n args: { userId: v.id(\"User\") },\n returns: v.array(vTotpFactorDoc),\n handler: async (ctx, { userId }) => {\n return await ctx.db\n .query(\"TotpFactor\")\n .withIndex(\"user_id\", (q) => q.eq(\"userId\", userId))\n .collect();\n },\n});\n\n/** Get a TOTP enrollment by its ID. */\nexport const totpGetById = query({\n args: { totpId: v.id(\"TotpFactor\") },\n returns: v.union(vTotpFactorDoc, v.null()),\n handler: async (ctx, { totpId }) => {\n return await ctx.db.get(\"TotpFactor\", totpId);\n },\n});\n\n/** Mark a TOTP enrollment as verified (setup complete). */\nexport const totpMarkVerified = mutation({\n args: { totpId: v.id(\"TotpFactor\"), lastUsedAt: v.number() },\n returns: v.null(),\n handler: async (ctx, { totpId, lastUsedAt }) => {\n await ctx.db.patch(\"TotpFactor\", totpId, { verified: true, lastUsedAt });\n return null;\n },\n});\n\n/** Update a TOTP enrollment's last used timestamp. */\nexport const totpUpdateLastUsed = mutation({\n args: { totpId: v.id(\"TotpFactor\"), lastUsedAt: v.number() },\n returns: v.null(),\n handler: async (ctx, { totpId, lastUsedAt }) => {\n await ctx.db.patch(\"TotpFactor\", totpId, { lastUsedAt });\n return null;\n },\n});\n\n/** Delete a TOTP enrollment. */\nexport const totpDelete = mutation({\n args: { totpId: v.id(\"TotpFactor\") },\n returns: v.null(),\n handler: async (ctx, { totpId }) => {\n await ctx.db.delete(\"TotpFactor\", totpId);\n return null;\n },\n});\n\n// ============================================================================\n// Rate Limits\n// ============================================================================\n\n/** Look up a rate limit entry by its identifier. */\nexport const rateLimitGet = query({\n args: { identifier: v.string() },\n returns: v.union(vRateLimitResult, v.null()),\n handler: async (ctx, { identifier }) => {\n const row = await ctx.db\n .query(\"RateLimit\")\n .withIndex(\"by_identifier\", (q) => q.eq(\"identifier\", identifier))\n .unique();\n if (row === null) {\n return null;\n }\n return {\n ...row,\n attemptsLeft: row.attempts_left,\n lastAttemptTime: row.last_attempt_time,\n };\n },\n});\n\n/** Create a new rate limit entry. */\nexport const rateLimitCreate = mutation({\n args: {\n identifier: v.string(),\n attemptsLeft: v.number(),\n lastAttemptTime: v.number(),\n },\n returns: v.id(\"RateLimit\"),\n handler: async (ctx, { identifier, attemptsLeft, lastAttemptTime }) => {\n return await ctx.db.insert(\"RateLimit\", {\n identifier,\n attempts_left: attemptsLeft,\n last_attempt_time: lastAttemptTime,\n });\n },\n});\n\n/** Patch a rate limit entry with partial data. */\nexport const rateLimitPatch = mutation({\n args: { rateLimitId: v.id(\"RateLimit\"), data: v.any() },\n returns: v.null(),\n handler: async (ctx, { rateLimitId, data }) => {\n const nextData: Record<string, unknown> = { ...data };\n if (nextData.attemptsLeft !== undefined) {\n nextData.attempts_left = nextData.attemptsLeft;\n delete nextData.attemptsLeft;\n }\n if (nextData.lastAttemptTime !== undefined) {\n nextData.last_attempt_time = nextData.lastAttemptTime;\n delete nextData.lastAttemptTime;\n }\n await ctx.db.patch(\"RateLimit\", rateLimitId, nextData);\n return null;\n },\n});\n\n/** Delete a rate limit entry. */\nexport const rateLimitDelete = mutation({\n args: { rateLimitId: v.id(\"RateLimit\") },\n returns: v.null(),\n handler: async (ctx, { rateLimitId }) => {\n await ctx.db.delete(\"RateLimit\", rateLimitId);\n return null;\n },\n});\n\n// ============================================================================\n// Device Authorization (RFC 8628)\n// ============================================================================\n\n/** Insert a new device authorization record. */\nexport const deviceInsert = mutation({\n args: {\n deviceCodeHash: v.string(),\n userCode: v.string(),\n expiresAt: v.number(),\n interval: v.number(),\n status: vDeviceStatus,\n },\n returns: v.id(\"DeviceCode\"),\n handler: async (ctx, args) => {\n return await ctx.db.insert(\"DeviceCode\", args);\n },\n});\n\n/** Look up a device authorization by its hashed device code. */\nexport const deviceGetByCodeHash = query({\n args: { deviceCodeHash: v.string() },\n returns: v.union(vDeviceCodeDoc, v.null()),\n handler: async (ctx, { deviceCodeHash }) => {\n return await ctx.db\n .query(\"DeviceCode\")\n .withIndex(\"device_code_hash\", (q) =>\n q.eq(\"deviceCodeHash\", deviceCodeHash),\n )\n .first();\n },\n});\n\n/** Look up a pending device authorization by its user code. */\nexport const deviceGetByUserCode = query({\n args: { userCode: v.string() },\n returns: v.union(vDeviceCodeDoc, v.null()),\n handler: async (ctx, { userCode }) => {\n return await ctx.db\n .query(\"DeviceCode\")\n .withIndex(\"user_code_status\", (q) =>\n q.eq(\"userCode\", userCode).eq(\"status\", \"pending\"),\n )\n .first();\n },\n});\n\n/** Authorize a device code — link it to a user and session. */\nexport const deviceAuthorize = mutation({\n args: {\n deviceId: v.id(\"DeviceCode\"),\n userId: v.id(\"User\"),\n sessionId: v.id(\"Session\"),\n },\n returns: v.null(),\n handler: async (ctx, { deviceId, userId, sessionId }) => {\n await ctx.db.patch(\"DeviceCode\", deviceId, {\n status: \"authorized\",\n userId,\n sessionId,\n });\n return null;\n },\n});\n\n/** Update the last-polled timestamp on a device authorization record. */\nexport const deviceUpdateLastPolled = mutation({\n args: { deviceId: v.id(\"DeviceCode\"), lastPolledAt: v.number() },\n returns: v.null(),\n handler: async (ctx, { deviceId, lastPolledAt }) => {\n await ctx.db.patch(\"DeviceCode\", deviceId, { lastPolledAt });\n return null;\n },\n});\n\n/** Delete a device authorization record (cleanup after use or expiry). */\nexport const deviceDelete = mutation({\n args: { deviceId: v.id(\"DeviceCode\") },\n returns: v.null(),\n handler: async (ctx, { deviceId }) => {\n await ctx.db.delete(\"DeviceCode\", deviceId);\n return null;\n },\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
declare namespace groups_d_exports {
|
|
2
|
+
export { groupCreate, groupDelete, groupGet, groupList, groupUpdate, inviteAccept, inviteAcceptByToken, inviteCreate, inviteGet, inviteGetByTokenHash, inviteList, inviteRevoke, memberAdd, memberGet, memberGetByGroupAndUser, memberList, memberListByUser, memberRemove, memberUpdate };
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Create a new group. Groups are hierarchical — set `parentGroupId` to nest
|
|
6
|
+
* under an existing group, or omit it to create a root-level group.
|
|
7
|
+
*
|
|
8
|
+
* @returns The ID of the newly created group.
|
|
9
|
+
*/
|
|
10
|
+
declare const groupCreate: any;
|
|
11
|
+
/** Retrieve a group by its document ID. Returns `null` if not found. */
|
|
12
|
+
declare const groupGet: any;
|
|
13
|
+
/**
|
|
14
|
+
* List groups with optional filtering, sorting, and pagination.
|
|
15
|
+
*
|
|
16
|
+
* Returns `{ items, nextCursor }`. Empty `where` returns **all** groups.
|
|
17
|
+
*/
|
|
18
|
+
declare const groupList: any;
|
|
19
|
+
/** Update a group's fields (name, slug, tags, extend, parentGroupId). */
|
|
20
|
+
declare const groupUpdate: any;
|
|
21
|
+
/**
|
|
22
|
+
* Delete a group and all of its descendants. This cascades to:
|
|
23
|
+
* - All child groups (recursively)
|
|
24
|
+
* - All members of this group and its descendants
|
|
25
|
+
* - All invites for this group and its descendants
|
|
26
|
+
*/
|
|
27
|
+
declare const groupDelete: any;
|
|
28
|
+
/**
|
|
29
|
+
* Add a user as a member of a group.
|
|
30
|
+
*
|
|
31
|
+
* The `role` field is an application-defined string (e.g. "owner", "admin",
|
|
32
|
+
* "member", "viewer"). The auth component stores it but does not enforce
|
|
33
|
+
* access control — your application defines what each role means.
|
|
34
|
+
*
|
|
35
|
+
* Throws `ConvexError` with code `DUPLICATE_MEMBERSHIP` when the user is
|
|
36
|
+
* already a member of the target group.
|
|
37
|
+
*
|
|
38
|
+
* @returns The ID of the new member record.
|
|
39
|
+
*/
|
|
40
|
+
declare const memberAdd: any;
|
|
41
|
+
/** Retrieve a member record by its document ID. Returns `null` if not found. */
|
|
42
|
+
declare const memberGet: any;
|
|
43
|
+
/**
|
|
44
|
+
* List members with optional filtering, sorting, and pagination.
|
|
45
|
+
*
|
|
46
|
+
* Returns `{ items, nextCursor }`. Supports filtering by `groupId`,
|
|
47
|
+
* `userId`, `role`, and `status`.
|
|
48
|
+
*/
|
|
49
|
+
declare const memberList: any;
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated Use `memberList` with `where: { userId }` instead.
|
|
52
|
+
* Kept for backward compatibility with generated component types.
|
|
53
|
+
*/
|
|
54
|
+
declare const memberListByUser: any;
|
|
55
|
+
/**
|
|
56
|
+
* Look up a specific user's membership in a specific group.
|
|
57
|
+
* Returns `null` if the user is not a member of the group.
|
|
58
|
+
*/
|
|
59
|
+
declare const memberGetByGroupAndUser: any;
|
|
60
|
+
/** Remove a member from a group by deleting the member record. */
|
|
61
|
+
declare const memberRemove: any;
|
|
62
|
+
/**
|
|
63
|
+
* Update a member record's fields (role, status, extend).
|
|
64
|
+
*
|
|
65
|
+
* Common usage: `memberUpdate({ memberId, data: { role: "admin" } })`
|
|
66
|
+
*/
|
|
67
|
+
declare const memberUpdate: any;
|
|
68
|
+
/**
|
|
69
|
+
* Create a new platform-level invitation. Optionally set `groupId` to tie
|
|
70
|
+
* the invite to a specific group. The invitation is sent to an email address
|
|
71
|
+
* and includes a hashed token for secure acceptance.
|
|
72
|
+
*
|
|
73
|
+
* Throws `ConvexError` with code `DUPLICATE_INVITE` when a pending invite
|
|
74
|
+
* already exists for the same email and scope:
|
|
75
|
+
* - group invite: same `email` + same `groupId`
|
|
76
|
+
* - platform invite: same `email` with no `groupId`
|
|
77
|
+
*
|
|
78
|
+
* @returns The ID of the new invite record.
|
|
79
|
+
*/
|
|
80
|
+
declare const inviteCreate: any;
|
|
81
|
+
/** Retrieve an invite by its document ID. Returns `null` if not found. */
|
|
82
|
+
declare const inviteGet: any;
|
|
83
|
+
/** Retrieve an invite by hashed token. Returns `null` if not found. */
|
|
84
|
+
declare const inviteGetByTokenHash: any;
|
|
85
|
+
/**
|
|
86
|
+
* List invites with optional filtering, sorting, and pagination.
|
|
87
|
+
*
|
|
88
|
+
* Returns `{ items, nextCursor }`. Supports filtering by `groupId`,
|
|
89
|
+
* `status`, `email`, `invitedByUserId`, `role`, `acceptedByUserId`, and `tokenHash`.
|
|
90
|
+
*/
|
|
91
|
+
declare const inviteList: any;
|
|
92
|
+
/**
|
|
93
|
+
* Accept a pending invitation.
|
|
94
|
+
*
|
|
95
|
+
* Marks the invite as "accepted" and records the acceptance timestamp.
|
|
96
|
+
* Throws a structured `ConvexError` when the invite doesn't exist or is not
|
|
97
|
+
* currently pending.
|
|
98
|
+
*
|
|
99
|
+
* The caller is responsible for creating the corresponding member record.
|
|
100
|
+
*/
|
|
101
|
+
declare const inviteAccept: any;
|
|
102
|
+
/**
|
|
103
|
+
* Accept an invitation by raw token hash and atomically join group membership.
|
|
104
|
+
*
|
|
105
|
+
* Returns idempotent success when the invite was already accepted by the same
|
|
106
|
+
* user. If the invite targets a group, this mutation also ensures membership.
|
|
107
|
+
*/
|
|
108
|
+
declare const inviteAcceptByToken: any;
|
|
109
|
+
/**
|
|
110
|
+
* Revoke a pending invitation.
|
|
111
|
+
*
|
|
112
|
+
* Marks the invite as "revoked". Throws a structured `ConvexError` when the
|
|
113
|
+
* invite doesn't exist or is not currently pending.
|
|
114
|
+
*/
|
|
115
|
+
declare const inviteRevoke: any;
|
|
116
|
+
//#endregion
|
|
117
|
+
export { groupCreate, groupDelete, groupGet, groupList, groupUpdate, groups_d_exports, inviteAccept, inviteAcceptByToken, inviteCreate, inviteGet, inviteGetByTokenHash, inviteList, inviteRevoke, memberAdd, memberGet, memberGetByGroupAndUser, memberList, memberListByUser, memberRemove, memberUpdate };
|
|
118
|
+
//# sourceMappingURL=groups.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"groups.d.ts","names":[],"sources":["../../../src/component/public/groups.ts"],"mappings":";;;;;;;;;cA4Ba,WAAA;;cAgCA,QAAA;;;;;;cAaA,SAAA;;cAuJA,WAAA;;;;;;;cA2CA,WAAA;AA/Ob;;;;;AAgCA;;;;;AAaA;;AA7CA,cA6Sa,SAAA;;cA8BA,SAAA;AAvIb;;;;;AA2CA;AA3CA,cAqJa,UAAA;;;;AA5Cb;cAuHa,gBAAA;;;;AAzFb;cAwGa,uBAAA;;cAcA,YAAA;;AAxGb;;;;cAsHa,YAAA;AA3Cb;;;;;AAeA;;;;;AAcA;;AA7BA,cAoEa,YAAA;;cA+EA,SAAA;AAxGb;AAAA,cAiHa,oBAAA;;;;AAxFb;;;cAyGa,UAAA;;AA1Bb;;;;;AASA;;;cA+Ja,YAAA;;AA9Ib;;;;;cA8La,mBAAA;;;;;AAAb;;cAoHa,YAAA"}
|