@robelest/convex-auth 0.0.4-preview.30 → 0.0.4-preview.32

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 (104) hide show
  1. package/dist/bin.js +125 -36
  2. package/dist/browser/index.d.ts +3 -13
  3. package/dist/browser/index.js +47 -12
  4. package/dist/browser/navigation.js +1 -1
  5. package/dist/browser/passkey.js +7 -7
  6. package/dist/browser/runtime.js +13 -15
  7. package/dist/client/core/types.d.ts +179 -63
  8. package/dist/client/core/types.js +6 -0
  9. package/dist/client/factors/totp.js +1 -1
  10. package/dist/client/index.d.ts +5 -4
  11. package/dist/client/index.js +115 -56
  12. package/dist/client/runtime/mutex.js +3 -2
  13. package/dist/component/_generated/component.d.ts +40 -0
  14. package/dist/component/http.js +9 -0
  15. package/dist/component/index.d.ts +1 -1
  16. package/dist/component/model.d.ts +27 -27
  17. package/dist/component/model.js +2 -1
  18. package/dist/component/modules.js +1 -0
  19. package/dist/component/public/factors/passkeys.js +31 -1
  20. package/dist/component/public/identity/codes.js +1 -1
  21. package/dist/component/public/identity/tokens.js +2 -1
  22. package/dist/component/public/identity/verifiers.js +15 -5
  23. package/dist/component/public.js +2 -2
  24. package/dist/component/schema.d.ts +287 -285
  25. package/dist/component/schema.js +2 -1
  26. package/dist/core/index.d.ts +8 -3
  27. package/dist/core/index.js +7 -2
  28. package/dist/expo/index.d.ts +21 -0
  29. package/dist/expo/index.js +148 -0
  30. package/dist/expo/passkey.js +174 -0
  31. package/dist/providers/apple.d.ts +1 -1
  32. package/dist/providers/apple.js +6 -8
  33. package/dist/providers/custom.d.ts +1 -1
  34. package/dist/providers/custom.js +4 -7
  35. package/dist/providers/github.d.ts +1 -1
  36. package/dist/providers/github.js +5 -8
  37. package/dist/providers/google.d.ts +1 -1
  38. package/dist/providers/google.js +5 -8
  39. package/dist/providers/microsoft.d.ts +1 -1
  40. package/dist/providers/microsoft.js +5 -9
  41. package/dist/providers/password.d.ts +18 -37
  42. package/dist/providers/password.js +170 -115
  43. package/dist/providers/redirect.d.ts +1 -0
  44. package/dist/providers/redirect.js +20 -0
  45. package/dist/server/auth.d.ts +6 -7
  46. package/dist/server/auth.js +3 -2
  47. package/dist/server/{ctxCache.js → cache/context.js} +2 -2
  48. package/dist/server/{componentContext.d.ts → component/context.d.ts} +2 -2
  49. package/dist/server/context.js +3 -10
  50. package/dist/server/contract.d.ts +2 -87
  51. package/dist/server/contract.js +1 -1
  52. package/dist/server/cookies.js +25 -1
  53. package/dist/server/core.js +1 -1
  54. package/dist/server/errors.js +24 -1
  55. package/dist/server/{auth-context.d.ts → facade.d.ts} +3 -45
  56. package/dist/server/{auth-context.js → facade.js} +11 -12
  57. package/dist/server/http.d.ts +7 -7
  58. package/dist/server/http.js +47 -7
  59. package/dist/server/{convexIdentity.d.ts → identity/convex.d.ts} +3 -3
  60. package/dist/server/index.d.ts +5 -3
  61. package/dist/server/index.js +3 -2
  62. package/dist/server/mounts.d.ts +171 -18
  63. package/dist/server/mutations/code.js +7 -1
  64. package/dist/server/mutations/{credentialsSignIn.js → credentials/signin.js} +10 -10
  65. package/dist/server/mutations/index.js +1 -1
  66. package/dist/server/mutations/invalidate.js +11 -1
  67. package/dist/server/mutations/oauth.js +25 -27
  68. package/dist/server/mutations/signin.js +6 -0
  69. package/dist/server/mutations/signout.js +5 -0
  70. package/dist/server/mutations/store.js +1 -1
  71. package/dist/server/oauth/factory.js +11 -3
  72. package/dist/server/passkey.js +126 -110
  73. package/dist/server/prefetch.js +8 -1
  74. package/dist/server/redirects.js +11 -3
  75. package/dist/server/refresh.js +6 -1
  76. package/dist/server/runtime.d.ts +68 -37
  77. package/dist/server/runtime.js +318 -36
  78. package/dist/server/services/group.js +4 -0
  79. package/dist/server/sessions.js +1 -0
  80. package/dist/server/signin.js +8 -6
  81. package/dist/server/sso/domain.d.ts +159 -16
  82. package/dist/server/sso/domain.js +1 -1
  83. package/dist/server/sso/http.js +144 -60
  84. package/dist/server/sso/oidc.js +28 -12
  85. package/dist/server/sso/policy.js +30 -14
  86. package/dist/server/sso/provision.js +1 -1
  87. package/dist/server/sso/saml.js +18 -9
  88. package/dist/server/sso/scim.js +12 -4
  89. package/dist/server/sso/shared.js +5 -5
  90. package/dist/server/telemetry.js +3 -0
  91. package/dist/server/tokens.js +10 -2
  92. package/dist/server/totp.js +127 -100
  93. package/dist/server/types.d.ts +224 -151
  94. package/dist/server/url.js +1 -1
  95. package/dist/server/users.js +93 -53
  96. package/dist/server/wellknown.d.ts +75 -0
  97. package/dist/server/wellknown.js +198 -0
  98. package/dist/shared/errors.js +0 -1
  99. package/package.json +36 -4
  100. package/dist/server/oauth/index.js +0 -12
  101. package/dist/server/utils/dispatch.js +0 -36
  102. package/dist/shared/authResults.d.ts +0 -16
  103. /package/dist/server/{componentContext.js → component/context.js} +0 -0
  104. /package/dist/server/{convexIdentity.js → identity/convex.js} +0 -0
