@spfn/auth 0.3.0-beta.2 → 0.3.0-beta.21
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/README.md +1488 -25
- package/dist/client-proof.d.ts +45 -15
- package/dist/client-proof.js +201 -5
- package/dist/client-proof.js.map +1 -1
- package/dist/client.d.ts +92 -1
- package/dist/client.js +58 -0
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +342 -0
- package/dist/config.js +153 -4
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +396 -3
- package/dist/errors.js +257 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +202 -2
- package/dist/index.js +277 -3
- package/dist/index.js.map +1 -1
- package/dist/machine-principals-B7N8gux0.d.ts +3087 -0
- package/dist/nextjs/api.js +350 -12
- package/dist/nextjs/api.js.map +1 -1
- package/dist/nextjs/client.d.ts +28 -1
- package/dist/nextjs/client.js +24 -3
- package/dist/nextjs/client.js.map +1 -1
- package/dist/nextjs/server.d.ts +173 -3
- package/dist/nextjs/server.js +372 -10
- package/dist/nextjs/server.js.map +1 -1
- package/dist/server.d.ts +4167 -582
- package/dist/server.js +9618 -4341
- package/dist/server.js.map +1 -1
- package/dist/{session-DTHahDQ9.d.ts → session-Dfwu5g2W.d.ts} +28 -1
- package/migrations/20260810112144_colorful_tomorrow_man/migration.sql +18 -0
- package/migrations/20260810112144_colorful_tomorrow_man/snapshot.json +3576 -0
- package/migrations/20260901091716_fine_arclight/migration.sql +21 -0
- package/migrations/20260901091716_fine_arclight/snapshot.json +3849 -0
- package/migrations/20260906155957_natural_moonstone/migration.sql +33 -0
- package/migrations/20260906155957_natural_moonstone/snapshot.json +4275 -0
- package/migrations/20260907020904_giant_eternals/migration.sql +21 -0
- package/migrations/20260907020904_giant_eternals/snapshot.json +4561 -0
- package/migrations/20260907044807_eminent_angel/migration.sql +2 -0
- package/migrations/20260907044807_eminent_angel/snapshot.json +4561 -0
- package/migrations/20260918083158_foamy_roughhouse/migration.sql +55 -0
- package/migrations/20260918083158_foamy_roughhouse/snapshot.json +5271 -0
- package/migrations/20260918142743_smart_cassandra_nova/migration.sql +2 -0
- package/migrations/20260918142743_smart_cassandra_nova/snapshot.json +5297 -0
- package/migrations/20260918143800_fat_princess_powerful/migration.sql +17 -0
- package/migrations/20260918143800_fat_princess_powerful/snapshot.json +5523 -0
- package/package.json +9 -6
- package/dist/authenticate-55LeXHqZ.d.ts +0 -1447
package/dist/client.d.ts
CHANGED
|
@@ -1,2 +1,93 @@
|
|
|
1
|
+
import { authApi } from '@spfn/auth';
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @spfn/auth/client - Passkeys (WebAuthn)
|
|
5
|
+
*
|
|
6
|
+
* Four browser helpers over the two ceremonies. Each one is `options` from the
|
|
7
|
+
* server, `navigator.credentials` in the browser, `verify` back to the server —
|
|
8
|
+
* and each answers with a discriminated union instead of throwing.
|
|
9
|
+
*
|
|
10
|
+
* That is the whole point of this file. A person closing the system passkey
|
|
11
|
+
* sheet raises `NotAllowedError`, and so does a person whose authenticator has
|
|
12
|
+
* nothing to offer; neither is an application error, and code that has to tell
|
|
13
|
+
* them apart by catching and re-reading `error.name` gets it wrong once and
|
|
14
|
+
* shows a red banner to someone who simply changed their mind.
|
|
15
|
+
*
|
|
16
|
+
* Ships to browsers: no Node built-ins here, `Buffer` included. The base64url
|
|
17
|
+
* helpers come from `@simplewebauthn/browser`, which is bundled into this entry.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** The typed auth client these helpers drive. */
|
|
21
|
+
type AuthApi = typeof authApi;
|
|
22
|
+
/**
|
|
23
|
+
* Why a ceremony did not produce a session.
|
|
24
|
+
*
|
|
25
|
+
* - `unsupported`: this browser has no WebAuthn at all
|
|
26
|
+
* - `cancelled`: the person dismissed the prompt
|
|
27
|
+
* - `no-credential`: the authenticator had nothing for this relying party
|
|
28
|
+
* - `error`: anything else, with the original error attached
|
|
29
|
+
*/
|
|
30
|
+
type PasskeyFailureReason = 'unsupported' | 'cancelled' | 'no-credential' | 'error';
|
|
31
|
+
type PasskeyResult<T> = ({
|
|
32
|
+
ok: true;
|
|
33
|
+
} & T) | {
|
|
34
|
+
ok: false;
|
|
35
|
+
reason: PasskeyFailureReason;
|
|
36
|
+
error?: unknown;
|
|
37
|
+
};
|
|
38
|
+
/** Whether this browser can run a WebAuthn ceremony at all. */
|
|
39
|
+
declare function isPasskeySupported(): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether the browser can offer passkeys inside the ordinary autofill dropdown.
|
|
42
|
+
*
|
|
43
|
+
* Worth checking before rendering a sign-in form: conditional mediation is what
|
|
44
|
+
* turns a passkey into "tap the suggestion above the keyboard", and where it is
|
|
45
|
+
* missing the form needs a visible "Sign in with a passkey" button instead.
|
|
46
|
+
*/
|
|
47
|
+
declare function isConditionalMediationAvailable(): Promise<boolean>;
|
|
48
|
+
interface EnrollPasskeyOptions {
|
|
49
|
+
/** Owner-facing name for the passkey list, e.g. the device model. */
|
|
50
|
+
label?: string;
|
|
51
|
+
/** Sent when the session proved itself longer ago than the recent-auth window. */
|
|
52
|
+
currentPassword?: string;
|
|
53
|
+
}
|
|
54
|
+
interface EnrollPasskeyValue {
|
|
55
|
+
passkeyId: string;
|
|
56
|
+
label: string | null;
|
|
57
|
+
createdAt: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Enroll a passkey on the device in front of the user.
|
|
61
|
+
*
|
|
62
|
+
* Requires a signed-in session. A 403 with code `RECENT_AUTH_REQUIRED` from the
|
|
63
|
+
* options call means the caller should prompt for the password and try again
|
|
64
|
+
* with `currentPassword`; that is a rejected promise, not a result here, because
|
|
65
|
+
* it is the server declining rather than the ceremony failing.
|
|
66
|
+
*/
|
|
67
|
+
declare function enrollPasskey(api: AuthApi, options?: EnrollPasskeyOptions): Promise<PasskeyResult<EnrollPasskeyValue>>;
|
|
68
|
+
interface SignInWithPasskeyOptions {
|
|
69
|
+
/**
|
|
70
|
+
* Offer the passkey through the browser's autofill dropdown instead of a
|
|
71
|
+
* modal. Needs an `<input autocomplete="username webauthn">` on the page.
|
|
72
|
+
*/
|
|
73
|
+
conditional?: boolean;
|
|
74
|
+
deviceName?: string;
|
|
75
|
+
platform?: string;
|
|
76
|
+
}
|
|
77
|
+
interface SignInWithPasskeyValue {
|
|
78
|
+
userId: string;
|
|
79
|
+
publicId: string;
|
|
80
|
+
email?: string;
|
|
81
|
+
phone?: string;
|
|
82
|
+
passwordChangeRequired: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sign in with a passkey, no identifier asked for.
|
|
86
|
+
*
|
|
87
|
+
* The device key the session runs on is generated and stored by the Next.js
|
|
88
|
+
* proxy interceptor, exactly as on a password login — nothing here handles a
|
|
89
|
+
* private key.
|
|
90
|
+
*/
|
|
91
|
+
declare function signInWithPasskey(api: AuthApi, options?: SignInWithPasskeyOptions): Promise<PasskeyResult<SignInWithPasskeyValue>>;
|
|
92
|
+
|
|
93
|
+
export { type AuthApi, type EnrollPasskeyOptions, type EnrollPasskeyValue, type PasskeyFailureReason, type PasskeyResult, type SignInWithPasskeyOptions, type SignInWithPasskeyValue, enrollPasskey, isConditionalMediationAvailable, isPasskeySupported, signInWithPasskey };
|
package/dist/client.js
CHANGED
|
@@ -1 +1,59 @@
|
|
|
1
|
+
// src/client/passkeys.ts
|
|
2
|
+
import {
|
|
3
|
+
browserSupportsWebAuthn,
|
|
4
|
+
browserSupportsWebAuthnAutofill,
|
|
5
|
+
startAuthentication,
|
|
6
|
+
startRegistration
|
|
7
|
+
} from "@simplewebauthn/browser";
|
|
8
|
+
function isPasskeySupported() {
|
|
9
|
+
return browserSupportsWebAuthn();
|
|
10
|
+
}
|
|
11
|
+
async function isConditionalMediationAvailable() {
|
|
12
|
+
return await browserSupportsWebAuthnAutofill();
|
|
13
|
+
}
|
|
14
|
+
function failureReason(error, whenNotAllowed) {
|
|
15
|
+
return error?.name === "NotAllowedError" ? whenNotAllowed : "error";
|
|
16
|
+
}
|
|
17
|
+
async function enrollPasskey(api, options = {}) {
|
|
18
|
+
if (!isPasskeySupported()) {
|
|
19
|
+
return { ok: false, reason: "unsupported" };
|
|
20
|
+
}
|
|
21
|
+
const optionsJSON = await api.passkeyRegisterOptions.call({
|
|
22
|
+
body: { currentPassword: options.currentPassword }
|
|
23
|
+
});
|
|
24
|
+
let response;
|
|
25
|
+
try {
|
|
26
|
+
response = await startRegistration({ optionsJSON });
|
|
27
|
+
} catch (error) {
|
|
28
|
+
return { ok: false, reason: failureReason(error, "cancelled"), error };
|
|
29
|
+
}
|
|
30
|
+
const enrolled = await api.passkeyRegisterVerify.call({
|
|
31
|
+
body: { response, label: options.label }
|
|
32
|
+
});
|
|
33
|
+
return { ok: true, ...enrolled };
|
|
34
|
+
}
|
|
35
|
+
async function signInWithPasskey(api, options = {}) {
|
|
36
|
+
if (!isPasskeySupported()) {
|
|
37
|
+
return { ok: false, reason: "unsupported" };
|
|
38
|
+
}
|
|
39
|
+
const optionsJSON = await api.passkeyLoginOptions.call({
|
|
40
|
+
body: {}
|
|
41
|
+
});
|
|
42
|
+
let response;
|
|
43
|
+
try {
|
|
44
|
+
response = await startAuthentication({ optionsJSON, useBrowserAutofill: options.conditional === true });
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return { ok: false, reason: failureReason(error, "no-credential"), error };
|
|
47
|
+
}
|
|
48
|
+
const session = await api.passkeyLoginVerify.call({
|
|
49
|
+
body: { response }
|
|
50
|
+
});
|
|
51
|
+
return { ok: true, ...session };
|
|
52
|
+
}
|
|
53
|
+
export {
|
|
54
|
+
enrollPasskey,
|
|
55
|
+
isConditionalMediationAvailable,
|
|
56
|
+
isPasskeySupported,
|
|
57
|
+
signInWithPasskey
|
|
58
|
+
};
|
|
1
59
|
//# sourceMappingURL=client.js.map
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/client/passkeys.ts"],"sourcesContent":["/**\n * @spfn/auth/client - Passkeys (WebAuthn)\n *\n * Four browser helpers over the two ceremonies. Each one is `options` from the\n * server, `navigator.credentials` in the browser, `verify` back to the server —\n * and each answers with a discriminated union instead of throwing.\n *\n * That is the whole point of this file. A person closing the system passkey\n * sheet raises `NotAllowedError`, and so does a person whose authenticator has\n * nothing to offer; neither is an application error, and code that has to tell\n * them apart by catching and re-reading `error.name` gets it wrong once and\n * shows a red banner to someone who simply changed their mind.\n *\n * Ships to browsers: no Node built-ins here, `Buffer` included. The base64url\n * helpers come from `@simplewebauthn/browser`, which is bundled into this entry.\n */\n\nimport {\n browserSupportsWebAuthn,\n browserSupportsWebAuthnAutofill,\n startAuthentication,\n startRegistration,\n type AuthenticationResponseJSON,\n type PublicKeyCredentialCreationOptionsJSON,\n type PublicKeyCredentialRequestOptionsJSON,\n type RegistrationResponseJSON,\n} from '@simplewebauthn/browser';\n\nimport type { authApi } from '@spfn/auth';\n\n/** The typed auth client these helpers drive. */\nexport type AuthApi = typeof authApi;\n\n/**\n * Why a ceremony did not produce a session.\n *\n * - `unsupported`: this browser has no WebAuthn at all\n * - `cancelled`: the person dismissed the prompt\n * - `no-credential`: the authenticator had nothing for this relying party\n * - `error`: anything else, with the original error attached\n */\nexport type PasskeyFailureReason = 'unsupported' | 'cancelled' | 'no-credential' | 'error';\n\nexport type PasskeyResult<T> =\n | ({ ok: true } & T)\n | { ok: false; reason: PasskeyFailureReason; error?: unknown };\n\n/** Whether this browser can run a WebAuthn ceremony at all. */\nexport function isPasskeySupported(): boolean\n{\n return browserSupportsWebAuthn();\n}\n\n/**\n * Whether the browser can offer passkeys inside the ordinary autofill dropdown.\n *\n * Worth checking before rendering a sign-in form: conditional mediation is what\n * turns a passkey into \"tap the suggestion above the keyboard\", and where it is\n * missing the form needs a visible \"Sign in with a passkey\" button instead.\n */\nexport async function isConditionalMediationAvailable(): Promise<boolean>\n{\n return await browserSupportsWebAuthnAutofill();\n}\n\n/**\n * The reason a ceremony failure should be reported as.\n *\n * `NotAllowedError` is the browser's answer both to \"the person said no\" and to\n * \"nothing here matched\", and the specification deliberately does not\n * distinguish them — telling a caller which applied would say whether a\n * credential for this site exists on the device. So it is `cancelled` in both\n * cases on registration, and `no-credential` on a sign-in that offered no\n * credentials to choose from, which is the reading a UI wants.\n */\nfunction failureReason(error: unknown, whenNotAllowed: PasskeyFailureReason): PasskeyFailureReason\n{\n return (error as { name?: string } | null)?.name === 'NotAllowedError' ? whenNotAllowed : 'error';\n}\n\nexport interface EnrollPasskeyOptions\n{\n /** Owner-facing name for the passkey list, e.g. the device model. */\n label?: string;\n /** Sent when the session proved itself longer ago than the recent-auth window. */\n currentPassword?: string;\n}\n\nexport interface EnrollPasskeyValue\n{\n passkeyId: string;\n label: string | null;\n createdAt: string;\n}\n\n/**\n * Enroll a passkey on the device in front of the user.\n *\n * Requires a signed-in session. A 403 with code `RECENT_AUTH_REQUIRED` from the\n * options call means the caller should prompt for the password and try again\n * with `currentPassword`; that is a rejected promise, not a result here, because\n * it is the server declining rather than the ceremony failing.\n */\nexport async function enrollPasskey(\n api: AuthApi,\n options: EnrollPasskeyOptions = {},\n): Promise<PasskeyResult<EnrollPasskeyValue>>\n{\n if (!isPasskeySupported())\n {\n return { ok: false, reason: 'unsupported' };\n }\n\n const optionsJSON = await api.passkeyRegisterOptions.call({\n body: { currentPassword: options.currentPassword },\n }) as PublicKeyCredentialCreationOptionsJSON;\n\n let response: RegistrationResponseJSON;\n\n try\n {\n response = await startRegistration({ optionsJSON });\n }\n catch (error)\n {\n return { ok: false, reason: failureReason(error, 'cancelled'), error };\n }\n\n const enrolled = await api.passkeyRegisterVerify.call({\n body: { response, label: options.label },\n }) as EnrollPasskeyValue;\n\n return { ok: true, ...enrolled };\n}\n\nexport interface SignInWithPasskeyOptions\n{\n /**\n * Offer the passkey through the browser's autofill dropdown instead of a\n * modal. Needs an `<input autocomplete=\"username webauthn\">` on the page.\n */\n conditional?: boolean;\n deviceName?: string;\n platform?: string;\n}\n\nexport interface SignInWithPasskeyValue\n{\n userId: string;\n publicId: string;\n email?: string;\n phone?: string;\n passwordChangeRequired: boolean;\n}\n\n/**\n * Sign in with a passkey, no identifier asked for.\n *\n * The device key the session runs on is generated and stored by the Next.js\n * proxy interceptor, exactly as on a password login — nothing here handles a\n * private key.\n */\nexport async function signInWithPasskey(\n api: AuthApi,\n options: SignInWithPasskeyOptions = {},\n): Promise<PasskeyResult<SignInWithPasskeyValue>>\n{\n if (!isPasskeySupported())\n {\n return { ok: false, reason: 'unsupported' };\n }\n\n const optionsJSON = await api.passkeyLoginOptions.call({\n body: {},\n }) as PublicKeyCredentialRequestOptionsJSON;\n\n let response: AuthenticationResponseJSON;\n\n try\n {\n response = await startAuthentication({ optionsJSON, useBrowserAutofill: options.conditional === true });\n }\n catch (error)\n {\n return { ok: false, reason: failureReason(error, 'no-credential'), error };\n }\n\n const session = await api.passkeyLoginVerify.call({\n body: { response },\n }) as SignInWithPasskeyValue;\n\n return { ok: true, ...session };\n}\n"],"mappings":";AAiBA;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKG;AAsBA,SAAS,qBAChB;AACI,SAAO,wBAAwB;AACnC;AASA,eAAsB,kCACtB;AACI,SAAO,MAAM,gCAAgC;AACjD;AAYA,SAAS,cAAc,OAAgB,gBACvC;AACI,SAAQ,OAAoC,SAAS,oBAAoB,iBAAiB;AAC9F;AAyBA,eAAsB,cAClB,KACA,UAAgC,CAAC,GAErC;AACI,MAAI,CAAC,mBAAmB,GACxB;AACI,WAAO,EAAE,IAAI,OAAO,QAAQ,cAAc;AAAA,EAC9C;AAEA,QAAM,cAAc,MAAM,IAAI,uBAAuB,KAAK;AAAA,IACtD,MAAM,EAAE,iBAAiB,QAAQ,gBAAgB;AAAA,EACrD,CAAC;AAED,MAAI;AAEJ,MACA;AACI,eAAW,MAAM,kBAAkB,EAAE,YAAY,CAAC;AAAA,EACtD,SACO,OACP;AACI,WAAO,EAAE,IAAI,OAAO,QAAQ,cAAc,OAAO,WAAW,GAAG,MAAM;AAAA,EACzE;AAEA,QAAM,WAAW,MAAM,IAAI,sBAAsB,KAAK;AAAA,IAClD,MAAM,EAAE,UAAU,OAAO,QAAQ,MAAM;AAAA,EAC3C,CAAC;AAED,SAAO,EAAE,IAAI,MAAM,GAAG,SAAS;AACnC;AA6BA,eAAsB,kBAClB,KACA,UAAoC,CAAC,GAEzC;AACI,MAAI,CAAC,mBAAmB,GACxB;AACI,WAAO,EAAE,IAAI,OAAO,QAAQ,cAAc;AAAA,EAC9C;AAEA,QAAM,cAAc,MAAM,IAAI,oBAAoB,KAAK;AAAA,IACnD,MAAM,CAAC;AAAA,EACX,CAAC;AAED,MAAI;AAEJ,MACA;AACI,eAAW,MAAM,oBAAoB,EAAE,aAAa,oBAAoB,QAAQ,gBAAgB,KAAK,CAAC;AAAA,EAC1G,SACO,OACP;AACI,WAAO,EAAE,IAAI,OAAO,QAAQ,cAAc,OAAO,eAAe,GAAG,MAAM;AAAA,EAC7E;AAEA,QAAM,UAAU,MAAM,IAAI,mBAAmB,KAAK;AAAA,IAC9C,MAAM,EAAE,SAAS;AAAA,EACrB,CAAC;AAED,SAAO,EAAE,IAAI,MAAM,GAAG,QAAQ;AAClC;","names":[]}
|
package/dist/config.d.ts
CHANGED
|
@@ -80,6 +80,16 @@ declare const authEnvSchema: {
|
|
|
80
80
|
} & {
|
|
81
81
|
key: "SPFN_AUTH_COOKIE_SECURE";
|
|
82
82
|
};
|
|
83
|
+
SPFN_AUTH_CSRF: {
|
|
84
|
+
description: string;
|
|
85
|
+
required: boolean;
|
|
86
|
+
nextjs: boolean;
|
|
87
|
+
examples: string[];
|
|
88
|
+
type: "string";
|
|
89
|
+
validator: (value: string) => string;
|
|
90
|
+
} & {
|
|
91
|
+
key: "SPFN_AUTH_CSRF";
|
|
92
|
+
};
|
|
83
93
|
SPFN_AUTH_BCRYPT_SALT_ROUNDS: {
|
|
84
94
|
key: string;
|
|
85
95
|
description: string;
|
|
@@ -195,6 +205,158 @@ declare const authEnvSchema: {
|
|
|
195
205
|
} & {
|
|
196
206
|
key: "SPFN_AUTH_USERNAME_MAX_LENGTH";
|
|
197
207
|
};
|
|
208
|
+
SPFN_AUTH_SIGNUP_LINK_TTL_MINUTES: {
|
|
209
|
+
description: string;
|
|
210
|
+
default: number;
|
|
211
|
+
required: boolean;
|
|
212
|
+
examples: number[];
|
|
213
|
+
type: "number";
|
|
214
|
+
validator: (value: string) => number;
|
|
215
|
+
} & {
|
|
216
|
+
key: "SPFN_AUTH_SIGNUP_LINK_TTL_MINUTES";
|
|
217
|
+
};
|
|
218
|
+
SPFN_AUTH_SIGNUP_SETUP_TTL_MINUTES: {
|
|
219
|
+
description: string;
|
|
220
|
+
default: number;
|
|
221
|
+
required: boolean;
|
|
222
|
+
examples: number[];
|
|
223
|
+
type: "number";
|
|
224
|
+
validator: (value: string) => number;
|
|
225
|
+
} & {
|
|
226
|
+
key: "SPFN_AUTH_SIGNUP_SETUP_TTL_MINUTES";
|
|
227
|
+
};
|
|
228
|
+
SPFN_AUTH_SIGNUP_CONFIRM_PATH: {
|
|
229
|
+
description: string;
|
|
230
|
+
default: string;
|
|
231
|
+
required: boolean;
|
|
232
|
+
examples: string[];
|
|
233
|
+
type: "string";
|
|
234
|
+
validator: (value: string) => string;
|
|
235
|
+
} & {
|
|
236
|
+
key: "SPFN_AUTH_SIGNUP_CONFIRM_PATH";
|
|
237
|
+
};
|
|
238
|
+
SPFN_AUTH_PASSWORD_RESET_LINK_TTL_MINUTES: {
|
|
239
|
+
description: string;
|
|
240
|
+
default: number;
|
|
241
|
+
required: boolean;
|
|
242
|
+
examples: number[];
|
|
243
|
+
type: "number";
|
|
244
|
+
validator: (value: string) => number;
|
|
245
|
+
} & {
|
|
246
|
+
key: "SPFN_AUTH_PASSWORD_RESET_LINK_TTL_MINUTES";
|
|
247
|
+
};
|
|
248
|
+
SPFN_AUTH_PASSWORD_RESET_SETUP_TTL_MINUTES: {
|
|
249
|
+
description: string;
|
|
250
|
+
default: number;
|
|
251
|
+
required: boolean;
|
|
252
|
+
examples: number[];
|
|
253
|
+
type: "number";
|
|
254
|
+
validator: (value: string) => number;
|
|
255
|
+
} & {
|
|
256
|
+
key: "SPFN_AUTH_PASSWORD_RESET_SETUP_TTL_MINUTES";
|
|
257
|
+
};
|
|
258
|
+
SPFN_AUTH_PASSWORD_RESET_CONFIRM_PATH: {
|
|
259
|
+
description: string;
|
|
260
|
+
default: string;
|
|
261
|
+
required: boolean;
|
|
262
|
+
examples: string[];
|
|
263
|
+
type: "string";
|
|
264
|
+
validator: (value: string) => string;
|
|
265
|
+
} & {
|
|
266
|
+
key: "SPFN_AUTH_PASSWORD_RESET_CONFIRM_PATH";
|
|
267
|
+
};
|
|
268
|
+
SPFN_AUTH_REVOKE_ALL_LINK_TTL_MINUTES: {
|
|
269
|
+
description: string;
|
|
270
|
+
default: number;
|
|
271
|
+
required: boolean;
|
|
272
|
+
examples: number[];
|
|
273
|
+
type: "number";
|
|
274
|
+
validator: (value: string) => number;
|
|
275
|
+
} & {
|
|
276
|
+
key: "SPFN_AUTH_REVOKE_ALL_LINK_TTL_MINUTES";
|
|
277
|
+
};
|
|
278
|
+
SPFN_AUTH_REVOKE_ALL_CONFIRM_PATH: {
|
|
279
|
+
description: string;
|
|
280
|
+
default: string;
|
|
281
|
+
required: boolean;
|
|
282
|
+
examples: string[];
|
|
283
|
+
type: "string";
|
|
284
|
+
validator: (value: string) => string;
|
|
285
|
+
} & {
|
|
286
|
+
key: "SPFN_AUTH_REVOKE_ALL_CONFIRM_PATH";
|
|
287
|
+
};
|
|
288
|
+
SPFN_AUTH_LINK_MAIL_DELIVERY: {
|
|
289
|
+
description: string;
|
|
290
|
+
default?: "auto" | "inline" | "queued" | undefined;
|
|
291
|
+
examples?: ("auto" | "inline" | "queued")[] | undefined;
|
|
292
|
+
minLength?: number | undefined;
|
|
293
|
+
required?: boolean | undefined;
|
|
294
|
+
fallbackKeys?: string[] | undefined;
|
|
295
|
+
sensitive?: boolean | undefined;
|
|
296
|
+
generate?: "hex32" | "hex64" | "uuid" | "base64url32" | undefined;
|
|
297
|
+
nextjs?: boolean | undefined;
|
|
298
|
+
type: "enum";
|
|
299
|
+
validator: (val: string) => "auto" | "inline" | "queued";
|
|
300
|
+
} & {
|
|
301
|
+
key: "SPFN_AUTH_LINK_MAIL_DELIVERY";
|
|
302
|
+
};
|
|
303
|
+
SPFN_AUTH_PASSKEY_RP_ID: {
|
|
304
|
+
description: string;
|
|
305
|
+
required: boolean;
|
|
306
|
+
examples: string[];
|
|
307
|
+
type: "string";
|
|
308
|
+
validator: (value: string) => string;
|
|
309
|
+
} & {
|
|
310
|
+
key: "SPFN_AUTH_PASSKEY_RP_ID";
|
|
311
|
+
};
|
|
312
|
+
SPFN_AUTH_PASSKEY_RP_NAME: {
|
|
313
|
+
description: string;
|
|
314
|
+
required: boolean;
|
|
315
|
+
examples: string[];
|
|
316
|
+
type: "string";
|
|
317
|
+
validator: (value: string) => string;
|
|
318
|
+
} & {
|
|
319
|
+
key: "SPFN_AUTH_PASSKEY_RP_NAME";
|
|
320
|
+
};
|
|
321
|
+
SPFN_AUTH_PASSKEY_ORIGINS: {
|
|
322
|
+
description: string;
|
|
323
|
+
required: boolean;
|
|
324
|
+
examples: string[];
|
|
325
|
+
type: "string";
|
|
326
|
+
validator: (value: string) => string;
|
|
327
|
+
} & {
|
|
328
|
+
key: "SPFN_AUTH_PASSKEY_ORIGINS";
|
|
329
|
+
};
|
|
330
|
+
SPFN_AUTH_PASSKEY_USER_VERIFICATION: {
|
|
331
|
+
description: string;
|
|
332
|
+
default: string;
|
|
333
|
+
required: boolean;
|
|
334
|
+
examples: string[];
|
|
335
|
+
type: "string";
|
|
336
|
+
validator: (value: string) => string;
|
|
337
|
+
} & {
|
|
338
|
+
key: "SPFN_AUTH_PASSKEY_USER_VERIFICATION";
|
|
339
|
+
};
|
|
340
|
+
SPFN_AUTH_PASSKEY_CHALLENGE_TTL_SECONDS: {
|
|
341
|
+
description: string;
|
|
342
|
+
default: number;
|
|
343
|
+
required: boolean;
|
|
344
|
+
examples: number[];
|
|
345
|
+
type: "number";
|
|
346
|
+
validator: (value: string) => number;
|
|
347
|
+
} & {
|
|
348
|
+
key: "SPFN_AUTH_PASSKEY_CHALLENGE_TTL_SECONDS";
|
|
349
|
+
};
|
|
350
|
+
SPFN_AUTH_PASSKEY_RECENT_AUTH_MINUTES: {
|
|
351
|
+
description: string;
|
|
352
|
+
default: number;
|
|
353
|
+
required: boolean;
|
|
354
|
+
examples: number[];
|
|
355
|
+
type: "number";
|
|
356
|
+
validator: (value: string) => number;
|
|
357
|
+
} & {
|
|
358
|
+
key: "SPFN_AUTH_PASSKEY_RECENT_AUTH_MINUTES";
|
|
359
|
+
};
|
|
198
360
|
SPFN_API_URL: {
|
|
199
361
|
description: string;
|
|
200
362
|
default: string;
|
|
@@ -382,6 +544,15 @@ declare const authEnvSchema: {
|
|
|
382
544
|
} & {
|
|
383
545
|
key: "SPFN_AUTH_GITHUB_REDIRECT_URI";
|
|
384
546
|
};
|
|
547
|
+
SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK: {
|
|
548
|
+
description: string;
|
|
549
|
+
required: boolean;
|
|
550
|
+
examples: string[];
|
|
551
|
+
type: "string";
|
|
552
|
+
validator: (value: string) => string;
|
|
553
|
+
} & {
|
|
554
|
+
key: "SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK";
|
|
555
|
+
};
|
|
385
556
|
SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS: {
|
|
386
557
|
description: string;
|
|
387
558
|
required: boolean;
|
|
@@ -494,6 +665,16 @@ declare const env: _spfn_core_env.InferEnvType<{
|
|
|
494
665
|
} & {
|
|
495
666
|
key: "SPFN_AUTH_COOKIE_SECURE";
|
|
496
667
|
};
|
|
668
|
+
SPFN_AUTH_CSRF: {
|
|
669
|
+
description: string;
|
|
670
|
+
required: boolean;
|
|
671
|
+
nextjs: boolean;
|
|
672
|
+
examples: string[];
|
|
673
|
+
type: "string";
|
|
674
|
+
validator: (value: string) => string;
|
|
675
|
+
} & {
|
|
676
|
+
key: "SPFN_AUTH_CSRF";
|
|
677
|
+
};
|
|
497
678
|
SPFN_AUTH_BCRYPT_SALT_ROUNDS: {
|
|
498
679
|
key: string;
|
|
499
680
|
description: string;
|
|
@@ -609,6 +790,158 @@ declare const env: _spfn_core_env.InferEnvType<{
|
|
|
609
790
|
} & {
|
|
610
791
|
key: "SPFN_AUTH_USERNAME_MAX_LENGTH";
|
|
611
792
|
};
|
|
793
|
+
SPFN_AUTH_SIGNUP_LINK_TTL_MINUTES: {
|
|
794
|
+
description: string;
|
|
795
|
+
default: number;
|
|
796
|
+
required: boolean;
|
|
797
|
+
examples: number[];
|
|
798
|
+
type: "number";
|
|
799
|
+
validator: (value: string) => number;
|
|
800
|
+
} & {
|
|
801
|
+
key: "SPFN_AUTH_SIGNUP_LINK_TTL_MINUTES";
|
|
802
|
+
};
|
|
803
|
+
SPFN_AUTH_SIGNUP_SETUP_TTL_MINUTES: {
|
|
804
|
+
description: string;
|
|
805
|
+
default: number;
|
|
806
|
+
required: boolean;
|
|
807
|
+
examples: number[];
|
|
808
|
+
type: "number";
|
|
809
|
+
validator: (value: string) => number;
|
|
810
|
+
} & {
|
|
811
|
+
key: "SPFN_AUTH_SIGNUP_SETUP_TTL_MINUTES";
|
|
812
|
+
};
|
|
813
|
+
SPFN_AUTH_SIGNUP_CONFIRM_PATH: {
|
|
814
|
+
description: string;
|
|
815
|
+
default: string;
|
|
816
|
+
required: boolean;
|
|
817
|
+
examples: string[];
|
|
818
|
+
type: "string";
|
|
819
|
+
validator: (value: string) => string;
|
|
820
|
+
} & {
|
|
821
|
+
key: "SPFN_AUTH_SIGNUP_CONFIRM_PATH";
|
|
822
|
+
};
|
|
823
|
+
SPFN_AUTH_PASSWORD_RESET_LINK_TTL_MINUTES: {
|
|
824
|
+
description: string;
|
|
825
|
+
default: number;
|
|
826
|
+
required: boolean;
|
|
827
|
+
examples: number[];
|
|
828
|
+
type: "number";
|
|
829
|
+
validator: (value: string) => number;
|
|
830
|
+
} & {
|
|
831
|
+
key: "SPFN_AUTH_PASSWORD_RESET_LINK_TTL_MINUTES";
|
|
832
|
+
};
|
|
833
|
+
SPFN_AUTH_PASSWORD_RESET_SETUP_TTL_MINUTES: {
|
|
834
|
+
description: string;
|
|
835
|
+
default: number;
|
|
836
|
+
required: boolean;
|
|
837
|
+
examples: number[];
|
|
838
|
+
type: "number";
|
|
839
|
+
validator: (value: string) => number;
|
|
840
|
+
} & {
|
|
841
|
+
key: "SPFN_AUTH_PASSWORD_RESET_SETUP_TTL_MINUTES";
|
|
842
|
+
};
|
|
843
|
+
SPFN_AUTH_PASSWORD_RESET_CONFIRM_PATH: {
|
|
844
|
+
description: string;
|
|
845
|
+
default: string;
|
|
846
|
+
required: boolean;
|
|
847
|
+
examples: string[];
|
|
848
|
+
type: "string";
|
|
849
|
+
validator: (value: string) => string;
|
|
850
|
+
} & {
|
|
851
|
+
key: "SPFN_AUTH_PASSWORD_RESET_CONFIRM_PATH";
|
|
852
|
+
};
|
|
853
|
+
SPFN_AUTH_REVOKE_ALL_LINK_TTL_MINUTES: {
|
|
854
|
+
description: string;
|
|
855
|
+
default: number;
|
|
856
|
+
required: boolean;
|
|
857
|
+
examples: number[];
|
|
858
|
+
type: "number";
|
|
859
|
+
validator: (value: string) => number;
|
|
860
|
+
} & {
|
|
861
|
+
key: "SPFN_AUTH_REVOKE_ALL_LINK_TTL_MINUTES";
|
|
862
|
+
};
|
|
863
|
+
SPFN_AUTH_REVOKE_ALL_CONFIRM_PATH: {
|
|
864
|
+
description: string;
|
|
865
|
+
default: string;
|
|
866
|
+
required: boolean;
|
|
867
|
+
examples: string[];
|
|
868
|
+
type: "string";
|
|
869
|
+
validator: (value: string) => string;
|
|
870
|
+
} & {
|
|
871
|
+
key: "SPFN_AUTH_REVOKE_ALL_CONFIRM_PATH";
|
|
872
|
+
};
|
|
873
|
+
SPFN_AUTH_LINK_MAIL_DELIVERY: {
|
|
874
|
+
description: string;
|
|
875
|
+
default?: "auto" | "inline" | "queued" | undefined;
|
|
876
|
+
examples?: ("auto" | "inline" | "queued")[] | undefined;
|
|
877
|
+
minLength?: number | undefined;
|
|
878
|
+
required?: boolean | undefined;
|
|
879
|
+
fallbackKeys?: string[] | undefined;
|
|
880
|
+
sensitive?: boolean | undefined;
|
|
881
|
+
generate?: "hex32" | "hex64" | "uuid" | "base64url32" | undefined;
|
|
882
|
+
nextjs?: boolean | undefined;
|
|
883
|
+
type: "enum";
|
|
884
|
+
validator: (val: string) => "auto" | "inline" | "queued";
|
|
885
|
+
} & {
|
|
886
|
+
key: "SPFN_AUTH_LINK_MAIL_DELIVERY";
|
|
887
|
+
};
|
|
888
|
+
SPFN_AUTH_PASSKEY_RP_ID: {
|
|
889
|
+
description: string;
|
|
890
|
+
required: boolean;
|
|
891
|
+
examples: string[];
|
|
892
|
+
type: "string";
|
|
893
|
+
validator: (value: string) => string;
|
|
894
|
+
} & {
|
|
895
|
+
key: "SPFN_AUTH_PASSKEY_RP_ID";
|
|
896
|
+
};
|
|
897
|
+
SPFN_AUTH_PASSKEY_RP_NAME: {
|
|
898
|
+
description: string;
|
|
899
|
+
required: boolean;
|
|
900
|
+
examples: string[];
|
|
901
|
+
type: "string";
|
|
902
|
+
validator: (value: string) => string;
|
|
903
|
+
} & {
|
|
904
|
+
key: "SPFN_AUTH_PASSKEY_RP_NAME";
|
|
905
|
+
};
|
|
906
|
+
SPFN_AUTH_PASSKEY_ORIGINS: {
|
|
907
|
+
description: string;
|
|
908
|
+
required: boolean;
|
|
909
|
+
examples: string[];
|
|
910
|
+
type: "string";
|
|
911
|
+
validator: (value: string) => string;
|
|
912
|
+
} & {
|
|
913
|
+
key: "SPFN_AUTH_PASSKEY_ORIGINS";
|
|
914
|
+
};
|
|
915
|
+
SPFN_AUTH_PASSKEY_USER_VERIFICATION: {
|
|
916
|
+
description: string;
|
|
917
|
+
default: string;
|
|
918
|
+
required: boolean;
|
|
919
|
+
examples: string[];
|
|
920
|
+
type: "string";
|
|
921
|
+
validator: (value: string) => string;
|
|
922
|
+
} & {
|
|
923
|
+
key: "SPFN_AUTH_PASSKEY_USER_VERIFICATION";
|
|
924
|
+
};
|
|
925
|
+
SPFN_AUTH_PASSKEY_CHALLENGE_TTL_SECONDS: {
|
|
926
|
+
description: string;
|
|
927
|
+
default: number;
|
|
928
|
+
required: boolean;
|
|
929
|
+
examples: number[];
|
|
930
|
+
type: "number";
|
|
931
|
+
validator: (value: string) => number;
|
|
932
|
+
} & {
|
|
933
|
+
key: "SPFN_AUTH_PASSKEY_CHALLENGE_TTL_SECONDS";
|
|
934
|
+
};
|
|
935
|
+
SPFN_AUTH_PASSKEY_RECENT_AUTH_MINUTES: {
|
|
936
|
+
description: string;
|
|
937
|
+
default: number;
|
|
938
|
+
required: boolean;
|
|
939
|
+
examples: number[];
|
|
940
|
+
type: "number";
|
|
941
|
+
validator: (value: string) => number;
|
|
942
|
+
} & {
|
|
943
|
+
key: "SPFN_AUTH_PASSKEY_RECENT_AUTH_MINUTES";
|
|
944
|
+
};
|
|
612
945
|
SPFN_API_URL: {
|
|
613
946
|
description: string;
|
|
614
947
|
default: string;
|
|
@@ -796,6 +1129,15 @@ declare const env: _spfn_core_env.InferEnvType<{
|
|
|
796
1129
|
} & {
|
|
797
1130
|
key: "SPFN_AUTH_GITHUB_REDIRECT_URI";
|
|
798
1131
|
};
|
|
1132
|
+
SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK: {
|
|
1133
|
+
description: string;
|
|
1134
|
+
required: boolean;
|
|
1135
|
+
examples: string[];
|
|
1136
|
+
type: "string";
|
|
1137
|
+
validator: (value: string) => string;
|
|
1138
|
+
} & {
|
|
1139
|
+
key: "SPFN_AUTH_OAUTH_CALLBACK_ORIGIN_CHECK";
|
|
1140
|
+
};
|
|
799
1141
|
SPFN_AUTH_GOOGLE_NATIVE_CLIENT_IDS: {
|
|
800
1142
|
description: string;
|
|
801
1143
|
required: boolean;
|