@atlasauth/js 0.11.0 → 0.13.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,42 @@
1
1
  # @atlasauth/js changelog
2
2
 
3
+ ## 0.13.0
4
+ - **New: referral attribution.** A `FapiClient` captures the referral the visitor arrived with and sends it as `referral: { code, click_id, anon_id, consent, captured_at }` on every sign-in / sign-up start (`/v1/client/sign_ups`, `/v1/client/sign_ins`, OAuth / SSO / SAML / native id_token / passkey / wallet starts) and the steps that continue one, when the instance has referrals on. The code comes from the instance's URL parameters (default `ref`, `via`, `aff`) on the current page, the page the SDK loaded on, and their `redirect_url` / `after_url`. The instance's tracking cookie is read only under consent: Cookie Munch on the page decides (the instance's category, else its fallback category); otherwise the new `referralConsent` option (`'granted'` or a function) does. The SDK never writes the cookie. New `FapiClientOptions.referral?: false` (opt out) and `referralConsent?`; page-wide `configureReferralCapture({ referral, referralConsent })`. The config is read from `referrals` in `GET /v1/client/environment` / `GET /v1/appearance` (one read per page; nothing is fetched when there is no query and no config yet).
5
+ - **Referred sign-up challenge.** `fetchInstanceSettings` switches the sign-up and sign-in captcha on when a referral code was captured and the instance's `referrals.challenge_referred_signups` is `always` (as long as a captcha provider is configured). New exports: `referralChallengeRequired`, `withReferralChallenge`, `referralChallengeFlows`, `captureReferral`, `referralConfigFrom`, `parseReferralCookie`, `acceptsReferral`, `seedReferralConfig`, `referralCacheKeyFor`, types `ReferralConfig`, `ReferralCapture`, `ReferralConsent`, `ReferralCaptureOptions`.
6
+ - `FapiClient.post` is now `async` (it already returned a promise).
7
+
8
+ ## 0.12.0
9
+ - **New: SDK identity and advisories.** `FapiClientOptions.sdk?: AtlasSdkInfo` (`{ name, version }`, default
10
+ `@atlasauth/js`) is sent as `X-Atlas-SDK: <name>/<version>`; an `Atlas-SDK-Advisory` response header is logged once
11
+ per advisory per page load. New exports: `ATLAS_JS_VERSION`, `ATLAS_JS_SDK`, `AtlasSdkInfo`, `SDK_HEADER`,
12
+ `SDK_ADVISORY_HEADER`, `sdkHeaderValue()`, `parseSdkAdvisory()`, `reportSdkAdvisory()`, `resetSdkAdvisoryLog()`,
13
+ `SdkAdvisoryNotice`.
14
+ - **New: sign-out events.** `SignOutNotifier` (`subscribe`, `expect(reason)`, `clear`, `signedOut(sessionId, fallback?)`),
15
+ `SignOutEvent` (`{ reason, sessionId }`), `SignOutReason` (`'user' | 'other_tab' | 'session_expired' | 'revoked' |
16
+ 'unknown'`), `SignOutListener`, `SIGN_OUT_EVENT` (`'atlas:signout'`), `dispatchSignOutEvent()`, `onAtlasSignOut()` and
17
+ `signOutReasonFromClient()` (reads the new `signed_out_reason` of a signed-out `GET /v1/client`). Every framework
18
+ provider drives one.
19
+ - **New: `getTemplateToken(client, sessionId, template)`** → `{ jwt, expiresIn } | null` (`getToken({ template })`), and
20
+ **`getForumulateReaderToken(client, spaceId?)`** → `{ jwt, expiresIn, orgId, spaceId, redeemUrl } | null`
21
+ (`GET /v1/client/forumulate/reader_token`).
22
+ - **New: the Atlas captcha (provider `atlas`).** Atlas's own captcha needs no provider account or keys.
23
+ `renderCaptchaWidget` (and so every prebuilt form using `createCaptchaController`) draws it when a flow's provider is
24
+ `atlas`: it fetches a challenge, solves the proof of work in Web Workers (on the page when workers are blocked) and
25
+ shows the shape-matching step only when the server asks for it, with an accessible alternative.
26
+ - **New exports:** `renderAtlasCaptcha(container, { fetchChallenge?, challengeUrl?, mode?, labels?, workers? })` →
27
+ `{ token: Promise<string>; stale(): boolean; remove(): void }`, `solveAtlasChallenge(challenge, { workers?, cancelled? })`
28
+ → `Promise<{ n, worker }>`, `searchAtlasRange`, `fetchAtlasChallenge(url, accessible?)`, `encodeAtlasToken(solution)`,
29
+ `ATLAS_CAPTCHA_LABELS`, types `AtlasChallenge`, `AtlasCaptchaOptions`, `AtlasCaptchaLabels`, `AtlasCaptchaHandle`.
30
+ - **Added `FlowCaptcha.challengeUrl?: string`** (read from `/v1/appearance` `captchaFlows[flow].challengeUrl`).
31
+ - **Added `CaptchaWidgetHandle.stale?(): boolean`**: a solved token about to expire unspent; the captcha controller
32
+ draws a fresh widget instead of sending it.
33
+ - **Added an optional third argument to `renderCaptchaWidget` / `getCaptchaToken`:** `{ atlas?: { fetchChallenge?, labels?, workers? } }`.
34
+ - `captcha(client).protect(el, action?)` supports `atlas` (the challenge is fetched through the client).
35
+ - **New: `atlasCaptchaLabels(lookup)`** → `Partial<AtlasCaptchaLabels>` from a translator or a flat catalog (keys in
36
+ `ATLAS_CAPTCHA_LABEL_KEYS`, e.g. `captcha.puzzleTile`); unknown or echoed keys keep the English default.
37
+ - **New: second argument to `createCaptchaController(initial?, settings?)`**: `{ atlasLabels?: () => Partial<AtlasCaptchaLabels> }`,
38
+ read each time a widget is drawn. New type `CaptchaControllerSettings`.
39
+
3
40
  ## 0.11.0
4
41
  - **New: `fetchAtlasInitialState({ publishableKey, frontendApi, fetchImpl?, init?, timeoutMs? })`** →
5
42
  `Promise<AtlasInitialState>` (`{ appearance?: unknown; environment?: unknown }`). Fetches `/v1/appearance` and
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Atlas's own captcha (provider `atlas`), the browser half. Dependency-free.
3
+ *
4
+ * No third-party script and no site key: the widget fetches a signed,
5
+ * single-use challenge from the instance's Frontend API, finds the number `n`
6
+ * with SHA-256(salt + n) = challenge (proof of work, in Web Workers via
7
+ * `crypto.subtle`, falling back to the page thread when workers are blocked),
8
+ * and, only when the server decided the request looks risky, shows a
9
+ * "select every matching shape" step with an accessible alternative (more
10
+ * work instead of the puzzle). The flow's request then carries
11
+ * `atlas1.<base64url JSON>` as `captcha_token`.
12
+ *
13
+ * Invisible by default: at low risk nothing is drawn and the work takes a
14
+ * fraction of a second.
15
+ */
16
+ /** A challenge, exactly as `GET /v1/client/captcha/challenge` returns it. */
17
+ export interface AtlasChallenge {
18
+ object: 'captcha_challenge';
19
+ provider: 'atlas';
20
+ token: string;
21
+ algorithm: 'SHA-256';
22
+ salt: string;
23
+ challenge: string;
24
+ maxnumber: number;
25
+ expires_at: string;
26
+ interactive: {
27
+ kind: 'match_shapes';
28
+ example: string;
29
+ tiles: string[];
30
+ } | null;
31
+ accessible_alternative: boolean;
32
+ }
33
+ /** The words the widget shows. English defaults; pass your own to localise. */
34
+ export interface AtlasCaptchaLabels {
35
+ checking: string;
36
+ verified: string;
37
+ puzzlePrompt: string;
38
+ confirm: string;
39
+ /** `{n}` is the tile number. */
40
+ tile: string;
41
+ alternative: string;
42
+ }
43
+ export declare const ATLAS_CAPTCHA_LABELS: AtlasCaptchaLabels;
44
+ /**
45
+ * The catalog keys of the widget's words, as in `@atlasauth/localizations` and
46
+ * every SDK's built-in catalog.
47
+ */
48
+ export declare const ATLAS_CAPTCHA_LABEL_KEYS: Readonly<Record<keyof AtlasCaptchaLabels, string>>;
49
+ /**
50
+ * The widget's labels from a form's translator (or any catalog lookup). A key
51
+ * the lookup does not know (no value, or the key echoed back) keeps the English
52
+ * default.
53
+ */
54
+ export declare function atlasCaptchaLabels(lookup: ((key: string) => string | null | undefined) | Readonly<Record<string, unknown>> | null | undefined): Partial<AtlasCaptchaLabels>;
55
+ export interface AtlasCaptchaOptions {
56
+ /**
57
+ * Fetch a fresh challenge. Defaults to a GET of the flow's `challengeUrl`
58
+ * (from `/v1/appearance`). `accessible` asks for the no-puzzle alternative.
59
+ */
60
+ fetchChallenge?: (accessible: boolean) => Promise<AtlasChallenge>;
61
+ /** Where the default fetcher GETs (the flow's `challengeUrl`). */
62
+ challengeUrl?: string;
63
+ /**
64
+ * `managed` (default) solves as soon as it is drawn and shows nothing unless
65
+ * the puzzle is needed; `invisible` is the same, drawn only at submit;
66
+ * `visible` always shows the check (and the server always adds the puzzle).
67
+ */
68
+ mode?: 'invisible' | 'managed' | 'visible';
69
+ labels?: Partial<AtlasCaptchaLabels>;
70
+ /** Use Web Workers when available (default true). */
71
+ workers?: boolean;
72
+ }
73
+ /**
74
+ * Search [from, to] for n with SHA-256(salt + n) = challenge, on this thread.
75
+ * Each batch awaits `crypto.subtle`, so the page stays responsive.
76
+ */
77
+ export declare function searchAtlasRange(c: Pick<AtlasChallenge, 'salt' | 'challenge'>, from: number, to: number, cancelled?: () => boolean): Promise<number | null>;
78
+ /**
79
+ * Solve a challenge's proof of work. Splits the range over up to four Web
80
+ * Workers; when workers cannot start (a CSP without `worker-src blob:`, an old
81
+ * browser) it searches on this thread instead. Resolves `{ n, worker }`.
82
+ */
83
+ export declare function solveAtlasChallenge(c: Pick<AtlasChallenge, 'salt' | 'challenge' | 'maxnumber'>, opts?: {
84
+ workers?: boolean;
85
+ cancelled?: () => boolean;
86
+ }): Promise<{
87
+ n: number;
88
+ worker: boolean;
89
+ }>;
90
+ /** Encode a solution as the `captcha_token` the flow's request carries. */
91
+ export declare function encodeAtlasToken(s: {
92
+ t: string;
93
+ n: number;
94
+ ms?: number;
95
+ w?: 0 | 1;
96
+ sel?: number;
97
+ }): string;
98
+ /** GET a challenge from a URL (the flow's `challengeUrl`). */
99
+ export declare function fetchAtlasChallenge(url: string, accessible?: boolean): Promise<AtlasChallenge>;
100
+ /** A drawn Atlas captcha: its token, whether it is about to expire, and teardown. */
101
+ export interface AtlasCaptchaHandle {
102
+ token: Promise<string>;
103
+ /** True once the solved challenge is within 15 s of expiring: draw a fresh one. */
104
+ stale(): boolean;
105
+ remove(): void;
106
+ }
107
+ /** Render Atlas's captcha into `container` and resolve the `captcha_token`. */
108
+ export declare function renderAtlasCaptcha(container: HTMLElement, opts: AtlasCaptchaOptions): AtlasCaptchaHandle;
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ /**
3
+ * Atlas's own captcha (provider `atlas`), the browser half. Dependency-free.
4
+ *
5
+ * No third-party script and no site key: the widget fetches a signed,
6
+ * single-use challenge from the instance's Frontend API, finds the number `n`
7
+ * with SHA-256(salt + n) = challenge (proof of work, in Web Workers via
8
+ * `crypto.subtle`, falling back to the page thread when workers are blocked),
9
+ * and, only when the server decided the request looks risky, shows a
10
+ * "select every matching shape" step with an accessible alternative (more
11
+ * work instead of the puzzle). The flow's request then carries
12
+ * `atlas1.<base64url JSON>` as `captcha_token`.
13
+ *
14
+ * Invisible by default: at low risk nothing is drawn and the work takes a
15
+ * fraction of a second.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.ATLAS_CAPTCHA_LABEL_KEYS = exports.ATLAS_CAPTCHA_LABELS = void 0;
19
+ exports.atlasCaptchaLabels = atlasCaptchaLabels;
20
+ exports.searchAtlasRange = searchAtlasRange;
21
+ exports.solveAtlasChallenge = solveAtlasChallenge;
22
+ exports.encodeAtlasToken = encodeAtlasToken;
23
+ exports.fetchAtlasChallenge = fetchAtlasChallenge;
24
+ exports.renderAtlasCaptcha = renderAtlasCaptcha;
25
+ exports.ATLAS_CAPTCHA_LABELS = {
26
+ checking: 'Checking your browser…',
27
+ verified: 'Security check complete.',
28
+ puzzlePrompt: "Select every picture that shows the same shape as this one. Colour and size don't matter.",
29
+ confirm: 'Confirm',
30
+ tile: 'Picture {n}',
31
+ alternative: "Can't do the picture check? Use a longer automatic check instead.",
32
+ };
33
+ /**
34
+ * The catalog keys of the widget's words, as in `@atlasauth/localizations` and
35
+ * every SDK's built-in catalog.
36
+ */
37
+ exports.ATLAS_CAPTCHA_LABEL_KEYS = {
38
+ checking: 'captcha.checking',
39
+ verified: 'captcha.verified',
40
+ puzzlePrompt: 'captcha.puzzlePrompt',
41
+ confirm: 'captcha.puzzleConfirm',
42
+ tile: 'captcha.puzzleTile',
43
+ alternative: 'captcha.puzzleAlternative',
44
+ };
45
+ /**
46
+ * The widget's labels from a form's translator (or any catalog lookup). A key
47
+ * the lookup does not know (no value, or the key echoed back) keeps the English
48
+ * default.
49
+ */
50
+ function atlasCaptchaLabels(lookup) {
51
+ if (!lookup)
52
+ return {};
53
+ const get = typeof lookup === 'function' ? lookup : (key) => lookup[key];
54
+ const out = {};
55
+ for (const [field, key] of Object.entries(exports.ATLAS_CAPTCHA_LABEL_KEYS)) {
56
+ const value = get(key);
57
+ if (typeof value === 'string' && value.trim() && value !== key)
58
+ out[field] = value;
59
+ }
60
+ return out;
61
+ }
62
+ const hex = (buf) => {
63
+ const b = new Uint8Array(buf);
64
+ let s = '';
65
+ for (let i = 0; i < b.length; i++)
66
+ s += (b[i] < 16 ? '0' : '') + b[i].toString(16);
67
+ return s;
68
+ };
69
+ const BATCH = 2000;
70
+ /**
71
+ * Search [from, to] for n with SHA-256(salt + n) = challenge, on this thread.
72
+ * Each batch awaits `crypto.subtle`, so the page stays responsive.
73
+ */
74
+ async function searchAtlasRange(c, from, to, cancelled = () => false) {
75
+ const enc = new TextEncoder();
76
+ for (let start = from; start <= to; start += BATCH) {
77
+ if (cancelled())
78
+ return null;
79
+ const end = Math.min(to, start + BATCH - 1);
80
+ const batch = [];
81
+ for (let n = start; n <= end; n++)
82
+ batch.push(crypto.subtle.digest('SHA-256', enc.encode(`${c.salt}${n}`)));
83
+ const hashes = await Promise.all(batch);
84
+ for (let i = 0; i < hashes.length; i++)
85
+ if (hex(hashes[i]) === c.challenge)
86
+ return start + i;
87
+ }
88
+ return null;
89
+ }
90
+ /** The worker: the same search, posted back as { n }. Kept as a string so it ships with no bundler setup. */
91
+ const WORKER_SOURCE = `
92
+ self.onmessage = async function (e) {
93
+ var d = e.data, enc = new TextEncoder();
94
+ function hex(buf) { var b = new Uint8Array(buf), s = ''; for (var i = 0; i < b.length; i++) s += (b[i] < 16 ? '0' : '') + b[i].toString(16); return s; }
95
+ for (var start = d.from; start <= d.to; start += ${BATCH}) {
96
+ var end = Math.min(d.to, start + ${BATCH} - 1), batch = [];
97
+ for (var n = start; n <= end; n++) batch.push(crypto.subtle.digest('SHA-256', enc.encode(d.salt + n)));
98
+ var hs = await Promise.all(batch);
99
+ for (var i = 0; i < hs.length; i++) if (hex(hs[i]) === d.challenge) { self.postMessage({ n: start + i }); return; }
100
+ }
101
+ self.postMessage({ n: null });
102
+ };`;
103
+ /**
104
+ * Solve a challenge's proof of work. Splits the range over up to four Web
105
+ * Workers; when workers cannot start (a CSP without `worker-src blob:`, an old
106
+ * browser) it searches on this thread instead. Resolves `{ n, worker }`.
107
+ */
108
+ async function solveAtlasChallenge(c, opts = {}) {
109
+ const cancelled = opts.cancelled ?? (() => false);
110
+ const g = globalThis;
111
+ if (opts.workers !== false && g.Worker && g.Blob && g.URL?.createObjectURL) {
112
+ const viaWorkers = await solveInWorkers(c, Math.max(1, Math.min(4, g.navigator?.hardwareConcurrency ?? 2)), cancelled).catch(() => undefined);
113
+ if (viaWorkers !== undefined) {
114
+ if (viaWorkers === null)
115
+ throw new Error('captcha: no solution');
116
+ return { n: viaWorkers, worker: true };
117
+ }
118
+ }
119
+ const n = await searchAtlasRange(c, 0, c.maxnumber, cancelled);
120
+ if (n === null)
121
+ throw new Error(cancelled() ? 'captcha: cancelled' : 'captcha: no solution');
122
+ return { n, worker: false };
123
+ }
124
+ function solveInWorkers(c, count, cancelled) {
125
+ const url = URL.createObjectURL(new Blob([WORKER_SOURCE], { type: 'text/javascript' }));
126
+ const workers = [];
127
+ const stop = () => {
128
+ for (const w of workers)
129
+ w.terminate();
130
+ URL.revokeObjectURL(url);
131
+ };
132
+ return new Promise((resolve, reject) => {
133
+ let pending = count;
134
+ const span = Math.ceil((c.maxnumber + 1) / count);
135
+ const poll = setInterval(() => {
136
+ if (cancelled()) {
137
+ clearInterval(poll);
138
+ stop();
139
+ resolve(null);
140
+ }
141
+ }, 100);
142
+ const finish = (value) => {
143
+ clearInterval(poll);
144
+ stop();
145
+ if (value instanceof Error)
146
+ reject(value);
147
+ else
148
+ resolve(value);
149
+ };
150
+ try {
151
+ for (let i = 0; i < count; i++) {
152
+ const w = new Worker(url);
153
+ workers.push(w);
154
+ w.onmessage = (e) => {
155
+ if (typeof e.data?.n === 'number')
156
+ finish(e.data.n);
157
+ else if (--pending === 0)
158
+ finish(null);
159
+ };
160
+ w.onerror = () => finish(new Error('captcha: worker failed'));
161
+ const from = i * span;
162
+ w.postMessage({ salt: c.salt, challenge: c.challenge, from, to: Math.min(c.maxnumber, from + span - 1) });
163
+ }
164
+ }
165
+ catch (e) {
166
+ finish(e instanceof Error ? e : new Error('captcha: worker failed'));
167
+ }
168
+ });
169
+ }
170
+ const b64url = (text) => {
171
+ const bytes = new TextEncoder().encode(text);
172
+ let bin = '';
173
+ for (let i = 0; i < bytes.length; i++)
174
+ bin += String.fromCharCode(bytes[i]);
175
+ return btoa(bin).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
176
+ };
177
+ /** Encode a solution as the `captcha_token` the flow's request carries. */
178
+ function encodeAtlasToken(s) {
179
+ return `atlas1.${b64url(JSON.stringify(s))}`;
180
+ }
181
+ /** GET a challenge from a URL (the flow's `challengeUrl`). */
182
+ async function fetchAtlasChallenge(url, accessible = false) {
183
+ const u = accessible ? `${url}${url.includes('?') ? '&' : '?'}accessible=true` : url;
184
+ const res = await fetch(u, { method: 'GET', credentials: 'omit' });
185
+ if (!res.ok)
186
+ throw new Error(`captcha: challenge refused (${res.status})`);
187
+ return (await res.json());
188
+ }
189
+ function svgImage(doc, svg) {
190
+ const img = doc.createElement('img');
191
+ // A data: image never runs script, whatever the markup.
192
+ img.src = `data:image/svg+xml;base64,${btoa(unescape(encodeURIComponent(svg)))}`;
193
+ img.alt = '';
194
+ img.width = 64;
195
+ img.height = 64;
196
+ img.style.cssText = 'display:block;width:64px;height:64px;border-radius:6px';
197
+ return img;
198
+ }
199
+ /** Draw the shape-matching step; resolves the tile mask, or 'accessible'. */
200
+ function askPuzzle(box, c, labels, cancelled) {
201
+ const doc = box.ownerDocument;
202
+ return new Promise((resolve, reject) => {
203
+ box.replaceChildren();
204
+ const wrap = doc.createElement('div');
205
+ wrap.setAttribute('role', 'group');
206
+ wrap.setAttribute('data-atlas-captcha-puzzle', '');
207
+ wrap.style.cssText = 'display:flex;flex-direction:column;align-items:center;gap:8px';
208
+ const prompt = doc.createElement('p');
209
+ prompt.style.cssText = 'margin:0;font-size:13px;text-align:center';
210
+ prompt.textContent = labels.puzzlePrompt;
211
+ wrap.append(prompt, svgImage(doc, c.interactive.example));
212
+ const grid = doc.createElement('div');
213
+ grid.style.cssText = 'display:grid;grid-template-columns:repeat(3,72px);gap:6px';
214
+ let mask = 0;
215
+ c.interactive.tiles.forEach((svg, i) => {
216
+ const b = doc.createElement('button');
217
+ b.type = 'button';
218
+ b.setAttribute('aria-pressed', 'false');
219
+ b.setAttribute('aria-label', labels.tile.replace('{n}', String(i + 1)));
220
+ b.setAttribute('data-atlas-captcha-tile', String(i));
221
+ b.style.cssText = 'padding:3px;border:2px solid transparent;border-radius:8px;background:none;cursor:pointer';
222
+ b.append(svgImage(doc, svg));
223
+ b.addEventListener('click', () => {
224
+ mask ^= 1 << i;
225
+ const on = (mask & (1 << i)) !== 0;
226
+ b.setAttribute('aria-pressed', on ? 'true' : 'false');
227
+ b.style.borderColor = on ? 'currentColor' : 'transparent';
228
+ });
229
+ grid.append(b);
230
+ });
231
+ const ok = doc.createElement('button');
232
+ ok.type = 'button';
233
+ ok.setAttribute('data-atlas-captcha-confirm', '');
234
+ ok.textContent = labels.confirm;
235
+ ok.addEventListener('click', () => (cancelled() ? reject(new Error('captcha: widget removed')) : resolve(mask)));
236
+ wrap.append(grid, ok);
237
+ if (c.accessible_alternative) {
238
+ const alt = doc.createElement('button');
239
+ alt.type = 'button';
240
+ alt.setAttribute('data-atlas-captcha-alternative', '');
241
+ alt.style.cssText = 'font-size:12px;background:none;border:0;text-decoration:underline;cursor:pointer';
242
+ alt.textContent = labels.alternative;
243
+ alt.addEventListener('click', () => resolve('accessible'));
244
+ wrap.append(alt);
245
+ }
246
+ box.append(wrap);
247
+ });
248
+ }
249
+ /** Render Atlas's captcha into `container` and resolve the `captcha_token`. */
250
+ function renderAtlasCaptcha(container, opts) {
251
+ const labels = { ...exports.ATLAS_CAPTCHA_LABELS, ...opts.labels };
252
+ const mode = opts.mode ?? 'managed';
253
+ const doc = container.ownerDocument;
254
+ const fetchChallenge = opts.fetchChallenge ??
255
+ ((accessible) => {
256
+ if (!opts.challengeUrl)
257
+ return Promise.reject(new Error('captcha: no challenge URL'));
258
+ return fetchAtlasChallenge(opts.challengeUrl, accessible);
259
+ });
260
+ let removed = false;
261
+ let expiresAt = 0;
262
+ const cancelled = () => removed;
263
+ const box = doc.createElement('div');
264
+ box.setAttribute('role', 'status');
265
+ box.setAttribute('aria-live', 'polite');
266
+ box.setAttribute('data-atlas-captcha-provider', 'atlas');
267
+ box.style.cssText = 'font-size:13px;opacity:.85;text-align:center';
268
+ container.append(box);
269
+ const say = (text) => {
270
+ box.replaceChildren();
271
+ box.textContent = text;
272
+ };
273
+ const run = async (accessible) => {
274
+ const c = await fetchChallenge(accessible);
275
+ if (removed)
276
+ throw new Error('captcha: widget removed');
277
+ expiresAt = Date.parse(c.expires_at) || 0;
278
+ if (mode === 'visible' || c.interactive)
279
+ say(labels.checking);
280
+ const started = Date.now();
281
+ const work = solveAtlasChallenge(c, { workers: opts.workers, cancelled }).then((r) => ({
282
+ ...r,
283
+ ms: Date.now() - started,
284
+ }));
285
+ // A rejection here is reported by whichever await reads it.
286
+ work.catch(() => undefined);
287
+ let sel;
288
+ if (c.interactive) {
289
+ const answer = await askPuzzle(box, c, labels, cancelled);
290
+ if (answer === 'accessible') {
291
+ say(labels.checking);
292
+ return run(true);
293
+ }
294
+ sel = answer;
295
+ say(labels.checking);
296
+ }
297
+ const { n, worker, ms } = await work;
298
+ if (removed)
299
+ throw new Error('captcha: widget removed');
300
+ if (mode === 'visible' || sel !== undefined)
301
+ say(labels.verified);
302
+ return encodeAtlasToken({ t: c.token, n, ms, ...(worker ? { w: 1 } : {}), ...(sel !== undefined ? { sel } : {}) });
303
+ };
304
+ const token = run(false);
305
+ token.catch(() => undefined);
306
+ return {
307
+ token,
308
+ stale: () => expiresAt > 0 && Date.now() > expiresAt - 15_000,
309
+ remove() {
310
+ removed = true;
311
+ box.remove();
312
+ },
313
+ };
314
+ }
315
+ //# sourceMappingURL=atlas-captcha.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlas-captcha.js","sourceRoot":"","sources":["../src/atlas-captcha.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { type FieldError } from './attempt';
2
2
  import { type FapiClient, type FlowState } from './fapi';
3
+ import type { AtlasCaptchaLabels } from './atlas-captcha';
3
4
  import { type FlowCaptcha } from './captcha-widget';
4
5
  /**
5
6
  * The captcha half of a prebuilt sign-in / sign-up form, without a framework.
@@ -43,7 +44,16 @@ export interface CaptchaController {
43
44
  /** Remove the widget for good (component teardown). */
44
45
  destroy(): void;
45
46
  }