@@ -1,76 +1,7 @@
1
1
  import "./types.js";
2
- import "./componentContext.js";
2
+ import "./component/context.js";
3
3
 
4
4
  //#region src/server/contract.d.ts
5
- type GroupConnectionRecord = {
6
- _id: string;
7
- _creationTime: number;
8
- groupId: string;
9
- slug?: string;
10
- name?: string;
11
- protocol: "oidc" | "saml";
12
- status: "draft" | "active" | "disabled";
13
- config?: unknown;
14
- extend?: unknown;
15
- };
16
- type GroupConnectionDomainLookupRecord = {
17
- connection: GroupConnectionRecord | null;
18
- domain: ConnectionDomainRecord | null;
19
- };
20
- type GroupConnectionListResult = {
21
- items: GroupConnectionRecord[];
22
- nextCursor: string | null;
23
- };
24
- type ConnectionDomainRecord = {
25
- _id: string;
26
- _creationTime: number;
27
- connectionId: string;
28
- groupId: string;
29
- domain: string;
30
- isPrimary: boolean;
31
- verifiedAt?: number;
32
- };
33
- type ScimConfigRecord = {
34
- _id: string;
35
- _creationTime: number;
36
- connectionId: string;
37
- groupId: string;
38
- status: string;
39
- basePath: string;
40
- tokenHash: string;
41
- lastRotatedAt?: number;
42
- extend?: unknown;
43
- };
44
- type WebhookEndpointRecord = {
45
- _id: string;
46
- _creationTime: number;
47
- connectionId: string;
48
- groupId: string;
49
- url: string;
50
- status: string;
51
- secretHash: string;
52
- subscriptions: string[];
53
- createdByUserId?: string;
54
- lastSuccessAt?: number;
55
- lastFailureAt?: number;
56
- failureCount: number;
57
- extend?: unknown;
58
- };
59
- type WebhookDeliveryRecord = {
60
- _id: string;
61
- _creationTime: number;
62
- connectionId: string;
63
- endpointId: string;
64
- auditEventId?: string;
65
- eventType: string;
66
- status: string;
67
- attemptCount: number;
68
- nextAttemptAt: number;
69
- lastAttemptAt?: number;
70
- lastResponseStatus?: number;
71
- lastError?: string;
72
- payload: unknown;
73
- };
74
5
  type ScimIdentityRecord = {
75
6
  _id: string;
76
7
  _creationTime: number;
@@ -84,22 +15,6 @@ type ScimIdentityRecord = {
84
15
  raw?: Record<string, unknown>;
85
16
  lastProvisionedAt?: number;
86
17
  };
87
- type AuditEventRecord = {
88
- _id: string;
89
- _creationTime: number;
90
- connectionId?: string;
91
- groupId: string;
92
- eventType: string;
93
- actorType: string;
94
- actorId?: string;
95
- subjectType: string;
96
- subjectId?: string;
97
- status: string;
98
- occurredAt: number;
99
- requestId?: string;
100
- ip?: string;
101
- metadata?: Record<string, unknown>;
102
- };
103
18
  //#endregion
104
- export { AuditEventRecord, ConnectionDomainRecord, GroupConnectionDomainLookupRecord, GroupConnectionListResult, GroupConnectionRecord, ScimConfigRecord, ScimIdentityRecord, WebhookDeliveryRecord, WebhookEndpointRecord };
19
+ export { ScimIdentityRecord };
105
20
  //# sourceMappingURL=contract.d.ts.map
@@ -1,4 +1,4 @@
1
- import { cached, invalidateCtxCache } from "./ctxCache.js";
1
+ import { cached, invalidateCtxCache } from "./cache/context.js";
2
2
 
3
3
  //#region src/server/contract.ts
4
4
  const query = (ctx, ref, args) => ctx.runQuery(ref, args);
@@ -10,6 +10,30 @@ const SHARED_COOKIE_OPTIONS = {
10
10
  path: "/",
11
11
  partitioned: true
12
12
  };
13
+ /** Encode a redirectTo URL into the OAuth state parameter. */
14
+ function encodeOAuthState(state, redirectTo) {
15
+ if (redirectTo === null) return state;
16
+ const json = JSON.stringify({
17
+ s: state,
18
+ r: redirectTo
19
+ });
20
+ return btoa(json).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
21
+ }
22
+ /** Decode an OAuth state parameter, extracting the original state and redirectTo. */
23
+ function decodeOAuthState(encoded) {
24
+ try {
25
+ const padded = encoded.replace(/-/g, "+").replace(/_/g, "/");
26
+ const json = JSON.parse(atob(padded));
27
+ if (typeof json === "object" && json !== null && typeof json.s === "string") return {
28
+ state: json.s,
29
+ redirectTo: typeof json.r === "string" ? json.r : null
30
+ };
31
+ } catch {}
32
+ return {
33
+ state: encoded,
34
+ redirectTo: null
35
+ };
36
+ }
13
37
  const REDIRECT_MAX_AGE = 900;
14
38
  /** @internal */
15
39
  function redirectToParamCookie(providerId, redirectTo) {
@@ -44,5 +68,5 @@ function redirectToParamCookieName(providerId) {
44
68
  }
45
69
 
46
70
  //#endregion
47
- export { SHARED_COOKIE_OPTIONS, redirectToParamCookie, useRedirectToParam };
71
+ export { SHARED_COOKIE_OPTIONS, decodeOAuthState, encodeOAuthState, redirectToParamCookie, useRedirectToParam };
48
72
  //# sourceMappingURL=cookies.js.map
@@ -1,5 +1,5 @@
1
1
  import { getSessionUserId } from "./context.js";
2
- import { cached, ctxCacheHas, invalidateCtxCache } from "./ctxCache.js";
2
+ import { cached, ctxCacheHas, invalidateCtxCache } from "./cache/context.js";
3
3
  import { generateRandomString, sha256 } from "./random.js";
4
4
  import { buildScopeChecker, checkKeyRateLimit, generateApiKey, hashApiKey } from "./keys.js";
5
5
  import { ConvexError } from "convex/values";
@@ -2,6 +2,29 @@ import { AuthFlowError } from "../shared/errors.js";
2
2
  import { ConvexError } from "convex/values";
3
3
 
4
4
  //#region src/server/errors.ts
5
+ /**
6
+ * Internal signal carrying a non-`signedIn` flow result up through a
7
+ * credentials authorize callback.
8
+ *
9
+ * `ctx.auth.provider.signIn` re-enters the canonical sign-in flow so a
10
+ * credentials provider (e.g. password.ts) can hand off to a verify/reset
11
+ * email provider, an OAuth redirect, or a device-code flow. Those handlers
12
+ * resolve to results like `{ kind: "started" }` or `{ kind: "redirect" }`,
13
+ * which the credentials runner has no shape to return — its `authorize`
14
+ * contract is `{ userId, ... } | null`. Throwing a `FlowSignal` lets the
15
+ * runner unwrap it and forward the carried result unchanged to the outer
16
+ * signIn action.
17
+ *
18
+ * @internal
19
+ */
20
+ var FlowSignal = class extends Error {
21
+ result;
22
+ constructor(result) {
23
+ super(`FlowSignal:${result.kind}`);
24
+ this.name = "FlowSignal";
25
+ this.result = result;
26
+ }
27
+ };
5
28
  /** @internal */
6
29
  const toConvexError = (error) => {
7
30
  if (error instanceof ConvexError) return error;
@@ -16,5 +39,5 @@ const toConvexError = (error) => {
16
39
  };
17
40
 
18
41
  //#endregion
19
- export { toConvexError };
42
+ export { FlowSignal, toConvexError };
20
43
  //# sourceMappingURL=errors.js.map
@@ -2,7 +2,7 @@ import { ConvexAuthConfig, Doc } from "./types.js";
2
2
  import { GenericId } from "convex/values";
3
3
  import { UserIdentity } from "convex/server";
4
4
 
5
- //#region src/server/auth-context.d.ts
5
+ //#region src/server/facade.d.ts
6
6
  /**
7
7
  * Config for auth setup. Extends the standard auth config
8
8
  * minus `component` (which is passed as the first constructor argument).
@@ -139,23 +139,6 @@ type AuthContextConfig<TResolve extends Record<string, unknown> = Record<string,
139
139
  * of throwing `NOT_SIGNED_IN`.
140
140
  */
141
141
  optional?: boolean;
142
- /**
143
- * Resolve the active group + membership when building `ctx.auth`.
144
- *
145
- * The full resolver fires three sequential component reads on every
146
- * call: `user.get`, `user.getActiveGroup`, `member.inspect`. For
147
- * handlers that only need `userId` / `user` (e.g. `account:listPasskeys`,
148
- * profile reads, self-service settings), the second and third reads are
149
- * pure overhead.
150
- *
151
- * Set `group: false` to skip them. `ctx.auth.groupId`, `ctx.auth.role`,
152
- * and `ctx.auth.grants` come back as `null` / `[]` without any
153
- * component round-trip. Saves ~10–30ms per auth-gated call on the
154
- * lightweight path.
155
- *
156
- * @defaultValue true
157
- */
158
- group?: boolean;
159
142
  /**
160
143
  * Attach additional derived fields to the auth context after the base auth
161
144
  * context is resolved.
@@ -163,31 +146,6 @@ type AuthContextConfig<TResolve extends Record<string, unknown> = Record<string,
163
146
  * This callback runs only when an authenticated user context is available.
164
147
  */
165
148
  resolve?: (ctx: TCtx, user: UserDoc, auth: AuthContext) => Promise<TResolve> | TResolve;
166
- /**
167
- * Override or wrap the base auth resolution used by {@link createAuth().ctx}.
168
- *
169
- * Return `undefined` to fall back to the built-in resolver,
170
- * `null` for an explicit unauthenticated state, or an
171
- * {@link AuthContext} object to provide a pre-resolved auth state.
172
- * This is useful for tests, proxy auth, impersonation flows, or any
173
- * environment that needs to inject auth without depending on the standard
174
- * Convex auth tables.
175
- *
176
- * @param ctx - The Convex function context.
177
- * @param fallback - The built-in auth resolver used by {@link createAuth().ctx}.
178
- * @returns Resolved auth state, `null`, or `undefined` to use the fallback.
179
- *
180
- * @example
181
- * ```ts
182
- * const authCtx = auth.ctx({
183
- * authResolve: async (ctx, fallback) => {
184
- * const injected = getInjectedAuth(ctx);
185
- * return injected ?? (await fallback());
186
- * },
187
- * });
188
- * ```
189
- */
190
- authResolve?: (ctx: TCtx, fallback: () => Promise<AuthContext | null>) => Promise<AuthContext | null | undefined> | AuthContext | null | undefined;
191
149
  };
192
150
  /**
193
151
  * Extract the resolved `auth` context type from an `auth.ctx()` customization.
@@ -217,5 +175,5 @@ type InferAuth<T extends {
217
175
  input: (...args: never[]) => CustomFunctionInputResult<Record<string, unknown>>;
218
176
  }> = Awaited<ReturnType<T["input"]>>["ctx"]["auth"];
219
177
  //#endregion
220
- export { AuthConfig, AuthContext, AuthContextConfig, AuthContextFactory, AuthContextResolver, InferAuth, OptionalAuthContext, UserDoc };
221
- //# sourceMappingURL=auth-context.d.ts.map
178
+ export { AuthConfig, AuthContext, AuthContextConfig, type AuthContextFactory, type AuthContextResolver, InferAuth, OptionalAuthContext, UserDoc };
179
+ //# sourceMappingURL=facade.d.ts.map
@@ -1,11 +1,9 @@
1
1
  import { createUnauthenticatedAuthContext, getAuthContext } from "./context.js";
2
2
  import { ConvexError } from "convex/values";
3
3
 
4
- //#region src/server/auth-context.ts
5
- async function resolveConfiguredAuthContext(auth, ctx, config) {
6
- const fallback = () => getAuthContext(auth, ctx, { group: config?.group !== false });
7
- const authOverride = config?.authResolve ? await config.authResolve(ctx, fallback) : void 0;
8
- return authOverride === void 0 ? await fallback() : authOverride;
4
+ //#region src/server/facade.ts
5
+ async function resolveConfiguredAuthContext(auth, ctx, _config) {
6
+ return await getAuthContext(auth, ctx);
9
7
  }
10
8
  function createNotSignedInError() {
11
9
  return new ConvexError({
@@ -13,6 +11,7 @@ function createNotSignedInError() {
13
11
  message: "Authentication required."
14
12
  });
15
13
  }
14
+ /** @internal */
16
15
  function assertAuthResolverContext(ctx) {
17
16
  const candidate = ctx;
18
17
  if (candidate === null || typeof candidate !== "object" || candidate.auth === void 0 || candidate.auth === null || typeof candidate.auth !== "object" || typeof candidate.auth.getUserIdentity !== "function" || typeof candidate.runQuery !== "function") throw new TypeError("auth.context(ctx) requires a Convex function context with auth.getUserIdentity() and runQuery().");
@@ -20,8 +19,7 @@ function assertAuthResolverContext(ctx) {
20
19
  /**
21
20
  * Resolve the public auth context for a Convex handler context.
22
21
  *
23
- * This low-level helper underpins `auth.context(...)` and remains exported for
24
- * compatibility with existing consumers using the server entrypoint.
22
+ * This low-level helper underpins `auth.context(...)`.
25
23
  */
26
24
  async function createPublicAuthContext(auth, ctx, config) {
27
25
  const resolved = await resolveConfiguredAuthContext(auth, ctx, config);
@@ -38,8 +36,7 @@ async function createPublicAuthContext(auth, ctx, config) {
38
36
  /**
39
37
  * Create a convex-helpers customization that injects `ctx.auth`.
40
38
  *
41
- * This low-level helper underpins `auth.ctx(...)` and remains exported for
42
- * compatibility with existing consumers using the server entrypoint.
39
+ * This low-level helper underpins `auth.ctx(...)`.
43
40
  */
44
41
  function createAuthContextCustomization(auth, config) {
45
42
  return {
@@ -71,8 +68,10 @@ function createAuthContextCustomization(auth, config) {
71
68
  };
72
69
  }
73
70
  /**
74
- * Build the shared public auth-context facade used by both `createAuth()` and
71
+ * Build the shared public auth context facade used by both `createAuth()` and
75
72
  * `createAuthContext()`.
73
+ *
74
+ * @internal
76
75
  */
77
76
  function createAuthContextFacade(auth) {
78
77
  return {
@@ -85,5 +84,5 @@ function createAuthContextFacade(auth) {
85
84
  }
86
85
 
87
86
  //#endregion
88
- export { createAuthContextCustomization, createAuthContextFacade, createPublicAuthContext };
89
- //# sourceMappingURL=auth-context.js.map
87
+ export { createAuthContextFacade };
88
+ //# sourceMappingURL=facade.js.map
@@ -1,6 +1,6 @@
1
1
  import { HttpKeyContext } from "./types.js";
2
- import { AuthContext, OptionalAuthContext, UserDoc } from "./auth-context.js";
3
- import { ComponentReadCtx } from "./componentContext.js";
2
+ import { AuthContext, OptionalAuthContext, UserDoc } from "./facade.js";
3
+ import { ComponentReadCtx } from "./component/context.js";
4
4
  import "./auth.js";
5
5
  import { GenericActionCtx, GenericDataModel, HttpRouter, UserIdentity } from "convex/server";
6
6
 
@@ -12,7 +12,7 @@ type HttpIdentityCtx = {
12
12
  };
13
13
  type HttpContextCtx = HttpIdentityCtx & ComponentReadCtx;
14
14
  /**
15
- * Auth context returned by `auth.http.context(ctx, request)`.
15
+ * Auth context returned by `auth.request.context(ctx, request)`.
16
16
  *
17
17
  * This resolves raw HTTP authentication in two steps:
18
18
  * 1. session auth from `ctx.auth.getUserIdentity()`
@@ -24,7 +24,7 @@ type HttpContextCtx = HttpIdentityCtx & ComponentReadCtx;
24
24
  *
25
25
  * @example
26
26
  * ```ts
27
- * const authContext = await auth.http.context(ctx, request);
27
+ * const authContext = await auth.request.context(ctx, request);
28
28
  * if (authContext.source === "key") {
29
29
  * console.log(authContext.key.keyId);
30
30
  * }
@@ -39,7 +39,7 @@ type HttpAuthContext = (AuthContext & {
39
39
  });
40
40
  /**
41
41
  * Nullable HTTP auth context returned by
42
- * `auth.http.context(ctx, request, { optional: true })`.
42
+ * `auth.request.context(ctx, request, { optional: true })`.
43
43
  *
44
44
  * This preserves a stable auth-shaped object for raw `httpAction` handlers
45
45
  * that allow anonymous callers.
@@ -49,7 +49,7 @@ type OptionalHttpAuthContext = (OptionalAuthContext & {
49
49
  key: null;
50
50
  }) | HttpAuthContext;
51
51
  /**
52
- * Configuration for {@link createAuth().http.context}.
52
+ * Configuration for {@link createAuth().request.context}.
53
53
  *
54
54
  * This mirrors {@link AuthContextConfig} for raw HTTP handlers and adds support
55
55
  * for enriching mixed session/API-key auth results.
@@ -59,7 +59,7 @@ type OptionalHttpAuthContext = (OptionalAuthContext & {
59
59
  *
60
60
  * @example
61
61
  * ```ts
62
- * const authContext = await auth.http.context(ctx, request, {
62
+ * const authContext = await auth.request.context(ctx, request, {
63
63
  * resolve: async (_ctx, user, authState) => ({
64
64
  * email: user.email,
65
65
  * isMachineRequest: authState.source === "key",
@@ -54,7 +54,7 @@ async function resolveHttpAuthContext(auth, ctx, request) {
54
54
  }
55
55
  /**
56
56
  * @internal
57
- * Create the implementation behind `auth.http.context(...)`.
57
+ * Create the implementation behind `auth.request.context(...)`.
58
58
  */
59
59
  function createHttpContext(auth) {
60
60
  return (async (ctx, request, config) => {
@@ -230,8 +230,9 @@ function parseConnectionRuntimeRoute(pathname, routeBase) {
230
230
  }
231
231
  function addOpenIdRoutes(http, deps) {
232
232
  const cacheControl = "public, max-age=15, stale-while-revalidate=15, stale-if-error=86400";
233
+ const routeBase = deps.routeBase ?? "";
233
234
  http.route({
234
- path: "/.well-known/openid-configuration",
235
+ path: `${routeBase}/.well-known/openid-configuration`,
235
236
  method: "GET",
236
237
  handler: httpActionGeneric(async () => {
237
238
  const issuer = deps.getIssuer();
@@ -248,7 +249,7 @@ function addOpenIdRoutes(http, deps) {
248
249
  })
249
250
  });
250
251
  http.route({
251
- path: "/.well-known/jwks.json",
252
+ path: `${routeBase}/.well-known/jwks.json`,
252
253
  method: "GET",
253
254
  handler: httpActionGeneric(async () => {
254
255
  return new Response(deps.getJwks(), {
@@ -261,20 +262,58 @@ function addOpenIdRoutes(http, deps) {
261
262
  })
262
263
  });
263
264
  }
265
+ /** Register root `/.well-known/*` app discovery routes on an HTTP router. */
266
+ function addWellKnownRoutes(http, deps) {
267
+ for (const route of [
268
+ {
269
+ endpoint: "apple-app-site-association",
270
+ path: "/.well-known/apple-app-site-association"
271
+ },
272
+ {
273
+ endpoint: "assetlinks.json",
274
+ path: "/.well-known/assetlinks.json"
275
+ },
276
+ {
277
+ endpoint: "webauthn",
278
+ path: "/.well-known/webauthn"
279
+ },
280
+ {
281
+ endpoint: "change-password",
282
+ path: "/.well-known/change-password"
283
+ },
284
+ {
285
+ endpoint: "security.txt",
286
+ path: "/.well-known/security.txt"
287
+ }
288
+ ]) http.route({
289
+ path: route.path,
290
+ method: "GET",
291
+ handler: httpActionGeneric(async () => {
292
+ const result = deps.getResponse(route.endpoint);
293
+ if (result === null) return new Response(null, { status: 404 });
294
+ return new Response(result.body, {
295
+ status: result.status,
296
+ headers: result.headers
297
+ });
298
+ })
299
+ });
300
+ }
264
301
  function addAuthRoutes(http, deps) {
302
+ const routeBase = deps.routeBase ?? "/api/auth";
303
+ const routePrefix = routeBase === "" ? "" : routeBase;
265
304
  http.route({
266
- pathPrefix: "/api/auth/signin/",
305
+ pathPrefix: `${routePrefix}/signin/`,
267
306
  method: "GET",
268
307
  handler: httpActionGeneric(deps.handleSignIn)
269
308
  });
270
309
  const callbackHandler = httpActionGeneric(deps.handleCallback);
271
310
  http.route({
272
- pathPrefix: "/api/auth/callback/",
311
+ pathPrefix: `${routePrefix}/callback/`,
273
312
  method: "GET",
274
313
  handler: callbackHandler
275
314
  });
276
315
  http.route({
277
- pathPrefix: "/api/auth/callback/",
316
+ pathPrefix: `${routePrefix}/callback/`,
278
317
  method: "POST",
279
318
  handler: callbackHandler
280
319
  });
@@ -332,6 +371,7 @@ function addSSORoutes(http, deps) {
332
371
  if (route.rest[0] === "acs") return await deps.handleSamlAcs(ctx, request, route);
333
372
  if (route.rest[0] === "slo") return await deps.handleSamlSlo(ctx, request, route);
334
373
  }
374
+ if (route?.protocol === "oidc" && route.rest.length === 1 && route.rest[0] === "callback") return await deps.handleOidcCallback(ctx, request, route);
335
375
  if (route?.protocol === "scim" && route.rest[0] === "v2") return await deps.handleScimRequest(ctx, request);
336
376
  throw new ConvexError({
337
377
  code: "INVALID_PARAMETERS",
@@ -363,5 +403,5 @@ function addSSORoutes(http, deps) {
363
403
  }
364
404
 
365
405
  //#endregion
366
- export { addAuthRoutes, addOpenIdRoutes, addSSORoutes, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies };
406
+ export { addAuthRoutes, addOpenIdRoutes, addSSORoutes, addWellKnownRoutes, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies };
367
407
  //# sourceMappingURL=http.js.map
@@ -1,6 +1,6 @@
1
1
  import { GenericId } from "convex/values";
2
2
 
3
- //#region src/server/convexIdentity.d.ts
3
+ //#region src/server/identity/convex.d.ts
4
4
  declare module "convex/server" {
5
5
  interface UserIdentity {
6
6
  /**
@@ -11,5 +11,5 @@ declare module "convex/server" {
11
11
  */
12
12
  readonly sid?: GenericId<"Session">;
13
13
  }
14
- } //# sourceMappingURL=convexIdentity.d.ts.map
15
- //# sourceMappingURL=convexIdentity.d.ts.map
14
+ } //# sourceMappingURL=convex.d.ts.map
15
+ //# sourceMappingURL=convex.d.ts.map
@@ -1,7 +1,9 @@
1
- import { AuthConfig, AuthContext, AuthContextConfig, InferAuth, OptionalAuthContext, UserDoc } from "./auth-context.js";
1
+ import { AfterCtx, AuthCallbackContext, AuthCallbackProfile, AuthCallbacks, AuthEvent, BeforeCtx, BeforeEvent, BeforeResult } from "./types.js";
2
+ import { AuthConfig, AuthContext, AuthContextConfig, InferAuth, OptionalAuthContext, UserDoc } from "./facade.js";
3
+ import { WellKnownEndpoint, WellKnownOptions, WellKnownResponse, wellKnown } from "./wellknown.js";
2
4
  import { HttpAuthContext, HttpAuthContextConfig, OptionalHttpAuthContext } from "./http.js";
3
5
  import { AuthApi, AuthApiBase, ConvexAuthResult, InferClientApi, createAuth } from "./auth.js";
4
- import "./convexIdentity.js";
6
+ import "./identity/convex.js";
5
7
  import { CreateAuthGroupSsoOptions, GroupSsoAccessHandler, GroupSsoAccessInput, GroupSsoAccessPermissions, GroupSsoPermission, GroupSsoResolvedAccessHandler, createAuthGroupSso, scim, sso } from "./mounts.js";
6
8
  import { AuthCookie, AuthCookieConfig, AuthCookies, RefreshResult, ServerOptions, authCookieNames, parseAuthCookies, serializeAuthCookies, server, shouldProxyAuthAction, structuredAuthCookies } from "./prefetch.js";
7
- export { type AuthApi, type AuthApiBase, type AuthConfig, type AuthContext, type AuthContextConfig, type AuthCookie, type AuthCookieConfig, type AuthCookies, type ConvexAuthResult, type CreateAuthGroupSsoOptions, type GroupSsoAccessHandler, type GroupSsoAccessInput, type GroupSsoAccessPermissions, type GroupSsoPermission, type GroupSsoResolvedAccessHandler, type HttpAuthContext, type HttpAuthContextConfig, type InferAuth, type InferClientApi, type OptionalAuthContext, type OptionalHttpAuthContext, type RefreshResult, type ServerOptions, type UserDoc, authCookieNames, createAuth, createAuthGroupSso, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
9
+ export { type AfterCtx, type AuthApi, type AuthApiBase, type AuthCallbackContext, type AuthCallbackProfile, type AuthCallbacks, type AuthConfig, type AuthContext, type AuthContextConfig, type AuthCookie, type AuthCookieConfig, type AuthCookies, type AuthEvent, type BeforeCtx, type BeforeEvent, type BeforeResult, type ConvexAuthResult, type CreateAuthGroupSsoOptions, type GroupSsoAccessHandler, type GroupSsoAccessInput, type GroupSsoAccessPermissions, type GroupSsoPermission, type GroupSsoResolvedAccessHandler, type HttpAuthContext, type HttpAuthContextConfig, type InferAuth, type InferClientApi, type OptionalAuthContext, type OptionalHttpAuthContext, type RefreshResult, type ServerOptions, type UserDoc, type WellKnownEndpoint, type WellKnownOptions, type WellKnownResponse, authCookieNames, createAuth, createAuthGroupSso, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies, wellKnown };
@@ -1,6 +1,7 @@
1
- import "./convexIdentity.js";
1
+ import "./identity/convex.js";
2
+ import { wellKnown } from "./wellknown.js";
2
3
  import { createAuth } from "./auth.js";
3
4
  import { createAuthGroupSso, scim, sso } from "./mounts.js";
4
5
  import { authCookieNames, parseAuthCookies, serializeAuthCookies, server, shouldProxyAuthAction, structuredAuthCookies } from "./prefetch.js";
5
6
 
6
- export { authCookieNames, createAuth, createAuthGroupSso, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
7
+ export { authCookieNames, createAuth, createAuthGroupSso, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies, wellKnown };