@robelest/convex-auth 0.0.4-preview.31 → 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.
@@ -1,7 +1,7 @@
1
- import * as convex_server4 from "convex/server";
1
+ import * as convex_server0 from "convex/server";
2
2
 
3
3
  //#region src/component/convex.config.d.ts
4
- declare const component: convex_server4.ComponentDefinition<any>;
4
+ declare const component: convex_server0.ComponentDefinition<any>;
5
5
  //#endregion
6
6
  export { component as default };
7
7
  //# sourceMappingURL=convex.config.d.ts.map
@@ -13,8 +13,8 @@ declare const vApiKeyDoc: convex_values440.VObject<{
13
13
  lastAttemptTime: number;
14
14
  } | undefined;
15
15
  metadata?: any;
16
- _creationTime: number;
17
16
  name: string;
17
+ _creationTime: number;
18
18
  revoked: boolean;
19
19
  userId: convex_values440.GenericId<"User">;
20
20
  prefix: string;
@@ -61,7 +61,7 @@ declare const vApiKeyDoc: convex_values440.VObject<{
61
61
  metadata: convex_values440.VAny<any, "optional", string>;
62
62
  _id: convex_values440.VId<convex_values440.GenericId<"ApiKey">, "required">;
63
63
  _creationTime: convex_values440.VFloat64<number, "required">;
64
- }, "required", "_creationTime" | "name" | "revoked" | "lastUsedAt" | "expiresAt" | "userId" | "prefix" | "hashedKey" | "scopes" | "rateLimit" | "rateLimitState" | "createdAt" | "metadata" | "_id" | "rateLimit.maxRequests" | "rateLimit.windowMs" | "rateLimitState.attemptsLeft" | "rateLimitState.lastAttemptTime" | `metadata.${string}`>;
64
+ }, "required", "name" | "_creationTime" | "revoked" | "lastUsedAt" | "expiresAt" | "userId" | "prefix" | "hashedKey" | "scopes" | "rateLimit" | "rateLimitState" | "createdAt" | "metadata" | "_id" | "rateLimit.maxRequests" | "rateLimit.windowMs" | "rateLimitState.attemptsLeft" | "rateLimitState.lastAttemptTime" | `metadata.${string}`>;
65
65
  //#endregion
66
66
  export { vApiKeyDoc };
67
67
  //# sourceMappingURL=model.d.ts.map
