@atlasauth/js 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/account-hints.d.ts +53 -0
  3. package/dist/account-hints.js +114 -0
  4. package/dist/account-hints.js.map +1 -0
  5. package/dist/attempt.d.ts +3 -1
  6. package/dist/attempt.js.map +1 -1
  7. package/dist/captcha-controller.d.ts +21 -0
  8. package/dist/captcha-controller.js +36 -1
  9. package/dist/captcha-controller.js.map +1 -1
  10. package/dist/captcha-widget.d.ts +20 -2
  11. package/dist/captcha-widget.js +79 -4
  12. package/dist/captcha-widget.js.map +1 -1
  13. package/dist/captcha.d.ts +5 -0
  14. package/dist/captcha.js +30 -0
  15. package/dist/captcha.js.map +1 -1
  16. package/dist/compat.d.ts +149 -0
  17. package/dist/compat.js +363 -0
  18. package/dist/compat.js.map +1 -0
  19. package/dist/device-authorization.d.ts +70 -0
  20. package/dist/device-authorization.js +97 -0
  21. package/dist/device-authorization.js.map +1 -0
  22. package/dist/email-code-check.d.ts +60 -0
  23. package/dist/email-code-check.js +51 -0
  24. package/dist/email-code-check.js.map +1 -0
  25. package/dist/environment.d.ts +48 -0
  26. package/dist/environment.js +54 -1
  27. package/dist/environment.js.map +1 -1
  28. package/dist/fapi.d.ts +29 -0
  29. package/dist/fapi.js +90 -7
  30. package/dist/fapi.js.map +1 -1
  31. package/dist/frontchannel-logout.d.ts +36 -0
  32. package/dist/frontchannel-logout.js.map +1 -1
  33. package/dist/impersonation.d.ts +44 -0
  34. package/dist/impersonation.js +47 -0
  35. package/dist/impersonation.js.map +1 -0
  36. package/dist/index.d.ts +12 -0
  37. package/dist/index.js +21 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/instance-settings.d.ts +7 -1
  40. package/dist/instance-settings.js +15 -1
  41. package/dist/instance-settings.js.map +1 -1
  42. package/dist/mfa-enrollment.d.ts +154 -0
  43. package/dist/mfa-enrollment.js +288 -0
  44. package/dist/mfa-enrollment.js.map +1 -0
  45. package/dist/organization-audit-log.d.ts +63 -0
  46. package/dist/organization-audit-log.js +96 -0
  47. package/dist/organization-audit-log.js.map +1 -0
  48. package/dist/organizations.d.ts +330 -0
  49. package/dist/organizations.js +375 -0
  50. package/dist/organizations.js.map +1 -0
  51. package/dist/passkey-sign-in.d.ts +40 -0
  52. package/dist/passkey-sign-in.js +41 -0
  53. package/dist/passkey-sign-in.js.map +1 -0
  54. package/dist/passkey-sign-up.d.ts +46 -0
  55. package/dist/passkey-sign-up.js +104 -0
  56. package/dist/passkey-sign-up.js.map +1 -0
  57. package/dist/passkey.d.ts +58 -2
  58. package/dist/passkey.js +61 -0
  59. package/dist/passkey.js.map +1 -1
  60. package/dist/password-reset.d.ts +12 -0
  61. package/dist/password-reset.js +15 -0
  62. package/dist/password-reset.js.map +1 -1
  63. package/dist/phone-numbers.d.ts +43 -0
  64. package/dist/phone-numbers.js +65 -0
  65. package/dist/phone-numbers.js.map +1 -0
  66. package/dist/profile.d.ts +24 -0
  67. package/dist/profile.js +24 -0
  68. package/dist/profile.js.map +1 -0
  69. package/dist/referral-detect.js +1 -1
  70. package/dist/referral.d.ts +1 -1
  71. package/dist/referral.js +3 -2
  72. package/dist/referral.js.map +1 -1
  73. package/dist/sign-out-guard.d.ts +15 -0
  74. package/dist/sign-out-guard.js +53 -4
  75. package/dist/sign-out-guard.js.map +1 -1
  76. package/dist/sign-out.d.ts +23 -0
  77. package/dist/sign-out.js +37 -2
  78. package/dist/sign-out.js.map +1 -1
  79. package/dist/upstream-logout.d.ts +26 -0
  80. package/dist/upstream-logout.js +60 -0
  81. package/dist/upstream-logout.js.map +1 -0
  82. package/dist/version.d.ts +1 -1
  83. package/dist/version.js +1 -1
  84. package/package.json +13 -2
