@atlasauth/js 0.5.0 → 0.6.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 +152 -0
- package/dist/api-keys.d.ts +84 -0
- package/dist/api-keys.js +77 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/captcha-controller.d.ts +95 -0
- package/dist/captcha-controller.js +205 -0
- package/dist/captcha-controller.js.map +1 -0
- package/dist/captcha-widget.d.ts +81 -0
- package/dist/captcha-widget.js +263 -0
- package/dist/captcha-widget.js.map +1 -0
- package/dist/config.d.ts +59 -0
- package/dist/config.js +146 -0
- package/dist/config.js.map +1 -0
- package/dist/frontchannel-logout.d.ts +7 -0
- package/dist/frontchannel-logout.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/instance-settings.d.ts +58 -0
- package/dist/instance-settings.js +74 -0
- package/dist/instance-settings.js.map +1 -0
- package/dist/redirect.d.ts +8 -0
- package/dist/redirect.js +21 -2
- package/dist/redirect.js.map +1 -1
- package/dist/sign-out.d.ts +74 -0
- package/dist/sign-out.js +134 -0
- package/dist/sign-out.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-flow captcha rendering for the prebuilt sign-in / sign-up surfaces.
|
|
3
|
+
*
|
|
4
|
+
* The server tells the browser, per flow, which provider to render and in what
|
|
5
|
+
* mode (`GET /v1/appearance` → `captchaFlows`). This module loads that
|
|
6
|
+
* provider's script once, renders (or executes) its widget into a container,
|
|
7
|
+
* and resolves the token the flow's request then carries as `captcha_token`.
|
|
8
|
+
*
|
|
9
|
+
* Shared by `@atlasauth/react`'s `<SignIn>`/`<SignUp>` and the
|
|
10
|
+
* `@atlasauth/embed` widget, so both draw the same widget the same way.
|
|
11
|
+
*
|
|
12
|
+
* Only providers that expose a standard browser widget are renderable;
|
|
13
|
+
* score/edge/fingerprint providers (SEON, PerimeterX, Akamai, Kasada, Incapsula,
|
|
14
|
+
* mCaptcha, AWS WAF, …) are verified server-side from a token a custom
|
|
15
|
+
* integration supplies, so the prebuilt UIs do not draw them —
|
|
16
|
+
* {@link isRenderableCaptcha} is false and the caller proceeds without a token
|
|
17
|
+
* (the server still fails closed if it required one).
|
|
18
|
+
*
|
|
19
|
+
* Everything is SSR-safe: nothing touches `window`/`document` until a call that
|
|
20
|
+
* renders into a DOM element.
|
|
21
|
+
*/
|
|
22
|
+
/** The flows `captchaFlows` covers. */
|
|
23
|
+
export type CaptchaFlowKey = 'signUp' | 'signIn' | 'guest' | 'passwordReset';
|
|
24
|
+
/** How a widget-drawing provider renders. */
|
|
25
|
+
export type CaptchaWidgetMode = 'invisible' | 'managed' | 'visible';
|
|
26
|
+
/**
|
|
27
|
+
* One flow's public captcha settings, exactly as `/v1/appearance` →
|
|
28
|
+
* `captchaFlows[flow]` returns them. No secrets: the provider secret never
|
|
29
|
+
* leaves the server. `enabled` means "this flow ALWAYS requires a token"; the
|
|
30
|
+
* provider is still reported when it is false so a risk-triggered sign-in
|
|
31
|
+
* challenge can be drawn.
|
|
32
|
+
*/
|
|
33
|
+
export interface FlowCaptcha {
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
provider?: string;
|
|
36
|
+
siteKey?: string | null;
|
|
37
|
+
widget?: CaptchaWidgetMode;
|
|
38
|
+
}
|
|
39
|
+
/** Whether the prebuilt UIs can draw this provider's widget. */
|
|
40
|
+
export declare function isRenderableCaptcha(provider?: string | null): boolean;
|
|
41
|
+
/** True when this flow always needs a rendered token before its request can proceed. */
|
|
42
|
+
export declare function flowNeedsCaptcha(flow: FlowCaptcha | null | undefined): flow is FlowCaptcha;
|
|
43
|
+
/** The two captcha error codes the Frontend API answers a gated request with. */
|
|
44
|
+
export declare const CAPTCHA_ERROR_CODES: readonly string[];
|
|
45
|
+
/** Whether a Frontend API error is a captcha refusal (missing or rejected token). */
|
|
46
|
+
export declare function isCaptchaError(error: {
|
|
47
|
+
code?: string;
|
|
48
|
+
} | null | undefined): boolean;
|
|
49
|
+
type Win = Window & Record<string, unknown>;
|
|
50
|
+
/**
|
|
51
|
+
* Load a provider's script and resolve its global. Idempotent: a second call for
|
|
52
|
+
* the same provider reuses the in-flight or resolved load. When the global is
|
|
53
|
+
* already present (a prior load, or a test that preset it) it resolves at once.
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadCaptchaProvider(provider: string, siteKey: string, win: Win): Promise<unknown>;
|
|
56
|
+
/** A widget rendered into a container: its eventual token, and a way to take it down. */
|
|
57
|
+
export interface CaptchaWidgetHandle {
|
|
58
|
+
/** Resolves with the solved token; rejects on provider error/timeout or removal. */
|
|
59
|
+
token: Promise<string>;
|
|
60
|
+
/**
|
|
61
|
+
* Remove the widget (provider teardown + empty the container). Tokens are
|
|
62
|
+
* single-use, so call this after a submit spent the token and render a fresh
|
|
63
|
+
* widget for the next try.
|
|
64
|
+
*/
|
|
65
|
+
remove(): void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Render a flow's captcha widget into `container` and return a handle on its
|
|
69
|
+
* token. Loads the provider, renders/executes the right widget for the mode.
|
|
70
|
+
* `container` is where a visible/managed widget draws; score providers draw
|
|
71
|
+
* nothing there.
|
|
72
|
+
*/
|
|
73
|
+
export declare function renderCaptchaWidget(flow: FlowCaptcha, container: HTMLElement): CaptchaWidgetHandle;
|
|
74
|
+
/**
|
|
75
|
+
* Obtain a captcha token for a flow: render the widget into `container` and
|
|
76
|
+
* resolve its token. Rejects on provider error/timeout — the caller decides
|
|
77
|
+
* whether to surface it or let the (fail-closed) server reject the tokenless
|
|
78
|
+
* request.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getCaptchaToken(flow: FlowCaptcha, container: HTMLElement): Promise<string>;
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Per-flow captcha rendering for the prebuilt sign-in / sign-up surfaces.
|
|
4
|
+
*
|
|
5
|
+
* The server tells the browser, per flow, which provider to render and in what
|
|
6
|
+
* mode (`GET /v1/appearance` → `captchaFlows`). This module loads that
|
|
7
|
+
* provider's script once, renders (or executes) its widget into a container,
|
|
8
|
+
* and resolves the token the flow's request then carries as `captcha_token`.
|
|
9
|
+
*
|
|
10
|
+
* Shared by `@atlasauth/react`'s `<SignIn>`/`<SignUp>` and the
|
|
11
|
+
* `@atlasauth/embed` widget, so both draw the same widget the same way.
|
|
12
|
+
*
|
|
13
|
+
* Only providers that expose a standard browser widget are renderable;
|
|
14
|
+
* score/edge/fingerprint providers (SEON, PerimeterX, Akamai, Kasada, Incapsula,
|
|
15
|
+
* mCaptcha, AWS WAF, …) are verified server-side from a token a custom
|
|
16
|
+
* integration supplies, so the prebuilt UIs do not draw them —
|
|
17
|
+
* {@link isRenderableCaptcha} is false and the caller proceeds without a token
|
|
18
|
+
* (the server still fails closed if it required one).
|
|
19
|
+
*
|
|
20
|
+
* Everything is SSR-safe: nothing touches `window`/`document` until a call that
|
|
21
|
+
* renders into a DOM element.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.CAPTCHA_ERROR_CODES = void 0;
|
|
25
|
+
exports.isRenderableCaptcha = isRenderableCaptcha;
|
|
26
|
+
exports.flowNeedsCaptcha = flowNeedsCaptcha;
|
|
27
|
+
exports.isCaptchaError = isCaptchaError;
|
|
28
|
+
exports.loadCaptchaProvider = loadCaptchaProvider;
|
|
29
|
+
exports.renderCaptchaWidget = renderCaptchaWidget;
|
|
30
|
+
exports.getCaptchaToken = getCaptchaToken;
|
|
31
|
+
/** The providers the prebuilt UIs can natively render. */
|
|
32
|
+
const RENDERABLE = new Set([
|
|
33
|
+
'turnstile',
|
|
34
|
+
'hcaptcha',
|
|
35
|
+
'recaptcha',
|
|
36
|
+
'recaptcha_v3',
|
|
37
|
+
'recaptcha_enterprise',
|
|
38
|
+
]);
|
|
39
|
+
/** Whether the prebuilt UIs can draw this provider's widget. */
|
|
40
|
+
function isRenderableCaptcha(provider) {
|
|
41
|
+
return !!provider && RENDERABLE.has(provider);
|
|
42
|
+
}
|
|
43
|
+
/** True when this flow always needs a rendered token before its request can proceed. */
|
|
44
|
+
function flowNeedsCaptcha(flow) {
|
|
45
|
+
return !!flow && flow.enabled === true && isRenderableCaptcha(flow.provider);
|
|
46
|
+
}
|
|
47
|
+
/** The two captcha error codes the Frontend API answers a gated request with. */
|
|
48
|
+
exports.CAPTCHA_ERROR_CODES = ['CAPTCHA_REQUIRED', 'CAPTCHA_FAILED'];
|
|
49
|
+
/** Whether a Frontend API error is a captcha refusal (missing or rejected token). */
|
|
50
|
+
function isCaptchaError(error) {
|
|
51
|
+
return !!error && typeof error.code === 'string' && exports.CAPTCHA_ERROR_CODES.includes(error.code);
|
|
52
|
+
}
|
|
53
|
+
const SCRIPTS = {
|
|
54
|
+
turnstile: {
|
|
55
|
+
src: () => 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit',
|
|
56
|
+
global: 'turnstile',
|
|
57
|
+
},
|
|
58
|
+
hcaptcha: {
|
|
59
|
+
src: () => 'https://js.hcaptcha.com/1/api.js?render=explicit',
|
|
60
|
+
global: 'hcaptcha',
|
|
61
|
+
},
|
|
62
|
+
recaptcha: {
|
|
63
|
+
src: () => 'https://www.google.com/recaptcha/api.js?render=explicit',
|
|
64
|
+
global: 'grecaptcha',
|
|
65
|
+
},
|
|
66
|
+
recaptcha_v3: {
|
|
67
|
+
src: (siteKey) => `https://www.google.com/recaptcha/api.js?render=${encodeURIComponent(siteKey)}`,
|
|
68
|
+
global: 'grecaptcha',
|
|
69
|
+
},
|
|
70
|
+
recaptcha_enterprise: {
|
|
71
|
+
src: (siteKey) => `https://www.google.com/recaptcha/enterprise.js?render=${encodeURIComponent(siteKey)}`,
|
|
72
|
+
global: 'grecaptcha',
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Load a provider's script and resolve its global. Idempotent: a second call for
|
|
77
|
+
* the same provider reuses the in-flight or resolved load. When the global is
|
|
78
|
+
* already present (a prior load, or a test that preset it) it resolves at once.
|
|
79
|
+
*/
|
|
80
|
+
function loadCaptchaProvider(provider, siteKey, win) {
|
|
81
|
+
const spec = SCRIPTS[provider];
|
|
82
|
+
if (!spec)
|
|
83
|
+
return Promise.reject(new Error(`captcha: ${provider} is not renderable`));
|
|
84
|
+
if (win[spec.global])
|
|
85
|
+
return Promise.resolve(win[spec.global]);
|
|
86
|
+
const doc = win.document;
|
|
87
|
+
const cacheKey = `__atlasCaptchaLoad_${provider}`;
|
|
88
|
+
const existing = win[cacheKey];
|
|
89
|
+
if (existing)
|
|
90
|
+
return existing;
|
|
91
|
+
const promise = new Promise((resolve, reject) => {
|
|
92
|
+
const done = () => {
|
|
93
|
+
if (win[spec.global])
|
|
94
|
+
resolve(win[spec.global]);
|
|
95
|
+
else
|
|
96
|
+
reject(new Error(`captcha: ${provider} script loaded but global missing`));
|
|
97
|
+
};
|
|
98
|
+
const src = spec.src(siteKey);
|
|
99
|
+
// Reuse a script tag another flow may have injected for the same src.
|
|
100
|
+
let el = doc.querySelector(`script[src="${src}"]`);
|
|
101
|
+
if (el) {
|
|
102
|
+
if (win[spec.global])
|
|
103
|
+
return resolve(win[spec.global]);
|
|
104
|
+
el.addEventListener('load', done, { once: true });
|
|
105
|
+
el.addEventListener('error', () => reject(new Error(`captcha: ${provider} script failed`)), {
|
|
106
|
+
once: true,
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
el = doc.createElement('script');
|
|
111
|
+
el.src = src;
|
|
112
|
+
el.async = true;
|
|
113
|
+
el.defer = true;
|
|
114
|
+
el.addEventListener('load', done, { once: true });
|
|
115
|
+
el.addEventListener('error', () => reject(new Error(`captcha: ${provider} script failed`)), {
|
|
116
|
+
once: true,
|
|
117
|
+
});
|
|
118
|
+
(doc.head ?? doc.body ?? doc.documentElement).appendChild(el);
|
|
119
|
+
});
|
|
120
|
+
win[cacheKey] = promise;
|
|
121
|
+
// A failed load must not poison every later attempt (a flaky network, a
|
|
122
|
+
// content blocker toggled off): forget it so the next render retries.
|
|
123
|
+
promise.catch(() => {
|
|
124
|
+
if (win[cacheKey] === promise)
|
|
125
|
+
delete win[cacheKey];
|
|
126
|
+
});
|
|
127
|
+
return promise;
|
|
128
|
+
}
|
|
129
|
+
/** Cloudflare Turnstile: render into the container, resolve on the callback. */
|
|
130
|
+
function turnstileToken(api, el, siteKey, mode, onTeardown) {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
const id = api.render(el, {
|
|
133
|
+
sitekey: siteKey,
|
|
134
|
+
// Turnstile's own modes map cleanly onto ours.
|
|
135
|
+
appearance: mode === 'invisible' ? 'interaction-only' : 'always',
|
|
136
|
+
callback: (token) => resolve(token),
|
|
137
|
+
'error-callback': () => reject(new Error('captcha: turnstile error')),
|
|
138
|
+
'timeout-callback': () => reject(new Error('captcha: turnstile timeout')),
|
|
139
|
+
});
|
|
140
|
+
onTeardown(() => api.remove?.(id));
|
|
141
|
+
if (mode === 'invisible' && api.execute)
|
|
142
|
+
api.execute(id);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/** hCaptcha: render, then execute for invisible; resolve on the callback. */
|
|
146
|
+
function hcaptchaToken(api, el, siteKey, mode, onTeardown) {
|
|
147
|
+
return new Promise((resolve, reject) => {
|
|
148
|
+
const id = api.render(el, {
|
|
149
|
+
sitekey: siteKey,
|
|
150
|
+
size: mode === 'invisible' ? 'invisible' : 'normal',
|
|
151
|
+
callback: (token) => resolve(token),
|
|
152
|
+
'error-callback': () => reject(new Error('captcha: hcaptcha error')),
|
|
153
|
+
});
|
|
154
|
+
onTeardown(() => api.remove?.(id));
|
|
155
|
+
if (mode === 'invisible') {
|
|
156
|
+
const r = api.execute(id, { async: true });
|
|
157
|
+
if (r && typeof r.then === 'function') {
|
|
158
|
+
r.then((v) => resolve(v.response), reject);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/** reCAPTCHA v2 (checkbox/invisible): render, resolve on callback. */
|
|
164
|
+
function recaptchaV2Token(api, el, siteKey, mode, onTeardown) {
|
|
165
|
+
return new Promise((resolve, reject) => {
|
|
166
|
+
const id = api.render(el, {
|
|
167
|
+
sitekey: siteKey,
|
|
168
|
+
size: mode === 'invisible' ? 'invisible' : 'normal',
|
|
169
|
+
callback: (token) => resolve(token),
|
|
170
|
+
'error-callback': () => reject(new Error('captcha: recaptcha error')),
|
|
171
|
+
});
|
|
172
|
+
// reCAPTCHA has no remove(); reset frees the widget, the container is cleared.
|
|
173
|
+
onTeardown(() => api.reset?.(id));
|
|
174
|
+
if (mode === 'invisible' && api.execute) {
|
|
175
|
+
const r = api.execute(undefined, { widgetId: id });
|
|
176
|
+
if (r && typeof r.then === 'function') {
|
|
177
|
+
r.then(resolve, reject);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/** reCAPTCHA v3 / Enterprise (score): execute programmatically, no visible widget. */
|
|
183
|
+
function recaptchaV3Token(api, siteKey) {
|
|
184
|
+
const run = () => {
|
|
185
|
+
const r = api.execute(siteKey, { action: 'submit' });
|
|
186
|
+
return r && typeof r.then === 'function'
|
|
187
|
+
? r
|
|
188
|
+
: Promise.reject(new Error('captcha: recaptcha v3 execute returned no promise'));
|
|
189
|
+
};
|
|
190
|
+
return new Promise((resolve, reject) => {
|
|
191
|
+
if (api.ready)
|
|
192
|
+
api.ready(() => run().then(resolve, reject));
|
|
193
|
+
else
|
|
194
|
+
run().then(resolve, reject);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Render a flow's captcha widget into `container` and return a handle on its
|
|
199
|
+
* token. Loads the provider, renders/executes the right widget for the mode.
|
|
200
|
+
* `container` is where a visible/managed widget draws; score providers draw
|
|
201
|
+
* nothing there.
|
|
202
|
+
*/
|
|
203
|
+
function renderCaptchaWidget(flow, container) {
|
|
204
|
+
const provider = flow.provider ?? '';
|
|
205
|
+
const siteKey = flow.siteKey ?? '';
|
|
206
|
+
const mode = flow.widget ?? 'managed';
|
|
207
|
+
const win = (container.ownerDocument?.defaultView ?? globalThis);
|
|
208
|
+
let removed = false;
|
|
209
|
+
let teardown = null;
|
|
210
|
+
let cancel = null;
|
|
211
|
+
const onTeardown = (t) => {
|
|
212
|
+
teardown = t;
|
|
213
|
+
};
|
|
214
|
+
const token = new Promise((resolve, reject) => {
|
|
215
|
+
cancel = reject;
|
|
216
|
+
loadCaptchaProvider(provider, siteKey, win)
|
|
217
|
+
.then((api) => {
|
|
218
|
+
if (removed)
|
|
219
|
+
throw new Error('captcha: widget removed');
|
|
220
|
+
switch (provider) {
|
|
221
|
+
case 'turnstile':
|
|
222
|
+
return turnstileToken(api, container, siteKey, mode, onTeardown);
|
|
223
|
+
case 'hcaptcha':
|
|
224
|
+
return hcaptchaToken(api, container, siteKey, mode, onTeardown);
|
|
225
|
+
case 'recaptcha':
|
|
226
|
+
return recaptchaV2Token(api, container, siteKey, mode, onTeardown);
|
|
227
|
+
case 'recaptcha_v3':
|
|
228
|
+
case 'recaptcha_enterprise':
|
|
229
|
+
return recaptchaV3Token(api, siteKey);
|
|
230
|
+
default:
|
|
231
|
+
throw new Error(`captcha: ${provider} is not renderable`);
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
.then(resolve, reject);
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
token,
|
|
238
|
+
remove() {
|
|
239
|
+
if (removed)
|
|
240
|
+
return;
|
|
241
|
+
removed = true;
|
|
242
|
+
try {
|
|
243
|
+
teardown?.();
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
/* a vendor that already tore itself down */
|
|
247
|
+
}
|
|
248
|
+
while (container.firstChild)
|
|
249
|
+
container.removeChild(container.firstChild);
|
|
250
|
+
cancel?.(new Error('captcha: widget removed'));
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Obtain a captcha token for a flow: render the widget into `container` and
|
|
256
|
+
* resolve its token. Rejects on provider error/timeout — the caller decides
|
|
257
|
+
* whether to surface it or let the (fail-closed) server reject the tokenless
|
|
258
|
+
* request.
|
|
259
|
+
*/
|
|
260
|
+
async function getCaptchaToken(flow, container) {
|
|
261
|
+
return renderCaptchaWidget(flow, container).token;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=captcha-widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"captcha-widget.js","sourceRoot":"","sources":["../src/captcha-widget.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAgCH,kDAEC;AAGD,4CAEC;AAMD,wCAEC;AAoDD,kDA2CC;AA8GD,kDAiDC;AAQD,0CAEC;AAjSD,0DAA0D;AAC1D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC;IACzB,WAAW;IACX,UAAU;IACV,WAAW;IACX,cAAc;IACd,sBAAsB;CACvB,CAAC,CAAC;AAEH,gEAAgE;AAChE,SAAgB,mBAAmB,CAAC,QAAwB;IAC1D,OAAO,CAAC,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,wFAAwF;AACxF,SAAgB,gBAAgB,CAAC,IAAoC;IACnE,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/E,CAAC;AAED,iFAAiF;AACpE,QAAA,mBAAmB,GAAsB,CAAC,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;AAE7F,qFAAqF;AACrF,SAAgB,cAAc,CAAC,KAA2C;IACxE,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,2BAAmB,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC/F,CAAC;AAuBD,MAAM,OAAO,GAAyE;IACpF,SAAS,EAAE;QACT,GAAG,EAAE,GAAG,EAAE,CAAC,uEAAuE;QAClF,MAAM,EAAE,WAAW;KACpB;IACD,QAAQ,EAAE;QACR,GAAG,EAAE,GAAG,EAAE,CAAC,kDAAkD;QAC7D,MAAM,EAAE,UAAU;KACnB;IACD,SAAS,EAAE;QACT,GAAG,EAAE,GAAG,EAAE,CAAC,yDAAyD;QACpE,MAAM,EAAE,YAAY;KACrB;IACD,YAAY,EAAE;QACZ,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,kDAAkD,kBAAkB,CAAC,OAAO,CAAC,EAAE;QACjG,MAAM,EAAE,YAAY;KACrB;IACD,oBAAoB,EAAE;QACpB,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,CACf,yDAAyD,kBAAkB,CAAC,OAAO,CAAC,EAAE;QACxF,MAAM,EAAE,YAAY;KACrB;CACF,CAAC;AAEF;;;;GAIG;AACH,SAAgB,mBAAmB,CAAC,QAAgB,EAAE,OAAe,EAAE,GAAQ;IAC7E,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,IAAI,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,QAAQ,oBAAoB,CAAC,CAAC,CAAC;IACtF,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;IACzB,MAAM,QAAQ,GAAG,sBAAsB,QAAQ,EAAE,CAAC;IAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAiC,CAAC;IAC/D,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;;gBAC3C,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,QAAQ,mCAAmC,CAAC,CAAC,CAAC;QAClF,CAAC,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC9B,sEAAsE;QACtE,IAAI,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC,eAAe,GAAG,IAAI,CAA6B,CAAC;QAC/E,IAAI,EAAE,EAAE,CAAC;YACP,IAAI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YACvD,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAClD,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,QAAQ,gBAAgB,CAAC,CAAC,EAAE;gBAC1F,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,EAAE,GAAG,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QACjC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC;QACb,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;QAChB,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC;QAChB,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,QAAQ,gBAAgB,CAAC,CAAC,EAAE;YAC1F,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;QACH,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,eAAe,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;IACxB,wEAAwE;IACxE,sEAAsE;IACtE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;QACjB,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,OAAO;YAAE,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AACjB,CAAC;AAKD,gFAAgF;AAChF,SAAS,cAAc,CACrB,GAAiB,EACjB,EAAe,EACf,OAAe,EACf,IAAuB,EACvB,UAAiC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;YACxB,OAAO,EAAE,OAAO;YAChB,+CAA+C;YAC/C,UAAU,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,QAAQ;YAChE,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;YAC3C,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YACrE,kBAAkB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;SAC1E,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,OAAO;YAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6EAA6E;AAC7E,SAAS,aAAa,CACpB,GAAgB,EAChB,EAAe,EACf,OAAe,EACf,IAAuB,EACvB,UAAiC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;YACxB,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ;YACnD,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;YAC3C,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;SACrE,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC3C,IAAI,CAAC,IAAI,OAAQ,CAAmC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACxE,CAAmC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;YAChF,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,sEAAsE;AACtE,SAAS,gBAAgB,CACvB,GAAkB,EAClB,EAAe,EACf,OAAe,EACf,IAAuB,EACvB,UAAiC;IAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE;YACxB,OAAO,EAAE,OAAO;YAChB,IAAI,EAAE,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,QAAQ;YACnD,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;YAC3C,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;SACtE,CAAC,CAAC;QACH,+EAA+E;QAC/E,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YACxC,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,IAAI,OAAQ,CAAqB,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC1D,CAAqB,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,sFAAsF;AACtF,SAAS,gBAAgB,CAAC,GAAkB,EAAE,OAAe;IAC3D,MAAM,GAAG,GAAG,GAAG,EAAE;QACf,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,OAAQ,CAAqB,CAAC,IAAI,KAAK,UAAU;YAC3D,CAAC,CAAE,CAAqB;YACxB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC,CAAC;IACrF,CAAC,CAAC;IACF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,GAAG,CAAC,KAAK;YAAE,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC;;YACvD,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC;AAcD;;;;;GAKG;AACH,SAAgB,mBAAmB,CAAC,IAAiB,EAAE,SAAsB;IAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC;IACnC,MAAM,IAAI,GAAsB,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC;IACzD,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,WAAW,IAAI,UAAU,CAAmB,CAAC;IAEnF,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,QAAQ,GAAoB,IAAI,CAAC;IACrC,IAAI,MAAM,GAAgC,IAAI,CAAC;IAC/C,MAAM,UAAU,GAAG,CAAC,CAAW,EAAE,EAAE;QACjC,QAAQ,GAAG,CAAC,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACpD,MAAM,GAAG,MAAM,CAAC;QAChB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC;aACxC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YACZ,IAAI,OAAO;gBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACxD,QAAQ,QAAQ,EAAE,CAAC;gBACjB,KAAK,WAAW;oBACd,OAAO,cAAc,CAAC,GAAmB,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;gBACnF,KAAK,UAAU;oBACb,OAAO,aAAa,CAAC,GAAkB,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;gBACjF,KAAK,WAAW;oBACd,OAAO,gBAAgB,CAAC,GAAoB,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;gBACtF,KAAK,cAAc,CAAC;gBACpB,KAAK,sBAAsB;oBACzB,OAAO,gBAAgB,CAAC,GAAoB,EAAE,OAAO,CAAC,CAAC;gBACzD;oBACE,MAAM,IAAI,KAAK,CAAC,YAAY,QAAQ,oBAAoB,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,CAAC;aACD,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK;QACL,MAAM;YACJ,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,CAAC;gBACF,QAA4B,EAAE,EAAE,CAAC;YACpC,CAAC;YAAC,MAAM,CAAC;gBACP,4CAA4C;YAC9C,CAAC;YACD,OAAO,SAAS,CAAC,UAAU;gBAAE,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;YACxE,MAAsC,EAAE,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QAClF,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CAAC,IAAiB,EAAE,SAAsB;IAC7E,OAAO,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC;AACpD,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider configuration checks shared by every framework SDK that wraps this
|
|
3
|
+
* package (React, Vue, Svelte, Angular, Solid, Qwik, React Native, …).
|
|
4
|
+
*
|
|
5
|
+
* The one that matters is `frontendApi`. The publishable key encodes the
|
|
6
|
+
* instance id but NOT a host, so the Frontend API origin cannot be derived from
|
|
7
|
+
* it. An SDK that quietly fell back to `''` sent every request to a relative
|
|
8
|
+
* path on the app's own origin — a 404 (or the app's HTML) that looked exactly
|
|
9
|
+
* like "signed out", with nothing in the console to say why. Every provider now
|
|
10
|
+
* resolves the value through {@link resolveFrontendApi}, which throws a clear
|
|
11
|
+
* {@link AtlasConfigError} at mount instead.
|
|
12
|
+
*/
|
|
13
|
+
/** The codes an {@link AtlasConfigError} carries. */
|
|
14
|
+
export type AtlasConfigErrorCode = 'FRONTEND_API_REQUIRED' | 'FRONTEND_API_INVALID';
|
|
15
|
+
/**
|
|
16
|
+
* A misconfigured provider. Thrown synchronously at mount/initialisation, so
|
|
17
|
+
* the mistake surfaces in development rather than as a silent signed-out state.
|
|
18
|
+
* Check `error.code` (or `instanceof AtlasConfigError`) to tell it apart.
|
|
19
|
+
*/
|
|
20
|
+
export declare class AtlasConfigError extends Error {
|
|
21
|
+
readonly code: AtlasConfigErrorCode;
|
|
22
|
+
constructor(code: AtlasConfigErrorCode, message: string);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The explicit value for a same-origin / reverse-proxy setup, where the Frontend
|
|
26
|
+
* API is served under the app's own origin. Resolves to relative request paths.
|
|
27
|
+
*/
|
|
28
|
+
export declare const SAME_ORIGIN_FRONTEND_API = "same-origin";
|
|
29
|
+
export interface ResolveFrontendApiOptions {
|
|
30
|
+
/** Name used in the error message, e.g. `"<AtlasProvider>"`. */
|
|
31
|
+
component?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Whether a same-origin value (`"same-origin"` or a path such as `"/atlas"`)
|
|
34
|
+
* is meaningful. `false` for native apps, which have no origin of their own.
|
|
35
|
+
* Default `true`.
|
|
36
|
+
*/
|
|
37
|
+
allowSameOrigin?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validate a provider's `frontendApi` and return the base URL requests are
|
|
41
|
+
* built from (`${base}/v1/client`). Throws an {@link AtlasConfigError} when it
|
|
42
|
+
* is missing, non-string, blank, or not an absolute `https:` URL (`http:` is accepted for
|
|
43
|
+
* localhost and local development hosts).
|
|
44
|
+
*
|
|
45
|
+
* Accepted:
|
|
46
|
+
* - an absolute URL, e.g. `"https://auth.example.com"` (a trailing slash is
|
|
47
|
+
* dropped; a path prefix such as `"https://example.com/auth"` is kept);
|
|
48
|
+
* - `"same-origin"` → `""`, for a reverse proxy serving the Frontend API on
|
|
49
|
+
* the app's own origin;
|
|
50
|
+
* - a root-relative path prefix such as `"/atlas"` → `"/atlas"`, for a reverse
|
|
51
|
+
* proxy under a path;
|
|
52
|
+
* - DEPRECATED: `""` → `""`, the original same-origin spelling. Still works
|
|
53
|
+
* (with a one-time console warning pointing at `"same-origin"`) so existing
|
|
54
|
+
* reverse-proxy setups keep running; refused when `allowSameOrigin` is false.
|
|
55
|
+
*
|
|
56
|
+
* Missing (`undefined`/`null`), non-string and whitespace-only values always
|
|
57
|
+
* throw `FRONTEND_API_REQUIRED`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function resolveFrontendApi(value: unknown, options?: ResolveFrontendApiOptions): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider configuration checks shared by every framework SDK that wraps this
|
|
4
|
+
* package (React, Vue, Svelte, Angular, Solid, Qwik, React Native, …).
|
|
5
|
+
*
|
|
6
|
+
* The one that matters is `frontendApi`. The publishable key encodes the
|
|
7
|
+
* instance id but NOT a host, so the Frontend API origin cannot be derived from
|
|
8
|
+
* it. An SDK that quietly fell back to `''` sent every request to a relative
|
|
9
|
+
* path on the app's own origin — a 404 (or the app's HTML) that looked exactly
|
|
10
|
+
* like "signed out", with nothing in the console to say why. Every provider now
|
|
11
|
+
* resolves the value through {@link resolveFrontendApi}, which throws a clear
|
|
12
|
+
* {@link AtlasConfigError} at mount instead.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.SAME_ORIGIN_FRONTEND_API = exports.AtlasConfigError = void 0;
|
|
16
|
+
exports.resolveFrontendApi = resolveFrontendApi;
|
|
17
|
+
/**
|
|
18
|
+
* A misconfigured provider. Thrown synchronously at mount/initialisation, so
|
|
19
|
+
* the mistake surfaces in development rather than as a silent signed-out state.
|
|
20
|
+
* Check `error.code` (or `instanceof AtlasConfigError`) to tell it apart.
|
|
21
|
+
*/
|
|
22
|
+
class AtlasConfigError extends Error {
|
|
23
|
+
code;
|
|
24
|
+
constructor(code, message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.name = 'AtlasConfigError';
|
|
27
|
+
this.code = code;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.AtlasConfigError = AtlasConfigError;
|
|
31
|
+
/**
|
|
32
|
+
* The explicit value for a same-origin / reverse-proxy setup, where the Frontend
|
|
33
|
+
* API is served under the app's own origin. Resolves to relative request paths.
|
|
34
|
+
*/
|
|
35
|
+
exports.SAME_ORIGIN_FRONTEND_API = 'same-origin';
|
|
36
|
+
const EXAMPLES = '"https://atlasauth.net" (before you verify a custom domain) or your verified custom domain, e.g. "https://auth.example.com"';
|
|
37
|
+
/** Hosts where plain `http:` is accepted: loopback and local development names. */
|
|
38
|
+
function isLocalDevHost(hostname) {
|
|
39
|
+
const host = hostname.replace(/^\[|\]$/g, '').toLowerCase();
|
|
40
|
+
if (host === 'localhost' || host.endsWith('.localhost'))
|
|
41
|
+
return true;
|
|
42
|
+
if (host.endsWith('.local') || host.endsWith('.test'))
|
|
43
|
+
return true;
|
|
44
|
+
if (host === '::1')
|
|
45
|
+
return true;
|
|
46
|
+
const v4 = host.match(/^(\d{1,3})\.(\d{1,3})\.\d{1,3}\.\d{1,3}$/);
|
|
47
|
+
if (!v4)
|
|
48
|
+
return false;
|
|
49
|
+
const a = Number(v4[1]);
|
|
50
|
+
const b = Number(v4[2]);
|
|
51
|
+
return a === 127 || a === 10 || (a === 192 && b === 168) || (a === 172 && b >= 16 && b <= 31);
|
|
52
|
+
}
|
|
53
|
+
function show(value) {
|
|
54
|
+
if (value === undefined)
|
|
55
|
+
return 'undefined';
|
|
56
|
+
if (value === null)
|
|
57
|
+
return 'null';
|
|
58
|
+
if (typeof value === 'string')
|
|
59
|
+
return JSON.stringify(value);
|
|
60
|
+
return typeof value;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Validate a provider's `frontendApi` and return the base URL requests are
|
|
64
|
+
* built from (`${base}/v1/client`). Throws an {@link AtlasConfigError} when it
|
|
65
|
+
* is missing, non-string, blank, or not an absolute `https:` URL (`http:` is accepted for
|
|
66
|
+
* localhost and local development hosts).
|
|
67
|
+
*
|
|
68
|
+
* Accepted:
|
|
69
|
+
* - an absolute URL, e.g. `"https://auth.example.com"` (a trailing slash is
|
|
70
|
+
* dropped; a path prefix such as `"https://example.com/auth"` is kept);
|
|
71
|
+
* - `"same-origin"` → `""`, for a reverse proxy serving the Frontend API on
|
|
72
|
+
* the app's own origin;
|
|
73
|
+
* - a root-relative path prefix such as `"/atlas"` → `"/atlas"`, for a reverse
|
|
74
|
+
* proxy under a path;
|
|
75
|
+
* - DEPRECATED: `""` → `""`, the original same-origin spelling. Still works
|
|
76
|
+
* (with a one-time console warning pointing at `"same-origin"`) so existing
|
|
77
|
+
* reverse-proxy setups keep running; refused when `allowSameOrigin` is false.
|
|
78
|
+
*
|
|
79
|
+
* Missing (`undefined`/`null`), non-string and whitespace-only values always
|
|
80
|
+
* throw `FRONTEND_API_REQUIRED`.
|
|
81
|
+
*/
|
|
82
|
+
function resolveFrontendApi(value, options = {}) {
|
|
83
|
+
const component = options.component ?? 'The Atlas provider';
|
|
84
|
+
const allowSameOrigin = options.allowSameOrigin !== false;
|
|
85
|
+
const sameOriginHint = allowSameOrigin
|
|
86
|
+
? ` If you serve the Frontend API from your own origin through a reverse proxy, pass "${exports.SAME_ORIGIN_FRONTEND_API}" (or its path, e.g. "/atlas").`
|
|
87
|
+
: '';
|
|
88
|
+
if (value === '' && allowSameOrigin) {
|
|
89
|
+
warnEmptyFrontendApiOnce(component);
|
|
90
|
+
return '';
|
|
91
|
+
}
|
|
92
|
+
if (typeof value !== 'string' || value.trim() === '') {
|
|
93
|
+
throw new AtlasConfigError('FRONTEND_API_REQUIRED', `${component} needs \`frontendApi\`: the absolute URL of your instance's Frontend API, ` +
|
|
94
|
+
`such as ${EXAMPLES}. It cannot be derived from the publishable key. Got ${show(value)}.` +
|
|
95
|
+
sameOriginHint);
|
|
96
|
+
}
|
|
97
|
+
const raw = value.trim();
|
|
98
|
+
const invalid = (why) => new AtlasConfigError('FRONTEND_API_INVALID', `${component} got an invalid \`frontendApi\` ${JSON.stringify(raw)}: ${why} ` +
|
|
99
|
+
`Use an absolute https URL such as ${EXAMPLES}.` +
|
|
100
|
+
sameOriginHint);
|
|
101
|
+
if (raw === exports.SAME_ORIGIN_FRONTEND_API) {
|
|
102
|
+
if (!allowSameOrigin)
|
|
103
|
+
throw invalid('a native app has no origin of its own.');
|
|
104
|
+
return '';
|
|
105
|
+
}
|
|
106
|
+
if (raw.startsWith('/') && !raw.startsWith('//')) {
|
|
107
|
+
if (!allowSameOrigin)
|
|
108
|
+
throw invalid('a native app has no origin of its own.');
|
|
109
|
+
if (/[?#]/.test(raw))
|
|
110
|
+
throw invalid('it must not carry a query string or fragment.');
|
|
111
|
+
return raw.replace(/\/+$/, '');
|
|
112
|
+
}
|
|
113
|
+
let url;
|
|
114
|
+
try {
|
|
115
|
+
url = new URL(raw);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
throw invalid('it is not an absolute URL.');
|
|
119
|
+
}
|
|
120
|
+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
|
|
121
|
+
throw invalid(`the ${url.protocol} scheme is not supported.`);
|
|
122
|
+
}
|
|
123
|
+
if (url.protocol === 'http:' && !isLocalDevHost(url.hostname)) {
|
|
124
|
+
throw invalid('plain http is only accepted for localhost and local development hosts.');
|
|
125
|
+
}
|
|
126
|
+
if (url.username || url.password)
|
|
127
|
+
throw invalid('it must not carry credentials.');
|
|
128
|
+
if (url.search || url.hash)
|
|
129
|
+
throw invalid('it must not carry a query string or fragment.');
|
|
130
|
+
return `${url.origin}${url.pathname.replace(/\/+$/, '')}`;
|
|
131
|
+
}
|
|
132
|
+
let warnedEmpty = false;
|
|
133
|
+
/**
|
|
134
|
+
* `frontendApi=""` was the documented same-origin spelling. It keeps working,
|
|
135
|
+
* but an empty string is also what an unset environment variable looks like —
|
|
136
|
+
* the explicit `"same-origin"` says what was meant. Warned once per page.
|
|
137
|
+
*/
|
|
138
|
+
function warnEmptyFrontendApiOnce(component) {
|
|
139
|
+
if (warnedEmpty || typeof console === 'undefined')
|
|
140
|
+
return;
|
|
141
|
+
warnedEmpty = true;
|
|
142
|
+
console.warn(`[Atlas] ${component}: \`frontendApi=""\` is deprecated. It still means same-origin ` +
|
|
143
|
+
`(requests go to relative paths on this origin), but pass "${exports.SAME_ORIGIN_FRONTEND_API}" to say so ` +
|
|
144
|
+
`explicitly, or your Frontend API URL, e.g. "https://atlasauth.net".`);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,13 @@ export interface SignOutOptions {
|
|
|
22
22
|
* (hidden iframes, capped at 5 s). Default `true`; pass `false` to skip it.
|
|
23
23
|
*/
|
|
24
24
|
frontchannel?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Reject with a `SignOutError` when the Frontend API could not revoke the
|
|
27
|
+
* session (after one retry). The local sign-out still happens either way.
|
|
28
|
+
* Default `false`: `signOut()` resolves and reports `revoked: false` instead.
|
|
29
|
+
* Honoured by `@atlasauth/react`.
|
|
30
|
+
*/
|
|
31
|
+
strict?: boolean;
|
|
25
32
|
}
|
|
26
33
|
/** The default wait for front-channel logout frames. */
|
|
27
34
|
export declare const FRONTCHANNEL_LOGOUT_TIMEOUT_MS = 5000;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frontchannel-logout.js","sourceRoot":"","sources":["../src/frontchannel-logout.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;
|
|
1
|
+
{"version":3,"file":"frontchannel-logout.js","sourceRoot":"","sources":["../src/frontchannel-logout.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export * from './config';
|
|
2
|
+
export * from './sign-out';
|
|
1
3
|
export * from './token-cache';
|
|
2
4
|
export * from './tab-election';
|
|
3
5
|
export * from './attempt';
|
|
@@ -10,9 +12,13 @@ export * from './telegram';
|
|
|
10
12
|
export * from './siwe';
|
|
11
13
|
export * from './telemetry';
|
|
12
14
|
export * from './reauth';
|
|
15
|
+
export * from './api-keys';
|
|
13
16
|
export * from './connect';
|
|
14
17
|
export * from './password-reset';
|
|
15
18
|
export * from './check-session';
|
|
16
19
|
export * from './frontchannel-logout';
|
|
17
20
|
export * from './captcha';
|
|
21
|
+
export * from './captcha-widget';
|
|
22
|
+
export * from './captcha-controller';
|
|
23
|
+
export * from './instance-settings';
|
|
18
24
|
export { type AuthzClaims, type ProtectCondition, type ProtectOutcome, type ProtectReason, evaluate, hasFromClaims, protectFromClaims, ForbiddenError, ROLE_KEY_PATTERN, PERMISSION_KEY_PATTERN, isRoleKey, isPermissionKey, } from '@atlasauth/authz';
|