@robelest/convex-auth 0.0.2-preview.2 → 0.0.3-preview
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/bin.cjs +467 -64
- package/dist/client/index.d.ts +127 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +424 -1
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +56 -1
- 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 +141 -3
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/convex.config.d.ts.map +1 -1
- package/dist/component/convex.config.js +2 -0
- package/dist/component/convex.config.js.map +1 -1
- package/dist/component/index.d.ts +5 -4
- package/dist/component/index.d.ts.map +1 -1
- package/dist/component/index.js +4 -3
- package/dist/component/index.js.map +1 -1
- package/dist/component/portalBridge.d.ts +80 -0
- package/dist/component/portalBridge.d.ts.map +1 -0
- package/dist/component/portalBridge.js +102 -0
- package/dist/component/portalBridge.js.map +1 -0
- package/dist/component/public.d.ts +353 -9
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +328 -33
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +168 -9
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +113 -7
- package/dist/component/schema.js.map +1 -1
- package/dist/providers/passkey.d.ts +20 -0
- package/dist/providers/passkey.d.ts.map +1 -0
- package/dist/providers/passkey.js +32 -0
- package/dist/providers/passkey.js.map +1 -0
- package/dist/providers/totp.d.ts +14 -0
- package/dist/providers/totp.d.ts.map +1 -0
- package/dist/providers/totp.js +23 -0
- package/dist/providers/totp.js.map +1 -0
- package/dist/server/convex-auth.d.ts +296 -0
- package/dist/server/convex-auth.d.ts.map +1 -0
- package/dist/server/convex-auth.js +480 -0
- package/dist/server/convex-auth.js.map +1 -0
- package/dist/server/email-templates.d.ts +18 -0
- package/dist/server/email-templates.d.ts.map +1 -0
- package/dist/server/email-templates.js +74 -0
- package/dist/server/email-templates.js.map +1 -0
- package/dist/server/implementation/apiKey.d.ts +74 -0
- package/dist/server/implementation/apiKey.d.ts.map +1 -0
- package/dist/server/implementation/apiKey.js +140 -0
- package/dist/server/implementation/apiKey.js.map +1 -0
- package/dist/server/implementation/index.d.ts +169 -7
- package/dist/server/implementation/index.d.ts.map +1 -1
- package/dist/server/implementation/index.js +220 -5
- package/dist/server/implementation/index.js.map +1 -1
- package/dist/server/implementation/passkey.d.ts +33 -0
- package/dist/server/implementation/passkey.d.ts.map +1 -0
- package/dist/server/implementation/passkey.js +450 -0
- package/dist/server/implementation/passkey.js.map +1 -0
- package/dist/server/implementation/redirects.d.ts.map +1 -1
- package/dist/server/implementation/redirects.js +4 -9
- package/dist/server/implementation/redirects.js.map +1 -1
- package/dist/server/implementation/signIn.d.ts +13 -0
- package/dist/server/implementation/signIn.d.ts.map +1 -1
- package/dist/server/implementation/signIn.js +29 -15
- package/dist/server/implementation/signIn.js.map +1 -1
- package/dist/server/implementation/totp.d.ts +40 -0
- package/dist/server/implementation/totp.d.ts.map +1 -0
- package/dist/server/implementation/totp.js +211 -0
- package/dist/server/implementation/totp.js.map +1 -0
- package/dist/server/index.d.ts +26 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +63 -16
- package/dist/server/index.js.map +1 -1
- package/dist/server/portal-email.d.ts +19 -0
- package/dist/server/portal-email.d.ts.map +1 -0
- package/dist/server/portal-email.js +89 -0
- package/dist/server/portal-email.js.map +1 -0
- package/dist/server/provider_utils.d.ts +3 -1
- package/dist/server/provider_utils.d.ts.map +1 -1
- package/dist/server/provider_utils.js +39 -1
- package/dist/server/provider_utils.js.map +1 -1
- package/dist/server/types.d.ts +263 -4
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/version.d.ts +2 -0
- package/dist/server/version.d.ts.map +1 -0
- package/dist/server/version.js +3 -0
- package/dist/server/version.js.map +1 -0
- package/package.json +7 -3
- package/src/cli/index.ts +49 -7
- package/src/cli/portal-link.ts +112 -0
- package/src/cli/portal-upload.ts +411 -0
- package/src/cli/utils.ts +248 -0
- package/src/client/index.ts +489 -1
- package/src/component/_generated/api.ts +72 -1
- package/src/component/_generated/component.ts +241 -4
- package/src/component/convex.config.ts +3 -0
- package/src/component/index.ts +8 -3
- package/src/component/portalBridge.ts +116 -0
- package/src/component/public.ts +373 -37
- package/src/component/schema.ts +122 -7
- package/src/providers/passkey.ts +35 -0
- package/src/providers/totp.ts +26 -0
- package/src/server/convex-auth.ts +602 -0
- package/src/server/email-templates.ts +77 -0
- package/src/server/implementation/apiKey.ts +185 -0
- package/src/server/implementation/index.ts +301 -8
- package/src/server/implementation/passkey.ts +650 -0
- package/src/server/implementation/redirects.ts +4 -11
- package/src/server/implementation/signIn.ts +41 -13
- package/src/server/implementation/totp.ts +366 -0
- package/src/server/index.ts +98 -34
- package/src/server/portal-email.ts +95 -0
- package/src/server/provider_utils.ts +42 -1
- package/src/server/types.ts +285 -4
- package/src/server/version.ts +2 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Key crypto utilities.
|
|
3
|
+
*
|
|
4
|
+
* Uses `@oslojs/crypto` primitives for key generation and hashing:
|
|
5
|
+
* - SHA-256 for hashing keys (API keys have high entropy, no need for bcrypt)
|
|
6
|
+
* - Cryptographically secure random generation for key material
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { KeyScope, ScopeChecker } from "../types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Generate a new API key.
|
|
13
|
+
*
|
|
14
|
+
* Returns the raw key (to be shown once to the user) and metadata for storage.
|
|
15
|
+
* The raw key is `{prefix}{32 random alphanumeric chars}`.
|
|
16
|
+
*
|
|
17
|
+
* @param prefix - Key prefix, defaults to "sk_live_"
|
|
18
|
+
* @returns `{ raw, hashedKey, displayPrefix }`
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateApiKey(prefix?: string): Promise<{
|
|
21
|
+
/** The full raw key — show to user once, never store. */
|
|
22
|
+
raw: string;
|
|
23
|
+
/** SHA-256 hex hash of the raw key — store this. */
|
|
24
|
+
hashedKey: string;
|
|
25
|
+
/** Truncated prefix for display (e.g. "sk_live_aBc1..."). */
|
|
26
|
+
displayPrefix: string;
|
|
27
|
+
}>;
|
|
28
|
+
/**
|
|
29
|
+
* Hash a raw API key for lookup.
|
|
30
|
+
*
|
|
31
|
+
* Used during Bearer token verification to find the stored key record.
|
|
32
|
+
*/
|
|
33
|
+
export declare function hashApiKey(rawKey: string): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Build a `ScopeChecker` from an array of `KeyScope` entries.
|
|
36
|
+
*
|
|
37
|
+
* The checker provides a `.can(resource, action)` method that returns `true`
|
|
38
|
+
* if any scope entry grants the requested permission.
|
|
39
|
+
*
|
|
40
|
+
* A wildcard action `"*"` grants all actions on that resource.
|
|
41
|
+
* A wildcard resource `"*"` grants the action on all resources.
|
|
42
|
+
*/
|
|
43
|
+
export declare function buildScopeChecker(scopes: KeyScope[]): ScopeChecker;
|
|
44
|
+
/**
|
|
45
|
+
* Validate that requested scopes are a subset of the allowed scopes
|
|
46
|
+
* defined in the API key config.
|
|
47
|
+
*
|
|
48
|
+
* @param requested - Scopes the user wants on the new key.
|
|
49
|
+
* @param allowed - The scope definition from `apiKeys.scopes` config.
|
|
50
|
+
* @throws Error if any requested scope is not in the allowed set.
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateScopes(requested: KeyScope[], allowed: Record<string, string[]> | undefined): void;
|
|
53
|
+
/**
|
|
54
|
+
* Check whether a key is rate-limited based on its stored state.
|
|
55
|
+
*
|
|
56
|
+
* Uses the same token-bucket algorithm as sign-in rate limiting:
|
|
57
|
+
* tokens refill linearly over the configured window.
|
|
58
|
+
*
|
|
59
|
+
* @returns `{ limited: boolean; newState: { attemptsLeft, lastAttemptTime } }`
|
|
60
|
+
*/
|
|
61
|
+
export declare function checkKeyRateLimit(rateLimit: {
|
|
62
|
+
maxRequests: number;
|
|
63
|
+
windowMs: number;
|
|
64
|
+
}, state: {
|
|
65
|
+
attemptsLeft: number;
|
|
66
|
+
lastAttemptTime: number;
|
|
67
|
+
} | undefined): {
|
|
68
|
+
limited: boolean;
|
|
69
|
+
newState: {
|
|
70
|
+
attemptsLeft: number;
|
|
71
|
+
lastAttemptTime: number;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=apiKey.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiKey.d.ts","sourceRoot":"","sources":["../../../src/server/implementation/apiKey.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqB1D;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAE,MAA2B,GAAG,OAAO,CAAC;IACjF,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAOD;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEhE;AAMD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAWlE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,QAAQ,EAAE,EACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,GAC5C,IAAI,CAuBN;AAMD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EACpD,KAAK,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GACnE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7D,CAsCA"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Key crypto utilities.
|
|
3
|
+
*
|
|
4
|
+
* Uses `@oslojs/crypto` primitives for key generation and hashing:
|
|
5
|
+
* - SHA-256 for hashing keys (API keys have high entropy, no need for bcrypt)
|
|
6
|
+
* - Cryptographically secure random generation for key material
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { sha256, generateRandomString } from "./utils.js";
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Constants
|
|
13
|
+
// ============================================================================
|
|
14
|
+
const DEFAULT_KEY_PREFIX = "sk_live_";
|
|
15
|
+
const KEY_RANDOM_LENGTH = 32;
|
|
16
|
+
const KEY_RANDOM_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
|
17
|
+
/**
|
|
18
|
+
* How many characters of the full key to store as the visible prefix.
|
|
19
|
+
* Includes the prefix string (e.g. "sk_live_") plus a few random chars.
|
|
20
|
+
*/
|
|
21
|
+
const VISIBLE_PREFIX_EXTRA_CHARS = 4;
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// Key generation
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Generate a new API key.
|
|
27
|
+
*
|
|
28
|
+
* Returns the raw key (to be shown once to the user) and metadata for storage.
|
|
29
|
+
* The raw key is `{prefix}{32 random alphanumeric chars}`.
|
|
30
|
+
*
|
|
31
|
+
* @param prefix - Key prefix, defaults to "sk_live_"
|
|
32
|
+
* @returns `{ raw, hashedKey, displayPrefix }`
|
|
33
|
+
*/
|
|
34
|
+
export async function generateApiKey(prefix = DEFAULT_KEY_PREFIX) {
|
|
35
|
+
const randomPart = generateRandomString(KEY_RANDOM_LENGTH, KEY_RANDOM_ALPHABET);
|
|
36
|
+
const raw = `${prefix}${randomPart}`;
|
|
37
|
+
const hashedKey = await sha256(raw);
|
|
38
|
+
const displayPrefix = `${raw.substring(0, prefix.length + VISIBLE_PREFIX_EXTRA_CHARS)}...`;
|
|
39
|
+
return { raw, hashedKey, displayPrefix };
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Hash a raw API key for lookup.
|
|
43
|
+
*
|
|
44
|
+
* Used during Bearer token verification to find the stored key record.
|
|
45
|
+
*/
|
|
46
|
+
export async function hashApiKey(rawKey) {
|
|
47
|
+
return sha256(rawKey);
|
|
48
|
+
}
|
|
49
|
+
// ============================================================================
|
|
50
|
+
// Scope checker
|
|
51
|
+
// ============================================================================
|
|
52
|
+
/**
|
|
53
|
+
* Build a `ScopeChecker` from an array of `KeyScope` entries.
|
|
54
|
+
*
|
|
55
|
+
* The checker provides a `.can(resource, action)` method that returns `true`
|
|
56
|
+
* if any scope entry grants the requested permission.
|
|
57
|
+
*
|
|
58
|
+
* A wildcard action `"*"` grants all actions on that resource.
|
|
59
|
+
* A wildcard resource `"*"` grants the action on all resources.
|
|
60
|
+
*/
|
|
61
|
+
export function buildScopeChecker(scopes) {
|
|
62
|
+
return {
|
|
63
|
+
scopes,
|
|
64
|
+
can(resource, action) {
|
|
65
|
+
return scopes.some((scope) => (scope.resource === resource || scope.resource === "*") &&
|
|
66
|
+
(scope.actions.includes(action) || scope.actions.includes("*")));
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Validate that requested scopes are a subset of the allowed scopes
|
|
72
|
+
* defined in the API key config.
|
|
73
|
+
*
|
|
74
|
+
* @param requested - Scopes the user wants on the new key.
|
|
75
|
+
* @param allowed - The scope definition from `apiKeys.scopes` config.
|
|
76
|
+
* @throws Error if any requested scope is not in the allowed set.
|
|
77
|
+
*/
|
|
78
|
+
export function validateScopes(requested, allowed) {
|
|
79
|
+
if (!allowed) {
|
|
80
|
+
// No scope restrictions configured — allow anything.
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
for (const scope of requested) {
|
|
84
|
+
const allowedActions = allowed[scope.resource];
|
|
85
|
+
if (!allowedActions) {
|
|
86
|
+
throw new Error(`Unknown resource "${scope.resource}" in API key scopes. ` +
|
|
87
|
+
`Allowed resources: ${Object.keys(allowed).join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
for (const action of scope.actions) {
|
|
90
|
+
if (action !== "*" && !allowedActions.includes(action)) {
|
|
91
|
+
throw new Error(`Unknown action "${action}" for resource "${scope.resource}". ` +
|
|
92
|
+
`Allowed actions: ${allowedActions.join(", ")}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// ============================================================================
|
|
98
|
+
// Per-key rate limiting (token-bucket)
|
|
99
|
+
// ============================================================================
|
|
100
|
+
/**
|
|
101
|
+
* Check whether a key is rate-limited based on its stored state.
|
|
102
|
+
*
|
|
103
|
+
* Uses the same token-bucket algorithm as sign-in rate limiting:
|
|
104
|
+
* tokens refill linearly over the configured window.
|
|
105
|
+
*
|
|
106
|
+
* @returns `{ limited: boolean; newState: { attemptsLeft, lastAttemptTime } }`
|
|
107
|
+
*/
|
|
108
|
+
export function checkKeyRateLimit(rateLimit, state) {
|
|
109
|
+
const now = Date.now();
|
|
110
|
+
if (!state) {
|
|
111
|
+
// First request — create initial state with one token consumed.
|
|
112
|
+
return {
|
|
113
|
+
limited: false,
|
|
114
|
+
newState: {
|
|
115
|
+
attemptsLeft: rateLimit.maxRequests - 1,
|
|
116
|
+
lastAttemptTime: now,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
const elapsed = now - state.lastAttemptTime;
|
|
121
|
+
const refillRate = rateLimit.maxRequests / rateLimit.windowMs;
|
|
122
|
+
const refilled = Math.min(rateLimit.maxRequests, state.attemptsLeft + elapsed * refillRate);
|
|
123
|
+
if (refilled < 1) {
|
|
124
|
+
return {
|
|
125
|
+
limited: true,
|
|
126
|
+
newState: {
|
|
127
|
+
attemptsLeft: refilled,
|
|
128
|
+
lastAttemptTime: now,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
limited: false,
|
|
134
|
+
newState: {
|
|
135
|
+
attemptsLeft: refilled - 1,
|
|
136
|
+
lastAttemptTime: now,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=apiKey.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiKey.js","sourceRoot":"","sources":["../../../src/server/implementation/apiKey.ts"],"names":[],"mappings":"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"}
|
|
@@ -266,12 +266,15 @@ export declare function Auth(config_: ConvexAuthConfig): {
|
|
|
266
266
|
* Create a new invitation.
|
|
267
267
|
*
|
|
268
268
|
* @param data.groupId - Optional group to invite the user into.
|
|
269
|
-
* @param data.invitedByUserId -
|
|
270
|
-
*
|
|
269
|
+
* @param data.invitedByUserId - Optional user sending the invitation
|
|
270
|
+
* (omit for CLI-generated invites).
|
|
271
|
+
* @param data.email - Optional email of the invitee (omit for
|
|
272
|
+
* CLI-generated invite links where the email is unknown upfront).
|
|
271
273
|
* @param data.tokenHash - Hashed token for secure acceptance.
|
|
272
274
|
* @param data.role - Optional role to assign on acceptance.
|
|
273
275
|
* @param data.status - Initial status (typically "pending").
|
|
274
|
-
* @param data.expiresTime -
|
|
276
|
+
* @param data.expiresTime - Optional expiration timestamp (omit for
|
|
277
|
+
* single-use, non-expiring invites).
|
|
275
278
|
* @param data.extend - Optional arbitrary JSON extension data.
|
|
276
279
|
* @throws ConvexError with code `DUPLICATE_INVITE` if a pending invite
|
|
277
280
|
* already exists for this email and scope.
|
|
@@ -279,18 +282,22 @@ export declare function Auth(config_: ConvexAuthConfig): {
|
|
|
279
282
|
*/
|
|
280
283
|
create: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, data: {
|
|
281
284
|
groupId?: string;
|
|
282
|
-
invitedByUserId
|
|
283
|
-
email
|
|
285
|
+
invitedByUserId?: string;
|
|
286
|
+
email?: string;
|
|
284
287
|
tokenHash: string;
|
|
285
288
|
role?: string;
|
|
286
289
|
status: "pending" | "accepted" | "revoked" | "expired";
|
|
287
|
-
expiresTime
|
|
290
|
+
expiresTime?: number;
|
|
288
291
|
extend?: Record<string, unknown>;
|
|
289
292
|
}) => Promise<string>;
|
|
290
293
|
/**
|
|
291
294
|
* Retrieve an invite by its ID. Returns `null` if not found.
|
|
292
295
|
*/
|
|
293
296
|
get: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery">, inviteId: string) => Promise<any>;
|
|
297
|
+
/**
|
|
298
|
+
* Retrieve an invite by its token hash. Returns `null` if not found.
|
|
299
|
+
*/
|
|
300
|
+
getByTokenHash: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery">, tokenHash: string) => Promise<any>;
|
|
294
301
|
/**
|
|
295
302
|
* List invites, optionally filtered by group and/or status.
|
|
296
303
|
*/
|
|
@@ -329,7 +336,7 @@ export declare function Auth(config_: ConvexAuthConfig): {
|
|
|
329
336
|
* });
|
|
330
337
|
* ```
|
|
331
338
|
*/
|
|
332
|
-
accept: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, inviteId: string) => Promise<void>;
|
|
339
|
+
accept: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, inviteId: string, acceptedByUserId?: string) => Promise<void>;
|
|
333
340
|
/**
|
|
334
341
|
* Revoke a pending invitation.
|
|
335
342
|
*
|
|
@@ -340,6 +347,154 @@ export declare function Auth(config_: ConvexAuthConfig): {
|
|
|
340
347
|
*/
|
|
341
348
|
revoke: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, inviteId: string) => Promise<void>;
|
|
342
349
|
};
|
|
350
|
+
/**
|
|
351
|
+
* Manage passkey credentials for users.
|
|
352
|
+
*
|
|
353
|
+
* ```ts
|
|
354
|
+
* const passkeys = await auth.passkey.list(ctx, { userId });
|
|
355
|
+
* await auth.passkey.rename(ctx, passkeyId, "MacBook Touch ID");
|
|
356
|
+
* await auth.passkey.remove(ctx, passkeyId);
|
|
357
|
+
* ```
|
|
358
|
+
*/
|
|
359
|
+
passkey: {
|
|
360
|
+
/**
|
|
361
|
+
* List all passkeys for a user.
|
|
362
|
+
*
|
|
363
|
+
* @param opts.userId - The user whose passkeys to list.
|
|
364
|
+
* @returns Array of passkey records with credentialId, name, deviceType,
|
|
365
|
+
* backedUp, createdAt, and lastUsedAt.
|
|
366
|
+
*/
|
|
367
|
+
list: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery">, opts: {
|
|
368
|
+
userId: string;
|
|
369
|
+
}) => Promise<any>;
|
|
370
|
+
/**
|
|
371
|
+
* Rename a passkey (set a user-friendly display name).
|
|
372
|
+
*
|
|
373
|
+
* @param passkeyId - The passkey document ID.
|
|
374
|
+
* @param name - New display name (e.g. "MacBook Touch ID").
|
|
375
|
+
*/
|
|
376
|
+
rename: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, passkeyId: string, name: string) => Promise<void>;
|
|
377
|
+
/**
|
|
378
|
+
* Delete a passkey credential.
|
|
379
|
+
*
|
|
380
|
+
* @param passkeyId - The passkey document ID to remove.
|
|
381
|
+
*/
|
|
382
|
+
remove: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, passkeyId: string) => Promise<void>;
|
|
383
|
+
};
|
|
384
|
+
/**
|
|
385
|
+
* Manage TOTP two-factor authentication enrollments for users.
|
|
386
|
+
*
|
|
387
|
+
* ```ts
|
|
388
|
+
* const enrollments = await auth.totp.list(ctx, { userId });
|
|
389
|
+
* await auth.totp.remove(ctx, totpId);
|
|
390
|
+
* ```
|
|
391
|
+
*/
|
|
392
|
+
totp: {
|
|
393
|
+
/**
|
|
394
|
+
* List all TOTP enrollments for a user.
|
|
395
|
+
*
|
|
396
|
+
* @param opts.userId - The user whose enrollments to list.
|
|
397
|
+
* @returns Array of TOTP enrollment records.
|
|
398
|
+
*/
|
|
399
|
+
list: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery">, opts: {
|
|
400
|
+
userId: string;
|
|
401
|
+
}) => Promise<any>;
|
|
402
|
+
/**
|
|
403
|
+
* Delete a TOTP enrollment.
|
|
404
|
+
*
|
|
405
|
+
* @param totpId - The TOTP document ID to remove.
|
|
406
|
+
*/
|
|
407
|
+
remove: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, totpId: string) => Promise<void>;
|
|
408
|
+
};
|
|
409
|
+
/**
|
|
410
|
+
* Manage API keys for programmatic access.
|
|
411
|
+
*
|
|
412
|
+
* Keys use SHA-256 hashing (via `@oslojs/crypto`) and support
|
|
413
|
+
* scoped resource:action permissions with optional per-key rate limiting.
|
|
414
|
+
*
|
|
415
|
+
* ```ts
|
|
416
|
+
* const { keyId, raw } = await auth.key.create(ctx, {
|
|
417
|
+
* userId,
|
|
418
|
+
* name: "CI Pipeline",
|
|
419
|
+
* scopes: [{ resource: "users", actions: ["read", "list"] }],
|
|
420
|
+
* });
|
|
421
|
+
* // raw = "sk_live_abc123..." — show once, never stored
|
|
422
|
+
*
|
|
423
|
+
* const result = await auth.key.verify(ctx, rawKey);
|
|
424
|
+
* result.scopes.can("users", "read"); // true
|
|
425
|
+
* ```
|
|
426
|
+
*/
|
|
427
|
+
key: {
|
|
428
|
+
/**
|
|
429
|
+
* Create a new API key. Returns the raw key **once** — it cannot
|
|
430
|
+
* be retrieved again after creation.
|
|
431
|
+
*
|
|
432
|
+
* @param opts.userId - The user this key belongs to.
|
|
433
|
+
* @param opts.name - Human-readable name (e.g. "CI Pipeline").
|
|
434
|
+
* @param opts.scopes - Resource:action permissions for this key.
|
|
435
|
+
* @param opts.rateLimit - Optional per-key rate limit override.
|
|
436
|
+
* @param opts.expiresAt - Optional expiration timestamp.
|
|
437
|
+
* @returns `{ keyId, raw }` where `raw` is the full key string.
|
|
438
|
+
*/
|
|
439
|
+
create: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, opts: {
|
|
440
|
+
userId: string;
|
|
441
|
+
name: string;
|
|
442
|
+
scopes: import("../types.js").KeyScope[];
|
|
443
|
+
rateLimit?: {
|
|
444
|
+
maxRequests: number;
|
|
445
|
+
windowMs: number;
|
|
446
|
+
};
|
|
447
|
+
expiresAt?: number;
|
|
448
|
+
}) => Promise<{
|
|
449
|
+
keyId: string;
|
|
450
|
+
raw: string;
|
|
451
|
+
}>;
|
|
452
|
+
/**
|
|
453
|
+
* Verify a raw API key string. Returns the userId and a scope checker
|
|
454
|
+
* if the key is valid, not revoked, not expired, and not rate-limited.
|
|
455
|
+
*
|
|
456
|
+
* Also updates `lastUsedAt` and rate limit state as a side effect.
|
|
457
|
+
*
|
|
458
|
+
* @throws Error if the key is invalid, revoked, expired, or rate-limited.
|
|
459
|
+
*/
|
|
460
|
+
verify: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, rawKey: string) => Promise<{
|
|
461
|
+
userId: string;
|
|
462
|
+
keyId: string;
|
|
463
|
+
scopes: import("../types.js").ScopeChecker;
|
|
464
|
+
}>;
|
|
465
|
+
/**
|
|
466
|
+
* List all API keys for a user.
|
|
467
|
+
* Never includes the raw key — only the display prefix.
|
|
468
|
+
*/
|
|
469
|
+
list: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery">, opts: {
|
|
470
|
+
userId: string;
|
|
471
|
+
}) => Promise<any>;
|
|
472
|
+
/**
|
|
473
|
+
* Get a single API key by its document ID.
|
|
474
|
+
* Returns `null` if not found.
|
|
475
|
+
*/
|
|
476
|
+
get: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery">, keyId: string) => Promise<any>;
|
|
477
|
+
/**
|
|
478
|
+
* Update an API key's metadata (name, scopes, rate limit).
|
|
479
|
+
*/
|
|
480
|
+
update: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, keyId: string, data: {
|
|
481
|
+
name?: string;
|
|
482
|
+
scopes?: import("../types.js").KeyScope[];
|
|
483
|
+
rateLimit?: {
|
|
484
|
+
maxRequests: number;
|
|
485
|
+
windowMs: number;
|
|
486
|
+
};
|
|
487
|
+
}) => Promise<void>;
|
|
488
|
+
/**
|
|
489
|
+
* Revoke an API key (soft delete). The key record is preserved
|
|
490
|
+
* for audit purposes but can no longer be used for authentication.
|
|
491
|
+
*/
|
|
492
|
+
revoke: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, keyId: string) => Promise<void>;
|
|
493
|
+
/**
|
|
494
|
+
* Hard delete an API key record.
|
|
495
|
+
*/
|
|
496
|
+
remove: (ctx: Pick<GenericActionCtx<GenericDataModel>, "runQuery" | "runMutation">, keyId: string) => Promise<void>;
|
|
497
|
+
};
|
|
343
498
|
/**
|
|
344
499
|
* Add HTTP actions for JWT verification and OAuth sign-in.
|
|
345
500
|
*
|
|
@@ -384,6 +539,13 @@ export declare function Auth(config_: ConvexAuthConfig): {
|
|
|
384
539
|
verifier?: string;
|
|
385
540
|
tokens?: Tokens | null;
|
|
386
541
|
started?: boolean;
|
|
542
|
+
options?: Record<string, any>;
|
|
543
|
+
totpRequired?: boolean;
|
|
544
|
+
totpSetup?: {
|
|
545
|
+
uri: string;
|
|
546
|
+
secret: string;
|
|
547
|
+
totpId: string;
|
|
548
|
+
};
|
|
387
549
|
}>>;
|
|
388
550
|
/**
|
|
389
551
|
* Action called by the client to invalidate the current session.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/implementation/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,IAAI,EACJ,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EAIX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAe,SAAS,EAAK,MAAM,eAAe,CAAC;AAG1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAMjE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,aAAa,CAAC;AAErB,OAAO,EAA0B,MAAM,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/implementation/index.ts"],"names":[],"mappings":"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"}
|