@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.
- package/dist/component/convex.config.d.ts +2 -2
- package/dist/component/model.d.ts +2 -2
- package/dist/component/schema.d.ts +5 -5
- package/dist/server/http.js +28 -17
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +2 -2
- package/dist/server/mounts.d.ts +4 -4
- package/dist/server/runtime.d.ts +16 -7
- package/dist/server/runtime.js +4 -19
- package/dist/server/wellknown.d.ts +52 -107
- package/dist/server/wellknown.js +47 -44
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as convex_server0 from "convex/server";
|
|
2
2
|
|
|
3
3
|
//#region src/component/convex.config.d.ts
|
|
4
|
-
declare const component:
|
|
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", "
|
|
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" | "
|
|
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" | "
|
|
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", "
|
|
124
|
+
}, "required", "emailVerified" | "expirationTime" | "provider" | "phoneVerified" | "accountId" | "code" | "verifier">, {
|
|
125
125
|
account_id: ["accountId", "_creationTime"];
|
|
126
126
|
code: ["code", "_creationTime"];
|
|
127
127
|
}, {}, {}>;
|
package/dist/server/http.js
CHANGED
|
@@ -262,26 +262,37 @@ function addOpenIdRoutes(http, deps) {
|
|
|
262
262
|
})
|
|
263
263
|
});
|
|
264
264
|
}
|
|
265
|
-
/**
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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:
|
|
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,
|
|
406
|
+
export { addAuthRoutes, addOpenIdRoutes, addSSORoutes, addWellKnownRoutes, convertErrorsToResponse, createHttpAction, createHttpContext, createHttpRoute, getCookies };
|
|
396
407
|
//# sourceMappingURL=http.js.map
|
package/dist/server/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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 };
|
package/dist/server/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "./identity/convex.js";
|
|
2
|
-
import {
|
|
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,
|
|
7
|
+
export { authCookieNames, createAuth, createAuthGroupSso, parseAuthCookies, scim, serializeAuthCookies, server, shouldProxyAuthAction, sso, structuredAuthCookies, wellKnown };
|
package/dist/server/mounts.d.ts
CHANGED
|
@@ -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;
|
package/dist/server/runtime.d.ts
CHANGED
|
@@ -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
|
|
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/
|
|
417
|
-
* - `/.well-known/
|
|
418
|
-
* - `/.well-known/webauthn`
|
|
419
|
-
*
|
|
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;
|
package/dist/server/runtime.js
CHANGED
|
@@ -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,
|
|
20
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
3
|
+
* Content generator for cross-platform `.well-known` endpoints.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* browsers, and password managers.
|
|
7
|
-
*
|
|
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
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
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
|
|
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
|
|
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
|
-
*
|
|
37
|
-
*
|
|
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
|
|
61
|
+
* @example
|
|
40
62
|
* ```ts
|
|
41
|
-
*
|
|
42
|
-
*
|
|
63
|
+
* import { wellKnown } from "@robelest/convex-auth/server";
|
|
64
|
+
*
|
|
43
65
|
* export const GET = () => {
|
|
44
|
-
* const r =
|
|
45
|
-
* if (
|
|
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
|
|
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 {
|
|
74
|
+
export { WellKnownEndpoint, WellKnownOptions, WellKnownResponse, wellKnown };
|
|
130
75
|
//# sourceMappingURL=wellknown.d.ts.map
|
package/dist/server/wellknown.js
CHANGED
|
@@ -3,21 +3,17 @@ import { normalizeUrl } from "./url.js";
|
|
|
3
3
|
|
|
4
4
|
//#region src/server/wellknown.ts
|
|
5
5
|
/**
|
|
6
|
-
* Content
|
|
6
|
+
* Content generator for cross-platform `.well-known` endpoints.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* browsers, and password managers.
|
|
10
|
-
*
|
|
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
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
197
|
+
export { wellKnown };
|
|
195
198
|
//# sourceMappingURL=wellknown.js.map
|