@@ -0,0 +1,70 @@
1
+ import type { FapiClient } from './fapi';
2
+ /**
3
+ * Device sign-in (OAuth 2.0 Device Authorization Grant, RFC 8628) from YOUR app:
4
+ * the signed-in user types — or scans — the code their TV, console or CLI shows,
5
+ * and your own page approves it. The alternative to sending them to Atlas's
6
+ * hosted `/oauth2/device` page.
7
+ *
8
+ * const auth = await lookupDeviceAuthorization(client, typedCode);
9
+ * // show auth.client.name and auth.scopes, then:
10
+ * await approveDeviceAuthorization(client, auth); // or denyDeviceAuthorization
11
+ *
12
+ * The calls use the signed-in session (the cookie, or a native app's session
13
+ * token). When the application requires a recent re-authentication to approve a
14
+ * device (`requiresStepUp`), a stale session gets a
15
+ * {@link DeviceAuthorizationError} with `needsReverification` — re-authenticate
16
+ * (`reauthenticate()`), then approve again.
17
+ */
18
+ export interface DeviceAuthorizationScope {
19
+ scope: string;
20
+ /** A human description for the consent text. */
21
+ description: string;
22
+ }
23
+ export interface DeviceAuthorization {
24
+ object: 'device_authorization';
25
+ id: string;
26
+ /** The code as the device shows it, e.g. `WDJB-MJHT`. */
27
+ userCode: string;
28
+ status: 'pending' | 'approved' | 'denied';
29
+ client: {
30
+ clientId: string;
31
+ name: string;
32
+ logoUrl: string | null;
33
+ homepageUrl: string | null;
34
+ firstParty: boolean;
35
+ };
36
+ scopes: DeviceAuthorizationScope[];
37
+ /** The API the device asked for a token for, if any. */
38
+ audience: string | null;
39
+ /** Approving needs a recent re-authentication. */
40
+ requiresStepUp: boolean;
41
+ createdAt: number;
42
+ expiresAt: number;
43
+ }
44
+ /** A refused request. `code` is the server's stable error code (`NOT_FOUND`, `RATE_LIMITED`, `STEP_UP_REQUIRED`, …). */
45
+ export declare class DeviceAuthorizationError extends Error {
46
+ readonly code: string;
47
+ readonly status: number;
48
+ readonly param?: string;
49
+ readonly reason?: string;
50
+ readonly meta?: Record<string, unknown>;
51
+ constructor(status: number, code: string, message: string, param?: string, reason?: string, meta?: Record<string, unknown>);
52
+ /** True when approving needs a fresh re-authentication first. */
53
+ get needsReverification(): boolean;
54
+ /** True when the code is unknown, expired or already used. */
55
+ get isInvalidCode(): boolean;
56
+ }
57
+ /**
58
+ * Normalise what a person typed into the `XXXX-XXXX` form devices show:
59
+ * uppercase, spaces and dashes ignored. Returns the input unchanged when it is
60
+ * not 8 letters or digits, so the server answers "not valid".
61
+ */
62
+ export declare function formatUserCode(input: string): string;
63
+ /** Read a `user_code` from a verification URL the device displayed (`?user_code=`), if any. */
64
+ export declare function userCodeFromUrl(url: string | URL): string | null;
65
+ /** Look up a pending device sign-in by the code the device shows. */
66
+ export declare function lookupDeviceAuthorization(client: FapiClient, userCode: string): Promise<DeviceAuthorization>;
67
+ /** Approve the device sign-in for the signed-in user. The device's next poll receives its tokens. */
68
+ export declare function approveDeviceAuthorization(client: FapiClient, authorization: Pick<DeviceAuthorization, 'id' | 'userCode'>): Promise<DeviceAuthorization>;
69
+ /** Deny the device sign-in. The device's next poll is told `access_denied`. */
70
+ export declare function denyDeviceAuthorization(client: FapiClient, authorization: Pick<DeviceAuthorization, 'id' | 'userCode'>): Promise<DeviceAuthorization>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeviceAuthorizationError = void 0;
4
+ exports.formatUserCode = formatUserCode;
5
+ exports.userCodeFromUrl = userCodeFromUrl;
6
+ exports.lookupDeviceAuthorization = lookupDeviceAuthorization;
7
+ exports.approveDeviceAuthorization = approveDeviceAuthorization;
8
+ exports.denyDeviceAuthorization = denyDeviceAuthorization;
9
+ /** A refused request. `code` is the server's stable error code (`NOT_FOUND`, `RATE_LIMITED`, `STEP_UP_REQUIRED`, …). */
10
+ class DeviceAuthorizationError extends Error {
11
+ code;
12
+ status;
13
+ param;
14
+ reason;
15
+ meta;
16
+ constructor(status, code, message, param, reason, meta) {
17
+ super(message);
18
+ this.name = 'DeviceAuthorizationError';
19
+ this.status = status;
20
+ this.code = code;
21
+ this.param = param;
22
+ if (reason)
23
+ this.reason = reason;
24
+ if (meta)
25
+ this.meta = meta;
26
+ }
27
+ /** True when approving needs a fresh re-authentication first. */
28
+ get needsReverification() {
29
+ return this.code === 'STEP_UP_REQUIRED';
30
+ }
31
+ /** True when the code is unknown, expired or already used. */
32
+ get isInvalidCode() {
33
+ return this.status === 404 || this.status === 409;
34
+ }
35
+ }
36
+ exports.DeviceAuthorizationError = DeviceAuthorizationError;
37
+ const BASE = '/v1/client/me/device_authorizations';
38
+ function fromWire(w) {
39
+ return {
40
+ object: 'device_authorization',
41
+ id: w.id,
42
+ userCode: w.user_code,
43
+ status: w.status,
44
+ client: {
45
+ clientId: w.client.client_id,
46
+ name: w.client.name,
47
+ logoUrl: w.client.logo_url ?? null,
48
+ homepageUrl: w.client.homepage_url ?? null,
49
+ firstParty: w.client.first_party === true,
50
+ },
51
+ scopes: w.scopes ?? [],
52
+ audience: w.audience ?? null,
53
+ requiresStepUp: w.requires_step_up === true,
54
+ createdAt: w.created_at,
55
+ expiresAt: w.expires_at,
56
+ };
57
+ }
58
+ async function call(client, path, body) {
59
+ const res = await client.request(path, { method: 'POST', body: JSON.stringify(body) });
60
+ if (!res.ok || !res.data) {
61
+ const first = res.errors[0];
62
+ throw new DeviceAuthorizationError(res.status, first?.code ?? 'UNKNOWN', first?.message ?? 'The request failed.', first?.param, first?.reason, first?.meta);
63
+ }
64
+ return fromWire(res.data);
65
+ }
66
+ /**
67
+ * Normalise what a person typed into the `XXXX-XXXX` form devices show:
68
+ * uppercase, spaces and dashes ignored. Returns the input unchanged when it is
69
+ * not 8 letters or digits, so the server answers "not valid".
70
+ */
71
+ function formatUserCode(input) {
72
+ const cleaned = input.toUpperCase().replace(/[^A-Z0-9]/g, '');
73
+ return cleaned.length === 8 ? `${cleaned.slice(0, 4)}-${cleaned.slice(4)}` : input.trim();
74
+ }
75
+ /** Read a `user_code` from a verification URL the device displayed (`?user_code=`), if any. */
76
+ function userCodeFromUrl(url) {
77
+ try {
78
+ const value = new URL(String(url)).searchParams.get('user_code');
79
+ return value ? formatUserCode(value) : null;
80
+ }
81
+ catch {
82
+ return null;
83
+ }
84
+ }
85
+ /** Look up a pending device sign-in by the code the device shows. */
86
+ async function lookupDeviceAuthorization(client, userCode) {
87
+ return call(client, `${BASE}/lookup`, { user_code: formatUserCode(userCode) });
88
+ }
89
+ /** Approve the device sign-in for the signed-in user. The device's next poll receives its tokens. */
90
+ async function approveDeviceAuthorization(client, authorization) {
91
+ return call(client, `${BASE}/${encodeURIComponent(authorization.id)}/approve`, { user_code: authorization.userCode });
92
+ }
93
+ /** Deny the device sign-in. The device's next poll is told `access_denied`. */
94
+ async function denyDeviceAuthorization(client, authorization) {
95
+ return call(client, `${BASE}/${encodeURIComponent(authorization.id)}/deny`, { user_code: authorization.userCode });
96
+ }
97
+ //# sourceMappingURL=device-authorization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-authorization.js","sourceRoot":"","sources":["../src/device-authorization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Check an emailed one-time code WITHOUT using it up.
3
+ *
4
+ * Every email-code step has a `check` endpoint beside its `attempt` endpoint:
5
+ * the server answers whether the code is right and still live (and until when),
6
+ * and leaves it redeemable, so a form can show "code accepted" as the user
7
+ * types and only submit the step when they confirm. A wrong code spends one of
8
+ * the code's attempts exactly like a submission — checking is no way around the
9
+ * lockout — and the check endpoints share the credential-verify rate budget.
10
+ *
11
+ * sign-in first factor POST /v1/client/sign_ins/:id/check_first_factor
12
+ * sign-in second factor POST /v1/client/sign_ins/:id/check_second_factor
13
+ * sign-up verification POST /v1/client/sign_ups/:id/check_verification
14
+ * step-up POST /v1/client/me/step_up/check
15
+ * add-email verification POST /v1/client/me/email_addresses/:id/check_verification
16
+ */
17
+ import type { FapiClient, FapiResponse } from './fapi';
18
+ import { type AttemptView } from './attempt';
19
+ /** A right, live code. */
20
+ export interface EmailCodeCheck {
21
+ object: 'email_code_check';
22
+ valid: true;
23
+ /** When the code stops working (ISO 8601). */
24
+ expires_at: string;
25
+ /** Wrong entries left before the code is locked. */
26
+ attempts_remaining: number;
27
+ }
28
+ /** Where the code being checked belongs. */
29
+ export type EmailCodeTarget = {
30
+ kind: 'sign_in_first_factor';
31
+ attemptId: string;
32
+ } | {
33
+ kind: 'sign_in_second_factor';
34
+ attemptId: string;
35
+ } | {
36
+ kind: 'sign_up_verification';
37
+ attemptId: string;
38
+ } | {
39
+ kind: 'step_up';
40
+ } | {
41
+ kind: 'email_address';
42
+ emailAddressId: string;
43
+ };
44
+ /** The check endpoint and body for a target. */
45
+ export declare function emailCodeCheckRequest(target: EmailCodeTarget, code: string): {
46
+ path: string;
47
+ body: Record<string, unknown>;
48
+ };
49
+ /**
50
+ * Check a code. `ok` with `data` for a right, live code; otherwise the server's
51
+ * errors — `VERIFICATION_FAILED` (wrong, expired or unknown) or
52
+ * `TOO_MANY_ATTEMPTS` (the code is locked; request a new one).
53
+ */
54
+ export declare function checkEmailCode(client: FapiClient, target: EmailCodeTarget, code: string): Promise<FapiResponse<EmailCodeCheck>>;
55
+ /**
56
+ * The check target for the code step a flow is on, or null when the current
57
+ * step takes no emailed code. An emailed code on the first-factor step, the
58
+ * email second factor, and sign-up verification are covered.
59
+ */
60
+ export declare function emailCodeTargetForAttempt(attempt: AttemptView | null | undefined): EmailCodeTarget | null;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emailCodeCheckRequest = emailCodeCheckRequest;
4
+ exports.checkEmailCode = checkEmailCode;
5
+ exports.emailCodeTargetForAttempt = emailCodeTargetForAttempt;
6
+ const attempt_1 = require("./attempt");
7
+ /** The check endpoint and body for a target. */
8
+ function emailCodeCheckRequest(target, code) {
9
+ const id = (v) => encodeURIComponent(v);
10
+ switch (target.kind) {
11
+ case 'sign_in_first_factor':
12
+ return { path: `/v1/client/sign_ins/${id(target.attemptId)}/check_first_factor`, body: { strategy: 'email_code', code } };
13
+ case 'sign_in_second_factor':
14
+ return { path: `/v1/client/sign_ins/${id(target.attemptId)}/check_second_factor`, body: { strategy: 'email_code', code } };
15
+ case 'sign_up_verification':
16
+ return { path: `/v1/client/sign_ups/${id(target.attemptId)}/check_verification`, body: { strategy: 'email_code', code } };
17
+ case 'step_up':
18
+ return { path: '/v1/client/me/step_up/check', body: { strategy: 'email_code', code } };
19
+ case 'email_address':
20
+ return { path: `/v1/client/me/email_addresses/${id(target.emailAddressId)}/check_verification`, body: { code } };
21
+ }
22
+ }
23
+ /**
24
+ * Check a code. `ok` with `data` for a right, live code; otherwise the server's
25
+ * errors — `VERIFICATION_FAILED` (wrong, expired or unknown) or
26
+ * `TOO_MANY_ATTEMPTS` (the code is locked; request a new one).
27
+ */
28
+ function checkEmailCode(client, target, code) {
29
+ const { path, body } = emailCodeCheckRequest(target, code);
30
+ return client.post(path, body);
31
+ }
32
+ /**
33
+ * The check target for the code step a flow is on, or null when the current
34
+ * step takes no emailed code. An emailed code on the first-factor step, the
35
+ * email second factor, and sign-up verification are covered.
36
+ */
37
+ function emailCodeTargetForAttempt(attempt) {
38
+ if (!attempt?.id)
39
+ return null;
40
+ switch ((0, attempt_1.nextStep)(attempt).kind) {
41
+ case 'collect_first_factor':
42
+ return { kind: 'sign_in_first_factor', attemptId: attempt.id };
43
+ case 'collect_second_factor':
44
+ return { kind: 'sign_in_second_factor', attemptId: attempt.id };
45
+ case 'collect_email_code':
46
+ return { kind: 'sign_up_verification', attemptId: attempt.id };
47
+ default:
48
+ return null;
49
+ }
50
+ }
51
+ //# sourceMappingURL=email-code-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-code-check.js","sourceRoot":"","sources":["../src/email-code-check.ts"],"names":[],"mappings":";;AAsCA,sDAcC;AAOD,wCAGC;AAOD,8DAYC;AAhED,uCAAuD;AAoBvD,gDAAgD;AAChD,SAAgB,qBAAqB,CAAC,MAAuB,EAAE,IAAY;IACzE,MAAM,EAAE,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAChD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,sBAAsB;YACzB,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5H,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,sBAAsB,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;QAC7H,KAAK,sBAAsB;YACzB,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,qBAAqB,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5H,KAAK,SAAS;YACZ,OAAO,EAAE,IAAI,EAAE,6BAA6B,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC;QACzF,KAAK,eAAe;YAClB,OAAO,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,qBAAqB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC;IACrH,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,MAAkB,EAAE,MAAuB,EAAE,IAAY;IACtF,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC3D,OAAO,MAAM,CAAC,IAAI,CAAiB,IAAI,EAAE,IAAI,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,SAAgB,yBAAyB,CAAC,OAAuC;IAC/E,IAAI,CAAC,OAAO,EAAE,EAAE;QAAE,OAAO,IAAI,CAAC;IAC9B,QAAQ,IAAA,kBAAQ,EAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,sBAAsB;YACzB,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;QACjE,KAAK,uBAAuB;YAC1B,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;QAClE,KAAK,oBAAoB;YACvB,OAAO,EAAE,IAAI,EAAE,sBAAsB,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;QACjE;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
@@ -41,6 +41,53 @@ export declare function emailDeliveryFrom(body: unknown): EmailDelivery;
41
41
  * `delivery` (not loaded yet) the list is returned unchanged.
