@robelest/convex-auth 0.0.4-preview.16 → 0.0.4-preview.18
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/authorization/index.d.ts +17 -0
- package/dist/authorization/index.d.ts.map +1 -0
- package/dist/authorization/index.js +17 -0
- package/dist/authorization/index.js.map +1 -0
- package/dist/client/index.js +73 -0
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +52 -0
- 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/index.js +2 -2
- package/dist/component/model.d.ts +75 -75
- package/dist/component/model.d.ts.map +1 -1
- package/dist/component/model.js +2 -0
- package/dist/component/model.js.map +1 -1
- package/dist/component/public/factors.d.ts.map +1 -1
- package/dist/component/public/factors.js +1 -1
- package/dist/component/public/factors.js.map +1 -1
- package/dist/component/public/groups.d.ts +10 -2
- package/dist/component/public/groups.d.ts.map +1 -1
- package/dist/component/public/groups.js +92 -8
- package/dist/component/public/groups.js.map +1 -1
- package/dist/component/public/identity.d.ts.map +1 -1
- package/dist/component/public/identity.js +3 -3
- package/dist/component/public/identity.js.map +1 -1
- package/dist/component/public/shared.d.ts +4 -4
- package/dist/component/public/shared.d.ts.map +1 -1
- package/dist/component/public.d.ts +3 -3
- package/dist/component/public.js +2 -2
- package/dist/component/schema.d.ts +13 -2
- package/dist/component/schema.js +7 -5
- package/dist/component/schema.js.map +1 -1
- package/dist/component/server/auth.d.ts +4 -25
- package/dist/component/server/auth.d.ts.map +1 -1
- package/dist/component/server/auth.js +4 -10
- package/dist/component/server/auth.js.map +1 -1
- package/dist/component/server/domains/core.js +196 -131
- package/dist/component/server/domains/core.js.map +1 -1
- package/dist/component/server/factory.d.ts +3 -3
- package/dist/component/server/signin.js +20 -1
- package/dist/component/server/signin.js.map +1 -1
- package/dist/server/auth.d.ts +4 -25
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +4 -10
- package/dist/server/auth.js.map +1 -1
- package/dist/server/domains/core.d.ts +73 -58
- package/dist/server/domains/core.d.ts.map +1 -1
- package/dist/server/domains/core.js +196 -131
- package/dist/server/domains/core.js.map +1 -1
- package/dist/server/http.d.ts +2 -2
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/index.d.ts +108 -69
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +138 -54
- package/dist/server/index.js.map +1 -1
- package/dist/server/mutations/code.d.ts +9 -9
- package/dist/server/mutations/index.d.ts +69 -69
- package/dist/server/mutations/invalidate.d.ts +4 -4
- package/dist/server/mutations/invalidate.d.ts.map +1 -1
- package/dist/server/mutations/oauth.d.ts +7 -7
- package/dist/server/mutations/register.d.ts +9 -9
- package/dist/server/mutations/retrieve.d.ts +6 -6
- package/dist/server/mutations/retrieve.d.ts.map +1 -1
- package/dist/server/mutations/signature.d.ts +4 -4
- package/dist/server/mutations/signature.d.ts.map +1 -1
- package/dist/server/mutations/signin.d.ts +5 -5
- package/dist/server/mutations/signin.d.ts.map +1 -1
- package/dist/server/mutations/verify.d.ts +7 -7
- package/dist/server/signin.js +20 -1
- package/dist/server/signin.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 +9 -5
- package/src/authorization/index.ts +37 -0
- package/src/client/index.ts +122 -0
- package/src/component/_generated/component.ts +64 -0
- package/src/component/index.ts +1 -1
- package/src/component/model.ts +2 -0
- package/src/component/public/factors.ts +3 -2
- package/src/component/public/groups.ts +142 -8
- package/src/component/public/identity.ts +9 -6
- package/src/component/schema.ts +14 -2
- package/src/server/auth.ts +9 -61
- package/src/server/domains/core.ts +235 -210
- package/src/server/index.ts +158 -75
- package/src/server/signin.ts +52 -0
- package/src/server/version.ts +1 -1
|
@@ -34,7 +34,9 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
34
34
|
extend: convex_values121.VAny<any, "optional", string>;
|
|
35
35
|
}, "required", "email" | "phone" | "extend" | "name" | "image" | "emailVerificationTime" | "phoneVerificationTime" | "isAnonymous" | `extend.${string}`>, {
|
|
36
36
|
email: ["email", "_creationTime"];
|
|
37
|
+
email_verified: ["email", "emailVerificationTime", "_creationTime"];
|
|
37
38
|
phone: ["phone", "_creationTime"];
|
|
39
|
+
phone_verified: ["phone", "phoneVerificationTime", "_creationTime"];
|
|
38
40
|
}, {}, {}>;
|
|
39
41
|
/**
|
|
40
42
|
* Active sessions. A single user can have multiple concurrent sessions
|
|
@@ -95,6 +97,7 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
95
97
|
parentRefreshTokenId: convex_values121.VId<convex_values121.GenericId<"RefreshToken"> | undefined, "optional">;
|
|
96
98
|
}, "required", "sessionId" | "expirationTime" | "firstUsedTime" | "parentRefreshTokenId">, {
|
|
97
99
|
session_id: ["sessionId", "_creationTime"];
|
|
100
|
+
session_id_first_used: ["sessionId", "firstUsedTime", "_creationTime"];
|
|
98
101
|
session_id_parent_refresh_token_id: ["sessionId", "parentRefreshTokenId", "_creationTime"];
|
|
99
102
|
}, {}, {}>;
|
|
100
103
|
/**
|
|
@@ -195,6 +198,7 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
195
198
|
lastUsedAt: convex_values121.VFloat64<number | undefined, "optional">;
|
|
196
199
|
}, "required", "userId" | "secret" | "name" | "createdAt" | "lastUsedAt" | "digits" | "period" | "verified">, {
|
|
197
200
|
user_id: ["userId", "_creationTime"];
|
|
201
|
+
user_id_verified: ["userId", "verified", "_creationTime"];
|
|
198
202
|
}, {}, {}>;
|
|
199
203
|
/**
|
|
200
204
|
* Device authorization codes (RFC 8628). Each record tracks a pending
|
|
@@ -247,6 +251,8 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
247
251
|
extend?: any;
|
|
248
252
|
slug?: string | undefined;
|
|
249
253
|
parentGroupId?: convex_values121.GenericId<"Group"> | undefined;
|
|
254
|
+
rootGroupId?: convex_values121.GenericId<"Group"> | undefined;
|
|
255
|
+
isRoot?: boolean | undefined;
|
|
250
256
|
tags?: {
|
|
251
257
|
value: string;
|
|
252
258
|
key: string;
|
|
@@ -256,7 +262,9 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
256
262
|
name: convex_values121.VString<string, "required">;
|
|
257
263
|
slug: convex_values121.VString<string | undefined, "optional">;
|
|
258
264
|
type: convex_values121.VString<string | undefined, "optional">;
|
|
259
|
-
parentGroupId: convex_values121.VId<convex_values121.GenericId<"Group"> | undefined, "optional">; /**
|
|
265
|
+
parentGroupId: convex_values121.VId<convex_values121.GenericId<"Group"> | undefined, "optional">; /** Denormalized root group ID. Self-referencing for root groups. */
|
|
266
|
+
rootGroupId: convex_values121.VId<convex_values121.GenericId<"Group"> | undefined, "optional">; /** Denormalized flag: `true` when `parentGroupId` is absent. */
|
|
267
|
+
isRoot: convex_values121.VBoolean<boolean | undefined, "optional">; /** Faceted classification tags. Normalized at write time (trimmed, lowercased). */
|
|
260
268
|
tags: convex_values121.VArray<{
|
|
261
269
|
value: string;
|
|
262
270
|
key: string;
|
|
@@ -268,9 +276,11 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
268
276
|
value: convex_values121.VString<string, "required">;
|
|
269
277
|
}, "required", "value" | "key">, "optional">;
|
|
270
278
|
extend: convex_values121.VAny<any, "optional", string>;
|
|
271
|
-
}, "required", "type" | "extend" | "name" | `extend.${string}` | "slug" | "parentGroupId" | "tags">, {
|
|
279
|
+
}, "required", "type" | "extend" | "name" | `extend.${string}` | "slug" | "parentGroupId" | "rootGroupId" | "isRoot" | "tags">, {
|
|
272
280
|
slug: ["slug", "_creationTime"];
|
|
273
281
|
parent_group_id: ["parentGroupId", "_creationTime"];
|
|
282
|
+
root_group_id: ["rootGroupId", "_creationTime"];
|
|
283
|
+
is_root: ["isRoot", "_creationTime"];
|
|
274
284
|
type: ["type", "_creationTime"];
|
|
275
285
|
type_parent_group_id: ["type", "parentGroupId", "_creationTime"];
|
|
276
286
|
}, {}, {}>;
|
|
@@ -314,6 +324,7 @@ declare const _default: convex_server66.SchemaDefinition<{
|
|
|
314
324
|
}, "required", "extend" | "userId" | `extend.${string}` | "status" | "groupId" | "role" | "roleIds">, {
|
|
315
325
|
group_id: ["groupId", "_creationTime"];
|
|
316
326
|
group_id_user_id: ["groupId", "userId", "_creationTime"];
|
|
327
|
+
group_id_status: ["groupId", "status", "_creationTime"];
|
|
317
328
|
user_id: ["userId", "_creationTime"];
|
|
318
329
|
}, {}, {}>;
|
|
319
330
|
/**
|
package/dist/component/schema.js
CHANGED
|
@@ -20,7 +20,7 @@ var schema_default = defineSchema({
|
|
|
20
20
|
phoneVerificationTime: v.optional(v.number()),
|
|
21
21
|
isAnonymous: v.optional(v.boolean()),
|
|
22
22
|
extend: v.optional(v.any())
|
|
23
|
-
}).index("email", ["email"]).index("phone", ["phone"]),
|
|
23
|
+
}).index("email", ["email"]).index("email_verified", ["email", "emailVerificationTime"]).index("phone", ["phone"]).index("phone_verified", ["phone", "phoneVerificationTime"]),
|
|
24
24
|
Session: defineTable({
|
|
25
25
|
userId: v.id("User"),
|
|
26
26
|
expirationTime: v.number()
|
|
@@ -39,7 +39,7 @@ var schema_default = defineSchema({
|
|
|
39
39
|
expirationTime: v.number(),
|
|
40
40
|
firstUsedTime: v.optional(v.number()),
|
|
41
41
|
parentRefreshTokenId: v.optional(v.id("RefreshToken"))
|
|
42
|
-
}).index("session_id", ["sessionId"]).index("session_id_parent_refresh_token_id", ["sessionId", "parentRefreshTokenId"]),
|
|
42
|
+
}).index("session_id", ["sessionId"]).index("session_id_first_used", ["sessionId", "firstUsedTime"]).index("session_id_parent_refresh_token_id", ["sessionId", "parentRefreshTokenId"]),
|
|
43
43
|
VerificationCode: defineTable({
|
|
44
44
|
accountId: v.id("Account"),
|
|
45
45
|
provider: v.string(),
|
|
@@ -75,7 +75,7 @@ var schema_default = defineSchema({
|
|
|
75
75
|
name: v.optional(v.string()),
|
|
76
76
|
createdAt: v.number(),
|
|
77
77
|
lastUsedAt: v.optional(v.number())
|
|
78
|
-
}).index("user_id", ["userId"]),
|
|
78
|
+
}).index("user_id", ["userId"]).index("user_id_verified", ["userId", "verified"]),
|
|
79
79
|
DeviceCode: defineTable({
|
|
80
80
|
deviceCodeHash: v.string(),
|
|
81
81
|
userCode: v.string(),
|
|
@@ -96,9 +96,11 @@ var schema_default = defineSchema({
|
|
|
96
96
|
slug: v.optional(v.string()),
|
|
97
97
|
type: v.optional(v.string()),
|
|
98
98
|
parentGroupId: v.optional(v.id("Group")),
|
|
99
|
+
rootGroupId: v.optional(v.id("Group")),
|
|
100
|
+
isRoot: v.optional(v.boolean()),
|
|
99
101
|
tags: v.optional(v.array(vTag)),
|
|
100
102
|
extend: v.optional(v.any())
|
|
101
|
-
}).index("slug", ["slug"]).index("parent_group_id", ["parentGroupId"]).index("type", ["type"]).index("type_parent_group_id", ["type", "parentGroupId"]),
|
|
103
|
+
}).index("slug", ["slug"]).index("parent_group_id", ["parentGroupId"]).index("root_group_id", ["rootGroupId"]).index("is_root", ["isRoot"]).index("type", ["type"]).index("type_parent_group_id", ["type", "parentGroupId"]),
|
|
102
104
|
GroupTag: defineTable({
|
|
103
105
|
group_id: v.id("Group"),
|
|
104
106
|
key: v.string(),
|
|
@@ -111,7 +113,7 @@ var schema_default = defineSchema({
|
|
|
111
113
|
roleIds: v.optional(v.array(v.string())),
|
|
112
114
|
status: v.optional(v.string()),
|
|
113
115
|
extend: v.optional(v.any())
|
|
114
|
-
}).index("group_id", ["groupId"]).index("group_id_user_id", ["groupId", "userId"]).index("user_id", ["userId"]),
|
|
116
|
+
}).index("group_id", ["groupId"]).index("group_id_user_id", ["groupId", "userId"]).index("group_id_status", ["groupId", "status"]).index("user_id", ["userId"]),
|
|
115
117
|
GroupInvite: defineTable({
|
|
116
118
|
groupId: v.optional(v.id("Group")),
|
|
117
119
|
invitedByUserId: v.optional(v.id("User")),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","names":[],"sources":["../../src/component/schema.ts"],"sourcesContent":["import { defineSchema, defineTable } from \"convex/server\";\nimport { v } from \"convex/values\";\n\nimport {\n vApiKeyRateLimit,\n vApiKeyRateLimitState,\n vApiKeyScope,\n vAuditActorType,\n vAuditStatus,\n vDeviceStatus,\n vEnterprisePolicy,\n vEnterpriseSecretKind,\n vEnterpriseStatus,\n vInviteStatus,\n vScimResourceType,\n vScimStatus,\n vTag,\n vWebhookDeliveryStatus,\n vWebhookEndpointStatus,\n} from \"./model\";\n\n/**\n * Schema for the auth component.\n *\n * Contains tables for core authentication (users, sessions, accounts, tokens,\n * verification codes, PKCE verifiers, rate limits) and hierarchical group\n * management (groups, members, invites).\n */\nexport default defineSchema({\n /**\n * Authenticated users. A user may have multiple linked accounts\n * and multiple concurrent sessions.\n */\n User: defineTable({\n name: v.optional(v.string()),\n image: v.optional(v.string()),\n email: v.optional(v.string()),\n emailVerificationTime: v.optional(v.number()),\n phone: v.optional(v.string()),\n phoneVerificationTime: v.optional(v.number()),\n isAnonymous: v.optional(v.boolean()),\n extend: v.optional(v.any()),\n })\n .index(\"email\", [\"email\"])\n .index(\"phone\", [\"phone\"]),\n\n /**\n * Active sessions. A single user can have multiple concurrent sessions\n * across different devices or browsers. Sessions expire after a\n * configurable duration.\n */\n Session: defineTable({\n userId: v.id(\"User\"),\n expirationTime: v.number(),\n }).index(\"user_id\", [\"userId\"]),\n\n /**\n * Authentication accounts. Each account links a user to a single\n * authentication provider (e.g. Google OAuth, email/password).\n * A user can have multiple accounts linked.\n */\n Account: defineTable({\n userId: v.id(\"User\"),\n provider: v.string(),\n providerAccountId: v.string(),\n secret: v.optional(v.string()),\n emailVerified: v.optional(v.string()),\n phoneVerified: v.optional(v.string()),\n extend: v.optional(v.any()),\n })\n .index(\"user_id_provider\", [\"userId\", \"provider\"])\n .index(\"provider_account_id\", [\"provider\", \"providerAccountId\"]),\n\n /**\n * Refresh tokens for session continuity. Tokens are single-use and form\n * a chain — each token references the one it was exchanged from.\n *\n * The active refresh token is the most recently created token that has not\n * been used yet. A 10-second reuse window allows for concurrent requests.\n * Any invalid use of a token invalidates the entire chain.\n */\n RefreshToken: defineTable({\n sessionId: v.id(\"Session\"),\n expirationTime: v.number(),\n firstUsedTime: v.optional(v.number()),\n parentRefreshTokenId: v.optional(v.id(\"RefreshToken\")),\n })\n .index(\"session_id\", [\"sessionId\"])\n .index(\"session_id_parent_refresh_token_id\", [\n \"sessionId\",\n \"parentRefreshTokenId\",\n ]),\n\n /**\n * Verification codes for OTP tokens, magic link tokens, and OAuth codes.\n */\n VerificationCode: defineTable({\n accountId: v.id(\"Account\"),\n provider: v.string(),\n code: v.string(),\n expirationTime: v.number(),\n verifier: v.optional(v.string()),\n emailVerified: v.optional(v.string()),\n phoneVerified: v.optional(v.string()),\n })\n .index(\"account_id\", [\"accountId\"])\n .index(\"code\", [\"code\"]),\n\n /**\n * PKCE verifiers for OAuth flows. Stores the cryptographic verifier\n * used to prove the authorization request originated from this client.\n */\n AuthVerifier: defineTable({\n sessionId: v.optional(v.id(\"Session\")),\n signature: v.optional(v.string()),\n }).index(\"signature\", [\"signature\"]),\n\n /**\n * WebAuthn passkey credentials. Each credential links a user to a\n * registered authenticator (Touch ID, Face ID, security key, etc.).\n * A user can have multiple passkeys across different devices.\n */\n Passkey: defineTable({\n userId: v.id(\"User\"),\n /** Base64url-encoded credential ID from the authenticator. */\n credentialId: v.string(),\n /** Public key bytes (SEC1 uncompressed for EC, SPKI for RSA). */\n publicKey: v.bytes(),\n /** COSE algorithm identifier (-7 for ES256, -257 for RS256, -8 for EdDSA). */\n algorithm: v.number(),\n /** Signature counter for clone detection. Many authenticators return 0. */\n counter: v.number(),\n /** Authenticator transport hints (e.g. \"internal\", \"hybrid\", \"usb\", \"ble\", \"nfc\"). */\n transports: v.optional(v.array(v.string())),\n /** Whether this is a single-device or multi-device (synced) credential. */\n deviceType: v.string(),\n /** Whether the credential is backed up (synced passkey). */\n backedUp: v.boolean(),\n /** User-assigned friendly name (e.g. \"MacBook Touch ID\"). */\n name: v.optional(v.string()),\n createdAt: v.number(),\n lastUsedAt: v.optional(v.number()),\n })\n .index(\"user_id\", [\"userId\"])\n .index(\"credential_id\", [\"credentialId\"]),\n\n /**\n * TOTP two-factor authentication secrets. Each record links a user to\n * an authenticator app. A user can have multiple TOTP enrollments\n * (e.g. different authenticator apps) but typically has one.\n *\n * The `verified` flag indicates whether the user has completed setup\n * by successfully entering a code from their authenticator app.\n * Unverified enrollments are in-progress setup that can be discarded.\n */\n TotpFactor: defineTable({\n userId: v.id(\"User\"),\n /** Raw TOTP secret key bytes. */\n secret: v.bytes(),\n /** Number of digits in each code (typically 6). */\n digits: v.number(),\n /** Time period in seconds for code rotation (typically 30). */\n period: v.number(),\n /** Whether setup has been confirmed with a valid code. */\n verified: v.boolean(),\n /** User-assigned friendly name (e.g. \"Google Authenticator\"). */\n name: v.optional(v.string()),\n createdAt: v.number(),\n lastUsedAt: v.optional(v.number()),\n }).index(\"user_id\", [\"userId\"]),\n\n /**\n * Device authorization codes (RFC 8628). Each record tracks a pending\n * device auth session — the device polls with `deviceCode` while the\n * user authorizes via `userCode` on a secondary device.\n */\n DeviceCode: defineTable({\n /** High-entropy code used by the device for polling. Stored as SHA-256 hash. */\n deviceCodeHash: v.string(),\n /** Short human-readable code the user enters (e.g. \"WDJB-MJHT\"). */\n userCode: v.string(),\n /** Expiration timestamp (ms since epoch). */\n expiresAt: v.number(),\n /** Minimum polling interval in seconds. */\n interval: v.number(),\n /** Current status of this device authorization session. */\n status: vDeviceStatus,\n /** Set when the user authorizes — links to the authorizing user. */\n userId: v.optional(v.id(\"User\")),\n /** Set when the user authorizes — the session created for the device. */\n sessionId: v.optional(v.id(\"Session\")),\n /** Timestamp of the last poll request (for slow_down enforcement). */\n lastPolledAt: v.optional(v.number()),\n })\n .index(\"device_code_hash\", [\"deviceCodeHash\"])\n .index(\"user_code_status\", [\"userCode\", \"status\"]),\n\n /**\n * Rate limit tracking for OTP and password sign-in attempts.\n */\n RateLimit: defineTable({\n identifier: v.string(),\n last_attempt_time: v.number(),\n attempts_left: v.number(),\n }).index(\"by_identifier\", [\"identifier\"]),\n\n /**\n * Hierarchical groups. A group with no `parentGroupId` is a root group.\n * Groups can nest arbitrarily deep via `parentGroupId` for modeling\n * organizations, teams, departments, or any tree structure.\n */\n Group: defineTable({\n name: v.string(),\n slug: v.optional(v.string()),\n type: v.optional(v.string()),\n parentGroupId: v.optional(v.id(\"Group\")),\n /** Faceted classification tags. Normalized at write time (trimmed, lowercased). */\n tags: v.optional(v.array(vTag)),\n extend: v.optional(v.any()),\n })\n .index(\"slug\", [\"slug\"])\n .index(\"parent_group_id\", [\"parentGroupId\"])\n .index(\"type\", [\"type\"])\n .index(\"type_parent_group_id\", [\"type\", \"parentGroupId\"]),\n\n /**\n * Denormalized group-tag index table for efficient tag-based filtering.\n * Each row maps one `(key, value)` pair to a group. Kept in sync by\n * `groupCreate`, `groupUpdate`, and `groupDelete`.\n */\n GroupTag: defineTable({\n group_id: v.id(\"Group\"),\n key: v.string(),\n value: v.string(),\n })\n .index(\"by_group\", [\"group_id\"])\n .index(\"by_key_value\", [\"key\", \"value\"])\n .index(\"by_key\", [\"key\"]),\n\n /**\n * Group membership. Links a user to a group with an application-defined\n * role (e.g. \"owner\", \"admin\", \"member\", \"viewer\"). A user can be a\n * member of multiple groups with different roles in each.\n */\n GroupMember: defineTable({\n groupId: v.id(\"Group\"),\n userId: v.id(\"User\"),\n role: v.optional(v.string()),\n roleIds: v.optional(v.array(v.string())),\n status: v.optional(v.string()),\n extend: v.optional(v.any()),\n })\n .index(\"group_id\", [\"groupId\"])\n .index(\"group_id_user_id\", [\"groupId\", \"userId\"])\n .index(\"user_id\", [\"userId\"]),\n\n /**\n * Invitations. Tracks pending, accepted, revoked, and expired\n * invitations. Optionally scoped to a group via `groupId`, or\n * platform-level when `groupId` is omitted.\n *\n * `email` and `invitedByUserId` are optional to support CLI-generated\n * invite links where neither is known upfront.\n */\n GroupInvite: defineTable({\n groupId: v.optional(v.id(\"Group\")),\n invitedByUserId: v.optional(v.id(\"User\")),\n email: v.optional(v.string()),\n tokenHash: v.string(),\n role: v.optional(v.string()),\n roleIds: v.optional(v.array(v.string())),\n status: vInviteStatus,\n expiresTime: v.optional(v.number()),\n acceptedByUserId: v.optional(v.id(\"User\")),\n acceptedTime: v.optional(v.number()),\n extend: v.optional(v.any()),\n })\n .index(\"token_hash\", [\"tokenHash\"])\n .index(\"status\", [\"status\"])\n .index(\"email_status\", [\"email\", \"status\"])\n .index(\"invited_by_user_id_status\", [\"invitedByUserId\", \"status\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"group_id_status\", [\"groupId\", \"status\"]),\n\n /**\n * Enterprise configuration attached to a root group/organization.\n *\n * The `config` payload intentionally stays flexible so the headless enterprise\n * SDK can evolve without forcing schema churn for every protocol-specific\n * field addition.\n */\n Enterprise: defineTable({\n groupId: v.id(\"Group\"),\n slug: v.optional(v.string()),\n name: v.optional(v.string()),\n status: vEnterpriseStatus,\n policy: v.optional(vEnterprisePolicy),\n config: v.optional(v.any()),\n extend: v.optional(v.any()),\n })\n .index(\"group_id\", [\"groupId\"])\n .index(\"slug\", [\"slug\"])\n .index(\"status\", [\"status\"]),\n\n /**\n * Verified or pending domains linked to an enterprise record.\n */\n EnterpriseDomain: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n domain: v.string(),\n isPrimary: v.boolean(),\n verifiedAt: v.optional(v.number()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"domain\", [\"domain\"]),\n\n /**\n * Pending DNS TXT verification challenges for enterprise domains.\n */\n EnterpriseDomainVerification: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n domainId: v.id(\"EnterpriseDomain\"),\n domain: v.string(),\n recordName: v.string(),\n token: v.string(),\n tokenHash: v.string(),\n requestedAt: v.number(),\n expiresAt: v.number(),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"domain_id\", [\"domainId\"])\n .index(\"token_hash\", [\"tokenHash\"]),\n\n /**\n * Encrypted enterprise secrets stored separately from protocol config.\n */\n EnterpriseSecret: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n kind: vEnterpriseSecretKind,\n ciphertext: v.string(),\n updatedAt: v.number(),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"enterprise_id_kind\", [\"enterpriseId\", \"kind\"])\n .index(\"group_id\", [\"groupId\"]),\n\n /**\n * SCIM configuration for an enterprise tenant.\n */\n EnterpriseScimConfig: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n status: vScimStatus,\n basePath: v.string(),\n tokenHash: v.string(),\n lastRotatedAt: v.optional(v.number()),\n extend: v.optional(v.any()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"token_hash\", [\"tokenHash\"])\n .index(\"status\", [\"status\"]),\n\n /**\n * External SCIM identities mapped into local users/groups.\n */\n EnterpriseScimIdentity: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n resourceType: vScimResourceType,\n externalId: v.string(),\n userId: v.optional(v.id(\"User\")),\n mappedGroupId: v.optional(v.id(\"Group\")),\n lastProvisionedAt: v.optional(v.number()),\n active: v.optional(v.boolean()),\n raw: v.optional(v.any()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"enterprise_id_resource_type_external_id\", [\n \"enterpriseId\",\n \"resourceType\",\n \"externalId\",\n ])\n .index(\"enterprise_id_user_id\", [\"enterpriseId\", \"userId\"])\n .index(\"user_id\", [\"userId\"])\n .index(\"mapped_group_id\", [\"mappedGroupId\"]),\n\n /**\n * Immutable audit trail for enterprise operations.\n */\n EnterpriseAuditEvent: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n eventType: v.string(),\n actorType: vAuditActorType,\n actorId: v.optional(v.string()),\n subjectType: v.string(),\n subjectId: v.optional(v.string()),\n status: vAuditStatus,\n occurredAt: v.number(),\n requestId: v.optional(v.string()),\n ip: v.optional(v.string()),\n metadata: v.optional(v.any()),\n })\n .index(\"enterprise_id_occurred_at\", [\"enterpriseId\", \"occurredAt\"])\n .index(\"group_id_occurred_at\", [\"groupId\", \"occurredAt\"])\n .index(\"event_type_occurred_at\", [\"eventType\", \"occurredAt\"]),\n\n /**\n * Webhook endpoints subscribed to enterprise audit and lifecycle events.\n */\n EnterpriseWebhookEndpoint: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n url: v.string(),\n status: vWebhookEndpointStatus,\n secretHash: v.string(),\n subscriptions: v.array(v.string()),\n createdByUserId: v.optional(v.id(\"User\")),\n lastSuccessAt: v.optional(v.number()),\n lastFailureAt: v.optional(v.number()),\n failureCount: v.number(),\n extend: v.optional(v.any()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"status\", [\"status\"]),\n\n /**\n * Delivery queue for outbound enterprise webhooks.\n */\n EnterpriseWebhookDelivery: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n endpointId: v.id(\"EnterpriseWebhookEndpoint\"),\n auditEventId: v.optional(v.id(\"EnterpriseAuditEvent\")),\n eventType: v.string(),\n status: vWebhookDeliveryStatus,\n attemptCount: v.number(),\n nextAttemptAt: v.number(),\n lastAttemptAt: v.optional(v.number()),\n lastResponseStatus: v.optional(v.number()),\n lastError: v.optional(v.string()),\n payload: v.any(),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"status_next_attempt_at\", [\"status\", \"nextAttemptAt\"])\n .index(\"endpoint_id_status\", [\"endpointId\", \"status\"])\n .index(\"audit_event_id\", [\"auditEventId\"]),\n\n /**\n * API keys for programmatic access. Each key links a user to a set of\n * scoped permissions and optional per-key rate limiting.\n *\n * The raw key is never stored — only a SHA-256 hash. A short prefix\n * (e.g. \"sk_abc1...\") is kept for display in admin interfaces.\n *\n * Keys support:\n * - **Scoped permissions**: resource:action pairs (e.g. users:read)\n * - **Per-key rate limiting**: token-bucket with configurable window\n * - **Expiration**: optional TTL\n * - **Soft revocation**: `revoked` flag preserves audit trail\n */\n ApiKey: defineTable({\n userId: v.id(\"User\"),\n /** First chars of the key for display (e.g. \"sk_abc1...\"). */\n prefix: v.string(),\n /** SHA-256 hex hash of the full raw key. */\n hashedKey: v.string(),\n /** User-assigned name (e.g. \"CI Pipeline\", \"Production API\"). */\n name: v.string(),\n /** Scoped permissions: [{ resource: \"users\", actions: [\"read\", \"list\"] }]. */\n scopes: v.array(vApiKeyScope),\n /** Optional per-key rate limit configuration. */\n rateLimit: v.optional(vApiKeyRateLimit),\n /** Rate limit state tracking (token-bucket). */\n rateLimitState: v.optional(vApiKeyRateLimitState),\n /** Expiration timestamp. Null/undefined = never expires. */\n expiresAt: v.optional(v.number()),\n lastUsedAt: v.optional(v.number()),\n createdAt: v.number(),\n /** Soft-revoke flag. Revoked keys are kept for audit trail. */\n revoked: v.boolean(),\n /** Arbitrary app-specific metadata attached to the key. */\n metadata: v.optional(v.any()),\n })\n .index(\"user_id\", [\"userId\"])\n .index(\"hashed_key\", [\"hashedKey\"]),\n});\n"],"mappings":";;;;;;;;;;;;AA4BA,qBAAe,aAAa;CAK1B,MAAM,YAAY;EAChB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7B,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7B,uBAAuB,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7C,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7B,uBAAuB,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7C,aAAa,EAAE,SAAS,EAAE,SAAS,CAAC;EACpC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,SAAS,CAAC,QAAQ,CAAC,CACzB,MAAM,SAAS,CAAC,QAAQ,CAAC;CAO5B,SAAS,YAAY;EACnB,QAAQ,EAAE,GAAG,OAAO;EACpB,gBAAgB,EAAE,QAAQ;EAC3B,CAAC,CAAC,MAAM,WAAW,CAAC,SAAS,CAAC;CAO/B,SAAS,YAAY;EACnB,QAAQ,EAAE,GAAG,OAAO;EACpB,UAAU,EAAE,QAAQ;EACpB,mBAAmB,EAAE,QAAQ;EAC7B,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC9B,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,oBAAoB,CAAC,UAAU,WAAW,CAAC,CACjD,MAAM,uBAAuB,CAAC,YAAY,oBAAoB,CAAC;CAUlE,cAAc,YAAY;EACxB,WAAW,EAAE,GAAG,UAAU;EAC1B,gBAAgB,EAAE,QAAQ;EAC1B,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,sBAAsB,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC;EACvD,CAAC,CACC,MAAM,cAAc,CAAC,YAAY,CAAC,CAClC,MAAM,sCAAsC,CAC3C,aACA,uBACD,CAAC;CAKJ,kBAAkB,YAAY;EAC5B,WAAW,EAAE,GAAG,UAAU;EAC1B,UAAU,EAAE,QAAQ;EACpB,MAAM,EAAE,QAAQ;EAChB,gBAAgB,EAAE,QAAQ;EAC1B,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC;EAChC,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACtC,CAAC,CACC,MAAM,cAAc,CAAC,YAAY,CAAC,CAClC,MAAM,QAAQ,CAAC,OAAO,CAAC;CAM1B,cAAc,YAAY;EACxB,WAAW,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;EACtC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EAClC,CAAC,CAAC,MAAM,aAAa,CAAC,YAAY,CAAC;CAOpC,SAAS,YAAY;EACnB,QAAQ,EAAE,GAAG,OAAO;EAEpB,cAAc,EAAE,QAAQ;EAExB,WAAW,EAAE,OAAO;EAEpB,WAAW,EAAE,QAAQ;EAErB,SAAS,EAAE,QAAQ;EAEnB,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;EAE3C,YAAY,EAAE,QAAQ;EAEtB,UAAU,EAAE,SAAS;EAErB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,WAAW,EAAE,QAAQ;EACrB,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;EACnC,CAAC,CACC,MAAM,WAAW,CAAC,SAAS,CAAC,CAC5B,MAAM,iBAAiB,CAAC,eAAe,CAAC;CAW3C,YAAY,YAAY;EACtB,QAAQ,EAAE,GAAG,OAAO;EAEpB,QAAQ,EAAE,OAAO;EAEjB,QAAQ,EAAE,QAAQ;EAElB,QAAQ,EAAE,QAAQ;EAElB,UAAU,EAAE,SAAS;EAErB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,WAAW,EAAE,QAAQ;EACrB,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;EACnC,CAAC,CAAC,MAAM,WAAW,CAAC,SAAS,CAAC;CAO/B,YAAY,YAAY;EAEtB,gBAAgB,EAAE,QAAQ;EAE1B,UAAU,EAAE,QAAQ;EAEpB,WAAW,EAAE,QAAQ;EAErB,UAAU,EAAE,QAAQ;EAEpB,QAAQ;EAER,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;EAEhC,WAAW,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC;EAEtC,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,CAAC,CACC,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAC7C,MAAM,oBAAoB,CAAC,YAAY,SAAS,CAAC;CAKpD,WAAW,YAAY;EACrB,YAAY,EAAE,QAAQ;EACtB,mBAAmB,EAAE,QAAQ;EAC7B,eAAe,EAAE,QAAQ;EAC1B,CAAC,CAAC,MAAM,iBAAiB,CAAC,aAAa,CAAC;CAOzC,OAAO,YAAY;EACjB,MAAM,EAAE,QAAQ;EAChB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,eAAe,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;EAExC,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;EAC/B,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,QAAQ,CAAC,OAAO,CAAC,CACvB,MAAM,mBAAmB,CAAC,gBAAgB,CAAC,CAC3C,MAAM,QAAQ,CAAC,OAAO,CAAC,CACvB,MAAM,wBAAwB,CAAC,QAAQ,gBAAgB,CAAC;CAO3D,UAAU,YAAY;EACpB,UAAU,EAAE,GAAG,QAAQ;EACvB,KAAK,EAAE,QAAQ;EACf,OAAO,EAAE,QAAQ;EAClB,CAAC,CACC,MAAM,YAAY,CAAC,WAAW,CAAC,CAC/B,MAAM,gBAAgB,CAAC,OAAO,QAAQ,CAAC,CACvC,MAAM,UAAU,CAAC,MAAM,CAAC;CAO3B,aAAa,YAAY;EACvB,SAAS,EAAE,GAAG,QAAQ;EACtB,QAAQ,EAAE,GAAG,OAAO;EACpB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;EACxC,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC9B,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,oBAAoB,CAAC,WAAW,SAAS,CAAC,CAChD,MAAM,WAAW,CAAC,SAAS,CAAC;CAU/B,aAAa,YAAY;EACvB,SAAS,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;EAClC,iBAAiB,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;EACzC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC7B,WAAW,EAAE,QAAQ;EACrB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;EACxC,QAAQ;EACR,aAAa,EAAE,SAAS,EAAE,QAAQ,CAAC;EACnC,kBAAkB,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;EAC1C,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC;EACpC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,cAAc,CAAC,YAAY,CAAC,CAClC,MAAM,UAAU,CAAC,SAAS,CAAC,CAC3B,MAAM,gBAAgB,CAAC,SAAS,SAAS,CAAC,CAC1C,MAAM,6BAA6B,CAAC,mBAAmB,SAAS,CAAC,CACjE,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,mBAAmB,CAAC,WAAW,SAAS,CAAC;CASlD,YAAY,YAAY;EACtB,SAAS,EAAE,GAAG,QAAQ;EACtB,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC5B,QAAQ;EACR,QAAQ,EAAE,SAAS,kBAAkB;EACrC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC3B,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,QAAQ,CAAC,OAAO,CAAC,CACvB,MAAM,UAAU,CAAC,SAAS,CAAC;CAK9B,kBAAkB,YAAY;EAC5B,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,QAAQ,EAAE,QAAQ;EAClB,WAAW,EAAE,SAAS;EACtB,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;EACnC,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,UAAU,CAAC,SAAS,CAAC;CAK9B,8BAA8B,YAAY;EACxC,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,UAAU,EAAE,GAAG,mBAAmB;EAClC,QAAQ,EAAE,QAAQ;EAClB,YAAY,EAAE,QAAQ;EACtB,OAAO,EAAE,QAAQ;EACjB,WAAW,EAAE,QAAQ;EACrB,aAAa,EAAE,QAAQ;EACvB,WAAW,EAAE,QAAQ;EACtB,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,aAAa,CAAC,WAAW,CAAC,CAChC,MAAM,cAAc,CAAC,YAAY,CAAC;CAKrC,kBAAkB,YAAY;EAC5B,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,MAAM;EACN,YAAY,EAAE,QAAQ;EACtB,WAAW,EAAE,QAAQ;EACtB,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,sBAAsB,CAAC,gBAAgB,OAAO,CAAC,CACrD,MAAM,YAAY,CAAC,UAAU,CAAC;CAKjC,sBAAsB,YAAY;EAChC,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,QAAQ;EACR,UAAU,EAAE,QAAQ;EACpB,WAAW,EAAE,QAAQ;EACrB,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,cAAc,CAAC,YAAY,CAAC,CAClC,MAAM,UAAU,CAAC,SAAS,CAAC;CAK9B,wBAAwB,YAAY;EAClC,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,cAAc;EACd,YAAY,EAAE,QAAQ;EACtB,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;EAChC,eAAe,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC;EACxC,mBAAmB,EAAE,SAAS,EAAE,QAAQ,CAAC;EACzC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;EAC/B,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC;EACzB,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,2CAA2C;EAChD;EACA;EACA;EACD,CAAC,CACD,MAAM,yBAAyB,CAAC,gBAAgB,SAAS,CAAC,CAC1D,MAAM,WAAW,CAAC,SAAS,CAAC,CAC5B,MAAM,mBAAmB,CAAC,gBAAgB,CAAC;CAK9C,sBAAsB,YAAY;EAChC,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,WAAW,EAAE,QAAQ;EACrB,WAAW;EACX,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC/B,aAAa,EAAE,QAAQ;EACvB,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,QAAQ;EACR,YAAY,EAAE,QAAQ;EACtB,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,IAAI,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC1B,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC;EAC9B,CAAC,CACC,MAAM,6BAA6B,CAAC,gBAAgB,aAAa,CAAC,CAClE,MAAM,wBAAwB,CAAC,WAAW,aAAa,CAAC,CACxD,MAAM,0BAA0B,CAAC,aAAa,aAAa,CAAC;CAK/D,2BAA2B,YAAY;EACrC,cAAc,EAAE,GAAG,aAAa;EAChC,SAAS,EAAE,GAAG,QAAQ;EACtB,KAAK,EAAE,QAAQ;EACf,QAAQ;EACR,YAAY,EAAE,QAAQ;EACtB,eAAe,EAAE,MAAM,EAAE,QAAQ,CAAC;EAClC,iBAAiB,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;EACzC,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,cAAc,EAAE,QAAQ;EACxB,QAAQ,EAAE,SAAS,EAAE,KAAK,CAAC;EAC5B,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,YAAY,CAAC,UAAU,CAAC,CAC9B,MAAM,UAAU,CAAC,SAAS,CAAC;CAK9B,2BAA2B,YAAY;EACrC,cAAc,EAAE,GAAG,aAAa;EAChC,YAAY,EAAE,GAAG,4BAA4B;EAC7C,cAAc,EAAE,SAAS,EAAE,GAAG,uBAAuB,CAAC;EACtD,WAAW,EAAE,QAAQ;EACrB,QAAQ;EACR,cAAc,EAAE,QAAQ;EACxB,eAAe,EAAE,QAAQ;EACzB,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC;EACrC,oBAAoB,EAAE,SAAS,EAAE,QAAQ,CAAC;EAC1C,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,SAAS,EAAE,KAAK;EACjB,CAAC,CACC,MAAM,iBAAiB,CAAC,eAAe,CAAC,CACxC,MAAM,0BAA0B,CAAC,UAAU,gBAAgB,CAAC,CAC5D,MAAM,sBAAsB,CAAC,cAAc,SAAS,CAAC,CACrD,MAAM,kBAAkB,CAAC,eAAe,CAAC;CAe5C,QAAQ,YAAY;EAClB,QAAQ,EAAE,GAAG,OAAO;EAEpB,QAAQ,EAAE,QAAQ;EAElB,WAAW,EAAE,QAAQ;EAErB,MAAM,EAAE,QAAQ;EAEhB,QAAQ,EAAE,MAAM,aAAa;EAE7B,WAAW,EAAE,SAAS,iBAAiB;EAEvC,gBAAgB,EAAE,SAAS,sBAAsB;EAEjD,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC;EACjC,YAAY,EAAE,SAAS,EAAE,QAAQ,CAAC;EAClC,WAAW,EAAE,QAAQ;EAErB,SAAS,EAAE,SAAS;EAEpB,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC;EAC9B,CAAC,CACC,MAAM,WAAW,CAAC,SAAS,CAAC,CAC5B,MAAM,cAAc,CAAC,YAAY,CAAC;CACtC,CAAC"}
|
|
1
|
+
{"version":3,"file":"schema.js","names":[],"sources":["../../src/component/schema.ts"],"sourcesContent":["import { defineSchema, defineTable } from \"convex/server\";\nimport { v } from \"convex/values\";\n\nimport {\n vApiKeyRateLimit,\n vApiKeyRateLimitState,\n vApiKeyScope,\n vAuditActorType,\n vAuditStatus,\n vDeviceStatus,\n vEnterprisePolicy,\n vEnterpriseSecretKind,\n vEnterpriseStatus,\n vInviteStatus,\n vScimResourceType,\n vScimStatus,\n vTag,\n vWebhookDeliveryStatus,\n vWebhookEndpointStatus,\n} from \"./model\";\n\n/**\n * Schema for the auth component.\n *\n * Contains tables for core authentication (users, sessions, accounts, tokens,\n * verification codes, PKCE verifiers, rate limits) and hierarchical group\n * management (groups, members, invites).\n */\nexport default defineSchema({\n /**\n * Authenticated users. A user may have multiple linked accounts\n * and multiple concurrent sessions.\n */\n User: defineTable({\n name: v.optional(v.string()),\n image: v.optional(v.string()),\n email: v.optional(v.string()),\n emailVerificationTime: v.optional(v.number()),\n phone: v.optional(v.string()),\n phoneVerificationTime: v.optional(v.number()),\n isAnonymous: v.optional(v.boolean()),\n extend: v.optional(v.any()),\n })\n .index(\"email\", [\"email\"])\n .index(\"email_verified\", [\"email\", \"emailVerificationTime\"])\n .index(\"phone\", [\"phone\"])\n .index(\"phone_verified\", [\"phone\", \"phoneVerificationTime\"]),\n\n /**\n * Active sessions. A single user can have multiple concurrent sessions\n * across different devices or browsers. Sessions expire after a\n * configurable duration.\n */\n Session: defineTable({\n userId: v.id(\"User\"),\n expirationTime: v.number(),\n }).index(\"user_id\", [\"userId\"]),\n\n /**\n * Authentication accounts. Each account links a user to a single\n * authentication provider (e.g. Google OAuth, email/password).\n * A user can have multiple accounts linked.\n */\n Account: defineTable({\n userId: v.id(\"User\"),\n provider: v.string(),\n providerAccountId: v.string(),\n secret: v.optional(v.string()),\n emailVerified: v.optional(v.string()),\n phoneVerified: v.optional(v.string()),\n extend: v.optional(v.any()),\n })\n .index(\"user_id_provider\", [\"userId\", \"provider\"])\n .index(\"provider_account_id\", [\"provider\", \"providerAccountId\"]),\n\n /**\n * Refresh tokens for session continuity. Tokens are single-use and form\n * a chain — each token references the one it was exchanged from.\n *\n * The active refresh token is the most recently created token that has not\n * been used yet. A 10-second reuse window allows for concurrent requests.\n * Any invalid use of a token invalidates the entire chain.\n */\n RefreshToken: defineTable({\n sessionId: v.id(\"Session\"),\n expirationTime: v.number(),\n firstUsedTime: v.optional(v.number()),\n parentRefreshTokenId: v.optional(v.id(\"RefreshToken\")),\n })\n .index(\"session_id\", [\"sessionId\"])\n .index(\"session_id_first_used\", [\"sessionId\", \"firstUsedTime\"])\n .index(\"session_id_parent_refresh_token_id\", [\n \"sessionId\",\n \"parentRefreshTokenId\",\n ]),\n\n /**\n * Verification codes for OTP tokens, magic link tokens, and OAuth codes.\n */\n VerificationCode: defineTable({\n accountId: v.id(\"Account\"),\n provider: v.string(),\n code: v.string(),\n expirationTime: v.number(),\n verifier: v.optional(v.string()),\n emailVerified: v.optional(v.string()),\n phoneVerified: v.optional(v.string()),\n })\n .index(\"account_id\", [\"accountId\"])\n .index(\"code\", [\"code\"]),\n\n /**\n * PKCE verifiers for OAuth flows. Stores the cryptographic verifier\n * used to prove the authorization request originated from this client.\n */\n AuthVerifier: defineTable({\n sessionId: v.optional(v.id(\"Session\")),\n signature: v.optional(v.string()),\n }).index(\"signature\", [\"signature\"]),\n\n /**\n * WebAuthn passkey credentials. Each credential links a user to a\n * registered authenticator (Touch ID, Face ID, security key, etc.).\n * A user can have multiple passkeys across different devices.\n */\n Passkey: defineTable({\n userId: v.id(\"User\"),\n /** Base64url-encoded credential ID from the authenticator. */\n credentialId: v.string(),\n /** Public key bytes (SEC1 uncompressed for EC, SPKI for RSA). */\n publicKey: v.bytes(),\n /** COSE algorithm identifier (-7 for ES256, -257 for RS256, -8 for EdDSA). */\n algorithm: v.number(),\n /** Signature counter for clone detection. Many authenticators return 0. */\n counter: v.number(),\n /** Authenticator transport hints (e.g. \"internal\", \"hybrid\", \"usb\", \"ble\", \"nfc\"). */\n transports: v.optional(v.array(v.string())),\n /** Whether this is a single-device or multi-device (synced) credential. */\n deviceType: v.string(),\n /** Whether the credential is backed up (synced passkey). */\n backedUp: v.boolean(),\n /** User-assigned friendly name (e.g. \"MacBook Touch ID\"). */\n name: v.optional(v.string()),\n createdAt: v.number(),\n lastUsedAt: v.optional(v.number()),\n })\n .index(\"user_id\", [\"userId\"])\n .index(\"credential_id\", [\"credentialId\"]),\n\n /**\n * TOTP two-factor authentication secrets. Each record links a user to\n * an authenticator app. A user can have multiple TOTP enrollments\n * (e.g. different authenticator apps) but typically has one.\n *\n * The `verified` flag indicates whether the user has completed setup\n * by successfully entering a code from their authenticator app.\n * Unverified enrollments are in-progress setup that can be discarded.\n */\n TotpFactor: defineTable({\n userId: v.id(\"User\"),\n /** Raw TOTP secret key bytes. */\n secret: v.bytes(),\n /** Number of digits in each code (typically 6). */\n digits: v.number(),\n /** Time period in seconds for code rotation (typically 30). */\n period: v.number(),\n /** Whether setup has been confirmed with a valid code. */\n verified: v.boolean(),\n /** User-assigned friendly name (e.g. \"Google Authenticator\"). */\n name: v.optional(v.string()),\n createdAt: v.number(),\n lastUsedAt: v.optional(v.number()),\n })\n .index(\"user_id\", [\"userId\"])\n .index(\"user_id_verified\", [\"userId\", \"verified\"]),\n\n /**\n * Device authorization codes (RFC 8628). Each record tracks a pending\n * device auth session — the device polls with `deviceCode` while the\n * user authorizes via `userCode` on a secondary device.\n */\n DeviceCode: defineTable({\n /** High-entropy code used by the device for polling. Stored as SHA-256 hash. */\n deviceCodeHash: v.string(),\n /** Short human-readable code the user enters (e.g. \"WDJB-MJHT\"). */\n userCode: v.string(),\n /** Expiration timestamp (ms since epoch). */\n expiresAt: v.number(),\n /** Minimum polling interval in seconds. */\n interval: v.number(),\n /** Current status of this device authorization session. */\n status: vDeviceStatus,\n /** Set when the user authorizes — links to the authorizing user. */\n userId: v.optional(v.id(\"User\")),\n /** Set when the user authorizes — the session created for the device. */\n sessionId: v.optional(v.id(\"Session\")),\n /** Timestamp of the last poll request (for slow_down enforcement). */\n lastPolledAt: v.optional(v.number()),\n })\n .index(\"device_code_hash\", [\"deviceCodeHash\"])\n .index(\"user_code_status\", [\"userCode\", \"status\"]),\n\n /**\n * Rate limit tracking for OTP and password sign-in attempts.\n */\n RateLimit: defineTable({\n identifier: v.string(),\n last_attempt_time: v.number(),\n attempts_left: v.number(),\n }).index(\"by_identifier\", [\"identifier\"]),\n\n /**\n * Hierarchical groups. A group with no `parentGroupId` is a root group.\n * Groups can nest arbitrarily deep via `parentGroupId` for modeling\n * organizations, teams, departments, or any tree structure.\n */\n Group: defineTable({\n name: v.string(),\n slug: v.optional(v.string()),\n type: v.optional(v.string()),\n parentGroupId: v.optional(v.id(\"Group\")),\n /** Denormalized root group ID. Self-referencing for root groups. */\n rootGroupId: v.optional(v.id(\"Group\")),\n /** Denormalized flag: `true` when `parentGroupId` is absent. */\n isRoot: v.optional(v.boolean()),\n /** Faceted classification tags. Normalized at write time (trimmed, lowercased). */\n tags: v.optional(v.array(vTag)),\n extend: v.optional(v.any()),\n })\n .index(\"slug\", [\"slug\"])\n .index(\"parent_group_id\", [\"parentGroupId\"])\n .index(\"root_group_id\", [\"rootGroupId\"])\n .index(\"is_root\", [\"isRoot\"])\n .index(\"type\", [\"type\"])\n .index(\"type_parent_group_id\", [\"type\", \"parentGroupId\"]),\n\n /**\n * Denormalized group-tag index table for efficient tag-based filtering.\n * Each row maps one `(key, value)` pair to a group. Kept in sync by\n * `groupCreate`, `groupUpdate`, and `groupDelete`.\n */\n GroupTag: defineTable({\n group_id: v.id(\"Group\"),\n key: v.string(),\n value: v.string(),\n })\n .index(\"by_group\", [\"group_id\"])\n .index(\"by_key_value\", [\"key\", \"value\"])\n .index(\"by_key\", [\"key\"]),\n\n /**\n * Group membership. Links a user to a group with an application-defined\n * role (e.g. \"owner\", \"admin\", \"member\", \"viewer\"). A user can be a\n * member of multiple groups with different roles in each.\n */\n GroupMember: defineTable({\n groupId: v.id(\"Group\"),\n userId: v.id(\"User\"),\n role: v.optional(v.string()),\n roleIds: v.optional(v.array(v.string())),\n status: v.optional(v.string()),\n extend: v.optional(v.any()),\n })\n .index(\"group_id\", [\"groupId\"])\n .index(\"group_id_user_id\", [\"groupId\", \"userId\"])\n .index(\"group_id_status\", [\"groupId\", \"status\"])\n .index(\"user_id\", [\"userId\"]),\n\n /**\n * Invitations. Tracks pending, accepted, revoked, and expired\n * invitations. Optionally scoped to a group via `groupId`, or\n * platform-level when `groupId` is omitted.\n *\n * `email` and `invitedByUserId` are optional to support CLI-generated\n * invite links where neither is known upfront.\n */\n GroupInvite: defineTable({\n groupId: v.optional(v.id(\"Group\")),\n invitedByUserId: v.optional(v.id(\"User\")),\n email: v.optional(v.string()),\n tokenHash: v.string(),\n role: v.optional(v.string()),\n roleIds: v.optional(v.array(v.string())),\n status: vInviteStatus,\n expiresTime: v.optional(v.number()),\n acceptedByUserId: v.optional(v.id(\"User\")),\n acceptedTime: v.optional(v.number()),\n extend: v.optional(v.any()),\n })\n .index(\"token_hash\", [\"tokenHash\"])\n .index(\"status\", [\"status\"])\n .index(\"email_status\", [\"email\", \"status\"])\n .index(\"invited_by_user_id_status\", [\"invitedByUserId\", \"status\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"group_id_status\", [\"groupId\", \"status\"]),\n\n /**\n * Enterprise configuration attached to a root group/organization.\n *\n * The `config` payload intentionally stays flexible so the headless enterprise\n * SDK can evolve without forcing schema churn for every protocol-specific\n * field addition.\n */\n Enterprise: defineTable({\n groupId: v.id(\"Group\"),\n slug: v.optional(v.string()),\n name: v.optional(v.string()),\n status: vEnterpriseStatus,\n policy: v.optional(vEnterprisePolicy),\n config: v.optional(v.any()),\n extend: v.optional(v.any()),\n })\n .index(\"group_id\", [\"groupId\"])\n .index(\"slug\", [\"slug\"])\n .index(\"status\", [\"status\"]),\n\n /**\n * Verified or pending domains linked to an enterprise record.\n */\n EnterpriseDomain: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n domain: v.string(),\n isPrimary: v.boolean(),\n verifiedAt: v.optional(v.number()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"domain\", [\"domain\"]),\n\n /**\n * Pending DNS TXT verification challenges for enterprise domains.\n */\n EnterpriseDomainVerification: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n domainId: v.id(\"EnterpriseDomain\"),\n domain: v.string(),\n recordName: v.string(),\n token: v.string(),\n tokenHash: v.string(),\n requestedAt: v.number(),\n expiresAt: v.number(),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"domain_id\", [\"domainId\"])\n .index(\"token_hash\", [\"tokenHash\"]),\n\n /**\n * Encrypted enterprise secrets stored separately from protocol config.\n */\n EnterpriseSecret: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n kind: vEnterpriseSecretKind,\n ciphertext: v.string(),\n updatedAt: v.number(),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"enterprise_id_kind\", [\"enterpriseId\", \"kind\"])\n .index(\"group_id\", [\"groupId\"]),\n\n /**\n * SCIM configuration for an enterprise tenant.\n */\n EnterpriseScimConfig: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n status: vScimStatus,\n basePath: v.string(),\n tokenHash: v.string(),\n lastRotatedAt: v.optional(v.number()),\n extend: v.optional(v.any()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"token_hash\", [\"tokenHash\"])\n .index(\"status\", [\"status\"]),\n\n /**\n * External SCIM identities mapped into local users/groups.\n */\n EnterpriseScimIdentity: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n resourceType: vScimResourceType,\n externalId: v.string(),\n userId: v.optional(v.id(\"User\")),\n mappedGroupId: v.optional(v.id(\"Group\")),\n lastProvisionedAt: v.optional(v.number()),\n active: v.optional(v.boolean()),\n raw: v.optional(v.any()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"enterprise_id_resource_type_external_id\", [\n \"enterpriseId\",\n \"resourceType\",\n \"externalId\",\n ])\n .index(\"enterprise_id_user_id\", [\"enterpriseId\", \"userId\"])\n .index(\"user_id\", [\"userId\"])\n .index(\"mapped_group_id\", [\"mappedGroupId\"]),\n\n /**\n * Immutable audit trail for enterprise operations.\n */\n EnterpriseAuditEvent: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n eventType: v.string(),\n actorType: vAuditActorType,\n actorId: v.optional(v.string()),\n subjectType: v.string(),\n subjectId: v.optional(v.string()),\n status: vAuditStatus,\n occurredAt: v.number(),\n requestId: v.optional(v.string()),\n ip: v.optional(v.string()),\n metadata: v.optional(v.any()),\n })\n .index(\"enterprise_id_occurred_at\", [\"enterpriseId\", \"occurredAt\"])\n .index(\"group_id_occurred_at\", [\"groupId\", \"occurredAt\"])\n .index(\"event_type_occurred_at\", [\"eventType\", \"occurredAt\"]),\n\n /**\n * Webhook endpoints subscribed to enterprise audit and lifecycle events.\n */\n EnterpriseWebhookEndpoint: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n groupId: v.id(\"Group\"),\n url: v.string(),\n status: vWebhookEndpointStatus,\n secretHash: v.string(),\n subscriptions: v.array(v.string()),\n createdByUserId: v.optional(v.id(\"User\")),\n lastSuccessAt: v.optional(v.number()),\n lastFailureAt: v.optional(v.number()),\n failureCount: v.number(),\n extend: v.optional(v.any()),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"group_id\", [\"groupId\"])\n .index(\"status\", [\"status\"]),\n\n /**\n * Delivery queue for outbound enterprise webhooks.\n */\n EnterpriseWebhookDelivery: defineTable({\n enterpriseId: v.id(\"Enterprise\"),\n endpointId: v.id(\"EnterpriseWebhookEndpoint\"),\n auditEventId: v.optional(v.id(\"EnterpriseAuditEvent\")),\n eventType: v.string(),\n status: vWebhookDeliveryStatus,\n attemptCount: v.number(),\n nextAttemptAt: v.number(),\n lastAttemptAt: v.optional(v.number()),\n lastResponseStatus: v.optional(v.number()),\n lastError: v.optional(v.string()),\n payload: v.any(),\n })\n .index(\"enterprise_id\", [\"enterpriseId\"])\n .index(\"status_next_attempt_at\", [\"status\", \"nextAttemptAt\"])\n .index(\"endpoint_id_status\", [\"endpointId\", \"status\"])\n .index(\"audit_event_id\", [\"auditEventId\"]),\n\n /**\n * API keys for programmatic access. Each key links a user to a set of\n * scoped permissions and optional per-key rate limiting.\n *\n * The raw key is never stored — only a SHA-256 hash. A short prefix\n * (e.g. \"sk_abc1...\") is kept for display in admin interfaces.\n *\n * Keys support:\n * - **Scoped permissions**: resource:action pairs (e.g. users:read)\n * - **Per-key rate limiting**: token-bucket with configurable window\n * - **Expiration**: optional TTL\n * - **Soft revocation**: `revoked` flag preserves audit trail\n */\n ApiKey: defineTable({\n userId: v.id(\"User\"),\n /** First chars of the key for display (e.g. \"sk_abc1...\"). */\n prefix: v.string(),\n /** SHA-256 hex hash of the full raw key. */\n hashedKey: v.string(),\n /** User-assigned name (e.g. \"CI Pipeline\", \"Production API\"). */\n name: v.string(),\n /** Scoped permissions: [{ resource: \"users\", actions: [\"read\", \"list\"] }]. */\n scopes: v.array(vApiKeyScope),\n /** Optional per-key rate limit configuration. */\n rateLimit: v.optional(vApiKeyRateLimit),\n /** Rate limit state tracking (token-bucket). */\n rateLimitState: v.optional(vApiKeyRateLimitState),\n /** Expiration timestamp. Null/undefined = never expires. */\n expiresAt: v.optional(v.number()),\n lastUsedAt: v.optional(v.number()),\n createdAt: v.number(),\n /** Soft-revoke flag. Revoked keys are kept for audit trail. */\n revoked: v.boolean(),\n /** Arbitrary app-specific metadata attached to the key. */\n metadata: v.optional(v.any()),\n })\n .index(\"user_id\", [\"userId\"])\n .index(\"hashed_key\", [\"hashedKey\"]),\n});\n"],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ import { GenericId } from "convex/values";
|
|
|
10
10
|
* minus `component` (which is passed as the first constructor argument).
|
|
11
11
|
*/
|
|
12
12
|
type AuthConfig = Omit<ConvexAuthConfig, "component">;
|
|
13
|
-
type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = Omit<ReturnType<typeof Auth>["auth"]["member"], "create" | "list" | "update" | "
|
|
13
|
+
type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = Omit<ReturnType<typeof Auth>["auth"]["member"], "create" | "list" | "update" | "resolve"> & {
|
|
14
14
|
create: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["create"]>[0], data: {
|
|
15
15
|
groupId: string;
|
|
16
16
|
userId: string;
|
|
@@ -39,20 +39,13 @@ type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig |
|
|
|
39
39
|
ok: true;
|
|
40
40
|
memberId: string;
|
|
41
41
|
}>;
|
|
42
|
-
|
|
42
|
+
resolve: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["resolve"]>[0], opts: {
|
|
43
43
|
userId: string;
|
|
44
44
|
groupId: string;
|
|
45
45
|
roleIds?: AuthRoleId<TAuthorization>[];
|
|
46
46
|
grants?: AuthGrant<TAuthorization>[];
|
|
47
47
|
maxDepth?: number;
|
|
48
|
-
}) => ReturnType<ReturnType<typeof Auth>["auth"]["member"]["
|
|
49
|
-
require: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["require"]>[0], opts: {
|
|
50
|
-
userId: string;
|
|
51
|
-
groupId: string;
|
|
52
|
-
roleIds?: AuthRoleId<TAuthorization>[];
|
|
53
|
-
grants?: AuthGrant<TAuthorization>[];
|
|
54
|
-
maxDepth?: number;
|
|
55
|
-
}) => ReturnType<ReturnType<typeof Auth>["auth"]["member"]["require"]>;
|
|
48
|
+
}) => ReturnType<ReturnType<typeof Auth>["auth"]["member"]["resolve"]>;
|
|
56
49
|
};
|
|
57
50
|
type AccessApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = {
|
|
58
51
|
check: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["access"]["check"]>[0], opts: {
|
|
@@ -61,12 +54,6 @@ type AccessApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig |
|
|
|
61
54
|
grants: AuthGrant<TAuthorization>[];
|
|
62
55
|
maxDepth?: number;
|
|
63
56
|
}) => ReturnType<ReturnType<typeof Auth>["auth"]["access"]["check"]>;
|
|
64
|
-
require: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["access"]["require"]>[0], opts: {
|
|
65
|
-
userId: string;
|
|
66
|
-
groupId: string;
|
|
67
|
-
grants: AuthGrant<TAuthorization>[];
|
|
68
|
-
maxDepth?: number;
|
|
69
|
-
}) => ReturnType<ReturnType<typeof Auth>["auth"]["access"]["require"]>;
|
|
70
57
|
};
|
|
71
58
|
/** The base auth API surface, without conditional namespaces. */
|
|
72
59
|
type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = undefined> = {
|
|
@@ -183,14 +170,6 @@ declare function createAuth<P extends AuthProviderConfig[], TAuthorization exten
|
|
|
183
170
|
providers: P;
|
|
184
171
|
authorization?: TAuthorization;
|
|
185
172
|
}): ConvexAuthResult<P, TAuthorization>;
|
|
186
|
-
declare function defineRoles<const TRoles extends Record<string, {
|
|
187
|
-
label?: string;
|
|
188
|
-
grants: readonly string[];
|
|
189
|
-
}>>(roles: TRoles): { [K in keyof TRoles]: {
|
|
190
|
-
id: K & string;
|
|
191
|
-
label?: TRoles[K]["label"];
|
|
192
|
-
grants: Array<TRoles[K]["grants"][number] & string>;
|
|
193
|
-
} };
|
|
194
173
|
type UserDoc = Doc<"User">;
|
|
195
174
|
type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, never>> = {
|
|
196
175
|
optional?: boolean;
|
|
@@ -234,5 +213,5 @@ type InferAuth<T extends {
|
|
|
234
213
|
}>;
|
|
235
214
|
}> = Awaited<ReturnType<T["input"]>>["ctx"]["auth"];
|
|
236
215
|
//#endregion
|
|
237
|
-
export { AuthApi, AuthConfig, AuthCtx, AuthCtxConfig, InferAuth, UserDoc, createAuth
|
|
216
|
+
export { AuthApi, AuthConfig, AuthCtx, AuthCtxConfig, InferAuth, UserDoc, createAuth };
|
|
238
217
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":";;;;;;;;AAmC6D;;;KAAjD,UAAA,GAAa,IAAA,CAAK,gBAAA;AAAA,KAEzB,0BAAA,wBACoB,uBAAA,gBACrB,IAAA,CACF,UAAA,QAAkB,IAAA;EAGlB,MAAA,GACE,GAAA,EAAK,UAAA,CACH,UAAA,QAAkB,IAAA,mCAEpB,IAAA;IACE,OAAA;IACA,MAAA;IACA,OAAA,GAAU,UAAA,CAAW,cAAA;IACrB,MAAA;IACA,MAAA,GAAS,MAAA;EAAA,MAER,OAAA;IAAU,EAAA;IAAU,QAAA;EAAA;EACzB,IAAA,GACE,GAAA,EAAK,UAAA,CACH,UAAA,QAAkB,IAAA,iCAEpB,IAAA;IACE,KAAA;MACE,OAAA;MACA,MAAA;MACA,MAAA,GAAS,UAAA,CAAW,cAAA;MACpB,MAAA;IAAA;IAEF,KAAA;IACA,MAAA;IACA,OAAA;IACA,KAAA;EAAA,MAEC,UAAA,CAAW,UAAA,QAAkB,IAAA;EAClC,MAAA,GACE,GAAA,EAAK,UAAA,CACH,UAAA,QAAkB,IAAA,mCAEpB,QAAA,UACA,IAAA,EAAM,MAAA;IAA4B,OAAA,GAAU,UAAA,CAAW,cAAA;EAAA,MACpD,OAAA;IAAU,EAAA;IAAU,QAAA;EAAA;EACzB,OAAA,GACE,GAAA,EAAK,UAAA,CACH,UAAA,QAAkB,IAAA,oCAEpB,IAAA;IACE,MAAA;IACA,OAAA;IACA,OAAA,GAAU,UAAA,CAAW,cAAA;IACrB,MAAA,GAAS,SAAA,CAAU,cAAA;IACnB,QAAA;EAAA,MAEC,UAAA,CAAW,UAAA,QAAkB,IAAA;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":"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"}
|
|
@@ -117,13 +117,6 @@ function createAuth(component, config) {
|
|
|
117
117
|
http: authResult.auth.http
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
|
-
function defineRoles(roles) {
|
|
121
|
-
return Object.fromEntries(Object.entries(roles).map(([id, role]) => [id, {
|
|
122
|
-
id,
|
|
123
|
-
...role.label ? { label: role.label } : {},
|
|
124
|
-
grants: [...role.grants]
|
|
125
|
-
}]));
|
|
126
|
-
}
|
|
127
120
|
function AuthCtx(auth, config) {
|
|
128
121
|
return {
|
|
129
122
|
args: {},
|
|
@@ -132,7 +125,7 @@ function AuthCtx(auth, config) {
|
|
|
132
125
|
const modeDispatch = config?.optional === true ? { mode: "optional" } : { mode: "required" };
|
|
133
126
|
const userContext = await Fx.run(Fx.match(modeDispatch, modeDispatch.mode, {
|
|
134
127
|
optional: async () => {
|
|
135
|
-
const userId = await auth.user.
|
|
128
|
+
const userId = await auth.user.id(ctx);
|
|
136
129
|
if (!userId) return null;
|
|
137
130
|
return {
|
|
138
131
|
userId,
|
|
@@ -140,7 +133,8 @@ function AuthCtx(auth, config) {
|
|
|
140
133
|
};
|
|
141
134
|
},
|
|
142
135
|
required: async () => {
|
|
143
|
-
const userId = await auth.user.
|
|
136
|
+
const userId = await auth.user.id(ctx);
|
|
137
|
+
if (!userId) return null;
|
|
144
138
|
return {
|
|
145
139
|
userId,
|
|
146
140
|
user: await auth.user.get(ctx, userId)
|
|
@@ -170,5 +164,5 @@ function AuthCtx(auth, config) {
|
|
|
170
164
|
}
|
|
171
165
|
|
|
172
166
|
//#endregion
|
|
173
|
-
export { AuthCtx, createAuth
|
|
167
|
+
export { AuthCtx, createAuth };
|
|
174
168
|
//# sourceMappingURL=auth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","names":["AuthFactory"],"sources":["../../../src/server/auth.ts"],"sourcesContent":["/**\n * Auth configuration helpers for Convex Auth.\n *\n * @module\n */\n\nimport type { UserIdentity } from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nimport type { AuthApiRefs } from \"../client/index\";\nimport { Auth as AuthFactory } from \"./factory\";\nimport { Fx } from \"./fx\";\nimport { AuthError } from \"./fx\";\nimport type { Doc } from \"./types\";\nimport type {\n AuthAuthorizationConfig,\n AuthGrant,\n AuthProviderConfig,\n AuthRoleDefinition,\n AuthRoleId,\n ConvexAuthConfig,\n HasDeviceProvider,\n HasPasskeyProvider,\n HasSSO,\n HasTotpProvider,\n} from \"./types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Config for auth setup. Extends the standard auth config\n * minus `component` (which is passed as the first constructor argument).\n */\nexport type AuthConfig = Omit<ConvexAuthConfig, \"component\">;\n\ntype MemberApiWithAuthorization<\n TAuthorization extends AuthAuthorizationConfig | undefined,\n> = Omit<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"],\n \"create\" | \"list\" | \"update\" | \"inherit\" | \"require\"\n> & {\n create: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"create\"]\n >[0],\n data: {\n groupId: string;\n userId: string;\n roleIds?: AuthRoleId<TAuthorization>[];\n status?: string;\n extend?: Record<string, unknown>;\n },\n ) => Promise<{ ok: true; memberId: string }>;\n list: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"list\"]\n >[0],\n opts?: {\n where?: {\n groupId?: string;\n userId?: string;\n roleId?: AuthRoleId<TAuthorization>;\n status?: string;\n };\n limit?: number;\n cursor?: string | null;\n orderBy?: \"_creationTime\" | \"status\";\n order?: \"asc\" | \"desc\";\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"list\"]>;\n update: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"update\"]\n >[0],\n memberId: string,\n data: Record<string, unknown> & { roleIds?: AuthRoleId<TAuthorization>[] },\n ) => Promise<{ ok: true; memberId: string }>;\n inherit: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"inherit\"]\n >[0],\n opts: {\n userId: string;\n groupId: string;\n roleIds?: AuthRoleId<TAuthorization>[];\n grants?: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"inherit\"]>;\n require: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"require\"]\n >[0],\n opts: {\n userId: string;\n groupId: string;\n roleIds?: AuthRoleId<TAuthorization>[];\n grants?: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"require\"]>;\n};\n\ntype AccessApiWithAuthorization<\n TAuthorization extends AuthAuthorizationConfig | undefined,\n> = {\n check: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"access\"][\"check\"]\n >[0],\n opts: {\n userId: string;\n groupId: string;\n grants: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"access\"][\"check\"]>;\n require: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"access\"][\"require\"]\n >[0],\n opts: {\n userId: string;\n groupId: string;\n grants: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"access\"][\"require\"]>;\n};\n\n/** The base auth API surface, without conditional namespaces. */\nexport type AuthApiBase<\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n> = {\n signIn: ReturnType<typeof AuthFactory>[\"signIn\"];\n signOut: ReturnType<typeof AuthFactory>[\"signOut\"];\n store: ReturnType<typeof AuthFactory>[\"store\"];\n user: ReturnType<typeof AuthFactory>[\"auth\"][\"user\"];\n session: ReturnType<typeof AuthFactory>[\"auth\"][\"session\"];\n provider: ReturnType<typeof AuthFactory>[\"auth\"][\"provider\"];\n account: ReturnType<typeof AuthFactory>[\"auth\"][\"account\"];\n group: ReturnType<typeof AuthFactory>[\"auth\"][\"group\"];\n member: MemberApiWithAuthorization<TAuthorization>;\n access: AccessApiWithAuthorization<TAuthorization>;\n invite: ReturnType<typeof AuthFactory>[\"auth\"][\"invite\"];\n key: ReturnType<typeof AuthFactory>[\"auth\"][\"key\"];\n http: ReturnType<typeof AuthFactory>[\"auth\"][\"http\"];\n};\n\ntype InternalSsoApi = ReturnType<typeof AuthFactory>[\"auth\"][\"sso\"];\n\ntype PublicSsoAdminApi = {\n connection: InternalSsoApi[\"connection\"] & {\n domain: {\n list: InternalSsoApi[\"domain\"][\"list\"];\n validate: InternalSsoApi[\"domain\"][\"validate\"];\n set: (\n ctx: Parameters<InternalSsoApi[\"connection\"][\"create\"]>[0],\n enterpriseId: string,\n domains: Array<{\n domain: string;\n isPrimary?: boolean;\n }>,\n ) => Promise<{\n ok: true;\n enterpriseId: string;\n domains: Array<{\n domainId: string;\n domain: string;\n isPrimary: boolean;\n verified: boolean;\n verifiedAt: number | null;\n }>;\n }>;\n verification: {\n request: (\n ctx: Parameters<InternalSsoApi[\"connection\"][\"create\"]>[0],\n args: { enterpriseId: string; domain: string },\n ) => Promise<{\n ok: true;\n enterpriseId: string;\n domain: string;\n requestedAt: number;\n expiresAt: number;\n challenge: {\n recordType: \"TXT\";\n recordName: string;\n recordValue: string;\n };\n }>;\n confirm: (\n ctx: Parameters<InternalSsoApi[\"connection\"][\"create\"]>[0],\n args: { enterpriseId: string; domain: string },\n ) => Promise<{\n ok: boolean;\n enterpriseId: string;\n domain: string;\n verifiedAt?: number;\n checks: Array<{ name: string; ok: boolean; message?: string }>;\n }>;\n };\n };\n };\n oidc: Omit<InternalSsoApi[\"oidc\"], \"signIn\">;\n saml: Omit<InternalSsoApi[\"saml\"], \"metadata\">;\n policy: InternalSsoApi[\"policy\"];\n audit: {\n list: InternalSsoApi[\"audit\"][\"list\"];\n };\n webhook: {\n endpoint: InternalSsoApi[\"webhook\"][\"endpoint\"];\n delivery: {\n list: InternalSsoApi[\"webhook\"][\"delivery\"][\"list\"];\n };\n };\n};\n\ntype PublicSsoClientApi = {\n signIn: InternalSsoApi[\"oidc\"][\"signIn\"];\n metadata: InternalSsoApi[\"saml\"][\"metadata\"];\n};\n\ntype PublicSsoApi = {\n admin: PublicSsoAdminApi;\n client: PublicSsoClientApi;\n};\n\ntype PublicScimApi = {\n admin: Omit<InternalSsoApi[\"scim\"], \"getConfigByToken\" | \"identity\">;\n};\n\n/** Auth API with enterprise namespaces — present only when `new SSO()` is in providers. */\nexport type AuthApi<\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n> = AuthApiBase<TAuthorization> & {\n sso: PublicSsoApi;\n scim: PublicScimApi;\n};\n\n/**\n * The return type of `createAuth`. Conditional namespaces:\n * - `auth.sso` and `auth.scim` — only when `new SSO()` is in providers\n * - `auth.clientApi` — typed API refs for the client SDK with capabilities\n */\nexport type ConvexAuthResult<\n P extends AuthProviderConfig[],\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n> =\n HasSSO<P> extends true\n ? AuthApi<TAuthorization>\n : AuthApiBase<TAuthorization>;\n\n/**\n * Infer the typed `AuthApiRefs` for the client SDK from a `createAuth` call.\n *\n * Use this as the generic parameter for `client()` on the frontend:\n *\n * ```ts\n * // convex/auth.ts\n * export const auth = createAuth(components.auth, { providers: [...] });\n *\n * // Frontend\n * import type { auth } from \"../convex/auth\";\n * import type { InferClientApi } from \"@robelest/convex-auth/component\";\n * const c = client<InferClientApi<typeof auth>>({ convex, api: api.auth });\n * ```\n */\nexport type InferClientApi<T> =\n T extends ConvexAuthResult<infer P>\n ? AuthApiRefs<\n HasPasskeyProvider<P>,\n HasTotpProvider<P>,\n HasDeviceProvider<P>\n >\n : AuthApiRefs;\n\n/** @internal */\nexport type AuthLike = Pick<AuthApiBase, \"user\">;\n\n// ============================================================================\n// Auth setup APIs\n// ============================================================================\n\n/**\n * Create an auth API object.\n *\n * When `new SSO()` is included in providers, `auth.sso` and `auth.scim`\n * are available on the returned object. Without it, those namespaces are\n * absent and accessing them is a TypeScript compile error.\n */\nexport function createAuth<\n P extends AuthProviderConfig[],\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n>(\n component: ConvexAuthConfig[\"component\"],\n config: Omit<AuthConfig, \"providers\" | \"authorization\"> & {\n providers: P;\n authorization?: TAuthorization;\n },\n): ConvexAuthResult<P, TAuthorization> {\n const authResult = AuthFactory({\n ...config,\n component,\n providers: [...config.providers],\n });\n const {\n domain: domainApi,\n scim: scimApi,\n connection: connectionApi,\n audit: auditApi,\n webhook: webhookApi,\n oidc: oidcApi,\n saml: samlApi,\n ...restSso\n } = authResult.auth.sso as InternalSsoApi;\n\n type SetEnterpriseDomains = PublicSsoAdminApi[\"connection\"][\"domain\"][\"set\"];\n type EnterpriseDomainInput = Array<{\n domain: string;\n isPrimary?: boolean;\n }>;\n const setEnterpriseDomains: PublicSsoAdminApi[\"connection\"][\"domain\"][\"set\"] =\n async (\n ctx: Parameters<SetEnterpriseDomains>[0],\n enterpriseId: Parameters<SetEnterpriseDomains>[1],\n domains: EnterpriseDomainInput,\n ) => {\n const enterprise = await connectionApi.get(ctx, enterpriseId);\n if (enterprise === null) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Enterprise not found.\",\n ).toConvexError();\n }\n\n const normalized = domains.map((entry: (typeof domains)[number]) => ({\n ...entry,\n domain: entry.domain.trim().toLowerCase(),\n }));\n const deduped = new Map<string, (typeof normalized)[number]>();\n for (const entry of normalized) {\n if (entry.domain.length === 0) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Domain must not be empty.\",\n ).toConvexError();\n }\n if (deduped.has(entry.domain)) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n `Duplicate domain: ${entry.domain}`,\n ).toConvexError();\n }\n deduped.set(entry.domain, entry);\n }\n\n const nextDomains = [...deduped.values()];\n const primaryCount = nextDomains.filter(\n (entry) => entry.isPrimary,\n ).length;\n if (primaryCount > 1) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Only one primary domain may be set.\",\n ).toConvexError();\n }\n if (nextDomains.length > 0 && primaryCount === 0) {\n nextDomains[0] = { ...nextDomains[0], isPrimary: true };\n }\n\n const currentDomains = await domainApi.list(ctx, enterpriseId);\n const currentByDomain = new Map<string, (typeof currentDomains)[number]>(\n currentDomains.map((entry: (typeof currentDomains)[number]) => [\n entry.domain.toLowerCase(),\n entry,\n ]),\n );\n\n for (const existing of currentDomains) {\n if (!deduped.has(existing.domain.toLowerCase())) {\n await domainApi.remove(ctx, existing._id);\n }\n }\n\n for (const nextDomain of nextDomains) {\n const current = currentByDomain.get(nextDomain.domain);\n if (current && current.isPrimary === Boolean(nextDomain.isPrimary)) {\n continue;\n }\n if (current) {\n await domainApi.remove(ctx, current._id);\n }\n const domainId = await domainApi.add(ctx, {\n enterpriseId: enterprise._id,\n groupId: enterprise.groupId,\n domain: nextDomain.domain,\n isPrimary: nextDomain.isPrimary,\n });\n if (current?.verifiedAt !== undefined) {\n await (ctx as any).runMutation(\n component.public.enterpriseDomainVerify,\n {\n domainId,\n verifiedAt: current.verifiedAt,\n },\n );\n }\n }\n\n const updatedDomains = await domainApi.list(ctx, enterpriseId);\n return {\n ok: true as const,\n enterpriseId,\n domains: updatedDomains.map(\n (domain: (typeof updatedDomains)[number]) => ({\n domainId: domain._id,\n domain: domain.domain,\n isPrimary: domain.isPrimary,\n verified: domain.verifiedAt !== undefined,\n verifiedAt: domain.verifiedAt ?? null,\n }),\n ),\n };\n };\n\n const publicSso: PublicSsoApi = {\n admin: {\n ...restSso,\n oidc: {\n ...oidcApi,\n },\n saml: {\n ...samlApi,\n },\n connection: {\n ...connectionApi,\n domain: {\n list: domainApi.list,\n validate: domainApi.validate,\n set: setEnterpriseDomains,\n verification: {\n request: domainApi.verification.request,\n confirm: domainApi.verification.confirm,\n },\n },\n },\n policy: restSso.policy,\n audit: {\n list: auditApi.list,\n },\n webhook: {\n endpoint: webhookApi.endpoint,\n delivery: {\n list: webhookApi.delivery.list,\n },\n },\n },\n client: {\n signIn: oidcApi.signIn,\n metadata: samlApi.metadata,\n },\n };\n\n return {\n signIn: authResult.signIn,\n signOut: authResult.signOut,\n store: authResult.store,\n user: authResult.auth.user,\n session: authResult.auth.session,\n provider: authResult.auth.provider,\n account: authResult.auth.account,\n group: authResult.auth.group,\n member: authResult.auth.member,\n access: authResult.auth.access,\n invite: authResult.auth.invite,\n key: authResult.auth.key,\n sso: publicSso,\n scim: {\n admin: {\n configure: scimApi.configure,\n get: scimApi.get,\n validate: scimApi.validate,\n },\n },\n http: authResult.auth.http,\n } as unknown as ConvexAuthResult<P, TAuthorization>;\n}\n\nexport function defineRoles<\n const TRoles extends Record<\n string,\n { label?: string; grants: readonly string[] }\n >,\n>(\n roles: TRoles,\n): {\n [K in keyof TRoles]: {\n id: K & string;\n label?: TRoles[K][\"label\"];\n grants: Array<TRoles[K][\"grants\"][number] & string>;\n };\n} {\n return Object.fromEntries(\n Object.entries(roles).map(([id, role]) => [\n id,\n {\n id,\n ...(role.label ? { label: role.label } : {}),\n grants: [...role.grants],\n },\n ]),\n ) as {\n [K in keyof TRoles]: {\n id: K & string;\n label?: TRoles[K][\"label\"];\n grants: Array<TRoles[K][\"grants\"][number] & string>;\n };\n };\n}\n\n// ============================================================================\n// AuthCtx — ctx enrichment for customQuery / customMutation\n// ============================================================================\n\nexport type UserDoc = Doc<\"User\">;\n\nexport type AuthCtxConfig<\n TResolve extends Record<string, unknown> = Record<string, never>,\n> = {\n optional?: boolean;\n resolve?: (ctx: any, user: UserDoc) => Promise<TResolve> | TResolve;\n};\n\n/** Overload: optional auth */\nexport function AuthCtx<\n TResolve extends Record<string, unknown> = Record<string, never>,\n>(\n auth: AuthLike,\n config: AuthCtxConfig<TResolve> & { optional: true },\n): {\n args: {};\n input: (\n ctx: any,\n _args: any,\n _extra?: any,\n ) => Promise<{\n ctx: {\n auth: {\n getUserIdentity: () => Promise<UserIdentity | null>;\n userId: GenericId<\"User\"> | null;\n user: UserDoc | null;\n } & TResolve;\n };\n args: {};\n }>;\n};\n/** Overload: required auth (default) */\nexport function AuthCtx<\n TResolve extends Record<string, unknown> = Record<string, never>,\n>(\n auth: AuthLike,\n config?: AuthCtxConfig<TResolve>,\n): {\n args: {};\n input: (\n ctx: any,\n _args: any,\n _extra?: any,\n ) => Promise<{\n ctx: {\n auth: {\n getUserIdentity: () => Promise<UserIdentity | null>;\n userId: GenericId<\"User\">;\n user: UserDoc;\n } & TResolve;\n };\n args: {};\n }>;\n};\n// Implementation\nexport function AuthCtx(auth: AuthLike, config?: AuthCtxConfig<any>) {\n return {\n args: {},\n input: async (ctx: any, _args: any, _extra?: any) => {\n const nativeAuth = ctx.auth;\n const modeDispatch =\n config?.optional === true\n ? { mode: \"optional\" as const }\n : { mode: \"required\" as const };\n\n const userContext = await Fx.run(\n Fx.match(modeDispatch, modeDispatch.mode, {\n optional: async () => {\n const userId = await auth.user.current(ctx);\n if (!userId) {\n return null;\n }\n const user = await auth.user.get(ctx, userId);\n return { userId, user };\n },\n required: async () => {\n const userId = await auth.user.require(ctx);\n const user = await auth.user.get(ctx, userId);\n return { userId, user };\n },\n }),\n );\n\n if (userContext === null) {\n return {\n ctx: {\n auth: {\n getUserIdentity: nativeAuth.getUserIdentity.bind(nativeAuth),\n userId: null,\n user: null,\n },\n },\n args: {},\n };\n }\n\n const extra = config?.resolve\n ? await config.resolve(ctx, userContext.user)\n : {};\n\n return {\n ctx: {\n auth: {\n getUserIdentity: nativeAuth.getUserIdentity.bind(nativeAuth),\n userId: userContext.userId,\n user: userContext.user,\n ...extra,\n },\n },\n args: {},\n };\n },\n };\n}\n\nexport type InferAuth<\n T extends { input: (...args: any[]) => Promise<{ ctx: { auth: any } }> },\n> = Awaited<ReturnType<T[\"input\"]>>[\"ctx\"][\"auth\"];\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"auth.js","names":["AuthFactory"],"sources":["../../../src/server/auth.ts"],"sourcesContent":["/**\n * Auth configuration helpers for Convex Auth.\n *\n * @module\n */\n\nimport type { UserIdentity } from \"convex/server\";\nimport type { GenericId } from \"convex/values\";\n\nimport type { AuthApiRefs } from \"../client/index\";\nimport { Auth as AuthFactory } from \"./factory\";\nimport { Fx } from \"./fx\";\nimport { AuthError } from \"./fx\";\nimport type { Doc } from \"./types\";\nimport type {\n AuthAuthorizationConfig,\n AuthGrant,\n AuthProviderConfig,\n AuthRoleDefinition,\n AuthRoleId,\n ConvexAuthConfig,\n HasDeviceProvider,\n HasPasskeyProvider,\n HasSSO,\n HasTotpProvider,\n} from \"./types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Config for auth setup. Extends the standard auth config\n * minus `component` (which is passed as the first constructor argument).\n */\nexport type AuthConfig = Omit<ConvexAuthConfig, \"component\">;\n\ntype MemberApiWithAuthorization<\n TAuthorization extends AuthAuthorizationConfig | undefined,\n> = Omit<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"],\n \"create\" | \"list\" | \"update\" | \"resolve\"\n> & {\n create: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"create\"]\n >[0],\n data: {\n groupId: string;\n userId: string;\n roleIds?: AuthRoleId<TAuthorization>[];\n status?: string;\n extend?: Record<string, unknown>;\n },\n ) => Promise<{ ok: true; memberId: string }>;\n list: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"list\"]\n >[0],\n opts?: {\n where?: {\n groupId?: string;\n userId?: string;\n roleId?: AuthRoleId<TAuthorization>;\n status?: string;\n };\n limit?: number;\n cursor?: string | null;\n orderBy?: \"_creationTime\" | \"status\";\n order?: \"asc\" | \"desc\";\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"list\"]>;\n update: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"update\"]\n >[0],\n memberId: string,\n data: Record<string, unknown> & { roleIds?: AuthRoleId<TAuthorization>[] },\n ) => Promise<{ ok: true; memberId: string }>;\n resolve: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"resolve\"]\n >[0],\n opts: {\n userId: string;\n groupId: string;\n roleIds?: AuthRoleId<TAuthorization>[];\n grants?: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"resolve\"]>;\n};\n\ntype AccessApiWithAuthorization<\n TAuthorization extends AuthAuthorizationConfig | undefined,\n> = {\n check: (\n ctx: Parameters<\n ReturnType<typeof AuthFactory>[\"auth\"][\"access\"][\"check\"]\n >[0],\n opts: {\n userId: string;\n groupId: string;\n grants: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"access\"][\"check\"]>;\n};\n\n/** The base auth API surface, without conditional namespaces. */\nexport type AuthApiBase<\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n> = {\n signIn: ReturnType<typeof AuthFactory>[\"signIn\"];\n signOut: ReturnType<typeof AuthFactory>[\"signOut\"];\n store: ReturnType<typeof AuthFactory>[\"store\"];\n user: ReturnType<typeof AuthFactory>[\"auth\"][\"user\"];\n session: ReturnType<typeof AuthFactory>[\"auth\"][\"session\"];\n provider: ReturnType<typeof AuthFactory>[\"auth\"][\"provider\"];\n account: ReturnType<typeof AuthFactory>[\"auth\"][\"account\"];\n group: ReturnType<typeof AuthFactory>[\"auth\"][\"group\"];\n member: MemberApiWithAuthorization<TAuthorization>;\n access: AccessApiWithAuthorization<TAuthorization>;\n invite: ReturnType<typeof AuthFactory>[\"auth\"][\"invite\"];\n key: ReturnType<typeof AuthFactory>[\"auth\"][\"key\"];\n http: ReturnType<typeof AuthFactory>[\"auth\"][\"http\"];\n};\n\ntype InternalSsoApi = ReturnType<typeof AuthFactory>[\"auth\"][\"sso\"];\n\ntype PublicSsoAdminApi = {\n connection: InternalSsoApi[\"connection\"] & {\n domain: {\n list: InternalSsoApi[\"domain\"][\"list\"];\n validate: InternalSsoApi[\"domain\"][\"validate\"];\n set: (\n ctx: Parameters<InternalSsoApi[\"connection\"][\"create\"]>[0],\n enterpriseId: string,\n domains: Array<{\n domain: string;\n isPrimary?: boolean;\n }>,\n ) => Promise<{\n ok: true;\n enterpriseId: string;\n domains: Array<{\n domainId: string;\n domain: string;\n isPrimary: boolean;\n verified: boolean;\n verifiedAt: number | null;\n }>;\n }>;\n verification: {\n request: (\n ctx: Parameters<InternalSsoApi[\"connection\"][\"create\"]>[0],\n args: { enterpriseId: string; domain: string },\n ) => Promise<{\n ok: true;\n enterpriseId: string;\n domain: string;\n requestedAt: number;\n expiresAt: number;\n challenge: {\n recordType: \"TXT\";\n recordName: string;\n recordValue: string;\n };\n }>;\n confirm: (\n ctx: Parameters<InternalSsoApi[\"connection\"][\"create\"]>[0],\n args: { enterpriseId: string; domain: string },\n ) => Promise<{\n ok: boolean;\n enterpriseId: string;\n domain: string;\n verifiedAt?: number;\n checks: Array<{ name: string; ok: boolean; message?: string }>;\n }>;\n };\n };\n };\n oidc: Omit<InternalSsoApi[\"oidc\"], \"signIn\">;\n saml: Omit<InternalSsoApi[\"saml\"], \"metadata\">;\n policy: InternalSsoApi[\"policy\"];\n audit: {\n list: InternalSsoApi[\"audit\"][\"list\"];\n };\n webhook: {\n endpoint: InternalSsoApi[\"webhook\"][\"endpoint\"];\n delivery: {\n list: InternalSsoApi[\"webhook\"][\"delivery\"][\"list\"];\n };\n };\n};\n\ntype PublicSsoClientApi = {\n signIn: InternalSsoApi[\"oidc\"][\"signIn\"];\n metadata: InternalSsoApi[\"saml\"][\"metadata\"];\n};\n\ntype PublicSsoApi = {\n admin: PublicSsoAdminApi;\n client: PublicSsoClientApi;\n};\n\ntype PublicScimApi = {\n admin: Omit<InternalSsoApi[\"scim\"], \"getConfigByToken\" | \"identity\">;\n};\n\n/** Auth API with enterprise namespaces — present only when `new SSO()` is in providers. */\nexport type AuthApi<\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n> = AuthApiBase<TAuthorization> & {\n sso: PublicSsoApi;\n scim: PublicScimApi;\n};\n\n/**\n * The return type of `createAuth`. Conditional namespaces:\n * - `auth.sso` and `auth.scim` — only when `new SSO()` is in providers\n * - `auth.clientApi` — typed API refs for the client SDK with capabilities\n */\nexport type ConvexAuthResult<\n P extends AuthProviderConfig[],\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n> =\n HasSSO<P> extends true\n ? AuthApi<TAuthorization>\n : AuthApiBase<TAuthorization>;\n\n/**\n * Infer the typed `AuthApiRefs` for the client SDK from a `createAuth` call.\n *\n * Use this as the generic parameter for `client()` on the frontend:\n *\n * ```ts\n * // convex/auth.ts\n * export const auth = createAuth(components.auth, { providers: [...] });\n *\n * // Frontend\n * import type { auth } from \"../convex/auth\";\n * import type { InferClientApi } from \"@robelest/convex-auth/component\";\n * const c = client<InferClientApi<typeof auth>>({ convex, api: api.auth });\n * ```\n */\nexport type InferClientApi<T> =\n T extends ConvexAuthResult<infer P>\n ? AuthApiRefs<\n HasPasskeyProvider<P>,\n HasTotpProvider<P>,\n HasDeviceProvider<P>\n >\n : AuthApiRefs;\n\n/** @internal */\nexport type AuthLike = Pick<AuthApiBase, \"user\">;\n\n// ============================================================================\n// Auth setup APIs\n// ============================================================================\n\n/**\n * Create an auth API object.\n *\n * When `new SSO()` is included in providers, `auth.sso` and `auth.scim`\n * are available on the returned object. Without it, those namespaces are\n * absent and accessing them is a TypeScript compile error.\n */\nexport function createAuth<\n P extends AuthProviderConfig[],\n TAuthorization extends AuthAuthorizationConfig | undefined = undefined,\n>(\n component: ConvexAuthConfig[\"component\"],\n config: Omit<AuthConfig, \"providers\" | \"authorization\"> & {\n providers: P;\n authorization?: TAuthorization;\n },\n): ConvexAuthResult<P, TAuthorization> {\n const authResult = AuthFactory({\n ...config,\n component,\n providers: [...config.providers],\n });\n const {\n domain: domainApi,\n scim: scimApi,\n connection: connectionApi,\n audit: auditApi,\n webhook: webhookApi,\n oidc: oidcApi,\n saml: samlApi,\n ...restSso\n } = authResult.auth.sso as InternalSsoApi;\n\n type SetEnterpriseDomains = PublicSsoAdminApi[\"connection\"][\"domain\"][\"set\"];\n type EnterpriseDomainInput = Array<{\n domain: string;\n isPrimary?: boolean;\n }>;\n const setEnterpriseDomains: PublicSsoAdminApi[\"connection\"][\"domain\"][\"set\"] =\n async (\n ctx: Parameters<SetEnterpriseDomains>[0],\n enterpriseId: Parameters<SetEnterpriseDomains>[1],\n domains: EnterpriseDomainInput,\n ) => {\n const enterprise = await connectionApi.get(ctx, enterpriseId);\n if (enterprise === null) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Enterprise not found.\",\n ).toConvexError();\n }\n\n const normalized = domains.map((entry: (typeof domains)[number]) => ({\n ...entry,\n domain: entry.domain.trim().toLowerCase(),\n }));\n const deduped = new Map<string, (typeof normalized)[number]>();\n for (const entry of normalized) {\n if (entry.domain.length === 0) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Domain must not be empty.\",\n ).toConvexError();\n }\n if (deduped.has(entry.domain)) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n `Duplicate domain: ${entry.domain}`,\n ).toConvexError();\n }\n deduped.set(entry.domain, entry);\n }\n\n const nextDomains = [...deduped.values()];\n const primaryCount = nextDomains.filter(\n (entry) => entry.isPrimary,\n ).length;\n if (primaryCount > 1) {\n throw new AuthError(\n \"INVALID_PARAMETERS\",\n \"Only one primary domain may be set.\",\n ).toConvexError();\n }\n if (nextDomains.length > 0 && primaryCount === 0) {\n nextDomains[0] = { ...nextDomains[0], isPrimary: true };\n }\n\n const currentDomains = await domainApi.list(ctx, enterpriseId);\n const currentByDomain = new Map<string, (typeof currentDomains)[number]>(\n currentDomains.map((entry: (typeof currentDomains)[number]) => [\n entry.domain.toLowerCase(),\n entry,\n ]),\n );\n\n for (const existing of currentDomains) {\n if (!deduped.has(existing.domain.toLowerCase())) {\n await domainApi.remove(ctx, existing._id);\n }\n }\n\n for (const nextDomain of nextDomains) {\n const current = currentByDomain.get(nextDomain.domain);\n if (current && current.isPrimary === Boolean(nextDomain.isPrimary)) {\n continue;\n }\n if (current) {\n await domainApi.remove(ctx, current._id);\n }\n const domainId = await domainApi.add(ctx, {\n enterpriseId: enterprise._id,\n groupId: enterprise.groupId,\n domain: nextDomain.domain,\n isPrimary: nextDomain.isPrimary,\n });\n if (current?.verifiedAt !== undefined) {\n await (ctx as any).runMutation(\n component.public.enterpriseDomainVerify,\n {\n domainId,\n verifiedAt: current.verifiedAt,\n },\n );\n }\n }\n\n const updatedDomains = await domainApi.list(ctx, enterpriseId);\n return {\n ok: true as const,\n enterpriseId,\n domains: updatedDomains.map(\n (domain: (typeof updatedDomains)[number]) => ({\n domainId: domain._id,\n domain: domain.domain,\n isPrimary: domain.isPrimary,\n verified: domain.verifiedAt !== undefined,\n verifiedAt: domain.verifiedAt ?? null,\n }),\n ),\n };\n };\n\n const publicSso: PublicSsoApi = {\n admin: {\n ...restSso,\n oidc: {\n ...oidcApi,\n },\n saml: {\n ...samlApi,\n },\n connection: {\n ...connectionApi,\n domain: {\n list: domainApi.list,\n validate: domainApi.validate,\n set: setEnterpriseDomains,\n verification: {\n request: domainApi.verification.request,\n confirm: domainApi.verification.confirm,\n },\n },\n },\n policy: restSso.policy,\n audit: {\n list: auditApi.list,\n },\n webhook: {\n endpoint: webhookApi.endpoint,\n delivery: {\n list: webhookApi.delivery.list,\n },\n },\n },\n client: {\n signIn: oidcApi.signIn,\n metadata: samlApi.metadata,\n },\n };\n\n return {\n signIn: authResult.signIn,\n signOut: authResult.signOut,\n store: authResult.store,\n user: authResult.auth.user,\n session: authResult.auth.session,\n provider: authResult.auth.provider,\n account: authResult.auth.account,\n group: authResult.auth.group,\n member: authResult.auth.member,\n access: authResult.auth.access,\n invite: authResult.auth.invite,\n key: authResult.auth.key,\n sso: publicSso,\n scim: {\n admin: {\n configure: scimApi.configure,\n get: scimApi.get,\n validate: scimApi.validate,\n },\n },\n http: authResult.auth.http,\n } as unknown as ConvexAuthResult<P, TAuthorization>;\n}\n\n// ============================================================================\n// AuthCtx — ctx enrichment for customQuery / customMutation\n// ============================================================================\n\nexport type UserDoc = Doc<\"User\">;\n\nexport type AuthCtxConfig<\n TResolve extends Record<string, unknown> = Record<string, never>,\n> = {\n optional?: boolean;\n resolve?: (ctx: any, user: UserDoc) => Promise<TResolve> | TResolve;\n};\n\n/** Overload: optional auth */\nexport function AuthCtx<\n TResolve extends Record<string, unknown> = Record<string, never>,\n>(\n auth: AuthLike,\n config: AuthCtxConfig<TResolve> & { optional: true },\n): {\n args: {};\n input: (\n ctx: any,\n _args: any,\n _extra?: any,\n ) => Promise<{\n ctx: {\n auth: {\n getUserIdentity: () => Promise<UserIdentity | null>;\n userId: GenericId<\"User\"> | null;\n user: UserDoc | null;\n } & TResolve;\n };\n args: {};\n }>;\n};\n/** Overload: required auth (default) */\nexport function AuthCtx<\n TResolve extends Record<string, unknown> = Record<string, never>,\n>(\n auth: AuthLike,\n config?: AuthCtxConfig<TResolve>,\n): {\n args: {};\n input: (\n ctx: any,\n _args: any,\n _extra?: any,\n ) => Promise<{\n ctx: {\n auth: {\n getUserIdentity: () => Promise<UserIdentity | null>;\n userId: GenericId<\"User\">;\n user: UserDoc;\n } & TResolve;\n };\n args: {};\n }>;\n};\n// Implementation\nexport function AuthCtx(auth: AuthLike, config?: AuthCtxConfig<any>) {\n return {\n args: {},\n input: async (ctx: any, _args: any, _extra?: any) => {\n const nativeAuth = ctx.auth;\n const modeDispatch =\n config?.optional === true\n ? { mode: \"optional\" as const }\n : { mode: \"required\" as const };\n\n const userContext = await Fx.run(\n Fx.match(modeDispatch, modeDispatch.mode, {\n optional: async () => {\n const userId = await auth.user.id(ctx);\n if (!userId) {\n return null;\n }\n const user = await auth.user.get(ctx, userId);\n return { userId, user };\n },\n required: async () => {\n const userId = await auth.user.id(ctx);\n if (!userId) {\n return null;\n }\n const user = await auth.user.get(ctx, userId);\n return { userId, user };\n },\n }),\n );\n\n if (userContext === null) {\n return {\n ctx: {\n auth: {\n getUserIdentity: nativeAuth.getUserIdentity.bind(nativeAuth),\n userId: null,\n user: null,\n },\n },\n args: {},\n };\n }\n\n const extra = config?.resolve\n ? await config.resolve(ctx, userContext.user)\n : {};\n\n return {\n ctx: {\n auth: {\n getUserIdentity: nativeAuth.getUserIdentity.bind(nativeAuth),\n userId: userContext.userId,\n user: userContext.user,\n ...extra,\n },\n },\n args: {},\n };\n },\n };\n}\n\nexport type InferAuth<\n T extends { input: (...args: any[]) => Promise<{ ctx: { auth: any } }> },\n> = Awaited<ReturnType<T[\"input\"]>>[\"ctx\"][\"auth\"];\n"],"mappings":"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"}
|