@atlasauth/js 0.33.1 → 0.34.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # @atlasauth/js changelog
2
2
 
3
+ ## 0.34.0 — 2026-11-06
4
+
5
+ - Breaking: `previewCrossDeviceLink` no longer returns a match code. Flow state carries `matchCode`, the tab stores its secret for the link page, and enrolment supports HOTP, YubiKey, Duo and passkey. A sign-up resend rotates the secret; `finished_elsewhere` ends the wait.
6
+
3
7
  ## 0.33.1 — 2026-11-05
4
8
 
5
9
  - A sign-up polls only while it waits for a proof, so a poll can no longer collect a ticket past the recovery codes.
package/dist/attempt.d.ts CHANGED
@@ -114,6 +114,8 @@ export interface AttemptIdentityVerification {
114
114
  export interface AttemptView {
115
115
  /** A sign-in link proved the address of an account whose password was on hold. No session was made: the password signs in now. */
116
116
  password_hold_released?: boolean;
117
+ /** A repeat sign-up whose earlier attempt finished: no ticket comes here; the person signs in. */
118
+ finished_elsewhere?: boolean;
117
119
  /** The code just proved an address on an existing account: the password typed at sign-up was not saved. Only on that response; `FlowState.existingAccount` keeps it. */
118
120
  existing_account?: boolean;
119
121
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"attempt.js","sourceRoot":"","sources":["../src/attempt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"attempt.js","sourceRoot":"","sources":["../src/attempt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Emailed links, both ends. A mailed link completes nothing by being opened: the
3
+ * opener must prove a tie to the tab that started the flow, or anyone who starts
4
+ * a flow with someone else's address would collect the session when they click.
5
+ *
6
+ * - Starting tab: the sign-up / sign-in response carries `poll_secret` and
7
+ * `match_code`. {@link rememberLinkProof} stores the secret for this browser;
8
+ * the flow shows the code (`FlowState.matchCode`) and polls as usual. An
9
+ * answer that mailed nothing has a secret and no code: nothing is stored or shown.
10
+ * - Link page: {@link createEmailLinkConfirmation} checks the link, tries the
11
+ * stored secret (same browser AND same origin: one click, no typing), and
12
+ * otherwise asks the person to type the code from the starting tab. Storage is
13
+ * per origin, so a flow started on another origin always types. The server never sends the
14
+ * code to this page. A success gives the opener nothing to sign in with: the
15
+ * starting tab collects the ticket by polling.
16
+ */
17
+ import type { FieldError } from './attempt';
18
+ import type { FapiClient } from './fapi';
19
+ /** Keep a mailed link's poll secret for this browser. Returns the code to show, or null when no link was mailed. */
20
+ export declare function rememberLinkProof(attemptId: string, response: {
21
+ poll_secret?: unknown;
22
+ match_code?: unknown;
23
+ }): string | null;
24
+ /** The poll secret this browser holds for an attempt, if it started it. */
25
+ export declare function readLinkSecret(attemptId: string): string | null;
26
+ /** Forget an attempt's poll secret (it completed, or the link was confirmed). */
27
+ export declare function forgetLinkSecret(attemptId: string): void;
28
+ /** Which route a mailed link belongs to: attempt ids don't say. */
29
+ export type EmailLinkFlow = 'sign_in' | 'sign_up' | 'password_reset';
30
+ /** A mailed link, as its page reads it. */
31
+ export interface EmailLink {
32
+ attempt: string;
33
+ token: string;
34
+ /** Default `sign_in`. */
35
+ flow?: EmailLinkFlow;
36
+ }
37
+ /**
38
+ * The mailed link in a URL (`?attempt=sia_…&token=…`), or null. The id's prefix
39
+ * keeps an app's own `?attempt=&token=` params from being taken for a link.
40
+ */
41
+ export declare function emailLinkFromUrl(href?: string, flow?: EmailLinkFlow): EmailLink | null;
42
+ /** Whether a mailed link is still live. Spends and completes nothing, so a mail scanner's visit is harmless. Null when refused. */
43
+ export declare function previewCrossDeviceLink(client: FapiClient, link: EmailLink): Promise<{
44
+ requiresConfirmation: boolean;
45
+ } | null>;
46
+ /** Exactly one proof: the secret this browser stored, or the code the person typed. */
47
+ export type EmailLinkProof = {
48
+ pollSecret: string;
49
+ matchCode?: never;
50
+ } | {
51
+ matchCode: string;
52
+ pollSecret?: never;
53
+ };
54
+ /**
55
+ * Confirm a mailed link. The starting tab's `pollAttempt` then returns the ticket.
56
+ * A wrong code burns the link; a wrong secret does not, so the page can ask for the code.
57
+ */
58
+ export declare function confirmCrossDeviceLink(client: FapiClient, link: EmailLink & EmailLinkProof): Promise<boolean>;
59
+ export interface EmailLinkConfirmationState {
60
+ /** `checking`, then `confirmed`, `needs_code` (draw the typed input) or `invalid` (the single refusal, for every failure). */
61
+ status: 'checking' | 'needs_code' | 'confirmed' | 'invalid';
62
+ busy: boolean;
63
+ /** Why a typed code could not be checked (rate limit, network). The link is still live. */
64
+ errors: FieldError[];
65
+ /** `confirmed`, a sign-up on an address with an account: where to reset its password. */
66
+ resetUrl?: string;
67
+ }
68
+ export interface EmailLinkConfirmation {
69
+ readonly state: EmailLinkConfirmationState;
70
+ /** Called after every state change; returns the unsubscribe. */
71
+ subscribe(listener: (state: EmailLinkConfirmationState) => void): () => void;
72
+ /** Check the link and try this browser's secret. Runs once, however often it is called. */
73
+ start(): Promise<void>;
74
+ /** Confirm with the code typed at `needs_code`. */
75
+ submitCode(code: string): Promise<void>;
76
+ }
77
+ /** The link page's state and requests, independent of any framework. */
78
+ export declare function createEmailLinkConfirmation(client: FapiClient, link: EmailLink): EmailLinkConfirmation;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.rememberLinkProof = rememberLinkProof;
4
+ exports.readLinkSecret = readLinkSecret;
5
+ exports.forgetLinkSecret = forgetLinkSecret;
6
+ exports.emailLinkFromUrl = emailLinkFromUrl;
7
+ exports.previewCrossDeviceLink = previewCrossDeviceLink;
8
+ exports.confirmCrossDeviceLink = confirmCrossDeviceLink;
9
+ exports.createEmailLinkConfirmation = createEmailLinkConfirmation;
10
+ const storageKey = (attemptId) => `atlas_link_${attemptId}`;
11
+ function storage() {
12
+ try {
13
+ return globalThis.localStorage ?? null;
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ }
19
+ /** Keep a mailed link's poll secret for this browser. Returns the code to show, or null when no link was mailed. */
20
+ function rememberLinkProof(attemptId, response) {
21
+ const code = typeof response.match_code === 'string' && response.match_code ? response.match_code : null;
22
+ if (code && typeof response.poll_secret === 'string' && response.poll_secret) {
23
+ try {
24
+ storage()?.setItem(storageKey(attemptId), response.poll_secret);
25
+ }
26
+ catch {
27
+ // Storage full or blocked: the link page falls back to the typed code.
28
+ }
29
+ }
30
+ return code;
31
+ }
32
+ /** The poll secret this browser holds for an attempt, if it started it. */
33
+ function readLinkSecret(attemptId) {
34
+ try {
35
+ return storage()?.getItem(storageKey(attemptId)) ?? null;
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ /** Forget an attempt's poll secret (it completed, or the link was confirmed). */
42
+ function forgetLinkSecret(attemptId) {
43
+ try {
44
+ storage()?.removeItem(storageKey(attemptId));
45
+ }
46
+ catch {
47
+ // Nothing to clean up where storage is blocked.
48
+ }
49
+ }
50
+ /**
51
+ * The mailed link in a URL (`?attempt=sia_…&token=…`), or null. The id's prefix
52
+ * keeps an app's own `?attempt=&token=` params from being taken for a link.
53
+ */
54
+ function emailLinkFromUrl(href, flow = 'sign_in') {
55
+ const url = href ?? globalThis.location?.href;
56
+ if (!url)
57
+ return null;
58
+ try {
59
+ const params = new URL(url).searchParams;
60
+ const attempt = params.get('attempt');
61
+ const token = params.get('token');
62
+ return attempt?.startsWith('sia_') && token ? { attempt, token, flow } : null;
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ const verifyPath = (link) => `/v1/client/${link.flow === 'sign_up' ? 'sign_ups' : link.flow === 'password_reset' ? 'password_resets' : 'sign_ins'}/verify`;
69
+ /** Whether a mailed link is still live. Spends and completes nothing, so a mail scanner's visit is harmless. Null when refused. */
70
+ async function previewCrossDeviceLink(client, link) {
71
+ const response = await client.get(`${verifyPath(link)}?attempt=${encodeURIComponent(link.attempt)}&token=${encodeURIComponent(link.token)}`);
72
+ if (!response.ok || !response.data)
73
+ return null;
74
+ return { requiresConfirmation: response.data.requires_confirmation === true };
75
+ }
76
+ function postConfirmation(client, link) {
77
+ return client.post(`${verifyPath(link)}/confirm`, {
78
+ attempt: link.attempt,
79
+ token: link.token,
80
+ ...(link.pollSecret ? { poll_secret: link.pollSecret } : { match_code: link.matchCode }),
81
+ });
82
+ }
83
+ /**
84
+ * Confirm a mailed link. The starting tab's `pollAttempt` then returns the ticket.
85
+ * A wrong code burns the link; a wrong secret does not, so the page can ask for the code.
86
+ */
87
+ async function confirmCrossDeviceLink(client, link) {
88
+ return (await postConfirmation(client, link)).ok;
89
+ }
90
+ /** The link page's state and requests, independent of any framework. */
91
+ function createEmailLinkConfirmation(client, link) {
92
+ let state = { status: 'checking', busy: false, errors: [] };
93
+ let started = false;
94
+ const listeners = new Set();
95
+ const set = (patch) => {
96
+ state = { ...state, ...patch };
97
+ for (const listener of listeners)
98
+ listener(state);
99
+ };
100
+ const confirmed = (response) => {
101
+ forgetLinkSecret(link.attempt);
102
+ const resetUrl = response.data?.reset_url;
103
+ // Only a page a link can safely go to.
104
+ set({ status: 'confirmed', busy: false, errors: [], ...(typeof resetUrl === 'string' && /^https:\/\//i.test(resetUrl) ? { resetUrl } : {}) });
105
+ };
106
+ return {
107
+ get state() {
108
+ return state;
109
+ },
110
+ subscribe(listener) {
111
+ listeners.add(listener);
112
+ return () => listeners.delete(listener);
113
+ },
114
+ async start() {
115
+ if (started)
116
+ return;
117
+ started = true;
118
+ const preview = await previewCrossDeviceLink(client, link);
119
+ if (!preview?.requiresConfirmation) {
120
+ set({ status: 'invalid' });
121
+ return;
122
+ }
123
+ const pollSecret = readLinkSecret(link.attempt);
124
+ if (pollSecret) {
125
+ const response = await postConfirmation(client, { ...link, pollSecret });
126
+ if (response.ok) {
127
+ confirmed(response);
128
+ return;
129
+ }
130
+ }
131
+ set({ status: 'needs_code' });
132
+ },
133
+ async submitCode(code) {
134
+ const matchCode = code.replace(/\s+/g, '');
135
+ // An empty submit must not reach the server: a wrong code burns the link.
136
+ if (state.status !== 'needs_code' || state.busy || !matchCode)
137
+ return;
138
+ set({ busy: true, errors: [] });
139
+ const response = await postConfirmation(client, { ...link, matchCode });
140
+ if (response.ok) {
141
+ confirmed(response);
142
+ }
143
+ else if (response.status === 0 || response.status === 429) {
144
+ // Never reached the check, so the link wasn't burned: let them try again.
145
+ set({ busy: false, errors: response.errors });
146
+ }
147
+ else {
148
+ set({ status: 'invalid', busy: false, errors: [] });
149
+ }
150
+ },
151
+ };
152
+ }
153
+ //# sourceMappingURL=email-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-link.js","sourceRoot":"","sources":["../src/email-link.ts"],"names":[],"mappings":";;AA8BA,8CAUC;AAGD,wCAMC;AAGD,4CAMC;AAiBD,4CAWC;AAMD,wDAMC;AAiBD,wDAEC;AAuBD,kEAwDC;AAjLD,MAAM,UAAU,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,cAAc,SAAS,EAAE,CAAC;AAEpE,SAAS,OAAO;IACd,IAAI,CAAC;QACH,OAAQ,UAAyC,CAAC,YAAY,IAAI,IAAI,CAAC;IACzE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,oHAAoH;AACpH,SAAgB,iBAAiB,CAAC,SAAiB,EAAE,QAAyD;IAC5G,MAAM,IAAI,GAAG,OAAO,QAAQ,CAAC,UAAU,KAAK,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;IACzG,IAAI,IAAI,IAAI,OAAO,QAAQ,CAAC,WAAW,KAAK,QAAQ,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC7E,IAAI,CAAC;YACH,OAAO,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;QAClE,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;QACzE,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2EAA2E;AAC3E,SAAgB,cAAc,CAAC,SAAiB;IAC9C,IAAI,CAAC;QACH,OAAO,OAAO,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,SAAgB,gBAAgB,CAAC,SAAiB;IAChD,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,gDAAgD;IAClD,CAAC;AACH,CAAC;AAaD;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,IAAa,EAAE,OAAsB,SAAS;IAC7E,MAAM,GAAG,GAAG,IAAI,IAAK,UAA+C,CAAC,QAAQ,EAAE,IAAI,CAAC;IACpF,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;QACzC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,OAAO,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAAe,EAAE,EAAE,CACrC,cAAc,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU,SAAS,CAAC;AAEhI,mIAAmI;AAC5H,KAAK,UAAU,sBAAsB,CAAC,MAAkB,EAAE,IAAe;IAC9E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,GAAG,CAC/B,GAAG,UAAU,CAAC,IAAI,CAAC,YAAY,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAC1G,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAChD,OAAO,EAAE,oBAAoB,EAAE,QAAQ,CAAC,IAAI,CAAC,qBAAqB,KAAK,IAAI,EAAE,CAAC;AAChF,CAAC;AAKD,SAAS,gBAAgB,CAAC,MAAkB,EAAE,IAAgC;IAC5E,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE;QAChD,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;KACzF,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,sBAAsB,CAAC,MAAkB,EAAE,IAAgC;IAC/F,OAAO,CAAC,MAAM,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AACnD,CAAC;AAsBD,wEAAwE;AACxE,SAAgB,2BAA2B,CAAC,MAAkB,EAAE,IAAe;IAC7E,IAAI,KAAK,GAA+B,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACxF,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,GAAG,EAA2C,CAAC;IACrE,MAAM,GAAG,GAAG,CAAC,KAA0C,EAAE,EAAE;QACzD,KAAK,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,CAAC;QAC/B,KAAK,MAAM,QAAQ,IAAI,SAAS;YAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,QAA+C,EAAE,EAAE;QACpE,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;QAC1C,uCAAuC;QACvC,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,QAAQ,KAAK,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAChJ,CAAC,CAAC;IACF,OAAO;QACL,IAAI,KAAK;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,SAAS,CAAC,QAAQ;YAChB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,CAAC,KAAK;YACT,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,CAAC;gBACnC,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,MAAM,UAAU,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;gBACzE,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAChB,SAAS,CAAC,QAAQ,CAAC,CAAC;oBACpB,OAAO;gBACT,CAAC;YACH,CAAC;YACD,GAAG,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,IAAI;YACnB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3C,0EAA0E;YAC1E,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAO;YACtE,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YAChC,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;YACxE,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,SAAS,CAAC,QAAQ,CAAC,CAAC;YACtB,CAAC;iBAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5D,0EAA0E;gBAC1E,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -85,6 +85,8 @@ export interface AccountUx {
85
85
  hotp?: boolean;
86
86
  yubikey?: boolean;
87
87
  duo?: boolean;
88
+ /** A verified passkey as the second factor. */
89
+ passkey?: boolean;
88
90
  securityQuestions?: boolean;
89
91
  smartCard?: boolean;
90
92
  };
@@ -91,6 +91,7 @@ function accountUxFrom(body) {
91
91
  ...(raw.mfa.hotp === true ? { hotp: true } : {}),
92
92
  ...(raw.mfa.yubikey === true ? { yubikey: true } : {}),
93
93
  ...(raw.mfa.duo === true ? { duo: true } : {}),
94
+ ...(raw.mfa.passkey === true ? { passkey: true } : {}),
94
95
  ...(raw.mfa.security_questions === true ? { securityQuestions: true } : {}),
95
96
  ...(raw.mfa.smart_card === true ? { smartCard: true } : {}),
96
97
  },
@@ -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/errors.d.ts CHANGED
@@ -13,7 +13,7 @@
13
13
  * `error.<reason>` keys. Listed for docs and coverage checks; a reason missing
14
14
  * from this list still renders (as the server's `message`).
15
15
  */
16
- export declare const ERROR_REASONS: readonly ["form_password_incorrect", "form_code_incorrect", "form_code_already_used", "form_code_expired", "form_code_max_attempts", "form_link_invalid", "form_identifier_not_found", "form_identifier_exists", "form_password_pwned", "form_password_too_short", "form_password_too_long", "form_password_requires_uppercase", "form_password_requires_lowercase", "form_password_requires_number", "form_password_requires_symbol", "form_password_not_allowed", "form_password_contains_identifier", "form_password_same_as_current", "form_password_reused", "password_expired", "email_not_verified", "sign_in_token_invalid", "too_many_attempts", "too_many_requests", "captcha_required", "captcha_failed", "captcha_unavailable", "email_delivery_unavailable", "strategy_disabled", "sign_up_restricted", "sign_up_denied", "password_not_yet_usable", "account_deleted", "waitlisted", "identifier_not_allowed", "disposable_email_blocked", "sso_required", "sign_ins_disabled", "sign_ups_disabled", "high_risk_blocked", "sms_region_blocked", "github_team_required"];
16
+ export declare const ERROR_REASONS: readonly ["form_password_incorrect", "form_code_incorrect", "form_code_already_used", "form_code_expired", "form_code_max_attempts", "form_link_invalid", "form_identifier_not_found", "form_identifier_exists", "form_password_pwned", "form_password_too_short", "form_password_too_long", "form_password_requires_uppercase", "form_password_requires_lowercase", "form_password_requires_number", "form_password_requires_symbol", "form_password_not_allowed", "form_password_contains_identifier", "form_password_same_as_current", "form_password_reused", "password_expired", "email_not_verified", "mfa_setup_unavailable", "sign_in_token_invalid", "too_many_attempts", "too_many_requests", "captcha_required", "captcha_failed", "captcha_unavailable", "email_delivery_unavailable", "strategy_disabled", "sign_up_restricted", "sign_up_denied", "password_not_yet_usable", "account_deleted", "waitlisted", "identifier_not_allowed", "disposable_email_blocked", "sso_required", "sign_ins_disabled", "sign_ups_disabled", "high_risk_blocked", "sms_region_blocked", "github_team_required"];
17
17
  /** A reason with a string in every shipped catalog. */
18
18
  export type ErrorReason = (typeof ERROR_REASONS)[number];
19
19
  /** The catalog key for a reason: `error.<reason>`. */
package/dist/errors.js CHANGED
@@ -41,6 +41,7 @@ exports.ERROR_REASONS = Object.freeze([
41
41
  'form_password_reused',
42
42
  'password_expired',
43
43
  'email_not_verified',
44
+ 'mfa_setup_unavailable',
44
45
  'sign_in_token_invalid',
45
46
  'too_many_attempts',
46
47
  'too_many_requests',
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/fapi.d.ts CHANGED
@@ -253,7 +253,7 @@ export interface FlowState {
253
253
  * server returns a new attempt.
254
254
  */
255
255
  prepared?: 'email_code' | 'email_link' | null;
256
- /** Cross-device link: the code to show on this device; the device that opens the link shows the same one. */
256
+ /** A mailed link: the code to show on this device, which a person opening the link on another device must type there. */
257
257
  matchCode?: string | null;
258
258
  /**
259
259
  * After a sign-in completed here: true when this browser now holds the
@@ -342,7 +342,9 @@ export declare function startSignUp(client: FapiClient, input: {
342
342
  * Resend a sign-up's emailed proof (a code, a link, or both — whatever the
343
343
  * instance sends): `POST /v1/client/sign_ups/:id/prepare_verification`. The
344
344
  * earlier code / link stops working. A refusal (a 429 with `retry_after`)
345
- * comes back as `errors` with the attempt kept.
345
+ * comes back as `errors` with the attempt kept. A new link rotates the poll
346
+ * secret (the old one stops working) and comes with a new code: both replace the
347
+ * old ones, here and in this browser's storage.
346
348
  */
347
349
  export declare function resendSignUpVerification(client: FapiClient, state: FlowState): Promise<FlowState>;
348
350
  /**
@@ -360,31 +362,11 @@ export declare function attemptPasswordHoldProof(client: FapiClient, state: Flow
360
362
  */
361
363
  export declare function awaitingSignUpLink(attempt: AttemptView | null | undefined, emailVerification: string | null | undefined): boolean;
362
364
  /** §5.3: ask the server to send a code or a magic link. */
363
- export declare function prepareFactor(client: FapiClient, state: FlowState, strategy: 'email_code' | 'email_link', opts?: {
365
+ export declare function prepareFactor(client: FapiClient, state: FlowState, strategy: 'email_code' | 'email_link',
366
+ /** @deprecated Every mailed link now needs a tie to this tab; this changes nothing. */
367
+ _opts?: {
364
368
  crossDevice?: boolean;
365
369
  }): Promise<FlowState>;
366
- /** What the page the cross-device link opens needs: whether to ask for confirmation, and the code to compare. */
367
- export interface CrossDeviceLinkPreview {
368
- requiresConfirmation: boolean;
369
- matchCode: string | null;
370
- }
371
- /**
372
- * Cross-device magic link, second device: read the code from the opened link (`?attempt=&token=&cross_device=1`)
373
- * so the page can show it next to the prompt "does this match the code on your other device?". Completes nothing.
374
- */
375
- export declare function previewCrossDeviceLink(client: FapiClient, link: {
376
- attempt: string;
377
- token: string;
378
- }): Promise<CrossDeviceLinkPreview | null>;
379
- /**
380
- * Cross-device magic link, second device: confirm with the code both devices show. The first device's
381
- * `pollAttempt` then returns the ticket. One use; a wrong code invalidates the link.
382
- */
383
- export declare function confirmCrossDeviceLink(client: FapiClient, link: {
384
- attempt: string;
385
- token: string;
386
- matchCode: string;
387
- }): Promise<boolean>;
388
370
  /**
389
371
  * §5.3 polling. Returns the updated flow, and a ticket once the link has been
390
372
  * opened somewhere.
@@ -407,7 +389,8 @@ export declare function acknowledgeExistingAccount(state: FlowState): FlowState;
407
389
  /**
408
390
  * A sign-up's emailed link proved the address and made no session, so this tab
409
391
  * can only go and sign in. The tab's poll secret proves nothing about the mailbox:
410
- * say the same thing whichever account the address belongs to.
392
+ * say the same thing whichever account the address belongs to. So too a repeat
393
+ * sign-up whose earlier attempt finished (`finished_elsewhere`).
411
394
  */
412
395
  export declare function signUpProvedByLink(attempt: AttemptView | null | undefined): boolean;
413
396
  /**
package/dist/fapi.js CHANGED
@@ -17,8 +17,6 @@ exports.preparePasswordHoldProof = preparePasswordHoldProof;
17
17
  exports.attemptPasswordHoldProof = attemptPasswordHoldProof;
18
18
  exports.awaitingSignUpLink = awaitingSignUpLink;
19
19
  exports.prepareFactor = prepareFactor;
20
- exports.previewCrossDeviceLink = previewCrossDeviceLink;
21
- exports.confirmCrossDeviceLink = confirmCrossDeviceLink;
22
20
  exports.pollAttempt = pollAttempt;
23
21
  exports.shouldKeepPolling = shouldKeepPolling;
24
22
  exports.pendingExistingAccountNotice = pendingExistingAccountNotice;
@@ -31,6 +29,7 @@ const policies_1 = require("./policies");
31
29
  const attempt_1 = require("./attempt");
32
30
  const sdk_advisory_1 = require("./sdk-advisory");
33
31
  const dev_browser_1 = require("./dev-browser");
32
+ const email_link_1 = require("./email-link");
34
33
  const mfa_enrollment_1 = require("./mfa-enrollment");
35
34
  const referral_1 = require("./referral");
36
35
  const telemetry_1 = require("./telemetry");
@@ -432,6 +431,19 @@ function requestForStep(attempt, values) {
432
431
  body: { factor_id: values.factorId ?? '', code: values.code ?? '' },
433
432
  };
434
433
  }
434
+ if (values.enrollStrategy === 'hotp' || values.enrollStrategy === 'duo' || values.enrollStrategy === 'yubikey' || values.enrollStrategy === 'passkey') {
435
+ const strategy = values.enrollStrategy;
436
+ return {
437
+ path: `/v1/client/sign_ins/${id}/attempt_mfa_enrollment`,
438
+ body: strategy === 'hotp'
439
+ ? { strategy, factor_id: values.factorId ?? '', code: values.code ?? '' }
440
+ : strategy === 'duo'
441
+ ? { strategy, factor_id: values.factorId ?? '' }
442
+ : strategy === 'yubikey'
443
+ ? { strategy, otp: values.otp ?? '' }
444
+ : { strategy, challenge: values.challenge ?? '', attestation_object: values.attestation_object ?? '', client_data_json: values.client_data_json ?? '' },
445
+ };
446
+ }
435
447
  return {
436
448
  path: `/v1/client/sign_ins/${id}/attempt_mfa_enrollment`,
437
449
  body: {
@@ -568,6 +580,8 @@ async function advance(client, state, values) {
568
580
  const { backup_codes: backupCodes, ...view } = response.data;
569
581
  const recoveryCodes = (0, mfa_enrollment_1.recoveryCodesFrom)(backupCodes);
570
582
  const sameAttempt = view.id === state.attempt?.id && view.status === state.attempt?.status;
583
+ if (state.attempt?.id && (0, attempt_1.isTerminal)(view))
584
+ (0, email_link_1.forgetLinkSecret)(state.attempt.id);
571
585
  return {
572
586
  attempt: view,
573
587
  errors: [],
@@ -576,6 +590,7 @@ async function advance(client, state, values) {
576
590
  // A completion response carries the ticket to exchange for cookies.
577
591
  ticket: view.ticket ?? null,
578
592
  prepared: sameAttempt ? (state.prepared ?? null) : null,
593
+ ...(sameAttempt && state.matchCode ? { matchCode: state.matchCode } : {}),
579
594
  ...(view.existing_account || state.existingAccount ? { existingAccount: true } : {}),
580
595
  ...(recoveryCodes ? { recoveryCodes } : {}),
581
596
  ...(view.policy_acceptance_token || view.required_action_token
@@ -610,6 +625,7 @@ async function startSignUp(client, input) {
610
625
  if (!response.ok || !response.data) {
611
626
  return { ...exports.initialFlow, busy: false, errors: response.errors };
612
627
  }
628
+ const matchCode = (0, email_link_1.rememberLinkProof)(response.data.id ?? '', response.data);
613
629
  return {
614
630
  attempt: response.data,
615
631
  errors: [],
@@ -618,6 +634,7 @@ async function startSignUp(client, input) {
618
634
  // tab collects the session by polling with the secret the create returned.
619
635
  pollSecret: response.data.poll_secret ?? exports.initialFlow.pollSecret,
620
636
  ticket: response.data.ticket ?? null,
637
+ ...(matchCode ? { matchCode } : {}),
621
638
  ...(response.data.policy_acceptance_token || response.data.required_action_token ? { policyToken: response.data.policy_acceptance_token ?? response.data.required_action_token } : {}),
622
639
  };
623
640
  }
@@ -625,14 +642,26 @@ async function startSignUp(client, input) {
625
642
  * Resend a sign-up's emailed proof (a code, a link, or both — whatever the
626
643
  * instance sends): `POST /v1/client/sign_ups/:id/prepare_verification`. The
627
644
  * earlier code / link stops working. A refusal (a 429 with `retry_after`)
628
- * comes back as `errors` with the attempt kept.
645
+ * comes back as `errors` with the attempt kept. A new link rotates the poll
646
+ * secret (the old one stops working) and comes with a new code: both replace the
647
+ * old ones, here and in this browser's storage.
629
648
  */
630
649
  async function resendSignUpVerification(client, state) {
631
650
  const id = state.attempt?.id;
632
651
  if (!id)
633
652
  return state;
634
653
  const response = await client.post(`/v1/client/sign_ups/${id}/prepare_verification`, {});
635
- return response.ok ? { ...state, busy: false, errors: [] } : { ...state, busy: false, errors: response.errors };
654
+ if (!response.ok)
655
+ return { ...state, busy: false, errors: response.errors };
656
+ const pollSecret = response.data?.poll_secret;
657
+ // No new secret: only a code went out, and the tab's wait is unchanged.
658
+ if (!pollSecret)
659
+ return { ...state, busy: false, errors: [] };
660
+ const matchCode = (0, email_link_1.rememberLinkProof)(id, response.data ?? {});
661
+ // Rotated with nothing mailed: the stored secret is dead, and there's no code to show.
662
+ if (!matchCode)
663
+ (0, email_link_1.forgetLinkSecret)(id);
664
+ return { ...state, busy: false, errors: [], pollSecret, matchCode };
636
665
  }
637
666
  /**
638
667
  * Email the proof that lifts a password hold (`FlowState.passwordHold`), through
@@ -646,12 +675,14 @@ async function preparePasswordHoldProof(client, state, via = 'email_code') {
646
675
  const response = await client.post(`/v1/client/sign_ups/${hold.attemptId}/prepare_verification`, {});
647
676
  if (!response.ok)
648
677
  return { ...state, busy: false, errors: response.errors };
678
+ const matchCode = (0, email_link_1.rememberLinkProof)(hold.attemptId, response.data ?? {});
649
679
  return {
650
680
  ...state,
651
681
  busy: false,
652
682
  errors: [],
653
683
  pollSecret: null,
654
684
  prepared: via,
685
+ ...(matchCode ? { matchCode } : {}),
655
686
  passwordHold: { ...hold, email: response.data?.identifier ?? null },
656
687
  };
657
688
  }
@@ -677,11 +708,13 @@ function awaitingSignUpLink(attempt, emailVerification) {
677
708
  emailVerification === 'link');
678
709
  }
679
710
  /** §5.3: ask the server to send a code or a magic link. */
680
- async function prepareFactor(client, state, strategy, opts = {}) {
711
+ async function prepareFactor(client, state, strategy,
712
+ /** @deprecated Every mailed link now needs a tie to this tab; this changes nothing. */
713
+ _opts = {}) {
681
714
  const id = state.attempt?.id;
682
715
  if (!id)
683
716
  return state;
684
- const response = await client.post(`/v1/client/sign_ins/${id}/prepare_first_factor`, { strategy, ...(opts.crossDevice && strategy === 'email_link' ? { cross_device: true } : {}) });
717
+ const response = await client.post(`/v1/client/sign_ins/${id}/prepare_first_factor`, { strategy });
685
718
  if (!response.ok)
686
719
  return { ...state, busy: false, errors: response.errors };
687
720
  return {
@@ -693,27 +726,9 @@ async function prepareFactor(client, state, strategy, opts = {}) {
693
726
  // there is nothing to poll for.
694
727
  pollSecret: strategy === 'email_link' ? (response.data?.poll_secret ?? null) : null,
695
728
  prepared: strategy,
696
- matchCode: response.data?.match_code ?? null,
729
+ matchCode: strategy === 'email_link' ? (0, email_link_1.rememberLinkProof)(id, response.data ?? {}) : null,
697
730
  };
698
731
  }
699
- /**
700
- * Cross-device magic link, second device: read the code from the opened link (`?attempt=&token=&cross_device=1`)
701
- * so the page can show it next to the prompt "does this match the code on your other device?". Completes nothing.
702
- */
703
- async function previewCrossDeviceLink(client, link) {
704
- const response = await client.get(`/v1/client/sign_ins/verify?attempt=${encodeURIComponent(link.attempt)}&token=${encodeURIComponent(link.token)}&cross_device=1`);
705
- if (!response.ok || !response.data)
706
- return null;
707
- return { requiresConfirmation: response.data.requires_confirmation === true, matchCode: response.data.match_code ?? null };
708
- }
709
- /**
710
- * Cross-device magic link, second device: confirm with the code both devices show. The first device's
711
- * `pollAttempt` then returns the ticket. One use; a wrong code invalidates the link.
712
- */
713
- async function confirmCrossDeviceLink(client, link) {
714
- const response = await client.post('/v1/client/sign_ins/verify/confirm', { attempt: link.attempt, token: link.token, match_code: link.matchCode });
715
- return response.ok;
716
- }
717
732
  /**
718
733
  * §5.3 polling. Returns the updated flow, and a ticket once the link has been
719
734
  * opened somewhere.
@@ -731,15 +746,18 @@ async function pollAttempt(client, state) {
731
746
  // no session: the password signs in now, so stop polling and ask for it.
732
747
  if (response.data.password_hold_released) {
733
748
  const email = response.data.identifier ?? null;
749
+ (0, email_link_1.forgetLinkSecret)(id);
734
750
  return {
735
- state: { ...state, attempt: response.data, pollSecret: null, prepared: null, passwordHold: { attemptId: id, email, released: true } },
751
+ state: { ...state, attempt: response.data, pollSecret: null, prepared: null, matchCode: null, passwordHold: { attemptId: id, email, released: true } },
736
752
  ticket: null,
737
753
  };
738
754
  }
739
- return {
740
- state: { ...state, attempt: response.data },
741
- ticket: response.data.ticket ?? null,
742
- };
755
+ const next = { ...state, attempt: response.data };
756
+ if (shouldKeepPolling(next))
757
+ return { state: next, ticket: response.data.ticket ?? null };
758
+ // The wait is over, one way or another: the code and the stored secret are done with.
759
+ (0, email_link_1.forgetLinkSecret)(id);
760
+ return { state: { ...next, matchCode: null }, ticket: response.data.ticket ?? null };
743
761
  }
744
762
  /** Whether polling should continue, so a tab does not poll a dead attempt forever. */
745
763
  function shouldKeepPolling(state) {
@@ -748,6 +766,9 @@ function shouldKeepPolling(state) {
748
766
  // A sign-up polls for its link only. Past that this tab drives every step (the passkey,
749
767
  // MFA set-up, policies), and a poll that collected a ticket would skip the recovery codes.
750
768
  const a = state.attempt;
769
+ // An earlier sign-up for this address finished: no ticket will ever come here.
770
+ if (a.finished_elsewhere)
771
+ return false;
751
772
  return !(a.object === 'sign_up_attempt' && a.status !== 'needs_email_verification');
752
773
  }
753
774
  /**
@@ -766,13 +787,14 @@ function acknowledgeExistingAccount(state) {
766
787
  /**
767
788
  * A sign-up's emailed link proved the address and made no session, so this tab
768
789
  * can only go and sign in. The tab's poll secret proves nothing about the mailbox:
769
- * say the same thing whichever account the address belongs to.
790
+ * say the same thing whichever account the address belongs to. So too a repeat
791
+ * sign-up whose earlier attempt finished (`finished_elsewhere`).
770
792
  */
771
793
  function signUpProvedByLink(attempt) {
772
794
  return (!!attempt &&
773
795
  attempt.object === 'sign_up_attempt' &&
774
- attempt.status === 'needs_first_factor' &&
775
- !(attempt.supported_first_factors ?? []).includes('passkey'));
796
+ (attempt.finished_elsewhere === true ||
797
+ (attempt.status === 'needs_first_factor' && !(attempt.supported_first_factors ?? []).includes('passkey'))));
776
798
  }
777
799
  /**
778
800
  * Where `signUpProvedByLink`'s "Sign in" goes: `url` when the app has its own page,