42
42
  */
43
43
  export declare function offeredFirstFactors(strategies: readonly string[], delivery: EmailDelivery | null | undefined): string[];
44
+ /** The username rule an instance enforces (from `account.username`). */
45
+ export interface UsernameRule {
46
+ minLength: number;
47
+ maxLength: number;
48
+ /** `default` = letters, digits and `. _ -`. */
49
+ charset: 'default' | 'alphanumeric' | 'alphanumeric_underscore';
50
+ requiredAtSignUp: boolean;
51
+ }
52
+ /** How an emailed proof arrives: a code to type, a link to click, or either. */
53
+ export type EmailProofDelivery = 'code' | 'link' | 'both';
54
+ /** `account`: what a sign-in / sign-up form needs to draw itself. */
55
+ export interface AccountUx {
56
+ /** Null while usernames are off. */
57
+ username: UsernameRule | null;
58
+ /** Badge the method this browser last signed in with as "Last used". */
59
+ lastSignInMethod: boolean;
60
+ emailVerification: EmailProofDelivery;
61
+ passwordReset: EmailProofDelivery;
62
+ /** The second-factor step may offer "email me a code" ({@link prepareEmailSecondFactor}). */
63
+ emailSecondFactor: boolean;
64
+ /**
65
+ * Passkey-only sign-up ({@link startPasskeySignUp}), when the instance offers
66
+ * it: whether the form collects an email address. Null when not offered.
67
+ */
68
+ passkeySignUp: {
69
+ email: 'off' | 'optional' | 'required';
70
+ } | null;
71
+ /**
72
+ * The second factors a sign-in may set up or use, when the server says
73
+ * (`account.mfa`): an authenticator app, texted codes (on AND the app can
74
+ * text), and how many authenticator codes enrolment asks for. Absent on a
75
+ * server that does not say: the MFA steps then offer the authenticator app
76
+ * only (see `mfaChoicesFrom`).
77
+ */
78
+ mfa?: {
79
+ totp: boolean;
80
+ sms: boolean;
81
+ totpCodes: 1 | 2;
82
+ };
83
+ }
84
+ /**
85
+ * What an older server (no `account`) is taken to mean: no usernames at
86
+ * sign-up, codes only, and no "Last used" hint (it has no endpoint for one).
87
+ */
88
+ export declare const ACCOUNT_UX_DEFAULT: Readonly<AccountUx>;
89
+ /** Read `account` from a `/v1/client/environment` or `/v1/appearance` body. */
90
+ export declare function accountUxFrom(body: unknown): AccountUx;
44
91
  /** One entry of the environment's `social_providers`. */