46
- export declare function createCaptchaController(initial?: CaptchaControllerOptions): CaptchaController;
47
+ /** Settings that hold for the controller's whole life. */
48
+ export interface CaptchaControllerSettings {
49
+ /**
50
+ * The Atlas captcha's words in the form's language, read each time a widget
51
+ * is drawn (so a locale switch applies to the next one). See
52
+ * `atlasCaptchaLabels(t)`.
53
+ */
54
+ atlasLabels?: () => Partial<AtlasCaptchaLabels>;
55
+ }
56
+ export declare function createCaptchaController(initial?: CaptchaControllerOptions, settings?: CaptchaControllerSettings): CaptchaController;
47
57
  /**
48
58
  * Swap the server's captcha refusals (CAPTCHA_REQUIRED / CAPTCHA_FAILED, which
49
59
  * the server ties to the `captcha_token` param) for a localized, form-level
@@ -9,7 +9,7 @@ const attempt_1 = require("./attempt");
9
9
  const fapi_1 = require("./fapi");
10
10
  const instance_settings_1 = require("./instance-settings");
11
11
  const captcha_widget_1 = require("./captcha-widget");
12
- function createCaptchaController(initial) {
12
+ function createCaptchaController(initial, settings = {}) {
13
13
  let options = initial ?? { flow: undefined, active: false };
14
14
  let container = null;
15
15
  let handle = null;
@@ -35,7 +35,9 @@ function createCaptchaController(initial) {
35
35
  const flow = options.flow;
36
36
  if (!needed() || !flow || !container)
37
37
  return null;
38
- const h = (0, captcha_widget_1.renderCaptchaWidget)(flow, container);
38
+ const h = (0, captcha_widget_1.renderCaptchaWidget)(flow, container, {
39
+ atlas: settings.atlasLabels ? { labels: settings.atlasLabels() } : undefined,
40
+ });
39
41
  handle = h;
40
42
  drawnKey = key();
41
43
  // Swallow here so a removed / failed widget is never an unhandled
@@ -76,7 +78,7 @@ function createCaptchaController(initial) {
76
78
  if (!needed())
77
79
  return null;
78
80
  let h = handle;
79
- if (!h || spent === h)
81
+ if (!h || spent === h || h.stale?.())
80
82
  h = mount();
81
83
  if (!h)
82
84
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"captcha-controller.js","sourceRoot":"","sources":["../src/captcha-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"captcha-controller.js","sourceRoot":"","sources":["../src/captcha-controller.ts"],"names":[],"mappings":"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"}
@@ -18,7 +18,11 @@
18
18
  *
19
19
  * Everything is SSR-safe: nothing touches `window`/`document` until a call that
20
20
  * renders into a DOM element.
21
+ *
22
+ * Provider `atlas` is Atlas's own captcha: no vendor script, no site key (see
23
+ * `atlas-captcha.ts`).
21
24
  */
