@robelest/convex-auth 0.0.4-preview.21 → 0.0.4-preview.22

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.
Files changed (39) hide show
  1. package/dist/component/convex.config.d.ts +2 -2
  2. package/dist/component/convex.config.d.ts.map +1 -1
  3. package/dist/component/model.d.ts +10 -10
  4. package/dist/component/model.d.ts.map +1 -1
  5. package/dist/component/schema.d.ts +51 -51
  6. package/dist/component/server/auth.d.ts +71 -25
  7. package/dist/component/server/auth.d.ts.map +1 -1
  8. package/dist/component/server/auth.js +13 -27
  9. package/dist/component/server/auth.js.map +1 -1
  10. package/dist/component/server/runtime.d.ts +2 -2
  11. package/dist/server/auth.d.ts +70 -24
  12. package/dist/server/auth.d.ts.map +1 -1
  13. package/dist/server/auth.js +13 -27
  14. package/dist/server/auth.js.map +1 -1
  15. package/dist/server/index.d.ts +2 -2
  16. package/dist/server/mounts.d.ts +12 -12
  17. package/dist/server/mutations/account.d.ts +6 -6
  18. package/dist/server/mutations/account.d.ts.map +1 -1
  19. package/dist/server/mutations/code.d.ts +13 -13
  20. package/dist/server/mutations/invalidate.d.ts +4 -4
  21. package/dist/server/mutations/invalidate.d.ts.map +1 -1
  22. package/dist/server/mutations/oauth.d.ts +9 -9
  23. package/dist/server/mutations/oauth.d.ts.map +1 -1
  24. package/dist/server/mutations/refresh.d.ts +3 -3
  25. package/dist/server/mutations/refresh.d.ts.map +1 -1
  26. package/dist/server/mutations/register.d.ts +11 -11
  27. package/dist/server/mutations/retrieve.d.ts +6 -6
  28. package/dist/server/mutations/retrieve.d.ts.map +1 -1
  29. package/dist/server/mutations/signature.d.ts +4 -4
  30. package/dist/server/mutations/signin.d.ts +5 -5
  31. package/dist/server/mutations/store.d.ts +100 -100
  32. package/dist/server/mutations/store.d.ts.map +1 -1
  33. package/dist/server/mutations/verify.d.ts +10 -10
  34. package/dist/server/runtime.d.ts +15 -15
  35. package/package.json +2 -2
  36. package/src/cli/index.ts +1 -1
  37. package/src/component/index.ts +1 -0
  38. package/src/server/auth.ts +103 -59
  39. package/src/server/index.ts +2 -0
@@ -10,6 +10,8 @@ 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
+ /** Canonical user document type exposed by Convex Auth. */
14
+ type UserDoc = Doc<"User">;
13
15
  type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = Omit<ReturnType<typeof Auth>["auth"]["member"], "create" | "list" | "update" | "resolve"> & {
14
16
  create: (ctx: Parameters<ReturnType<typeof Auth>["auth"]["member"]["create"]>[0], data: {
15
17
  groupId: string;
@@ -151,19 +153,45 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
151
153
  };
152
154
  };
153
155
  /**
154
- * Resolved auth context injected into `ctx.auth` by `auth.ctx()`.
156
+ * Resolved auth context injected into `ctx.auth` by `auth.ctx()` and
157
+ * {@link AuthCtx}. Also the expected return shape for custom
158
+ * {@link AuthCtxConfig.authResolve | authResolve} hooks.
155
159
  *
156
160
  * - `null` when unauthenticated.
157
161
  * - `groupId` is `null` when the user has no active group set.
158
162
  * - `role` / `grants` are `null` / `[]` when no active group or no membership.
163
+ *
164
+ * @example
165
+ * ```ts
166
+ * import type { AuthResolvedContext } from "@robelest/convex-auth/server";
167
+ *
168
+ * const mockAuth: AuthResolvedContext = {
169
+ * userId: "user123" as Id<"User">,
170
+ * user: { _id: "user123", email: "test@example.com" },
171
+ * groupId: "group456",
172
+ * role: "admin",
173
+ * grants: ["read", "write"],
174
+ * };
175
+ * ```
159
176
  */
160
177
  type AuthResolvedContext = {
161
- /** The authenticated user's document ID. */userId: string; /** The authenticated user's full document. */
162
- user: any; /** The user's active group ID, or `null` if none set. */
178
+ /** The authenticated user's document ID. */userId: GenericId<"User">; /** The authenticated user's full document. */
179
+ user: UserDoc; /** The user's active group ID, or `null` if none set. */
163
180
  groupId: string | null; /** The user's primary role in the active group, or `null`. */
164
181
  role: string | null; /** Resolved grant strings from the user's role definitions. */
165
182
  grants: string[];
166
183
  };
184
+ type AuthCtxBase = {
185
+ getUserIdentity: () => Promise<UserIdentity | null>;
186
+ };
187
+ type RequiredAuthCtxState = AuthCtxBase & AuthResolvedContext;
188
+ type OptionalAuthCtxState = AuthCtxBase & {
189
+ userId: GenericId<"User"> | null;
190
+ user: UserDoc | null;
191
+ groupId: string | null;
192
+ role: string | null;
193
+ grants: string[];
194
+ };
167
195
  type InternalSsoApi = ReturnType<typeof Auth>["auth"]["sso"];
168
196
  type PublicSsoAdminApi = {
169
197
  connection: InternalSsoApi["connection"] & {
@@ -280,8 +308,6 @@ declare function createAuth<P extends AuthProviderConfig[], TAuthorization exten
280
308
  providers: P;
281
309
  authorization?: TAuthorization;
282
310
  }): ConvexAuthResult<P, TAuthorization>;
283
- /** Canonical user document type exposed by Convex Auth. */
284
- type UserDoc = Doc<"User">;
285
311
  /**
286
312
  * Configuration for {@link AuthCtx} context enrichment.
287
313
  *
@@ -291,16 +317,42 @@ type UserDoc = Doc<"User">;
291
317
  type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, never>> = {
292
318
  /** Allow unauthenticated callers and return `userId: null` / `user: null`. */optional?: boolean;
293
319
  /**
294
- * Attach additional derived fields to the auth context after the user is resolved.
320
+ * Attach additional derived fields to the auth context after the base auth
321
+ * context is resolved.
322
+ */
323
+ resolve?: (ctx: any, user: UserDoc, auth: AuthResolvedContext) => Promise<TResolve> | TResolve;
324
+ /**
325
+ * Override or wrap the base auth resolution used by {@link AuthCtx}.
326
+ *
327
+ * Return `undefined` to fall back to the built-in resolver,
328
+ * `null` for an explicit unauthenticated state, or an
329
+ * {@link AuthResolvedContext} object to provide a pre-resolved auth state.
330
+ * This is useful for tests, proxy auth, impersonation flows, or any
331
+ * environment that needs to inject auth without depending on the standard
332
+ * Convex auth tables.
333
+ *
334
+ * @param ctx - The Convex function context.
335
+ * @param fallback - The built-in auth resolver used by {@link AuthCtx}.
336
+ * @returns Resolved auth state, `null`, or `undefined` to use the fallback.
337
+ *
338
+ * @example
339
+ * ```ts
340
+ * const authCtx = AuthCtx(auth, {
341
+ * authResolve: async (ctx, fallback) => {
342
+ * const injected = getInjectedAuth(ctx);
343
+ * return injected ?? (await fallback());
344
+ * },
345
+ * });
346
+ * ```
295
347
  */
296
- resolve?: (ctx: any, user: UserDoc) => Promise<TResolve> | TResolve;
348
+ authResolve?: (ctx: any, fallback: () => Promise<AuthResolvedContext | null>) => Promise<AuthResolvedContext | null | undefined> | AuthResolvedContext | null | undefined;
297
349
  };