@@ -17,9 +17,9 @@ declare const _default: convex_server80.SchemaDefinition<{
17
17
  User: convex_server80.TableDefinition<convex_values50.VObject<{
18
18
  name?: string | undefined;
19
19
  email?: string | undefined;
20
+ image?: string | undefined;
20
21
  phone?: string | undefined;
21
22
  extend?: any;
22
- image?: string | undefined;
23
23
  emailVerificationTime?: number | undefined;
24
24
  phoneVerificationTime?: number | undefined;
25
25
  isAnonymous?: boolean | undefined;
@@ -34,7 +34,7 @@ declare const _default: convex_server80.SchemaDefinition<{
34
34
  isAnonymous: convex_values50.VBoolean<boolean | undefined, "optional">;
35
35
  hasTotp: convex_values50.VBoolean<boolean | undefined, "optional">;
36
36
  extend: convex_values50.VAny<any, "optional", string>;
37
- }, "required", "name" | "email" | "phone" | "extend" | "image" | "emailVerificationTime" | "phoneVerificationTime" | "isAnonymous" | "hasTotp" | `extend.${string}`>, {
37
+ }, "required", "name" | "email" | "image" | "phone" | "extend" | "emailVerificationTime" | "phoneVerificationTime" | "isAnonymous" | "hasTotp" | `extend.${string}`>, {
38
38
  email: ["email", "_creationTime"];
39
39
  email_verified: ["email", "emailVerificationTime", "_creationTime"];
40
40
  phone: ["phone", "_creationTime"];
@@ -60,9 +60,9 @@ declare const _default: convex_server80.SchemaDefinition<{
60
60
  * A user can have multiple accounts linked.
61
61
  */
62
62
  Account: convex_server80.TableDefinition<convex_values50.VObject<{
63
+ emailVerified?: string | undefined;
63
64
  extend?: any;
64
65
  secret?: string | undefined;
65
- emailVerified?: string | undefined;
66
66
  phoneVerified?: string | undefined;
67
67
  userId: convex_values50.GenericId<"User">;
68
68
  provider: string;
@@ -75,7 +75,7 @@ declare const _default: convex_server80.SchemaDefinition<{
75
75
  emailVerified: convex_values50.VString<string | undefined, "optional">;
76
76
  phoneVerified: convex_values50.VString<string | undefined, "optional">;
77
77
  extend: convex_values50.VAny<any, "optional", string>;
78
- }, "required", "userId" | "extend" | `extend.${string}` | "provider" | "providerAccountId" | "secret" | "emailVerified" | "phoneVerified">, {
78
+ }, "required", "emailVerified" | "userId" | "extend" | `extend.${string}` | "provider" | "providerAccountId" | "secret" | "phoneVerified">, {
79
79
  user_id_provider: ["userId", "provider", "_creationTime"];
80
80
  provider_account_id: ["provider", "providerAccountId", "_creationTime"];
81
81
  }, {}, {}>;
@@ -121,7 +121,7 @@ declare const _default: convex_server80.SchemaDefinition<{
121
121
  verifier: convex_values50.VString<string | undefined, "optional">;
122
122
  emailVerified: convex_values50.VString<string | undefined, "optional">;
123
123
  phoneVerified: convex_values50.VString<string | undefined, "optional">;
124
- }, "required", "expirationTime" | "provider" | "emailVerified" | "phoneVerified" | "accountId" | "code" | "verifier">, {
124
+ }, "required", "emailVerified" | "expirationTime" | "provider" | "phoneVerified" | "accountId" | "code" | "verifier">, {
125
125
  account_id: ["accountId", "_creationTime"];
126
126
  code: ["code", "_creationTime"];
127
127
  }, {}, {}>;
@@ -262,26 +262,37 @@ function addOpenIdRoutes(http, deps) {
262
262
  })
263
263
  });
264
264
  }
265
- /**
266
- * Register `/.well-known/webauthn` on the Convex backend.
267
- *
268
- * Useful when the WebAuthn RP ID matches the `CONVEX_SITE_URL` host. Apps
269
- * whose RP ID is the frontend domain should host this endpoint themselves
270
- * (see {@link generateWebAuthnConfig} from `@robelest/convex-auth/server`).
271
- *
272
- * Returns 404 when no alternative origins are configured (no
273
- * `WEBAUTHN_ALT_ORIGINS` and no `SECONDARY_URL`).
274
- */
275
- function addWebAuthnRoute(http, deps) {
276
- const routeBase = deps.routeBase ?? "";
277
- http.route({
278
- path: `${routeBase}/.well-known/webauthn`,
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,
279
290
  method: "GET",
280
291
  handler: httpActionGeneric(async () => {
281
- const result = deps.getResponse();
292
+ const result = deps.getResponse(route.endpoint);
282
293
  if (result === null) return new Response(null, { status: 404 });
283
294
  return new Response(result.body, {
284
- status: 200,
295
+ status: result.status,
285
296
  headers: result.headers
286
297
  });
287
298
  })
@@ -392,5 +403,5 @@ function addSSORoutes(http, deps) {
392
403
  }
393
404
 
394
405
  //#endregion
395
- export { addAuthRoutes, addOpenIdRoutes, addSSORoutes, addWebAuthnRoute, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies };
406
+ export { addAuthRoutes, addOpenIdRoutes, addSSORoutes, addWellKnownRoutes, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies };
396
407
  //# sourceMappingURL=http.js.map
@@ -1,9 +1,9 @@
1
1
  import { AfterCtx, AuthCallbackContext, AuthCallbackProfile, AuthCallbacks, AuthEvent, BeforeCtx, BeforeEvent, BeforeResult } from "./types.js";
2
2
  import { AuthConfig, AuthContext, AuthContextConfig, InferAuth, OptionalAuthContext, UserDoc } from "./facade.js";
3
+ import { WellKnownEndpoint, WellKnownOptions, WellKnownResponse, wellKnown } from "./wellknown.js";
3
4
  import { HttpAuthContext, HttpAuthContextConfig, OptionalHttpAuthContext } from "./http.js";
4
5
  import { AuthApi, AuthApiBase, ConvexAuthResult, InferClientApi, createAuth } from "./auth.js";
5
6
  import "./identity/convex.js";
6
7
  import { CreateAuthGroupSsoOptions, GroupSsoAccessHandler, GroupSsoAccessInput, GroupSsoAccessPermissions, GroupSsoPermission, GroupSsoResolvedAccessHandler, createAuthGroupSso, scim, sso } from "./mounts.js";
7
8
  import { AuthCookie, AuthCookieConfig, AuthCookies, RefreshResult, ServerOptions, authCookieNames, parseAuthCookies, serializeAuthCookies, server, shouldProxyAuthAction, structuredAuthCookies } from "./prefetch.js";
8
- import { WellKnownResponse, generateAppleAppSiteAssociation, generateAssetLinks, generateChangePasswordRedirect, generateSecurityTxt, generateWebAuthnConfig } from "./wellknown.js";
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 WellKnownResponse, authCookieNames, createAuth, createAuthGroupSso, generateAppleAppSiteAssociation, generateAssetLinks, generateChangePasswordRedirect, generateSecurityTxt, generateWebAuthnConfig, 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,7 +1,7 @@
1
1
  import "./identity/convex.js";
2
- import { generateAppleAppSiteAssociation, generateAssetLinks, generateChangePasswordRedirect, generateSecurityTxt, generateWebAuthnConfig } from "./wellknown.js";
2
+ import { wellKnown } from "./wellknown.js";
3
3
  import { createAuth } from "./auth.js";
4
4
  import { createAuthGroupSso, scim, sso } from "./mounts.js";
5
5
  import { authCookieNames, parseAuthCookies, serializeAuthCookies, server, shouldProxyAuthAction, structuredAuthCookies } from "./prefetch.js";
6
6
 
7
- export { authCookieNames, createAuth, createAuthGroupSso, generateAppleAppSiteAssociation, generateAssetLinks, generateChangePasswordRedirect, generateSecurityTxt, generateWebAuthnConfig, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies };
7
+ export { authCookieNames, createAuth, createAuthGroupSso, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies, wellKnown };
@@ -443,8 +443,8 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
443
443
  mapping?: {
444
444
  name?: string | undefined;
445
445
  email?: string | undefined;
446
- image?: string | undefined;
447
446
  emailVerified?: string | undefined;
447
+ image?: string | undefined;
448
448
  groups?: string | undefined;
449
449
  roles?: string | undefined;
450
450
  subject?: string | undefined;
@@ -772,7 +772,6 @@ declare function sso<TAuthorization extends AuthAuthorizationConfig | undefined
772
772
  declare function scim<TAuthorization extends AuthAuthorizationConfig | undefined = undefined, TRequirement = unknown>(auth: Pick<AuthApi<TAuthorization>, "context" | "group">, options?: CreateAuthGroupSsoOptions<TRequirement>): {
773
773
  admin: {
774
774
  configure: convex_server6.RegisteredMutation<"public", {
775
- status?: "draft" | "active" | "disabled" | undefined;
776
775
  profile?: {
777
776
  mapping?: {
778
777
  name?: string | undefined;
@@ -788,6 +787,7 @@ declare function scim<TAuthorization extends AuthAuthorizationConfig | undefined
788
787
  } | undefined;
789
788
  extraFields?: Record<string, string> | undefined;
790
789
  } | undefined;
790
+ status?: "draft" | "active" | "disabled" | undefined;
791
791
  security?: {
792
792
  maxRequestSize?: number | undefined;
793
793
  } | undefined;
@@ -1163,8 +1163,8 @@ declare function createAuthGroupSso<TAuthorization extends AuthAuthorizationConf
1163
1163
  mapping?: {
1164
1164
  name?: string | undefined;
1165
1165
  email?: string | undefined;
1166
- image?: string | undefined;
1167
1166
  emailVerified?: string | undefined;
1167
+ image?: string | undefined;
1168
1168
  groups?: string | undefined;
1169
1169
  roles?: string | undefined;
1170
1170
  subject?: string | undefined;
@@ -1421,7 +1421,6 @@ declare function createAuthGroupSso<TAuthorization extends AuthAuthorizationConf
1421
1421
  endpointId: string;
1422
1422
  }>>;
1423
1423
  configureScim: convex_server6.RegisteredMutation<"public", {
1424
- status?: "draft" | "active" | "disabled" | undefined;
1425
1424
  profile?: {
1426
1425
  mapping?: {
1427
1426
  name?: string | undefined;
@@ -1437,6 +1436,7 @@ declare function createAuthGroupSso<TAuthorization extends AuthAuthorizationConf
1437
1436
  } | undefined;
1438
1437
  extraFields?: Record<string, string> | undefined;
1439
1438
  } | undefined;
1439
+ status?: "draft" | "active" | "disabled" | undefined;
1440
1440
  security?: {
1441
1441
  maxRequestSize?: number | undefined;
1442
1442
  } | undefined;
@@ -201,7 +201,13 @@ declare function Auth(config_: ConvexAuthConfig): {
201
201
  ancestors: (ctx: ComponentReadCtx, opts: {
202
202
  groupId: string;
203
203
  maxDepth?: number;
204
- includeSelf?: boolean;
204
+ includeSelf /**
205
+ * Action called by the client to invalidate the current session.
206
+ */?
207
+ /**
208
+ * Action called by the client to invalidate the current session.
209
+ */
210
+ : boolean;
205
211
  }) => Promise<{
206
212
  ancestors: Array<Exclude<Doc<"Group"> | null, null>>;
207
213
  cycleDetected: boolean;
@@ -413,10 +419,13 @@ declare function Auth(config_: ConvexAuthConfig): {
413
419
  *
414
420
  * The following routes are handled always:
415
421
  *
416
- * - `/.well-known/openid-configuration`
417
- * - `/.well-known/jwks.json`
418
- * - `/.well-known/webauthn` (returns 404 unless `WEBAUTHN_ALT_ORIGINS` or
419
- * `SECONDARY_URL` is set)
422
+ * - `/.well-known/apple-app-site-association`
423
+ * - `/.well-known/assetlinks.json`
424
+ * - `/.well-known/webauthn`
425
+ * - `/.well-known/change-password`
426
+ * - `/.well-known/security.txt`
427
+ * - `<prefix>/.well-known/openid-configuration`
428
+ * - `<prefix>/.well-known/jwks.json`
420
429
  *
421
430
  * The following routes are handled if OAuth is configured:
422
431
  *
@@ -620,11 +629,11 @@ declare function Auth(config_: ConvexAuthConfig): {
620
629
  sessionIndex?: string | undefined;
621
630
  } | undefined;
622
631
  } | undefined;
632
+ profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
623
633
  type: "userOAuth";
624
634
  provider: string;
625
635
  providerAccountId: string;
626
636
  signature: string;
627
- profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
628
637
  } | {
629
638
  email?: string | undefined;
630
639
  phone?: string | undefined;
@@ -637,9 +646,9 @@ declare function Auth(config_: ConvexAuthConfig): {
637
646
  } | {
638
647
  shouldLinkViaEmail?: boolean | undefined;
639
648
  shouldLinkViaPhone?: boolean | undefined;
649
+ profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
640
650
  type: "createAccountFromCredentials";
641
651
  provider: string;
642
- profile: Record<string, string | number | boolean | (string | number | boolean | null)[] | Record<string, string | number | boolean | (string | number | boolean | null)[] | null> | null>;
643
652
  account: {
644
653
  secret?: string | undefined;
645
654
  id: string;
@@ -16,8 +16,8 @@ import { storeArgs, storeImpl } from "./mutations/store.js";
16
16
  import { siteUrlsFromEnv } from "./url.js";
17
17
  import { decodeOAuthState, encodeOAuthState } from "./cookies.js";
18
18
  import { FlowSignal } from "./errors.js";
19
- import { addAuthRoutes, addOpenIdRoutes, addWebAuthnRoute, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies } from "./http.js";
20
- import { generateWebAuthnConfig } from "./wellknown.js";
19
+ import { addAuthRoutes, addOpenIdRoutes, addWellKnownRoutes, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies } from "./http.js";
20
+ import { wellKnown } from "./wellknown.js";
21
21
  import { createOAuthAuthorizationURL, handleOAuthCallback } from "./oauth/runtime.js";
22
22
  import { redirectAbsoluteUrl, setURLSearchParam } from "./redirects.js";
23
23
  import { encryptSecret } from "./secret.js";
@@ -174,13 +174,7 @@ function Auth(config_) {
174
174
  getIssuer: () => authSiteUrl,
175
175
  getJwks: () => requireEnv("JWKS")
176
176
  });
177
- addWebAuthnRoute(protocolHttp, { getResponse: () => {
178
- const r = generateWebAuthnConfig();
179
- return r === null ? null : {
180
- body: r.body,
181
- headers: r.headers
182
- };
183
- } });
177
+ addWellKnownRoutes(protocolHttp, { getResponse: (endpoint) => wellKnown(endpoint) });
184
178
  addGroupHttpRuntime({
185
179
  http: protocolHttp,
186
180
  hasSSO,
@@ -287,16 +281,7 @@ function Auth(config_) {
287
281
  getIssuer: authSiteUrl,
288
282
  getJwks: () => requireEnv("JWKS")
289
283
  });
290
- addWebAuthnRoute(http$1, {
291
- routeBase: routePrefix,
292
- getResponse: () => {
293
- const r = generateWebAuthnConfig();
294
- return r === null ? null : {
295
- body: r.body,
296
- headers: r.headers
297
- };
298
- }
299
- });
284
+ addWellKnownRoutes(http$1, { getResponse: (endpoint) => wellKnown(endpoint) });
300
285
  addGroupHttpRuntime({
301
286
  http: http$1,
302
287
  hasSSO,
@@ -1,130 +1,75 @@
1
1
  //#region src/server/wellknown.d.ts
2
2
  /**
3
- * Content generators for cross-platform `.well-known` endpoints.
3
+ * Content generator for cross-platform `.well-known` endpoints.
4
4
  *
5
- * These helpers produce the exact response shape expected by Apple, Google,
6
- * browsers, and password managers. Each helper reads convention env vars but
7
- * accepts explicit overrides; if neither is set, it returns `null` so the
8
- * caller can serve a 404.
5
+ * The helper produces the exact response shape expected by Apple, Google,
6
+ * browsers, and password managers. It reads convention env vars but accepts
7
+ * explicit overrides; if an endpoint is not configured, it returns `null` so
8
+ * the caller can serve a 404.
9
9
  *
10
- * The library serves `/.well-known/openid-configuration` and `/.well-known/jwks.json`
11
- * from the Convex backend (`CONVEX_SITE_URL`). The endpoints in this module
12
- * must be served from the WebAuthn RP ID host (typically `SITE_URL` — the
13
- * frontend domain), so they're shipped as framework-agnostic generators that
14
- * apps wire into their own route handlers (SvelteKit `+server.ts`, Next.js
15
- * route handlers, Cloudflare Workers, Express, etc.). One exception:
16
- * `generateWebAuthnConfig` can also be served from Convex via
17
- * {@link addWebAuthnRoute} when RP ID equals `CONVEX_SITE_URL` host.
10
+ * These endpoints must be reachable from the public app/RP ID origin at root
11
+ * `/.well-known/*`. `auth.http()` serves them from Convex; apps using a
12
+ * separate frontend domain should route those root paths to Convex or adapt
13
+ * this helper in their framework route handlers.
18
14
  *
19
15
  * @module
20
16
  */
21
- /** Uniform shape returned by every generator. Adapt to any framework. */
17
+ /** Uniform shape returned by the well-known helper. Adapt to any framework. */
22
18
  type WellKnownResponse = {
23
19
  status: number;
24
20
  headers: Record<string, string>;
25
21
  body: string;
26
22
  };
23
+ type WellKnownEndpoint = "apple-app-site-association" | "assetlinks.json" | "webauthn" | "security.txt" | "change-password";
24
+ type WellKnownOptions = {
25
+ /** Options for `/.well-known/apple-app-site-association`. */appleAppSiteAssociation?: {
26
+ /** Override `IOS_APP_IDS`; e.g., `["ABC123DEF.com.example.app"]`. */appIds?: string[]; /** Override `IOS_APPLINK_PATHS`; default `["/auth/*", "/callback/*"]`. */
27
+ applinkPaths?: string[];
28
+ }; /** Options for `/.well-known/assetlinks.json`. */
29
+ assetLinks?: {
30
+ apps?: Array<{
31
+ packageName: string;
32
+ sha256Fingerprints: string[];
33
+ }>;
34
+ }; /** Options for `/.well-known/webauthn`. */
35
+ webAuthn?: {
36
+ /** Override `WEBAUTHN_ALT_ORIGINS`. */origins?: string[];
37
+ }; /** Options for `/.well-known/security.txt`. */
38
+ securityTxt?: {
39
+ /** Override `SECURITY_CONTACT`. Should be a `mailto:` or `https:` URI. */contact?: string; /** Override `SECURITY_TXT_EXPIRES_DAYS`. Default 365 days from now. */
40
+ expiresInDays?: number; /** RFC 5646 language tags, e.g., `["en"]`. */
41
+ preferredLanguages?: string[]; /** Optional canonical URL of the security.txt file (for signed copies). */
42
+ canonical?: string; /** Optional public key URL for encrypted reports. */
43
+ encryption?: string; /** Optional acknowledgments URL. */
44
+ acknowledgments?: string; /** Optional policy URL. */
45
+ policy?: string; /** Optional hiring URL. */
46
+ hiring?: string;
47
+ }; /** Options for `/.well-known/change-password`. */
48
+ changePassword?: {
49
+ /** Override `CHANGE_PASSWORD_URL`. */targetUrl?: string;
50
+ };
51
+ };
27
52
  /**
28
- * Generate `/.well-known/apple-app-site-association` (AASA) content.
29
- *
30
- * Required for native iOS passkeys (`webcredentials`), Universal Links
31
- * (`applinks`), and Sign in with Apple. Apple's CDN fetches this file from
32
- * the WebAuthn RP ID host on app install/update; the file MUST be served as
33
- * `application/json` at the exact path with no `.json` extension and no
34
- * redirects.
53
+ * Generate a standard `/.well-known/*` response.
35
54
  *
36
- * Reads {@link IOS_APP_IDS} (comma-separated `TEAMID.bundle.id` entries) and
37
- * {@link IOS_APPLINK_PATHS} (comma-separated path patterns, default `/auth/*,/callback/*`).
55
+ * @param endpoint The well-known endpoint name, without the `/.well-known/` prefix.
56
+ * @param options Optional explicit configuration. When omitted, the helper reads
57
+ * convention environment variables for the selected endpoint.
58
+ * @returns A framework-neutral response descriptor, or `null` when the endpoint
59
+ * is not configured.
38
60
  *
39
- * @example Hosting in SvelteKit
61
+ * @example
40
62
  * ```ts
41
- * // src/routes/.well-known/apple-app-site-association/+server.ts
42
- * import { generateAppleAppSiteAssociation } from "@robelest/convex-auth/server";
63
+ * import { wellKnown } from "@robelest/convex-auth/server";
64
+ *
43
65
  * export const GET = () => {
44
- * const r = generateAppleAppSiteAssociation();
45
- * if (!r) return new Response(null, { status: 404 });
66
+ * const r = wellKnown("assetlinks.json");
67
+ * if (r === null) return new Response(null, { status: 404 });
46
68
  * return new Response(r.body, { status: r.status, headers: r.headers });
47
69
  * };
48
70
  * ```
49
71
  */
50
- declare function generateAppleAppSiteAssociation(opts?: {
51
- /** Override `IOS_APP_IDS`; e.g., `["ABC123DEF.com.example.app"]`. */appIds?: string[]; /** Override `IOS_APPLINK_PATHS`; default `["/auth/*", "/callback/*"]`. */
52
- applinkPaths?: string[];
53
- }): WellKnownResponse | null;
54
- /**
55
- * Generate `/.well-known/assetlinks.json` content for Android.
56
- *
57
- * Required for Android Credential Manager to surface passkeys for the app,
58
- * and for App Link verification (`autoVerify="true"` intent filters). Google
59
- * fetches this file from the WebAuthn RP ID host.
60
- *
61
- * Reads {@link ANDROID_APP_LINKS} in the format
62
- * `package1:FP1:FP2;package2:FP1:FP2` where each fingerprint is a colon-
63
- * separated SHA-256 hex string. Use `;` between apps and `:` to separate
64
- * package name from fingerprints (and fingerprints share the standard
65
- * `AA:BB:CC:...` colon format — split on `:`, the first segment is the
66
- * package, the rest is the fingerprint reassembled).
67
- *
68
- * For programmatic config, prefer the `apps` option which avoids parsing.
69
- *
70
- * @example Direct config
71
- * ```ts
72
- * generateAssetLinks({
73
- * apps: [{
74
- * packageName: "com.example.app",
75
- * sha256Fingerprints: ["AA:BB:CC:..."],
76
- * }],
77
- * });
78
- * ```
79
- */
80
- declare function generateAssetLinks(opts?: {
81
- apps?: Array<{
82
- packageName: string;
83
- sha256Fingerprints: string[];
84
- }>;
85
- }): WellKnownResponse | null;
86
- /**
87
- * Generate `/.well-known/webauthn` content (W3C WebAuthn Level 3).
88
- *
89
- * Declares alternative origins permitted to use this RP ID. Lets a passkey
90
- * registered at `app.example.com` work on `staging.example.com`, browser
91
- * extensions, or wrapped native webviews.
92
- *
93
- * Reads {@link WEBAUTHN_ALT_ORIGINS}; falls back to `SECONDARY_URL` parsed
94
- * from the existing site URL convention.
95
- */
96
- declare function generateWebAuthnConfig(opts?: {
97
- /** Override `WEBAUTHN_ALT_ORIGINS`. */origins?: string[];
98
- }): WellKnownResponse | null;
99
- /**
100
- * Generate `/.well-known/security.txt` content (RFC 9116).
101
- *
102
- * Plain-text contact info for security researchers. Reads {@link SECURITY_CONTACT}
103
- * (e.g., `mailto:security@example.com` or `https://example.com/security`) and
104
- * optional {@link SECURITY_TXT_EXPIRES_DAYS} (default 365).
105
- */
106
- declare function generateSecurityTxt(opts?: {
107
- /** Override `SECURITY_CONTACT`. Should be a `mailto:` or `https:` URI. */contact?: string; /** Override `SECURITY_TXT_EXPIRES_DAYS`. Default 365 days from now. */
108
- expiresInDays?: number; /** RFC 5646 language tags, e.g., `["en"]`. */
109
- preferredLanguages?: string[]; /** Optional canonical URL of the security.txt file (for signed copies). */
110
- canonical?: string; /** Optional public key URL for encrypted reports. */
111
- encryption?: string; /** Optional acknowledgments URL. */
112
- acknowledgments?: string; /** Optional policy URL. */
113
- policy?: string; /** Optional hiring URL. */
114
- hiring?: string;
115
- }): WellKnownResponse | null;
116
- /**
117
- * Generate a 302 redirect for `/.well-known/change-password` (RFC 8615).
118
- *
119
- * Password managers (1Password, iCloud Keychain, Bitwarden, Chrome) deep-link
120
- * here when the user picks "Change password". The route should redirect to
121
- * the actual change-password UI in your app.
122
- *
123
- * Reads {@link CHANGE_PASSWORD_URL}.
124
- */
125
- declare function generateChangePasswordRedirect(opts?: {
126
- /** Override `CHANGE_PASSWORD_URL`. */targetUrl?: string;
127
- }): WellKnownResponse | null;
72
+ declare function wellKnown(endpoint: WellKnownEndpoint, options?: WellKnownOptions): WellKnownResponse | null;
128
73
  //#endregion
129
- export { WellKnownResponse, generateAppleAppSiteAssociation, generateAssetLinks, generateChangePasswordRedirect, generateSecurityTxt, generateWebAuthnConfig };
74
+ export { WellKnownEndpoint, WellKnownOptions, WellKnownResponse, wellKnown };
130
75
  //# sourceMappingURL=wellknown.d.ts.map
@@ -3,21 +3,17 @@ import { normalizeUrl } from "./url.js";
3
3
 
4
4
  //#region src/server/wellknown.ts
5
5
  /**
6
- * Content generators for cross-platform `.well-known` endpoints.
6
+ * Content generator for cross-platform `.well-known` endpoints.
7
7
  *
8
- * These helpers produce the exact response shape expected by Apple, Google,
9
- * browsers, and password managers. Each helper reads convention env vars but
10
- * accepts explicit overrides; if neither is set, it returns `null` so the
11
- * caller can serve a 404.
8
+ * The helper produces the exact response shape expected by Apple, Google,
9
+ * browsers, and password managers. It reads convention env vars but accepts
10
+ * explicit overrides; if an endpoint is not configured, it returns `null` so
11
+ * the caller can serve a 404.
12
12
  *
13
- * The library serves `/.well-known/openid-configuration` and `/.well-known/jwks.json`
14
- * from the Convex backend (`CONVEX_SITE_URL`). The endpoints in this module
15
- * must be served from the WebAuthn RP ID host (typically `SITE_URL` — the
16
- * frontend domain), so they're shipped as framework-agnostic generators that
17
- * apps wire into their own route handlers (SvelteKit `+server.ts`, Next.js
18
- * route handlers, Cloudflare Workers, Express, etc.). One exception:
19
- * `generateWebAuthnConfig` can also be served from Convex via
20
- * {@link addWebAuthnRoute} when RP ID equals `CONVEX_SITE_URL` host.
13
+ * These endpoints must be reachable from the public app/RP ID origin at root
14
+ * `/.well-known/*`. `auth.http()` serves them from Convex; apps using a
15
+ * separate frontend domain should route those root paths to Convex or adapt
16
+ * this helper in their framework route handlers.
21
17
  *
22
18
  * @module
23
19
  */
@@ -36,30 +32,7 @@ function ok(body, contentType) {
36
32
  body
37
33
  };
38
34
  }
39
- /**
40
- * Generate `/.well-known/apple-app-site-association` (AASA) content.
41
- *
42
- * Required for native iOS passkeys (`webcredentials`), Universal Links
43
- * (`applinks`), and Sign in with Apple. Apple's CDN fetches this file from
44
- * the WebAuthn RP ID host on app install/update; the file MUST be served as
45
- * `application/json` at the exact path with no `.json` extension and no
46
- * redirects.
47
- *
48
- * Reads {@link IOS_APP_IDS} (comma-separated `TEAMID.bundle.id` entries) and
49
- * {@link IOS_APPLINK_PATHS} (comma-separated path patterns, default `/auth/*,/callback/*`).
50
- *
51
- * @example Hosting in SvelteKit
52
- * ```ts
53
- * // src/routes/.well-known/apple-app-site-association/+server.ts
54
- * import { generateAppleAppSiteAssociation } from "@robelest/convex-auth/server";
55
- * export const GET = () => {
56
- * const r = generateAppleAppSiteAssociation();
57
- * if (!r) return new Response(null, { status: 404 });
58
- * return new Response(r.body, { status: r.status, headers: r.headers });
59
- * };
60
- * ```
61
- */
62
- function generateAppleAppSiteAssociation(opts) {
35
+ function appleAppSiteAssociationResponse(opts) {
63
36
  const appIds = opts?.appIds ?? parseList(envOptionalString("IOS_APP_IDS"));
64
37
  if (appIds.length === 0) return null;
65
38
  const applinkPaths = opts?.applinkPaths ?? parseList(envOptionalString("IOS_APPLINK_PATHS"));
@@ -90,15 +63,15 @@ function generateAppleAppSiteAssociation(opts) {
90
63
  *
91
64
  * @example Direct config
92
65
  * ```ts
93
- * generateAssetLinks({
66
+ * wellKnown("assetlinks.json", { assetLinks: {
94
67
  * apps: [{
95
68
  * packageName: "com.example.app",
96
69
  * sha256Fingerprints: ["AA:BB:CC:..."],
97
70
  * }],
98
- * });
71
+ * }});
99
72
  * ```
100
73
  */
101
- function generateAssetLinks(opts) {
74
+ function assetLinksResponse(opts) {
102
75
  const apps = opts?.apps ?? parseAndroidAppLinksEnv(envOptionalString("ANDROID_APP_LINKS"));
103
76
  if (apps.length === 0) return null;
104
77
  return ok(JSON.stringify(apps.map((app) => ({
@@ -138,7 +111,7 @@ function parseAndroidAppLinksEnv(raw) {
138
111
  * Reads {@link WEBAUTHN_ALT_ORIGINS}; falls back to `SECONDARY_URL` parsed
139
112
  * from the existing site URL convention.
140
113
  */
141
- function generateWebAuthnConfig(opts) {
114
+ function webAuthnResponse(opts) {
142
115
  const explicit = opts?.origins;
143
116
  const fromEnv = parseList(envOptionalString("WEBAUTHN_ALT_ORIGINS"));
144
117
  const fromSecondary = parseList(envOptionalString("SECONDARY_URL")).map(normalizeUrl);
@@ -153,7 +126,7 @@ function generateWebAuthnConfig(opts) {
153
126
  * (e.g., `mailto:security@example.com` or `https://example.com/security`) and
154
127
  * optional {@link SECURITY_TXT_EXPIRES_DAYS} (default 365).
155
128
  */
156
- function generateSecurityTxt(opts) {
129
+ function securityTxtResponse(opts) {
157
130
  const contact = opts?.contact ?? envOptionalString("SECURITY_CONTACT");
158
131
  if (contact === void 0 || contact.length === 0) return null;
159
132
  const days = opts?.expiresInDays ?? envOptionalNumber("SECURITY_TXT_EXPIRES_DAYS") ?? 365;
@@ -177,7 +150,7 @@ function generateSecurityTxt(opts) {
177
150
  *
178
151
  * Reads {@link CHANGE_PASSWORD_URL}.
179
152
  */
180
- function generateChangePasswordRedirect(opts) {
153
+ function changePasswordResponse(opts) {
181
154
  const target = opts?.targetUrl ?? envOptionalString("CHANGE_PASSWORD_URL");
182
155
  if (target === void 0 || target.length === 0) return null;
183
156
  return {
@@ -189,7 +162,37 @@ function generateChangePasswordRedirect(opts) {
189
162
  body: ""
190
163
  };
191
164
  }
165
+ /**
166
+ * Generate a standard `/.well-known/*` response.
167
+ *
168
+ * @param endpoint The well-known endpoint name, without the `/.well-known/` prefix.
169
+ * @param options Optional explicit configuration. When omitted, the helper reads
170
+ * convention environment variables for the selected endpoint.
171
+ * @returns A framework-neutral response descriptor, or `null` when the endpoint
172
+ * is not configured.
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * import { wellKnown } from "@robelest/convex-auth/server";
177
+ *
178
+ * export const GET = () => {
179
+ * const r = wellKnown("assetlinks.json");
180
+ * if (r === null) return new Response(null, { status: 404 });
181
+ * return new Response(r.body, { status: r.status, headers: r.headers });
182
+ * };
183
+ * ```
184
+ */
185
+ function wellKnown(endpoint, options) {
186
+ switch (endpoint) {
187
+ case "apple-app-site-association": return appleAppSiteAssociationResponse(options?.appleAppSiteAssociation);
188
+ case "assetlinks.json": return assetLinksResponse(options?.assetLinks);
189
+ case "webauthn": return webAuthnResponse(options?.webAuthn);
190
+ case "security.txt": return securityTxtResponse(options?.securityTxt);
191
+ case "change-password": return changePasswordResponse(options?.changePassword);
192
+ }
193
+ return endpoint;
194
+ }
192
195
 
193
196
  //#endregion
194
- export { generateAppleAppSiteAssociation, generateAssetLinks, generateChangePasswordRedirect, generateSecurityTxt, generateWebAuthnConfig };
197
+ export { wellKnown };
195
198
  //# sourceMappingURL=wellknown.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robelest/convex-auth",
3
- "version": "0.0.4-preview.31",
3
+ "version": "0.0.4-preview.32",
4
4
  "description": "Authentication for Convex",
5
5
  "keywords": [
6
6
  "auth",