25
+ import { type AtlasCaptchaOptions } from './atlas-captcha';
22
26
  /** The flows `captchaFlows` covers. */
23
27
  export type CaptchaFlowKey = 'signUp' | 'signIn' | 'guest' | 'passwordReset';
24
28
  /** How a widget-drawing provider renders. */
@@ -35,6 +39,11 @@ export interface FlowCaptcha {
35
39
  provider?: string;
36
40
  siteKey?: string | null;
37
41
  widget?: CaptchaWidgetMode;
42
+ /**
43
+ * Provider `atlas` (Atlas's own captcha, no keys): where the widget fetches
44
+ * each fresh challenge. Set by `/v1/appearance`.
45
+ */
46
+ challengeUrl?: string;
38
47
  }
39
48
  /** Whether the prebuilt UIs can draw this provider's widget. */
40
49
  export declare function isRenderableCaptcha(provider?: string | null): boolean;
@@ -53,10 +62,20 @@ type Win = Window & Record<string, unknown>;
53
62
  * already present (a prior load, or a test that preset it) it resolves at once.
54
63
  */
55
64
  export declare function loadCaptchaProvider(provider: string, siteKey: string, win: Win): Promise<unknown>;
65
+ /** Per-render options. Only Atlas's own captcha reads any today. */
66
+ export interface RenderCaptchaOptions {
67
+ /** Atlas captcha: a custom challenge fetcher (e.g. through your FAPI proxy) and localised labels. */
68
+ atlas?: Pick<AtlasCaptchaOptions, 'fetchChallenge' | 'labels' | 'workers'>;
69
+ }
56
70
  /** A widget rendered into a container: its eventual token, and a way to take it down. */