298
350
  /**
299
351
  * Create a context enrichment for `customQuery` / `customMutation` — optional auth.
300
352
  *
301
353
  * When `optional: true` is set, unauthenticated requests are allowed.
302
- * The enriched `ctx.auth` will have `userId: null` and `user: null`
303
- * for unauthenticated callers.
354
+ * The enriched `ctx.auth` will have `userId: null`, `user: null`,
355
+ * `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.
304
356
  *
305
357
  * @param auth - The auth API object returned by {@link createAuth}.
306
358
  * @param config - Configuration with `optional: true` and an optional
@@ -324,11 +376,7 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
324
376
  args: {};
325
377
  input: (ctx: any, _args: any, _extra?: any) => Promise<{
326
378
  ctx: {
327
- auth: {
328
- getUserIdentity: () => Promise<UserIdentity | null>;
329
- userId: GenericId<"User"> | null;
330
- user: UserDoc | null;
331
- } & TResolve;
379
+ auth: OptionalAuthCtxState & TResolve;
332
380
  };
333
381
  args: {};
334
382
  }>;
@@ -338,8 +386,9 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
338
386
  *
339
387
  * When `optional` is omitted or `false`, the inferred type is the authenticated
340
388
  * auth shape. At runtime this helper still resolves instead of throwing, so if
341
- * no user is signed in the returned `ctx.auth.userId` and `ctx.auth.user` are
342
- * `null`.
389
+ * no user is signed in the returned `ctx.auth.userId` / `ctx.auth.user` are
390
+ * `null`, `ctx.auth.groupId` / `ctx.auth.role` are `null`, and
391
+ * `ctx.auth.grants` is `[]`.
343
392
  *
344
393
  * @param auth - The auth API object returned by {@link createAuth}.
345
394
  * @param config - Optional configuration with a `resolve` callback
@@ -360,11 +409,7 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
360
409
  args: {};
361
410
  input: (ctx: any, _args: any, _extra?: any) => Promise<{
362
411
  ctx: {
363
- auth: {
364
- getUserIdentity: () => Promise<UserIdentity | null>;
365
- userId: GenericId<"User">;
366
- user: UserDoc;
367
- } & TResolve;
412
+ auth: RequiredAuthCtxState & TResolve;
368
413
  };
369
414
  args: {};
370
415
  }>;
@@ -374,9 +419,10 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
374
419
  *
375
420
  * Use this to type function parameters or variables that receive the
376
421
  * enriched auth context produced by `AuthCtx`. The inferred type includes
377
- * `userId`, `user`, `getUserIdentity`, and any additional fields added
378
- * by the `resolve` callback. This is the generic utility for reusing the
379
- * enriched auth shape without manually duplicating conditional auth types.
422
+ * `userId`, `user`, `groupId`, `role`, `grants`, `getUserIdentity`, and any
423
+ * additional fields added by the `resolve` callback. This is the generic
424
+ * utility for reusing the enriched auth shape without manually duplicating
425
+ * conditional auth types.
380
426
  *
381
427
  * @typeParam T - An `AuthCtx` return value (must have an `input` method
382
428
  * that returns `{ ctx: { auth: ... } }`).
@@ -400,5 +446,5 @@ type InferAuth<T extends {
400
446
  }>;
401
447
  }> = Awaited<ReturnType<T["input"]>>["ctx"]["auth"];
402
448
  //#endregion
403
- export { AuthApi, AuthConfig, AuthCtx, AuthCtxConfig, InferAuth, UserDoc, createAuth };
449
+ export { AuthApi, AuthConfig, AuthCtx, AuthCtxConfig, AuthResolvedContext, InferAuth, UserDoc, createAuth };
404
450
  //# sourceMappingURL=auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","names":[],"sources":["../../../src/server/auth.ts"],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { AuthError } from "./authError.js";
2
2
  import { Auth } from "./runtime.js";
3
- import { Fx } from "@robelest/fx";
4
3
 
5
4
  //#region src/server/auth.ts
6
5
  /**
@@ -186,39 +185,26 @@ function AuthCtx(auth, config) {
186
185
  args: {},
187
186
  input: async (ctx, _args, _extra) => {
188
187
  const nativeAuth = ctx.auth;
189
- const modeDispatch = config?.optional === true ? { mode: "optional" } : { mode: "required" };
190
- const userContext = await Fx.run(Fx.match(modeDispatch, modeDispatch.mode, {
191
- optional: async () => {
192
- const userId = await auth.user.id(ctx);
193
- if (!userId) return null;
194
- return {
195
- userId,
196
- user: await auth.user.get(ctx, userId)
197
- };
198
- },
199
- required: async () => {
200
- const userId = await auth.user.id(ctx);
201
- if (!userId) return null;
202
- return {
203
- userId,
204
- user: await auth.user.get(ctx, userId)
205
- };
206
- }
207
- }));
208
- if (userContext === null) return {
188
+ const getUserIdentity = nativeAuth.getUserIdentity.bind(nativeAuth);
189
+ const fallback = () => resolveAuthContext(auth, ctx);
190
+ const authOverride = config?.authResolve ? await config.authResolve(ctx, fallback) : void 0;
191
+ const resolved = authOverride === void 0 ? await fallback() : authOverride;
192
+ if (resolved === null) return {
209
193
  ctx: { auth: {
210
- getUserIdentity: nativeAuth.getUserIdentity.bind(nativeAuth),
194
+ getUserIdentity,
211
195
  userId: null,
212
- user: null
196
+ user: null,
197
+ groupId: null,
198
+ role: null,
199
+ grants: []
213
200
  } },
214
201
  args: {}
215
202
  };
216
- const extra = config?.resolve ? await config.resolve(ctx, userContext.user) : {};
203
+ const extra = config?.resolve ? await config.resolve(ctx, resolved.user, resolved) : {};
217
204
  return {
218
205
  ctx: { auth: {
219
- getUserIdentity: nativeAuth.getUserIdentity.bind(nativeAuth),
220
- userId: userContext.userId,
221
- user: userContext.user,
206
+ getUserIdentity,
207
+ ...resolved,
222
208
  ...extra
223
209
  } },
224
210
  args: {}
@@ -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 \"./runtime\";\nimport { Fx } from \"@robelest/fx\";\nimport { AuthError } from \"./authError\";\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 ancestry?: boolean;\n roleIds?: AuthRoleId<TAuthorization>[];\n grants?: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"resolve\"]>;\n};\n\n\n/**\n * The base auth API surface returned by {@link createAuth}.\n *\n * Provides core namespaces — `signIn`, `signOut`, `user`, `session`,\n * `member`, `invite`, `group`, `key`, and `http` — that are\n * always available regardless of which providers are configured.\n * Enterprise namespaces (`sso`, `scim`) are added conditionally by\n * {@link AuthApi} when an SSO provider is present.\n *\n * Use this type when you want to describe code that only depends on the\n * standard auth surface and should not assume enterprise features exist.\n *\n * @typeParam TAuthorization - The authorization config, used to narrow\n * role IDs and grant strings on the `member` API.\n */\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 invite: ReturnType<typeof AuthFactory>[\"auth\"][\"invite\"];\n key: ReturnType<typeof AuthFactory>[\"auth\"][\"key\"];\n http: ReturnType<typeof AuthFactory>[\"auth\"][\"http\"];\n /**\n * Resolve the current user's auth context. Framework-agnostic — use\n * this in fluent-convex middleware, custom wrappers, or anywhere you\n * need the resolved `{ userId, user, groupId, role, grants }` object.\n *\n * Returns `null` when unauthenticated. Does not throw.\n *\n * @param ctx - Convex query, mutation, or action context.\n * @returns The resolved auth context, or `null`.\n *\n * @example fluent-convex middleware\n * ```ts\n * const withAuth = convex.createMiddleware(async (ctx, next) => {\n * return next({ ...ctx, auth: await auth.resolve(ctx) });\n * });\n * ```\n *\n * @example Direct usage in a handler\n * ```ts\n * const resolved = await auth.resolve(ctx);\n * if (!resolved) return { ok: false, code: \"NOT_SIGNED_IN\" };\n * const { userId, grants } = resolved;\n * ```\n */\n resolve: (ctx: any) => Promise<AuthResolvedContext | null>;\n /**\n * Context enrichment for convex-helpers `customQuery` / `customMutation` /\n * `customAction`.\n *\n * Resolves the current user's identity, active group, membership role,\n * and grants, then attaches them to `ctx.auth`. Returns a `Customization`\n * object compatible with convex-helpers' custom function builders.\n *\n * `ctx.auth` is `{ userId, user, groupId, role, grants }` when\n * authenticated, `null` when unauthenticated. No throwing — your\n * handler decides how to respond.\n *\n * @returns A convex-helpers `Customization` object.\n *\n * @example One-time setup in `convex/functions.ts`\n * ```ts\n * import { query, mutation, action } from \"./_generated/server\";\n * import { customQuery, customMutation, customAction } from \"convex-helpers/server/customFunctions\";\n * import { auth } from \"./auth\";\n *\n * export const authQuery = customQuery(query, auth.ctx());\n * export const authMutation = customMutation(mutation, auth.ctx());\n * export const authAction = customAction(action, auth.ctx());\n * ```\n *\n * @example Per-function usage\n * ```ts\n * import { authQuery } from \"./functions\";\n *\n * export const list = authQuery({\n * args: { workspaceId: v.string() },\n * handler: async (ctx, args) => {\n * if (!ctx.auth) return [];\n * const { userId, groupId, grants } = ctx.auth;\n * // business logic\n * },\n * });\n * ```\n */\n ctx: () => {\n args: Record<string, never>;\n input: (ctx: any) => Promise<{\n ctx: { auth: AuthResolvedContext | null };\n args: Record<string, never>;\n }>;\n };\n};\n\n/**\n * Resolved auth context injected into `ctx.auth` by `auth.ctx()`.\n *\n * - `null` when unauthenticated.\n * - `groupId` is `null` when the user has no active group set.\n * - `role` / `grants` are `null` / `[]` when no active group or no membership.\n */\nexport type AuthResolvedContext = {\n /** The authenticated user's document ID. */\n userId: string;\n /** The authenticated user's full document. */\n user: any;\n /** The user's active group ID, or `null` if none set. */\n groupId: string | null;\n /** The user's primary role in the active group, or `null`. */\n role: string | null;\n /** Resolved grant strings from the user's role definitions. */\n grants: string[];\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/**\n * Extended auth API that includes enterprise SSO and SCIM namespaces.\n *\n * This type is the union of {@link AuthApiBase} plus `sso` (SSO connection\n * management, OIDC/SAML, domain verification, policies, audit, webhooks)\n * and `scim` (SCIM provisioning configuration). It is returned by\n * {@link createAuth} only when `new SSO()` is included in the providers\n * array; otherwise the narrower {@link AuthApiBase} is returned instead.\n * Attempting to access `auth.sso` or `auth.scim` without an SSO provider\n * produces a compile-time error because the return type narrows back to\n * {@link AuthApiBase}.\n *\n * @typeParam TAuthorization - The authorization config, forwarded to\n * {@link AuthApiBase} for typed role IDs and grant strings.\n */\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 {@link createAuth}.\n *\n * Resolves to {@link AuthApi} (with `sso` and `scim` namespaces) when\n * `new SSO()` is present in the providers array, or to the narrower\n * {@link AuthApiBase} otherwise. This conditional type ensures that\n * enterprise-only APIs are only accessible when the SSO provider is\n * configured, producing a compile-time error if you try to access\n * `auth.sso` without it.\n * This lets application code keep a single `createAuth()` call while still\n * getting provider-aware typing on the resulting API object.\n *\n * @typeParam P - The tuple of provider configs passed to `createAuth`.\n * @typeParam TAuthorization - Optional authorization config for typed roles/grants.\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/server\";\n * const c = client<InferClientApi<typeof auth>>({ convex, api: api.auth });\n * ```\n *\n * @typeParam T - A ConvexAuthResult to extract the client API from.\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 *\n * @param component - The installed auth component reference from\n * `components.auth` in your Convex app definition.\n * @param config - Auth configuration including `providers` and optional\n * `authorization`. All fields from {@link AuthConfig} are accepted\n * except `component` (passed as the first argument).\n * @returns A {@link ConvexAuthResult} object — either {@link AuthApi}\n * (with `sso`/`scim`) or {@link AuthApiBase}, depending on whether\n * an SSO provider is present.\n *\n * @example\n * ```ts\n * export const auth = createAuth(components.auth, {\n * providers: [password(), google()],\n * authorization: { roles },\n * });\n * ```\n *\n * @see {@link AuthCtx}\n */\n\n// ---------------------------------------------------------------------------\n// Function builders — shared auth resolution logic\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve auth context for the current user. Returns the enriched\n * `ctx.auth` object or `null` when unauthenticated.\n *\n * Resolution flow:\n * 1. `user.id(ctx)` → userId or null (exit early)\n * 2. `user.get(ctx, userId)` → user doc (cached per-execution)\n * 3. `user.getActiveGroup(ctx, { userId })` → groupId or null\n * 4. If groupId → `member.resolve(ctx, { userId, groupId })` → role + grants\n */\nasync function resolveAuthContext(auth: any, ctx: any) {\n const userId = await auth.user.id(ctx);\n if (!userId) return null;\n const user = await auth.user.get(ctx, userId);\n const groupId = await auth.user.getActiveGroup(ctx, { userId });\n let role: string | null = null;\n let grants: string[] = [];\n if (groupId) {\n const resolved = await auth.member.resolve(ctx, { userId, groupId });\n if (resolved.membership) {\n role = resolved.roleIds[0] ?? null;\n grants = resolved.grants;\n }\n }\n return { userId, user, groupId, role, grants };\n}\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 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\n resolve: (ctx: any) => resolveAuthContext(authResult.auth, ctx),\n\n ctx: () => ({\n args: {},\n input: async (ctx: any) => {\n const authCtx = await resolveAuthContext(authResult.auth, ctx);\n return { ctx: { auth: authCtx }, args: {} };\n },\n }),\n } as unknown as ConvexAuthResult<P, TAuthorization>;\n}\n\n// ============================================================================\n// AuthCtx — ctx enrichment for customQuery / customMutation\n// ============================================================================\n\n/** Canonical user document type exposed by Convex Auth. */\nexport type UserDoc = Doc<\"User\">;\n\n/**\n * Configuration for {@link AuthCtx} context enrichment.\n *\n * @typeParam TResolve - Extra fields returned from `resolve()` and merged into\n * the resulting `ctx.auth` object.\n */\nexport type AuthCtxConfig<\n TResolve extends Record<string, unknown> = Record<string, never>,\n> = {\n /** Allow unauthenticated callers and return `userId: null` / `user: null`. */\n optional?: boolean;\n /**\n * Attach additional derived fields to the auth context after the user is resolved.\n */\n resolve?: (ctx: any, user: UserDoc) => Promise<TResolve> | TResolve;\n};\n\n/**\n * Create a context enrichment for `customQuery` / `customMutation` — optional auth.\n *\n * When `optional: true` is set, unauthenticated requests are allowed.\n * The enriched `ctx.auth` will have `userId: null` and `user: null`\n * for unauthenticated callers.\n *\n * @param auth - The auth API object returned by {@link createAuth}.\n * @param config - Configuration with `optional: true` and an optional\n * `resolve` callback for attaching extra fields to the auth context.\n * @returns An object with `args` and `input` compatible with Convex\n * custom function builders.\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * optional: true,\n * resolve: async (_ctx, user) => ({ plan: user?.extend?.plan ?? null }),\n * });\n * ```\n *\n * @see {@link createAuth}\n */\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/**\n * Create a context enrichment for `customQuery` / `customMutation` — required auth (default).\n *\n * When `optional` is omitted or `false`, the inferred type is the authenticated\n * auth shape. At runtime this helper still resolves instead of throwing, so if\n * no user is signed in the returned `ctx.auth.userId` and `ctx.auth.user` are\n * `null`.\n *\n * @param auth - The auth API object returned by {@link createAuth}.\n * @param config - Optional configuration with a `resolve` callback\n * for attaching extra fields to the auth context.\n * @returns An object with `args` and `input` compatible with Convex\n * custom function builders.\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * resolve: async (_ctx, user) => ({ email: user.email }),\n * });\n * ```\n *\n * @see {@link createAuth}\n */\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\n/**\n * Extract the resolved `auth` context type from an {@link AuthCtx} instance.\n *\n * Use this to type function parameters or variables that receive the\n * enriched auth context produced by `AuthCtx`. The inferred type includes\n * `userId`, `user`, `getUserIdentity`, and any additional fields added\n * by the `resolve` callback. This is the generic utility for reusing the\n * enriched auth shape without manually duplicating conditional auth types.\n *\n * @typeParam T - An `AuthCtx` return value (must have an `input` method\n * that returns `{ ctx: { auth: ... } }`).\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * resolve: async (ctx, user) => ({ orgId: user.orgId }),\n * });\n * type Auth = InferAuth<typeof authCtx>;\n * // Auth = { userId: Id<\"User\">; user: UserDoc; getUserIdentity: ...; orgId: string }\n * ```\n *\n * @see {@link createAuth}\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 \"./runtime\";\nimport { AuthError } from \"./authError\";\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\n/** Canonical user document type exposed by Convex Auth. */\nexport type UserDoc = Doc<\"User\">;\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 ancestry?: boolean;\n roleIds?: AuthRoleId<TAuthorization>[];\n grants?: AuthGrant<TAuthorization>[];\n maxDepth?: number;\n },\n ) => ReturnType<ReturnType<typeof AuthFactory>[\"auth\"][\"member\"][\"resolve\"]>;\n};\n\n\n/**\n * The base auth API surface returned by {@link createAuth}.\n *\n * Provides core namespaces — `signIn`, `signOut`, `user`, `session`,\n * `member`, `invite`, `group`, `key`, and `http` — that are\n * always available regardless of which providers are configured.\n * Enterprise namespaces (`sso`, `scim`) are added conditionally by\n * {@link AuthApi} when an SSO provider is present.\n *\n * Use this type when you want to describe code that only depends on the\n * standard auth surface and should not assume enterprise features exist.\n *\n * @typeParam TAuthorization - The authorization config, used to narrow\n * role IDs and grant strings on the `member` API.\n */\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 invite: ReturnType<typeof AuthFactory>[\"auth\"][\"invite\"];\n key: ReturnType<typeof AuthFactory>[\"auth\"][\"key\"];\n http: ReturnType<typeof AuthFactory>[\"auth\"][\"http\"];\n /**\n * Resolve the current user's auth context. Framework-agnostic — use\n * this in fluent-convex middleware, custom wrappers, or anywhere you\n * need the resolved `{ userId, user, groupId, role, grants }` object.\n *\n * Returns `null` when unauthenticated. Does not throw.\n *\n * @param ctx - Convex query, mutation, or action context.\n * @returns The resolved auth context, or `null`.\n *\n * @example fluent-convex middleware\n * ```ts\n * const withAuth = convex.createMiddleware(async (ctx, next) => {\n * return next({ ...ctx, auth: await auth.resolve(ctx) });\n * });\n * ```\n *\n * @example Direct usage in a handler\n * ```ts\n * const resolved = await auth.resolve(ctx);\n * if (!resolved) return { ok: false, code: \"NOT_SIGNED_IN\" };\n * const { userId, grants } = resolved;\n * ```\n */\n resolve: (ctx: any) => Promise<AuthResolvedContext | null>;\n /**\n * Context enrichment for convex-helpers `customQuery` / `customMutation` /\n * `customAction`.\n *\n * Resolves the current user's identity, active group, membership role,\n * and grants, then attaches them to `ctx.auth`. Returns a `Customization`\n * object compatible with convex-helpers' custom function builders.\n *\n * `ctx.auth` is `{ userId, user, groupId, role, grants }` when\n * authenticated, `null` when unauthenticated. No throwing — your\n * handler decides how to respond.\n *\n * @returns A convex-helpers `Customization` object.\n *\n * @example One-time setup in `convex/functions.ts`\n * ```ts\n * import { query, mutation, action } from \"./_generated/server\";\n * import { customQuery, customMutation, customAction } from \"convex-helpers/server/customFunctions\";\n * import { auth } from \"./auth\";\n *\n * export const authQuery = customQuery(query, auth.ctx());\n * export const authMutation = customMutation(mutation, auth.ctx());\n * export const authAction = customAction(action, auth.ctx());\n * ```\n *\n * @example Per-function usage\n * ```ts\n * import { authQuery } from \"./functions\";\n *\n * export const list = authQuery({\n * args: { workspaceId: v.string() },\n * handler: async (ctx, args) => {\n * if (!ctx.auth) return [];\n * const { userId, groupId, grants } = ctx.auth;\n * // business logic\n * },\n * });\n * ```\n */\n ctx: () => {\n args: Record<string, never>;\n input: (ctx: any) => Promise<{\n ctx: { auth: AuthResolvedContext | null };\n args: Record<string, never>;\n }>;\n };\n};\n\n/**\n * Resolved auth context injected into `ctx.auth` by `auth.ctx()` and\n * {@link AuthCtx}. Also the expected return shape for custom\n * {@link AuthCtxConfig.authResolve | authResolve} hooks.\n *\n * - `null` when unauthenticated.\n * - `groupId` is `null` when the user has no active group set.\n * - `role` / `grants` are `null` / `[]` when no active group or no membership.\n *\n * @example\n * ```ts\n * import type { AuthResolvedContext } from \"@robelest/convex-auth/server\";\n *\n * const mockAuth: AuthResolvedContext = {\n * userId: \"user123\" as Id<\"User\">,\n * user: { _id: \"user123\", email: \"test@example.com\" },\n * groupId: \"group456\",\n * role: \"admin\",\n * grants: [\"read\", \"write\"],\n * };\n * ```\n */\nexport type AuthResolvedContext = {\n /** The authenticated user's document ID. */\n userId: GenericId<\"User\">;\n /** The authenticated user's full document. */\n user: UserDoc;\n /** The user's active group ID, or `null` if none set. */\n groupId: string | null;\n /** The user's primary role in the active group, or `null`. */\n role: string | null;\n /** Resolved grant strings from the user's role definitions. */\n grants: string[];\n};\n\ntype AuthCtxBase = {\n getUserIdentity: () => Promise<UserIdentity | null>;\n};\n\ntype RequiredAuthCtxState = AuthCtxBase & AuthResolvedContext;\n\ntype OptionalAuthCtxState = AuthCtxBase & {\n userId: GenericId<\"User\"> | null;\n user: UserDoc | null;\n groupId: string | null;\n role: string | null;\n grants: string[];\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/**\n * Extended auth API that includes enterprise SSO and SCIM namespaces.\n *\n * This type is the union of {@link AuthApiBase} plus `sso` (SSO connection\n * management, OIDC/SAML, domain verification, policies, audit, webhooks)\n * and `scim` (SCIM provisioning configuration). It is returned by\n * {@link createAuth} only when `new SSO()` is included in the providers\n * array; otherwise the narrower {@link AuthApiBase} is returned instead.\n * Attempting to access `auth.sso` or `auth.scim` without an SSO provider\n * produces a compile-time error because the return type narrows back to\n * {@link AuthApiBase}.\n *\n * @typeParam TAuthorization - The authorization config, forwarded to\n * {@link AuthApiBase} for typed role IDs and grant strings.\n */\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 {@link createAuth}.\n *\n * Resolves to {@link AuthApi} (with `sso` and `scim` namespaces) when\n * `new SSO()` is present in the providers array, or to the narrower\n * {@link AuthApiBase} otherwise. This conditional type ensures that\n * enterprise-only APIs are only accessible when the SSO provider is\n * configured, producing a compile-time error if you try to access\n * `auth.sso` without it.\n * This lets application code keep a single `createAuth()` call while still\n * getting provider-aware typing on the resulting API object.\n *\n * @typeParam P - The tuple of provider configs passed to `createAuth`.\n * @typeParam TAuthorization - Optional authorization config for typed roles/grants.\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/server\";\n * const c = client<InferClientApi<typeof auth>>({ convex, api: api.auth });\n * ```\n *\n * @typeParam T - A ConvexAuthResult to extract the client API from.\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\" | \"member\">;\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 *\n * @param component - The installed auth component reference from\n * `components.auth` in your Convex app definition.\n * @param config - Auth configuration including `providers` and optional\n * `authorization`. All fields from {@link AuthConfig} are accepted\n * except `component` (passed as the first argument).\n * @returns A {@link ConvexAuthResult} object — either {@link AuthApi}\n * (with `sso`/`scim`) or {@link AuthApiBase}, depending on whether\n * an SSO provider is present.\n *\n * @example\n * ```ts\n * export const auth = createAuth(components.auth, {\n * providers: [password(), google()],\n * authorization: { roles },\n * });\n * ```\n *\n * @see {@link AuthCtx}\n */\n\n// ---------------------------------------------------------------------------\n// Function builders — shared auth resolution logic\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve auth context for the current user. Returns the enriched\n * `ctx.auth` object or `null` when unauthenticated.\n *\n * Resolution flow:\n * 1. `user.id(ctx)` → userId or null (exit early)\n * 2. `user.get(ctx, userId)` → user doc (cached per-execution)\n * 3. `user.getActiveGroup(ctx, { userId })` → groupId or null\n * 4. If groupId → `member.resolve(ctx, { userId, groupId })` → role + grants\n */\nasync function resolveAuthContext(auth: AuthLike, ctx: any) {\n const userId = await auth.user.id(ctx);\n if (!userId) return null;\n const user = await auth.user.get(ctx, userId);\n const groupId = await auth.user.getActiveGroup(ctx, { userId });\n let role: string | null = null;\n let grants: string[] = [];\n if (groupId) {\n const resolved = await auth.member.resolve(ctx, { userId, groupId });\n if (resolved.membership) {\n role = resolved.roleIds[0] ?? null;\n grants = resolved.grants;\n }\n }\n return { userId, user, groupId, role, grants };\n}\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 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\n resolve: (ctx: any) => resolveAuthContext(authResult.auth, ctx),\n\n ctx: () => ({\n args: {},\n input: async (ctx: any) => {\n const authCtx = await resolveAuthContext(authResult.auth, ctx);\n return { ctx: { auth: authCtx }, args: {} };\n },\n }),\n } as unknown as ConvexAuthResult<P, TAuthorization>;\n}\n\n// ============================================================================\n// AuthCtx — ctx enrichment for customQuery / customMutation\n// ============================================================================\n\n/**\n * Configuration for {@link AuthCtx} context enrichment.\n *\n * @typeParam TResolve - Extra fields returned from `resolve()` and merged into\n * the resulting `ctx.auth` object.\n */\nexport type AuthCtxConfig<\n TResolve extends Record<string, unknown> = Record<string, never>,\n> = {\n /** Allow unauthenticated callers and return `userId: null` / `user: null`. */\n optional?: boolean;\n /**\n * Attach additional derived fields to the auth context after the base auth\n * context is resolved.\n */\n resolve?: (\n ctx: any,\n user: UserDoc,\n auth: AuthResolvedContext,\n ) => Promise<TResolve> | TResolve;\n /**\n * Override or wrap the base auth resolution used by {@link AuthCtx}.\n *\n * Return `undefined` to fall back to the built-in resolver,\n * `null` for an explicit unauthenticated state, or an\n * {@link AuthResolvedContext} object to provide a pre-resolved auth state.\n * This is useful for tests, proxy auth, impersonation flows, or any\n * environment that needs to inject auth without depending on the standard\n * Convex auth tables.\n *\n * @param ctx - The Convex function context.\n * @param fallback - The built-in auth resolver used by {@link AuthCtx}.\n * @returns Resolved auth state, `null`, or `undefined` to use the fallback.\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * authResolve: async (ctx, fallback) => {\n * const injected = getInjectedAuth(ctx);\n * return injected ?? (await fallback());\n * },\n * });\n * ```\n */\n authResolve?: (\n ctx: any,\n fallback: () => Promise<AuthResolvedContext | null>,\n ) =>\n | Promise<AuthResolvedContext | null | undefined>\n | AuthResolvedContext\n | null\n | undefined;\n};\n\n/**\n * Create a context enrichment for `customQuery` / `customMutation` — optional auth.\n *\n * When `optional: true` is set, unauthenticated requests are allowed.\n * The enriched `ctx.auth` will have `userId: null`, `user: null`,\n * `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.\n *\n * @param auth - The auth API object returned by {@link createAuth}.\n * @param config - Configuration with `optional: true` and an optional\n * `resolve` callback for attaching extra fields to the auth context.\n * @returns An object with `args` and `input` compatible with Convex\n * custom function builders.\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * optional: true,\n * resolve: async (_ctx, user) => ({ plan: user?.extend?.plan ?? null }),\n * });\n * ```\n *\n * @see {@link createAuth}\n */\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: OptionalAuthCtxState & TResolve;\n };\n args: {};\n }>;\n};\n/**\n * Create a context enrichment for `customQuery` / `customMutation` — required auth (default).\n *\n * When `optional` is omitted or `false`, the inferred type is the authenticated\n * auth shape. At runtime this helper still resolves instead of throwing, so if\n * no user is signed in the returned `ctx.auth.userId` / `ctx.auth.user` are\n * `null`, `ctx.auth.groupId` / `ctx.auth.role` are `null`, and\n * `ctx.auth.grants` is `[]`.\n *\n * @param auth - The auth API object returned by {@link createAuth}.\n * @param config - Optional configuration with a `resolve` callback\n * for attaching extra fields to the auth context.\n * @returns An object with `args` and `input` compatible with Convex\n * custom function builders.\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * resolve: async (_ctx, user) => ({ email: user.email }),\n * });\n * ```\n *\n * @see {@link createAuth}\n */\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: RequiredAuthCtxState & 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 getUserIdentity = nativeAuth.getUserIdentity.bind(nativeAuth);\n const fallback = () => resolveAuthContext(auth, ctx);\n\n const authOverride = config?.authResolve\n ? await config.authResolve(ctx, fallback)\n : undefined;\n const resolved =\n authOverride === undefined ? await fallback() : authOverride;\n\n if (resolved === null) {\n return {\n ctx: {\n auth: {\n getUserIdentity,\n userId: null,\n user: null,\n groupId: null,\n role: null,\n grants: [],\n },\n },\n args: {},\n };\n }\n\n const extra = config?.resolve\n ? await config.resolve(ctx, resolved.user, resolved)\n : {};\n\n return {\n ctx: {\n auth: {\n getUserIdentity,\n ...resolved,\n ...extra,\n },\n },\n args: {},\n };\n },\n };\n}\n\n/**\n * Extract the resolved `auth` context type from an {@link AuthCtx} instance.\n *\n * Use this to type function parameters or variables that receive the\n * enriched auth context produced by `AuthCtx`. The inferred type includes\n * `userId`, `user`, `groupId`, `role`, `grants`, `getUserIdentity`, and any\n * additional fields added by the `resolve` callback. This is the generic\n * utility for reusing the enriched auth shape without manually duplicating\n * conditional auth types.\n *\n * @typeParam T - An `AuthCtx` return value (must have an `input` method\n * that returns `{ ctx: { auth: ... } }`).\n *\n * @example\n * ```ts\n * const authCtx = AuthCtx(auth, {\n * resolve: async (ctx, user) => ({ orgId: user.orgId }),\n * });\n * type Auth = InferAuth<typeof authCtx>;\n * // Auth = { userId: Id<\"User\">; user: UserDoc; getUserIdentity: ...; orgId: string }\n * ```\n *\n * @see {@link createAuth}\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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"}
@@ -49,8 +49,8 @@ declare function Auth(config_: ConvexAuthConfig): {
49
49
  store: convex_server25.RegisteredMutation<"internal", {
50
50
  args: {
51
51
  sessionId?: string | undefined;
52
- userId: string;
53
52
  type: "signIn";
53
+ userId: string;
54
54
  generateTokens: boolean;
55
55
  } | {
56
56
  type: "signOut";
@@ -112,8 +112,8 @@ declare function Auth(config_: ConvexAuthConfig): {
112
112
  };
113
113
  } | {
114
114
  except?: string[] | undefined;
115
- userId: string;
116
115
  type: "invalidateSessions";
116
+ userId: string;
117
117
  };
118
118
  }, Promise<string | void | {
119
119
  userId: convex_values926.GenericId<"User">;
@@ -11,6 +11,8 @@ import { GenericId } from "convex/values";
11
11
  * minus `component` (which is passed as the first constructor argument).
12
12
  */
13
13
  type AuthConfig = Omit<ConvexAuthConfig, "component">;
14
+ /** Canonical user document type exposed by Convex Auth. */
15
+ type UserDoc = Doc<"User">;
14
16
  type MemberApiWithAuthorization<TAuthorization extends AuthAuthorizationConfig | undefined> = Omit<ReturnType<typeof Auth$1>["auth"]["member"], "create" | "list" | "update" | "resolve"> & {
15
17
  create: (ctx: Parameters<ReturnType<typeof Auth$1>["auth"]["member"]["create"]>[0], data: {
16
18
  groupId: string;
@@ -152,19 +154,45 @@ type AuthApiBase<TAuthorization extends AuthAuthorizationConfig | undefined = un
152
154
  };
153
155
  };
154
156
  /**
155
- * Resolved auth context injected into `ctx.auth` by `auth.ctx()`.
157
+ * Resolved auth context injected into `ctx.auth` by `auth.ctx()` and
158
+ * {@link AuthCtx}. Also the expected return shape for custom
159
+ * {@link AuthCtxConfig.authResolve | authResolve} hooks.
156
160
  *
157
161
  * - `null` when unauthenticated.
158
162
  * - `groupId` is `null` when the user has no active group set.
159
163
  * - `role` / `grants` are `null` / `[]` when no active group or no membership.
164
+ *
165
+ * @example
166
+ * ```ts
167
+ * import type { AuthResolvedContext } from "@robelest/convex-auth/server";
168
+ *
169
+ * const mockAuth: AuthResolvedContext = {
170
+ * userId: "user123" as Id<"User">,
171
+ * user: { _id: "user123", email: "test@example.com" },
172
+ * groupId: "group456",
173
+ * role: "admin",
174
+ * grants: ["read", "write"],
175
+ * };
176
+ * ```
160
177
  */
161
178
  type AuthResolvedContext = {
162
- /** The authenticated user's document ID. */userId: string; /** The authenticated user's full document. */
163
- user: any; /** The user's active group ID, or `null` if none set. */
179
+ /** The authenticated user's document ID. */userId: GenericId<"User">; /** The authenticated user's full document. */
180
+ user: UserDoc; /** The user's active group ID, or `null` if none set. */
164
181
  groupId: string | null; /** The user's primary role in the active group, or `null`. */
165
182
  role: string | null; /** Resolved grant strings from the user's role definitions. */
166
183
  grants: string[];
167
184
  };
185
+ type AuthCtxBase = {
186
+ getUserIdentity: () => Promise<UserIdentity | null>;
187
+ };
188
+ type RequiredAuthCtxState = AuthCtxBase & AuthResolvedContext;
189
+ type OptionalAuthCtxState = AuthCtxBase & {
190
+ userId: GenericId<"User"> | null;
191
+ user: UserDoc | null;
192
+ groupId: string | null;
193
+ role: string | null;
194
+ grants: string[];
195
+ };
168
196
  type InternalSsoApi = ReturnType<typeof Auth$1>["auth"]["sso"];
169
197
  type PublicSsoAdminApi = {
170
198
  connection: InternalSsoApi["connection"] & {
@@ -299,8 +327,6 @@ declare function createAuth<P extends AuthProviderConfig[], TAuthorization exten
299
327
  providers: P;
300
328
  authorization?: TAuthorization;
301
329
  }): ConvexAuthResult<P, TAuthorization>;
302
- /** Canonical user document type exposed by Convex Auth. */
303
- type UserDoc = Doc<"User">;
304
330
  /**
305
331
  * Configuration for {@link AuthCtx} context enrichment.
306
332
  *
@@ -310,16 +336,42 @@ type UserDoc = Doc<"User">;
310
336
  type AuthCtxConfig<TResolve extends Record<string, unknown> = Record<string, never>> = {
311
337
  /** Allow unauthenticated callers and return `userId: null` / `user: null`. */optional?: boolean;
312
338
  /**
313
- * Attach additional derived fields to the auth context after the user is resolved.
339
+ * Attach additional derived fields to the auth context after the base auth
340
+ * context is resolved.
341
+ */
342
+ resolve?: (ctx: any, user: UserDoc, auth: AuthResolvedContext) => Promise<TResolve> | TResolve;
343
+ /**
344
+ * Override or wrap the base auth resolution used by {@link AuthCtx}.
345
+ *
346
+ * Return `undefined` to fall back to the built-in resolver,
347
+ * `null` for an explicit unauthenticated state, or an
348
+ * {@link AuthResolvedContext} object to provide a pre-resolved auth state.
349
+ * This is useful for tests, proxy auth, impersonation flows, or any
350
+ * environment that needs to inject auth without depending on the standard
351
+ * Convex auth tables.
352
+ *
353
+ * @param ctx - The Convex function context.
354
+ * @param fallback - The built-in auth resolver used by {@link AuthCtx}.
355
+ * @returns Resolved auth state, `null`, or `undefined` to use the fallback.
356
+ *
357
+ * @example
358
+ * ```ts
359
+ * const authCtx = AuthCtx(auth, {
360
+ * authResolve: async (ctx, fallback) => {
361
+ * const injected = getInjectedAuth(ctx);
362
+ * return injected ?? (await fallback());
363
+ * },
364
+ * });
365
+ * ```
314
366
  */
315
- resolve?: (ctx: any, user: UserDoc) => Promise<TResolve> | TResolve;
367
+ authResolve?: (ctx: any, fallback: () => Promise<AuthResolvedContext | null>) => Promise<AuthResolvedContext | null | undefined> | AuthResolvedContext | null | undefined;
316
368
  };
317
369
  /**
318
370
  * Create a context enrichment for `customQuery` / `customMutation` — optional auth.
319
371
  *
320
372
  * When `optional: true` is set, unauthenticated requests are allowed.
321
- * The enriched `ctx.auth` will have `userId: null` and `user: null`
322
- * for unauthenticated callers.
373
+ * The enriched `ctx.auth` will have `userId: null`, `user: null`,
374
+ * `groupId: null`, `role: null`, and `grants: []` for unauthenticated callers.
323
375
  *
324
376
  * @param auth - The auth API object returned by {@link createAuth}.
325
377
  * @param config - Configuration with `optional: true` and an optional
@@ -343,11 +395,7 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
343
395
  args: {};
344
396
  input: (ctx: any, _args: any, _extra?: any) => Promise<{
345
397
  ctx: {
346
- auth: {
347
- getUserIdentity: () => Promise<UserIdentity | null>;
348
- userId: GenericId<"User"> | null;
349
- user: UserDoc | null;
350
- } & TResolve;
398
+ auth: OptionalAuthCtxState & TResolve;
351
399
  };
352
400
  args: {};
353
401
  }>;
@@ -357,8 +405,9 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
357
405
  *
358
406
  * When `optional` is omitted or `false`, the inferred type is the authenticated
359
407
  * auth shape. At runtime this helper still resolves instead of throwing, so if
360
- * no user is signed in the returned `ctx.auth.userId` and `ctx.auth.user` are
361
- * `null`.
408
+ * no user is signed in the returned `ctx.auth.userId` / `ctx.auth.user` are
409
+ * `null`, `ctx.auth.groupId` / `ctx.auth.role` are `null`, and
410
+ * `ctx.auth.grants` is `[]`.
362
411
  *
363
412
  * @param auth - The auth API object returned by {@link createAuth}.
364
413
  * @param config - Optional configuration with a `resolve` callback
@@ -379,11 +428,7 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
379
428
  args: {};
380
429
  input: (ctx: any, _args: any, _extra?: any) => Promise<{
381
430
  ctx: {
382
- auth: {
383
- getUserIdentity: () => Promise<UserIdentity | null>;
384
- userId: GenericId<"User">;
385
- user: UserDoc;
386
- } & TResolve;
431
+ auth: RequiredAuthCtxState & TResolve;
387
432
  };
388
433
  args: {};
389
434
  }>;
@@ -393,9 +438,10 @@ declare function AuthCtx<TResolve extends Record<string, unknown> = Record<strin
393
438
  *
394
439
  * Use this to type function parameters or variables that receive the
395
440
  * enriched auth context produced by `AuthCtx`. The inferred type includes
396
- * `userId`, `user`, `getUserIdentity`, and any additional fields added
397
- * by the `resolve` callback. This is the generic utility for reusing the
398
- * enriched auth shape without manually duplicating conditional auth types.
441
+ * `userId`, `user`, `groupId`, `role`, `grants`, `getUserIdentity`, and any
442
+ * additional fields added by the `resolve` callback. This is the generic
443
+ * utility for reusing the enriched auth shape without manually duplicating
444
+ * conditional auth types.
399
445
  *
400
446
  * @typeParam T - An `AuthCtx` return value (must have an `input` method
401
447
  * that returns `{ ctx: { auth: ... } }`).
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","names":[],"sources":["../../src/server/auth.ts"],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","names":[],"sources":["../../src/server/auth.ts"],"mappings":"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"}