45
92
  export interface EnvironmentSocialProvider {
46
93
  provider: string;
@@ -72,6 +119,7 @@ export interface ClientEnvironment {
72
119
  strategies: Record<string, unknown>;
73
120
  emailDelivery: EmailDelivery;
74
121
  socialProviders: EnvironmentSocialProvider[];
122
+ account: AccountUx;
75
123
  }
76
124
  /** Read a `/v1/client/environment` body. Defensive: malformed parts read as empty. */
77
125
  export declare function clientEnvironmentFrom(body: unknown): ClientEnvironment;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EMAIL_FIRST_FACTORS = exports.EMAIL_UNAVAILABLE_MESSAGE = exports.EMAIL_DELIVERY_UNKNOWN = void 0;
3
+ exports.ACCOUNT_UX_DEFAULT = exports.EMAIL_FIRST_FACTORS = exports.EMAIL_UNAVAILABLE_MESSAGE = exports.EMAIL_DELIVERY_UNKNOWN = void 0;
4
4
  exports.emailDeliveryFrom = emailDeliveryFrom;
5
5
  exports.offeredFirstFactors = offeredFirstFactors;
6
+ exports.accountUxFrom = accountUxFrom;
6
7
  exports.clientEnvironmentFrom = clientEnvironmentFrom;
7
8
  exports.fetchClientEnvironment = fetchClientEnvironment;
8
9
  /**
@@ -47,6 +48,57 @@ function offeredFirstFactors(strategies, delivery) {
47
48
  return [...strategies];
48
49
  return strategies.filter((s) => !exports.EMAIL_FIRST_FACTORS.includes(s));
49
50
  }
51
+ /**
52
+ * What an older server (no `account`) is taken to mean: no usernames at
53
+ * sign-up, codes only, and no "Last used" hint (it has no endpoint for one).
54
+ */
55
+ exports.ACCOUNT_UX_DEFAULT = Object.freeze({
56
+ username: null,
57
+ lastSignInMethod: false,
58
+ emailVerification: 'code',
59
+ passwordReset: 'code',
60
+ emailSecondFactor: false,
61
+ passkeySignUp: null,
62
+ });
63
+ const proof = (v) => (v === 'link' || v === 'both' ? v : 'code');
64
+ /** Read `account` from a `/v1/client/environment` or `/v1/appearance` body. */
65
+ function accountUxFrom(body) {
66
+ const raw = isRecord(body) && isRecord(body.account) ? body.account : null;
67
+ if (!raw)
68
+ return { ...exports.ACCOUNT_UX_DEFAULT };
69
+ const u = isRecord(raw.username) ? raw.username : null;
70
+ const n = (v, d) => (typeof v === 'number' && Number.isInteger(v) ? v : d);
71
+ return {
72
+ username: u
73
+ ? {
74
+ minLength: n(u.min_length, 3),
75
+ maxLength: n(u.max_length, 30),
76
+ charset: u.charset === 'alphanumeric' || u.charset === 'alphanumeric_underscore' ? u.charset : 'default',
77
+ requiredAtSignUp: u.required_at_sign_up === true,
78
+ }
79
+ : null,
80
+ lastSignInMethod: raw.last_sign_in_method === true,
81
+ emailVerification: proof(raw.email_verification),
82
+ passwordReset: proof(raw.password_reset),
83
+ emailSecondFactor: raw.email_second_factor === true,
84
+ ...(isRecord(raw.mfa)
85
+ ? {
86
+ mfa: {
87
+ totp: raw.mfa.totp !== false,
88
+ sms: raw.mfa.sms === true,
89
+ totpCodes: Number(raw.mfa.totp_codes ?? raw.mfa.totpCodes) >= 2 ? 2 : 1,
90
+ },
91
+ }
92
+ : {}),
93
+ passkeySignUp: isRecord(raw.passkey_sign_up)
94
+ ? {
95
+ email: raw.passkey_sign_up.email === 'off' || raw.passkey_sign_up.email === 'optional'
96
+ ? raw.passkey_sign_up.email
97
+ : 'required',
98
+ }
99
+ : null,
100
+ };
101
+ }
50
102
  /** Read a `/v1/client/environment` body. Defensive: malformed parts read as empty. */
51
103
  function clientEnvironmentFrom(body) {
52
104
  const root = isRecord(body) ? body : {};
@@ -59,6 +111,7 @@ function clientEnvironmentFrom(body) {
59
111
  socialProviders: Array.isArray(root.social_providers)
60
112
  ? root.social_providers.filter((p) => isRecord(p) && typeof p.provider === 'string')
61
113
  : [],
114
+ account: accountUxFrom(root),
62
115
  };
63
116
  }
64
117
  /** Fetch the client environment. Null when the server can't be reached or errors. */
@@ -1 +1 @@
1
- {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../src/environment.ts"],"names":[],"mappings":"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"}
package/dist/fapi.d.ts CHANGED
@@ -66,6 +66,12 @@ export interface FapiResponse<T> {
66
66
  data: T | null;
67
67
  errors: FieldError[];
68
68
  }
69
+ /**
70
+ * The starts that can create an account, and so carry the SDK's stable device
71
+ * id for the accounts-per-device abuse limit. Password and passwordless
72
+ * sign-ins never create one and do not send it.
73
+ */
74
+ export declare const DEVICE_ID_ROUTES: ReadonlySet<string>;
69
75
  export declare class FapiClient {
70
76
  private readonly options;
71
77
  constructor(options: FapiClientOptions);
@@ -155,6 +161,14 @@ export interface FlowState {
155
161
  * unknown, and for a sign-in completed on another device.
156
162
  */
157
163
  sessionKept?: boolean;
164
+ /**
165
+ * The one-time recovery codes a mid-sign-in MFA enrolment came with
166
+ * (`attempt_mfa_enrollment`'s `backup_codes`). Kept here, in memory only and
167
+ * never in `attempt` or any storage, until the user says they saved them
168
+ * (`pendingRecoveryCodes` / `acknowledgeRecoveryCodes`): the prebuilt
169
+ * components show them before exchanging the ticket.
170
+ */
171
+ recoveryCodes?: string[] | null;
158
172
  }
159
173
  export declare const initialFlow: FlowState;
160
174
  /**
@@ -195,7 +209,22 @@ export declare function startSignUp(client: FapiClient, input: {
195
209
  fields?: Record<string, string>;
196
210
  consent?: boolean;
197
211
  captchaToken?: string;
212
+ /** The username to claim, when the instance offers usernames. */
213
+ username?: string;
198
214
  }): Promise<FlowState>;
215
+ /**
216
+ * Resend a sign-up's emailed proof (a code, a link, or both — whatever the
217
+ * instance sends): `POST /v1/client/sign_ups/:id/prepare_verification`. The
218
+ * earlier code / link stops working. A refusal (a 429 with `retry_after`)
219
+ * comes back as `errors` with the attempt kept.
220
+ */
221
+ export declare function resendSignUpVerification(client: FapiClient, state: FlowState): Promise<FlowState>;
222
+ /**
223
+ * Whether a sign-up attempt is waiting on an emailed LINK only (no code to
224
+ * type): the form says "check your email" and the tab polls. `emailVerification`
225
+ * is the instance's `account.emailVerification`.
226
+ */
227
+ export declare function awaitingSignUpLink(attempt: AttemptView | null | undefined, emailVerification: string | null | undefined): boolean;
199
228
  /** §5.3: ask the server to send a code or a magic link. */
200
229
  export declare function prepareFactor(client: FapiClient, state: FlowState, strategy: 'email_code' | 'email_link'): Promise<FlowState>;
201
230
  /**