57
71
  export interface CaptchaWidgetHandle {
58
72
  /** Resolves with the solved token; rejects on provider error/timeout or removal. */
59
73
  token: Promise<string>;
74
+ /**
75
+ * True when the solved token is about to expire unspent (Atlas's captcha), so
76
+ * the caller draws a fresh widget instead of sending it. Absent: never stale.
77
+ */
78
+ stale?(): boolean;
60
79
  /**
61
80
  * Remove the widget (provider teardown + empty the container). Tokens are
62
81
  * single-use, so call this after a submit spent the token and render a fresh
@@ -70,12 +89,12 @@ export interface CaptchaWidgetHandle {
70
89
  * `container` is where a visible/managed widget draws; score providers draw
71
90
  * nothing there.
72
91
  */
73
- export declare function renderCaptchaWidget(flow: FlowCaptcha, container: HTMLElement): CaptchaWidgetHandle;
92
+ export declare function renderCaptchaWidget(flow: FlowCaptcha, container: HTMLElement, options?: RenderCaptchaOptions): CaptchaWidgetHandle;
74
93
  /**
75
94
  * Obtain a captcha token for a flow: render the widget into `container` and
76
95
  * resolve its token. Rejects on provider error/timeout — the caller decides
77
96
  * whether to surface it or let the (fail-closed) server reject the tokenless
78
97
  * request.
79
98
  */
80
- export declare function getCaptchaToken(flow: FlowCaptcha, container: HTMLElement): Promise<string>;
99
+ export declare function getCaptchaToken(flow: FlowCaptcha, container: HTMLElement, options?: RenderCaptchaOptions): Promise<string>;
81
100
  export {};