@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.
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Referral attribution: capture the referral a visitor arrived with and send it
3
+ * on every sign-in / sign-up start, so the user Atlas creates is attributed to
4
+ * whoever referred them.
5
+ *
6
+ * What is captured, when the instance has referrals on (`referrals` in
7
+ * `GET /v1/client/environment`):
8
+ * - the referral code from the page URL — the instance's URL parameters
9
+ * (default `ref`, `via`, `aff`) on the current page, the page the SDK first
10
+ * loaded on, and the `redirect_url` / `after_url` query of either;
11
+ * - with consent, the referral platform's first-party tracking cookie (the
12
+ * instance's `context_cookie`): JSON or URL-encoded JSON
13
+ * `{code?, clickId?, anonId?}`, or a plain click id. A URL code wins over the
14
+ * cookie's code.
15
+ *
16
+ * Consent: when Cookie Munch is on the page (`window.CookieMunch`), the cookie
17
+ * is read only when the instance's consent category is granted (else its
18
+ * fallback category). Without a consent manager the cookie is read only when
19
+ * the app says its own consent manager allowed it (`referralConsent:
20
+ * 'granted'`). Otherwise the URL code alone is sent. The SDK never writes the
21
+ * cookie. Nothing captured is trusted: the server re-validates every field.
22
+ *
23
+ * Opt out with `referral: false` (per client, or page-wide with
24
+ * {@link configureReferralCapture}).
25
+ */
26
+ /** The instance's public referral settings, camelCased. */
27
+ export interface ReferralConfig {
28
+ enabled: boolean;
29
+ /** URL query parameters that carry a code, in priority order. */
30
+ urlParams: string[];
31
+ /** The tracking cookie to read under consent; null = never read a cookie. */
32
+ contextCookie: string | null;
33
+ consentCategory: string;
34
+ consentFallbackCategory: string | null;
35
+ /** `always`: a sign-up carrying a referral code must pass the bot challenge. */
36
+ challengeReferredSignups: 'always' | 'inherit';
37
+ }
38
+ /** The `referral` object a sign-in / sign-up request carries (snake_case, as the API takes it). */
39
+ export interface ReferralCapture {
40
+ code: string | null;
41
+ click_id: string | null;
42
+ anon_id: string | null;
43
+ consent: 'granted' | 'not_required';
44
+ /** ISO 8601. */
45
+ captured_at: string;
46
+ }
47
+ /**
48
+ * The app's own consent decision for the referral cookie, used only when no
49
+ * Cookie Munch is on the page. `'granted'` / `true` allow reading it; anything
50
+ * else does not. A function is asked at each sign-in / sign-up start.
51
+ */
52
+ export type ReferralConsent = 'granted' | 'denied' | boolean | (() => 'granted' | 'denied' | boolean | null | undefined);
53
+ /** The referral options a FAPI client and the prebuilt components take. */
54
+ export interface ReferralCaptureOptions {
55
+ /** `false` turns referral capture off. */
56
+ referral?: false | undefined;
57
+ /** See {@link ReferralConsent}. */
58
+ referralConsent?: ReferralConsent;
59
+ }
60
+ export declare const DISABLED_REFERRAL_CONFIG: Readonly<ReferralConfig>;
61
+ /** A well-formed code / click id / anonymous id, or null. */
62
+ export declare function referralToken(value: unknown): string | null;
63
+ /**
64
+ * Read the referral config from a `/v1/client/environment` body (or its
65
+ * `referrals` object). Missing or malformed → disabled.
66
+ */
67
+ export declare function referralConfigFrom(body: unknown): ReferralConfig;
68
+ /** The first well-formed code among `params` in a query string. */
69
+ export declare function referralCodeFromSearch(search: string | null | undefined, params: readonly string[]): string | null;
70
+ /** The query strings a code may be in: each search, plus its `redirect_url` / `after_url` targets' queries. */
71
+ export declare function referralSearches(searches: readonly string[], base?: string): string[];
72
+ /**
73
+ * Parse a tracking-cookie value: JSON or URL-encoded JSON `{code?, clickId?,
74
+ * anonId?}` (snake_case accepted too); a plain value is a click id.
75
+ */
76
+ export declare function parseReferralCookie(value: string | null | undefined): {
77
+ code: string | null;
78
+ clickId: string | null;
79
+ anonId: string | null;
80
+ } | null;
81
+ /** A cookie's value from a `document.cookie` string, or null. */
82
+ export declare function readCookieValue(cookies: string | null | undefined, name: string): string | null;
83
+ /**
84
+ * Whether the referral cookie may be read. Cookie Munch on the page decides
85
+ * when present (the instance's category, else its fallback category); else
86
+ * the app's own `referralConsent`.
87
+ */
88
+ export declare function referralConsentGranted(config: Pick<ReferralConfig, 'consentCategory' | 'consentFallbackCategory'>, cookieMunch: unknown, appConsent: ReferralConsent | undefined): boolean;
89
+ /** Everything {@link captureReferral} reads from the page. */
90
+ export interface ReferralPage {
91
+ /** Query strings to look in, most relevant first (current page, landing page). */
92
+ searches: readonly string[];
93
+ /** `document.cookie`. */
94
+ cookies?: string | null;
95
+ /** `window.CookieMunch`, if any. */
96
+ cookieMunch?: unknown;
97
+ /** Base for resolving a relative redirect_url. */
98
+ base?: string;
99
+ /** ISO time of capture. */
100
+ capturedAt?: string;
101
+ }
102
+ /** Capture the referral for a request, or null when there is nothing to send. Pure. */
103
+ export declare function captureReferral(config: ReferralConfig, page: ReferralPage, appConsent?: ReferralConsent): ReferralCapture | null;
104
+ /** Whether a FAPI POST path starts or continues a sign-in / sign-up (and so takes `referral`). */
105
+ export declare function acceptsReferral(path: string): boolean;
106
+ /**
107
+ * Remember the current page's query, so a code the visitor landed with
108
+ * survives client-side navigation that drops it. In memory only (never
109
+ * stored). Called when the SDK loads and whenever a client is created.
110
+ */
111
+ export declare function rememberReferralLanding(): void;
112
+ /**
113
+ * Page-wide referral options, for apps whose framework creates FAPI clients
114
+ * internally: `configureReferralCapture({ referral: false })` opts out,
115
+ * `{ referralConsent: 'granted' }` tells the SDK the app's own consent
116
+ * manager allowed the referral cookie. A client's own options win.
117
+ */
118
+ export declare function configureReferralCapture(options: ReferralCaptureOptions): void;
119
+ /** The page-wide options set with {@link configureReferralCapture}. */
120
+ export declare function referralCaptureDefaults(): ReferralCaptureOptions;
121
+ /** The key an instance's referral config is cached under (a FAPI origin + publishable key). */
122
+ export declare function referralCacheKeyFor(baseUrl: string | null | undefined, publishableKey: string): string;
123
+ /**
124
+ * Record an instance's referral config from a `/v1/client/environment` or
125
+ * `/v1/appearance` body it was fetched with. A body without `referrals` (an
126
+ * older server) is ignored.
127
+ */
128
+ export declare function seedReferralConfig(cacheKey: string, environmentBody: unknown): void;
129
+ /** Forget every cached referral config (tests; an app switching instances). */
130
+ export declare function resetReferralCapture(): void;
131
+ /** What the referral helpers need from a FAPI client. */
132
+ export interface ReferralClient {
133
+ readonly referralCacheKey: string;
134
+ readonly referralOptions: ReferralCaptureOptions;
135
+ get<T>(path: string): Promise<{
136
+ ok: boolean;
137
+ data: T | null;
138
+ }>;
139
+ }
140
+ /** The instance's referral config, fetched once per page (and seeded by any environment read). */
141
+ export declare function loadReferralConfig(client: ReferralClient): Promise<ReferralConfig>;
142
+ /** The referral this client should send now, or null (off, opted out, nothing captured). Never throws. */
143
+ export declare function currentReferral(client: ReferralClient): Promise<ReferralCapture | null>;
144
+ /**
145
+ * Whether a sign-up / sign-in form should show the bot challenge because a
146
+ * referral code was captured and the instance requires it for referred
147
+ * sign-ups (even with the captcha otherwise off).
148
+ */
149
+ export declare function referralChallengeRequired(client: ReferralClient): Promise<boolean>;
@@ -0,0 +1,399 @@
1
+ "use strict";
2
+ /**
3
+ * Referral attribution: capture the referral a visitor arrived with and send it
4
+ * on every sign-in / sign-up start, so the user Atlas creates is attributed to
5
+ * whoever referred them.
6
+ *
7
+ * What is captured, when the instance has referrals on (`referrals` in
8
+ * `GET /v1/client/environment`):
9
+ * - the referral code from the page URL — the instance's URL parameters
10
+ * (default `ref`, `via`, `aff`) on the current page, the page the SDK first
11
+ * loaded on, and the `redirect_url` / `after_url` query of either;
12
+ * - with consent, the referral platform's first-party tracking cookie (the
13
+ * instance's `context_cookie`): JSON or URL-encoded JSON
14
+ * `{code?, clickId?, anonId?}`, or a plain click id. A URL code wins over the
15
+ * cookie's code.
16
+ *
17
+ * Consent: when Cookie Munch is on the page (`window.CookieMunch`), the cookie
18
+ * is read only when the instance's consent category is granted (else its
19
+ * fallback category). Without a consent manager the cookie is read only when
20
+ * the app says its own consent manager allowed it (`referralConsent:
21
+ * 'granted'`). Otherwise the URL code alone is sent. The SDK never writes the
22
+ * cookie. Nothing captured is trusted: the server re-validates every field.
23
+ *
24
+ * Opt out with `referral: false` (per client, or page-wide with
25
+ * {@link configureReferralCapture}).
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.DISABLED_REFERRAL_CONFIG = void 0;
29
+ exports.referralToken = referralToken;
30
+ exports.referralConfigFrom = referralConfigFrom;
31
+ exports.referralCodeFromSearch = referralCodeFromSearch;
32
+ exports.referralSearches = referralSearches;
33
+ exports.parseReferralCookie = parseReferralCookie;
34
+ exports.readCookieValue = readCookieValue;
35
+ exports.referralConsentGranted = referralConsentGranted;
36
+ exports.captureReferral = captureReferral;
37
+ exports.acceptsReferral = acceptsReferral;
38
+ exports.rememberReferralLanding = rememberReferralLanding;
39
+ exports.configureReferralCapture = configureReferralCapture;
40
+ exports.referralCaptureDefaults = referralCaptureDefaults;
41
+ exports.referralCacheKeyFor = referralCacheKeyFor;
42
+ exports.seedReferralConfig = seedReferralConfig;
43
+ exports.resetReferralCapture = resetReferralCapture;
44
+ exports.loadReferralConfig = loadReferralConfig;
45
+ exports.currentReferral = currentReferral;
46
+ exports.referralChallengeRequired = referralChallengeRequired;
47
+ exports.DISABLED_REFERRAL_CONFIG = Object.freeze({
48
+ enabled: false,
49
+ urlParams: [],
50
+ contextCookie: null,
51
+ consentCategory: 'referrals',
52
+ consentFallbackCategory: 'marketing',
53
+ challengeReferredSignups: 'inherit',
54
+ });
55
+ const TOKEN = /^[A-Za-z0-9_-]{3,64}$/;
56
+ const PARAM = /^[A-Za-z0-9_.-]{1,40}$/;
57
+ const COOKIE_NAME = /^[A-Za-z0-9_.-]{1,64}$/;
58
+ const isRecord = (v) => !!v && typeof v === 'object' && !Array.isArray(v);
59
+ /** A well-formed code / click id / anonymous id, or null. */
60
+ function referralToken(value) {
61
+ if (typeof value !== 'string')
62
+ return null;
63
+ const v = value.trim();
64
+ return TOKEN.test(v) ? v : null;
65
+ }
66
+ /**
67
+ * Read the referral config from a `/v1/client/environment` body (or its
68
+ * `referrals` object). Missing or malformed → disabled.
69
+ */
70
+ function referralConfigFrom(body) {
71
+ const raw = isRecord(body) && isRecord(body.referrals) ? body.referrals : body;
72
+ if (!isRecord(raw) || raw.enabled !== true)
73
+ return { ...exports.DISABLED_REFERRAL_CONFIG, urlParams: [] };
74
+ const params = Array.isArray(raw.url_params)
75
+ ? raw.url_params.filter((p) => typeof p === 'string' && PARAM.test(p)).slice(0, 10)
76
+ : [];
77
+ return {
78
+ enabled: true,
79
+ urlParams: params.length ? params : ['ref', 'via', 'aff'],
80
+ contextCookie: typeof raw.context_cookie === 'string' && COOKIE_NAME.test(raw.context_cookie) ? raw.context_cookie : null,
81
+ consentCategory: typeof raw.consent_category === 'string' && raw.consent_category ? raw.consent_category : 'referrals',
82
+ consentFallbackCategory: typeof raw.consent_fallback_category === 'string' && raw.consent_fallback_category
83
+ ? raw.consent_fallback_category
84
+ : null,
85
+ challengeReferredSignups: raw.challenge_referred_signups === 'always' ? 'always' : 'inherit',
86
+ };
87
+ }
88
+ /** The first well-formed code among `params` in a query string. */
89
+ function referralCodeFromSearch(search, params) {
90
+ if (!search)
91
+ return null;
92
+ let query;
93
+ try {
94
+ query = new URLSearchParams(search);
95
+ }
96
+ catch {
97
+ return null;
98
+ }
99
+ for (const name of params) {
100
+ const code = referralToken(query.get(name));
101
+ if (code)
102
+ return code;
103
+ }
104
+ return null;
105
+ }
106
+ /** The query strings a code may be in: each search, plus its `redirect_url` / `after_url` targets' queries. */
107
+ function referralSearches(searches, base) {
108
+ const out = [];
109
+ const add = (s) => {
110
+ if (s && !out.includes(s))
111
+ out.push(s);
112
+ };
113
+ for (const search of searches)
114
+ add(search);
115
+ for (const search of searches) {
116
+ let query;
117
+ try {
118
+ query = new URLSearchParams(search);
119
+ }
120
+ catch {
121
+ continue;
122
+ }
123
+ for (const key of ['redirect_url', 'after_url', 'redirect_url_complete', 'after_sign_up_url', 'after_sign_in_url']) {
124
+ const target = query.get(key);
125
+ if (!target)
126
+ continue;
127
+ try {
128
+ add(new URL(target, base ?? 'https://invalid.example').search);
129
+ }
130
+ catch {
131
+ // not a URL
132
+ }
133
+ }
134
+ }
135
+ return out;
136
+ }
137
+ /**
138
+ * Parse a tracking-cookie value: JSON or URL-encoded JSON `{code?, clickId?,
139
+ * anonId?}` (snake_case accepted too); a plain value is a click id.
140
+ */
141
+ function parseReferralCookie(value) {
142
+ if (typeof value !== 'string' || !value || value.length > 4096)
143
+ return null;
144
+ let decoded = value;
145
+ try {
146
+ decoded = decodeURIComponent(value);
147
+ }
148
+ catch {
149
+ // keep the raw value
150
+ }
151
+ const json = (s) => {
152
+ if (!s.startsWith('{'))
153
+ return null;
154
+ try {
155
+ const parsed = JSON.parse(s);
156
+ return isRecord(parsed) ? parsed : null;
157
+ }
158
+ catch {
159
+ return null;
160
+ }
161
+ };
162
+ const obj = json(value.trim()) ?? json(decoded.trim());
163
+ if (obj) {
164
+ const out = {
165
+ code: referralToken(obj.code),
166
+ clickId: referralToken(obj.clickId ?? obj.click_id),
167
+ anonId: referralToken(obj.anonId ?? obj.anon_id),
168
+ };
169
+ return out.code || out.clickId || out.anonId ? out : null;
170
+ }
171
+ const clickId = referralToken(decoded);
172
+ return clickId ? { code: null, clickId, anonId: null } : null;
173
+ }
174
+ /** A cookie's value from a `document.cookie` string, or null. */
175
+ function readCookieValue(cookies, name) {
176
+ if (!cookies)
177
+ return null;
178
+ for (const part of cookies.split(';')) {
179
+ const p = part.trim();
180
+ if (p.startsWith(`${name}=`))
181
+ return p.slice(name.length + 1);
182
+ }
183
+ return null;
184
+ }
185
+ /**
186
+ * Whether the referral cookie may be read. Cookie Munch on the page decides
187
+ * when present (the instance's category, else its fallback category); else
188
+ * the app's own `referralConsent`.
189
+ */
190
+ function referralConsentGranted(config, cookieMunch, appConsent) {
191
+ let consent;
192
+ try {
193
+ consent = isRecord(cookieMunch) || typeof cookieMunch === 'function' ? cookieMunch.consent : undefined;
194
+ }
195
+ catch {
196
+ consent = undefined;
197
+ }
198
+ if (isRecord(consent)) {
199
+ let v = consent[config.consentCategory];
200
+ if (typeof v !== 'boolean' && config.consentFallbackCategory)
201
+ v = consent[config.consentFallbackCategory];
202
+ return v === true;
203
+ }
204
+ let decision = appConsent;
205
+ if (typeof appConsent === 'function') {
206
+ try {
207
+ decision = appConsent();
208
+ }
209
+ catch {
210
+ decision = undefined;
211
+ }
212
+ }
213
+ return decision === 'granted' || decision === true;
214
+ }
215
+ /** Capture the referral for a request, or null when there is nothing to send. Pure. */
216
+ function captureReferral(config, page, appConsent) {
217
+ if (!config.enabled)
218
+ return null;
219
+ let code = null;
220
+ for (const search of referralSearches(page.searches, page.base)) {
221
+ code = referralCodeFromSearch(search, config.urlParams);
222
+ if (code)
223
+ break;
224
+ }
225
+ const cookie = config.contextCookie && referralConsentGranted(config, page.cookieMunch, appConsent)
226
+ ? parseReferralCookie(readCookieValue(page.cookies, config.contextCookie))
227
+ : null;
228
+ const out = {
229
+ code: code ?? cookie?.code ?? null,
230
+ click_id: cookie?.clickId ?? null,
231
+ anon_id: cookie?.anonId ?? null,
232
+ consent: cookie ? 'granted' : 'not_required',
233
+ captured_at: page.capturedAt ?? new Date().toISOString(),
234
+ };
235
+ return out.code || out.click_id || out.anon_id ? out : null;
236
+ }
237
+ /** The FAPI POST paths that take `referral`: every sign-in / sign-up start and the steps that continue one. */
238
+ const REFERRAL_EXACT = new Set([
239
+ '/v1/client/sign_ups',
240
+ '/v1/client/sign_ins',
241
+ '/v1/client/sign_ins/oauth',
242
+ '/v1/client/sign_ins/sso',
243
+ '/v1/client/sign_ins/saml',
244
+ '/v1/client/sign_ins/discourse',
245
+ '/v1/client/sign_ins/id_token',
246
+ '/v1/client/sign_ins/id_token/nonce',
247
+ '/v1/client/sign_ins/external_jwt',
248
+ '/v1/client/sign_ins/ldap',
249
+ '/v1/client/sign_ins/passkey/finish',
250
+ '/v1/oauth/telegram',
251
+ '/v1/oauth/siwe/nonce',
252
+ '/v1/oauth/siwe/verify',
253
+ '/v1/oauth/siws/nonce',
254
+ '/v1/oauth/siws/verify',
255
+ '/v1/oauth/siwf/nonce',
256
+ '/v1/oauth/siwf/verify',
257
+ ]);
258
+ const REFERRAL_STEP = /^\/v1\/client\/(sign_ins\/[^/]+\/(prepare_first_factor|attempt_first_factor)|sign_ups\/[^/]+\/(prepare_verification|attempt_verification))$/;
259
+ /** Whether a FAPI POST path starts or continues a sign-in / sign-up (and so takes `referral`). */
260
+ function acceptsReferral(path) {
261
+ const p = path.split('?')[0] ?? path;
262
+ return REFERRAL_EXACT.has(p) || REFERRAL_STEP.test(p);
263
+ }
264
+ const browser = () => typeof window === 'undefined' ? null : window;
265
+ /** The query strings the page has shown since the SDK loaded (the landing query first). */
266
+ const landingSearches = [];
267
+ let landingAt = null;
268
+ /**
269
+ * Remember the current page's query, so a code the visitor landed with
270
+ * survives client-side navigation that drops it. In memory only (never
271
+ * stored). Called when the SDK loads and whenever a client is created.
272
+ */
273
+ function rememberReferralLanding() {
274
+ const search = browser()?.location?.search;
275
+ if (!search || landingSearches.includes(search))
276
+ return;
277
+ landingSearches.push(search);
278
+ landingAt ??= new Date().toISOString();
279
+ }
280
+ rememberReferralLanding();
281
+ let pageOptions = {};
282
+ /**
283
+ * Page-wide referral options, for apps whose framework creates FAPI clients
284
+ * internally: `configureReferralCapture({ referral: false })` opts out,
285
+ * `{ referralConsent: 'granted' }` tells the SDK the app's own consent
286
+ * manager allowed the referral cookie. A client's own options win.
287
+ */
288
+ function configureReferralCapture(options) {
289
+ pageOptions = { ...options };
290
+ }
291
+ /** The page-wide options set with {@link configureReferralCapture}. */
292
+ function referralCaptureDefaults() {
293
+ return pageOptions;
294
+ }
295
+ const configs = new Map();
296
+ /** The key an instance's referral config is cached under (a FAPI origin + publishable key). */
297
+ function referralCacheKeyFor(baseUrl, publishableKey) {
298
+ return `${baseUrl ?? ''}|${publishableKey}`;
299
+ }
300
+ /**
301
+ * Record an instance's referral config from a `/v1/client/environment` or
302
+ * `/v1/appearance` body it was fetched with. A body without `referrals` (an
303
+ * older server) is ignored.
304
+ */
305
+ function seedReferralConfig(cacheKey, environmentBody) {
306
+ if (!isRecord(environmentBody) || !('referrals' in environmentBody))
307
+ return;
308
+ configs.set(cacheKey, Promise.resolve(referralConfigFrom(environmentBody)));
309
+ }
310
+ /** Forget every cached referral config (tests; an app switching instances). */
311
+ function resetReferralCapture() {
312
+ configs.clear();
313
+ landingSearches.length = 0;
314
+ landingAt = null;
315
+ pageOptions = {};
316
+ }
317
+ /** The instance's referral config, fetched once per page (and seeded by any environment read). */
318
+ function loadReferralConfig(client) {
319
+ let pending = configs.get(client.referralCacheKey);
320
+ if (!pending) {
321
+ const key = client.referralCacheKey;
322
+ // A failed read reads as "off" for this start and is not cached, so a later
323
+ // start asks again.
324
+ const failed = () => {
325
+ if (configs.get(key) === pending)
326
+ configs.delete(key);
327
+ return { ...exports.DISABLED_REFERRAL_CONFIG, urlParams: [] };
328
+ };
329
+ pending = client
330
+ .get('/v1/client/environment')
331
+ .then((r) => (r.ok ? referralConfigFrom(r.data) : failed()))
332
+ .catch(failed);
333
+ configs.set(key, pending);
334
+ }
335
+ return pending;
336
+ }
337
+ /**
338
+ * No config yet (no environment / appearance read on this page) and no query
339
+ * anywhere to find a code in: nothing to send, and no reason to ask the
340
+ * server. A cookie-only referral is sent once a prebuilt form (or any
341
+ * environment read) has loaded the config.
342
+ */
343
+ function worthAsking(client) {
344
+ return configs.has(client.referralCacheKey) || !!browser()?.location?.search || landingSearches.length > 0;
345
+ }
346
+ function effectiveOptions(client) {
347
+ const own = client.referralOptions;
348
+ return {
349
+ referral: own.referral ?? pageOptions.referral,
350
+ referralConsent: own.referralConsent ?? pageOptions.referralConsent,
351
+ };
352
+ }
353
+ /** The referral this client should send now, or null (off, opted out, nothing captured). Never throws. */
354
+ async function currentReferral(client) {
355
+ const win = browser();
356
+ if (!win)
357
+ return null;
358
+ const options = effectiveOptions(client);
359
+ if (options.referral === false)
360
+ return null;
361
+ try {
362
+ const current = win.location?.search ?? '';
363
+ if (!worthAsking(client))
364
+ return null;
365
+ const config = await loadReferralConfig(client);
366
+ if (!config.enabled)
367
+ return null;
368
+ return captureReferral(config, {
369
+ searches: [current, ...landingSearches],
370
+ cookies: win.document?.cookie ?? null,
371
+ cookieMunch: win.CookieMunch,
372
+ base: win.location?.href,
373
+ capturedAt: landingAt ?? undefined,
374
+ }, options.referralConsent);
375
+ }
376
+ catch {
377
+ return null;
378
+ }
379
+ }
380
+ /**
381
+ * Whether a sign-up / sign-in form should show the bot challenge because a
382
+ * referral code was captured and the instance requires it for referred
383
+ * sign-ups (even with the captcha otherwise off).
384
+ */
385
+ async function referralChallengeRequired(client) {
386
+ if (!browser() || effectiveOptions(client).referral === false || !worthAsking(client))
387
+ return false;
388
+ try {
389
+ const config = await loadReferralConfig(client);
390
+ if (config.challengeReferredSignups !== 'always')
391
+ return false;
392
+ const ref = await currentReferral(client);
393
+ return !!ref?.code;
394
+ }
395
+ catch {
396
+ return false;
397
+ }
398
+ }
399
+ //# sourceMappingURL=referral.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"referral.js","sourceRoot":"","sources":["../src/referral.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * SDK version advisories.
3
+ *
4
+ * Every Atlas browser SDK names itself on its Frontend API requests
5
+ * (`X-Atlas-SDK: @atlasauth/react/0.10.0`). When that version has a known bug
6
+ * fixed in a later release, the response carries
7
+ * `Atlas-SDK-Advisory: upgrade; min=0.8.1; reason=email_code_sign_in` (several
8
+ * comma-separated), and the SDK logs ONE console warning per advisory per page
9
+ * load, so a pinned 0.x version (the caret trap: `^0.8.0` never moves past a
10
+ * lockfile's 0.8.0) is noticed by whoever opens the console.
11
+ */
12
+ /** Which SDK a request comes from. */
13
+ export interface AtlasSdkInfo {
14
+ /** The npm package, e.g. `@atlasauth/react`. */
15
+ name: string;
16
+ version: string;
17
+ }
18
+ export declare const ATLAS_JS_SDK: AtlasSdkInfo;
19
+ /** The request header naming the SDK. */
20
+ export declare const SDK_HEADER = "x-atlas-sdk";
21
+ /** The response header carrying advisories (exposed to cross-origin SDKs by the Frontend API). */
22
+ export declare const SDK_ADVISORY_HEADER = "atlas-sdk-advisory";
23
+ /** `@atlasauth/react/0.10.0`. */
24
+ export declare function sdkHeaderValue(sdk: AtlasSdkInfo): string;
25
+ export interface SdkAdvisoryNotice {
26
+ action: string;
27
+ /** The first version that fixes it. */
28
+ min: string | null;
29
+ reason: string | null;
30
+ }
31
+ /** Parse an `Atlas-SDK-Advisory` value; unknown parameters are ignored, garbage yields []. */
32
+ export declare function parseSdkAdvisory(value: string | null | undefined): SdkAdvisoryNotice[];
33
+ /** Test hook: forget what has been logged, as a new page load would. */
34
+ export declare function resetSdkAdvisoryLog(): void;
35
+ /**
36
+ * Read a response's advisory header and warn once per page load per advisory.
37
+ * Never throws; a response without the header (or a server that does not send
38
+ * it) does nothing. Returns the advisories newly logged.
39
+ */
40
+ export declare function reportSdkAdvisory(response: {
41
+ headers?: {
42
+ get(name: string): string | null;
43
+ };
44
+ } | null | undefined, sdk: AtlasSdkInfo, warn?: (message: string) => void): SdkAdvisoryNotice[];