@rhinestone/1auth 0.6.9 → 0.6.10
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/dist/chunk-GUAI55LL.mjs +179 -0
- package/dist/chunk-GUAI55LL.mjs.map +1 -0
- package/dist/{chunk-VZYHCFEH.mjs → chunk-THKG3FAG.mjs} +4 -177
- package/dist/chunk-THKG3FAG.mjs.map +1 -0
- package/dist/{client-BNluVe4_.d.ts → client-B_CzDa_I.d.ts} +57 -10
- package/dist/{client-CLCdahyj.d.mts → client-F4DnFM8d.d.mts} +57 -10
- package/dist/headless.d.mts +24 -5
- package/dist/headless.d.ts +24 -5
- package/dist/headless.js +142 -2
- package/dist/headless.js.map +1 -1
- package/dist/headless.mjs +103 -1
- package/dist/headless.mjs.map +1 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +314 -124
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +318 -126
- package/dist/index.mjs.map +1 -1
- package/dist/{provider-BgD9PeDX.d.ts → provider-Cd7Ip5L-.d.ts} +2 -2
- package/dist/{provider-hxHGb6SX.d.mts → provider-IvYXPMpk.d.mts} +2 -2
- package/dist/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/{types-1BMD1PSH.d.mts → types-U_dwxbtS.d.mts} +63 -0
- package/dist/{types-1BMD1PSH.d.ts → types-U_dwxbtS.d.ts} +63 -0
- package/dist/{verify-CZe-m_Vf.d.ts → verify-BLgZzwmJ.d.ts} +1 -1
- package/dist/{verify-D3FaLeAi.d.mts → verify-C8-a5c3K.d.mts} +1 -1
- package/dist/wagmi.d.mts +3 -3
- package/dist/wagmi.d.ts +3 -3
- package/dist/wagmi.mjs +2 -1
- package/dist/wagmi.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-VZYHCFEH.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,9 @@ import {
|
|
|
7
7
|
verifyMessageHash
|
|
8
8
|
} from "./chunk-IHBVEU33.mjs";
|
|
9
9
|
import {
|
|
10
|
-
createOneAuthProvider
|
|
10
|
+
createOneAuthProvider
|
|
11
|
+
} from "./chunk-THKG3FAG.mjs";
|
|
12
|
+
import {
|
|
11
13
|
getAllSupportedChainsAndTokens,
|
|
12
14
|
getChainById,
|
|
13
15
|
getChainExplorerUrl,
|
|
@@ -23,7 +25,7 @@ import {
|
|
|
23
25
|
isTestnet,
|
|
24
26
|
isTokenAddressSupported,
|
|
25
27
|
resolveTokenAddress
|
|
26
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-GUAI55LL.mjs";
|
|
27
29
|
import {
|
|
28
30
|
buildTransactionReview,
|
|
29
31
|
encodeWebAuthnSignature,
|
|
@@ -127,25 +129,19 @@ var SPINNER_RADIUS = (SPINNER_SIZE - SPINNER_STROKE) / 2;
|
|
|
127
129
|
var SPINNER_CIRCUMFERENCE = 2 * Math.PI * SPINNER_RADIUS;
|
|
128
130
|
var SPINNER_ARC_FRACTION = 0.17;
|
|
129
131
|
var SPINNER_ARC = SPINNER_CIRCUMFERENCE * SPINNER_ARC_FRACTION;
|
|
132
|
+
var SPINNER_SPIN_DURATION_MS = 800;
|
|
130
133
|
var LOADING_MODAL_WIDTH = 380;
|
|
131
134
|
var LOADING_MODAL_PADDING = 12;
|
|
132
135
|
var LOADING_MODAL_RADIUS = 16;
|
|
133
|
-
var LOADING_MOBILE_BREAKPOINT = 640;
|
|
134
|
-
var LOADING_CARD_GAP = 16;
|
|
135
136
|
var LOADING_BODY_GAP = 12;
|
|
136
137
|
var LOADING_ICON_PADDING = 12;
|
|
137
138
|
var LOADING_TITLE_BLOCK_GAP = 4;
|
|
138
|
-
var LOADING_FOOTER_GAP = 4;
|
|
139
139
|
var LOADING_TITLE_FONT_SIZE = 20;
|
|
140
140
|
var LOADING_TITLE_FONT_WEIGHT = 700;
|
|
141
141
|
var LOADING_SUBTITLE_FONT_SIZE = 12;
|
|
142
142
|
var LOADING_SUBTITLE_FONT_WEIGHT = 500;
|
|
143
|
-
var LOADING_FOOTER_FONT_SIZE = 11;
|
|
144
|
-
var LOADING_FOOTER_FONT_WEIGHT = 500;
|
|
145
143
|
var LOADING_LINE_HEIGHT = "normal";
|
|
146
144
|
var LOADING_FONT_FAMILY = "'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'";
|
|
147
|
-
var LOGO_WIDTH = 72;
|
|
148
|
-
var LOGO_HEIGHT = 16;
|
|
149
145
|
var BRAND_PURPLE = "#685bff";
|
|
150
146
|
var LIGHT_TOKENS = {
|
|
151
147
|
bgPrimary: "#ffffff",
|
|
@@ -159,7 +155,6 @@ var DARK_TOKENS = {
|
|
|
159
155
|
textPrimary: "#e4e4e7",
|
|
160
156
|
textSecondary: "#9f9fa9"
|
|
161
157
|
};
|
|
162
|
-
var FOOTER_TEXT_COLOR = "#71717b";
|
|
163
158
|
var LOADING_TITLE = "Loading...";
|
|
164
159
|
var LOADING_SUBTITLE = "This will only take a few moments, do not close the window.";
|
|
165
160
|
|
|
@@ -169,7 +164,36 @@ var POPUP_HEIGHT = 600;
|
|
|
169
164
|
var DEFAULT_EMBED_WIDTH = `${LOADING_MODAL_WIDTH}px`;
|
|
170
165
|
var DEFAULT_EMBED_HEIGHT = "500px";
|
|
171
166
|
var DEFAULT_PROVIDER_URL = "https://passkey.1auth.box";
|
|
167
|
+
function currentWindowOrigin() {
|
|
168
|
+
if (typeof window === "undefined") return null;
|
|
169
|
+
const origin = window.location?.origin;
|
|
170
|
+
return typeof origin === "string" && origin.length > 0 ? origin : null;
|
|
171
|
+
}
|
|
172
|
+
function appendParentOriginParam(params) {
|
|
173
|
+
const origin = currentWindowOrigin();
|
|
174
|
+
if (origin) params.set("parentOrigin", origin);
|
|
175
|
+
}
|
|
172
176
|
var MAX_LABEL_LEN = 20;
|
|
177
|
+
var DEFAULT_BACKDROP_COLOR = "#000000";
|
|
178
|
+
var DEFAULT_BACKDROP_OPACITY = 0.4;
|
|
179
|
+
var DEFAULT_BACKDROP_BLUR = 8;
|
|
180
|
+
var HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;
|
|
181
|
+
function resolveBackdropStyle(params) {
|
|
182
|
+
const rawColor = params.get("backdropColor");
|
|
183
|
+
const hex = (rawColor && HEX_COLOR_RE.test(rawColor) ? rawColor : DEFAULT_BACKDROP_COLOR).slice(1);
|
|
184
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
185
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
186
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
187
|
+
const clampNumber = (key, min, max, fallback) => {
|
|
188
|
+
const raw = params.get(key);
|
|
189
|
+
if (!raw) return fallback;
|
|
190
|
+
const n = Number(raw);
|
|
191
|
+
return Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : fallback;
|
|
192
|
+
};
|
|
193
|
+
const opacity = clampNumber("backdropOpacity", 0, 1, DEFAULT_BACKDROP_OPACITY);
|
|
194
|
+
const blur = clampNumber("backdropBlur", 0, 40, DEFAULT_BACKDROP_BLUR);
|
|
195
|
+
return { background: `rgba(${r}, ${g}, ${b}, ${opacity})`, blur };
|
|
196
|
+
}
|
|
173
197
|
function generateModalNonce() {
|
|
174
198
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
175
199
|
return crypto.randomUUID();
|
|
@@ -293,6 +317,15 @@ var OneAuthClient = class {
|
|
|
293
317
|
// "Restore will override" warnings and "emitting session_request:N
|
|
294
318
|
// without any listeners" errors on the second and later txs.
|
|
295
319
|
this.eoaDialogState = null;
|
|
320
|
+
// Hidden iframe that warms the dialog ahead of the first real open (see
|
|
321
|
+
// `prewarm()`). The passkey app runs on a long-lived server (not serverless),
|
|
322
|
+
// so there is no backend cold-start to hide — what stays expensive is the
|
|
323
|
+
// *browser-side* cost of a freshly created cross-origin iframe: downloading
|
|
324
|
+
// the dialog HTML + JS bundle, parsing it, hydrating React, and loading the
|
|
325
|
+
// font. Loading that bundle once into a parked hidden iframe lets the real
|
|
326
|
+
// open hit the HTTP cache (Next.js chunks/fonts are immutable-cached) over an
|
|
327
|
+
// already-warm connection, so the SDK preload overlay is shown only briefly.
|
|
328
|
+
this.prewarmState = null;
|
|
296
329
|
// Serialises concurrent `requestWithWallet` calls — they would otherwise
|
|
297
330
|
// both try to drive the same iframe and cross-resolve each other.
|
|
298
331
|
this.eoaSerialQueue = Promise.resolve();
|
|
@@ -306,6 +339,15 @@ var OneAuthClient = class {
|
|
|
306
339
|
if (dialogUrl !== providerUrl) {
|
|
307
340
|
this.injectPreconnect(dialogUrl);
|
|
308
341
|
}
|
|
342
|
+
if (this.config.prewarm) {
|
|
343
|
+
const warm = () => void this.prewarm();
|
|
344
|
+
const ric = window.requestIdleCallback;
|
|
345
|
+
if (typeof ric === "function") {
|
|
346
|
+
ric(warm, { timeout: 2e3 });
|
|
347
|
+
} else {
|
|
348
|
+
setTimeout(warm, 200);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
309
351
|
}
|
|
310
352
|
const initOperation = this.createTelemetryOperation("client", {
|
|
311
353
|
hasClientId: !!this.config.clientId,
|
|
@@ -539,6 +581,18 @@ var OneAuthClient = class {
|
|
|
539
581
|
if (primary) {
|
|
540
582
|
params.set("accent", primary);
|
|
541
583
|
}
|
|
584
|
+
const backdrop = theme.backdrop;
|
|
585
|
+
if (backdrop) {
|
|
586
|
+
if (backdrop.color) {
|
|
587
|
+
params.set("backdropColor", backdrop.color);
|
|
588
|
+
}
|
|
589
|
+
if (backdrop.opacity !== void 0) {
|
|
590
|
+
params.set("backdropOpacity", String(backdrop.opacity));
|
|
591
|
+
}
|
|
592
|
+
if (backdrop.blur !== void 0) {
|
|
593
|
+
params.set("backdropBlur", String(backdrop.blur));
|
|
594
|
+
}
|
|
595
|
+
}
|
|
542
596
|
return params.toString();
|
|
543
597
|
}
|
|
544
598
|
/**
|
|
@@ -777,9 +831,7 @@ var OneAuthClient = class {
|
|
|
777
831
|
if (options?.flow === "create-account") {
|
|
778
832
|
params.set("switch", "1");
|
|
779
833
|
}
|
|
780
|
-
|
|
781
|
-
params.set("parentOrigin", window.location.origin);
|
|
782
|
-
}
|
|
834
|
+
appendParentOriginParam(params);
|
|
783
835
|
this.appendTelemetryParams(params, telemetry);
|
|
784
836
|
const themeParams = this.getThemeParams(options?.theme);
|
|
785
837
|
if (themeParams) {
|
|
@@ -860,9 +912,7 @@ var OneAuthClient = class {
|
|
|
860
912
|
if (this.config.clientId) {
|
|
861
913
|
params.set("clientId", this.config.clientId);
|
|
862
914
|
}
|
|
863
|
-
|
|
864
|
-
params.set("parentOrigin", window.location.origin);
|
|
865
|
-
}
|
|
915
|
+
appendParentOriginParam(params);
|
|
866
916
|
this.appendTelemetryParams(params, telemetry);
|
|
867
917
|
const themeParams = this.getThemeParams(options?.theme);
|
|
868
918
|
if (themeParams) {
|
|
@@ -993,10 +1043,13 @@ var OneAuthClient = class {
|
|
|
993
1043
|
themeParsed.forEach((value, key) => params.set(key, value));
|
|
994
1044
|
}
|
|
995
1045
|
const url = `${dialogUrl}/dialog/account?${params.toString()}`;
|
|
1046
|
+
const accessTokenResult = await this.fetchAccessToken();
|
|
1047
|
+
const initMessage = { mode: "iframe" };
|
|
1048
|
+
if (accessTokenResult.ok) {
|
|
1049
|
+
initMessage.auth = { accessToken: accessTokenResult.accessToken };
|
|
1050
|
+
}
|
|
996
1051
|
const { dialog, iframe, cleanup } = this.createModalDialog(url);
|
|
997
|
-
const ready = await this.waitForDialogReady(dialog, iframe, cleanup,
|
|
998
|
-
mode: "iframe"
|
|
999
|
-
});
|
|
1052
|
+
const ready = await this.waitForDialogReady(dialog, iframe, cleanup, initMessage);
|
|
1000
1053
|
if (!ready) return;
|
|
1001
1054
|
const dialogOrigin = this.getDialogOrigin();
|
|
1002
1055
|
return new Promise((resolve) => {
|
|
@@ -1181,6 +1234,7 @@ var OneAuthClient = class {
|
|
|
1181
1234
|
}
|
|
1182
1235
|
const dialogUrl = this.getDialogUrl();
|
|
1183
1236
|
const params = new URLSearchParams({ mode: "iframe" });
|
|
1237
|
+
appendParentOriginParam(params);
|
|
1184
1238
|
this.appendTelemetryParams(params, telemetry);
|
|
1185
1239
|
const themeParams = this.getThemeParams(options.theme);
|
|
1186
1240
|
if (themeParams) {
|
|
@@ -1227,6 +1281,7 @@ var OneAuthClient = class {
|
|
|
1227
1281
|
targetChains,
|
|
1228
1282
|
status: result.status ? String(result.status) : void 0
|
|
1229
1283
|
});
|
|
1284
|
+
await this.waitForDialogClose(dialog, cleanup);
|
|
1230
1285
|
} else {
|
|
1231
1286
|
this.emitTelemetry(
|
|
1232
1287
|
result.error?.code === "USER_CANCELLED" ? "dialog.cancelled" : "grant_permission.failed",
|
|
@@ -1408,6 +1463,7 @@ var OneAuthClient = class {
|
|
|
1408
1463
|
});
|
|
1409
1464
|
const dialogUrl = this.getDialogUrl();
|
|
1410
1465
|
const params = new URLSearchParams({ mode: "iframe" });
|
|
1466
|
+
appendParentOriginParam(params);
|
|
1411
1467
|
this.appendTelemetryParams(params, telemetry);
|
|
1412
1468
|
const themeParams = this.getThemeParams(options?.theme);
|
|
1413
1469
|
if (themeParams) {
|
|
@@ -1578,6 +1634,7 @@ var OneAuthClient = class {
|
|
|
1578
1634
|
let prepareResponse;
|
|
1579
1635
|
const dialogUrl = this.getDialogUrl();
|
|
1580
1636
|
const params = new URLSearchParams({ mode: "iframe" });
|
|
1637
|
+
appendParentOriginParam(params);
|
|
1581
1638
|
this.appendTelemetryParams(params, telemetry);
|
|
1582
1639
|
const themeParams = this.getThemeParams();
|
|
1583
1640
|
if (themeParams) {
|
|
@@ -1854,6 +1911,10 @@ var OneAuthClient = class {
|
|
|
1854
1911
|
expiresAt: refreshedData.expiresAt,
|
|
1855
1912
|
intentOp: refreshedData.intentOp,
|
|
1856
1913
|
digestResult: refreshedData.digestResult,
|
|
1914
|
+
// A refreshed quote mints a fresh binding — it MUST replace the old
|
|
1915
|
+
// one, or execute would verify the new intentOp against a stale
|
|
1916
|
+
// binding and reject (once enforce mode is on).
|
|
1917
|
+
binding: refreshedData.binding,
|
|
1857
1918
|
auth: refreshedAuth
|
|
1858
1919
|
};
|
|
1859
1920
|
return {
|
|
@@ -1863,6 +1924,7 @@ var OneAuthClient = class {
|
|
|
1863
1924
|
originMessages: refreshedData.originMessages,
|
|
1864
1925
|
transaction: refreshedData.transaction,
|
|
1865
1926
|
digestResult: refreshedData.digestResult,
|
|
1927
|
+
binding: refreshedData.binding,
|
|
1866
1928
|
// Dialog-executed intents read auth from dialog state — ship the
|
|
1867
1929
|
// rebound bundle with the refresh so PASSKEY_REFRESH_COMPLETE
|
|
1868
1930
|
// updates it alongside the quote.
|
|
@@ -1927,6 +1989,7 @@ var OneAuthClient = class {
|
|
|
1927
1989
|
userId: prepareResponse.userId,
|
|
1928
1990
|
intentOp: prepareResponse.intentOp,
|
|
1929
1991
|
digestResult: prepareResponse.digestResult,
|
|
1992
|
+
binding: prepareResponse.binding,
|
|
1930
1993
|
tier: prepareResult.tier,
|
|
1931
1994
|
auth: sponsorshipTokens,
|
|
1932
1995
|
telemetry: this.telemetryPayload(telemetry)
|
|
@@ -2057,6 +2120,7 @@ var OneAuthClient = class {
|
|
|
2057
2120
|
userId: prepareResponse.userId,
|
|
2058
2121
|
intentOp: prepareResponse.intentOp,
|
|
2059
2122
|
digestResult: prepareResponse.digestResult,
|
|
2123
|
+
binding: prepareResponse.binding,
|
|
2060
2124
|
tier: prepareResult.tier,
|
|
2061
2125
|
...authReady && { auth: authReady },
|
|
2062
2126
|
telemetry: this.telemetryPayload(telemetry)
|
|
@@ -2230,6 +2294,8 @@ var OneAuthClient = class {
|
|
|
2230
2294
|
calls: prepareResponse.calls,
|
|
2231
2295
|
expiresAt: prepareResponse.expiresAt,
|
|
2232
2296
|
digestResult: prepareResponse.digestResult,
|
|
2297
|
+
// Opaque prepare->execute binding, forwarded unchanged.
|
|
2298
|
+
binding: prepareResponse.binding,
|
|
2233
2299
|
// Signature from dialog
|
|
2234
2300
|
signature: signingResult.signature,
|
|
2235
2301
|
passkey: signingResult.passkey,
|
|
@@ -2555,6 +2621,7 @@ var OneAuthClient = class {
|
|
|
2555
2621
|
};
|
|
2556
2622
|
const dialogUrl = this.getDialogUrl();
|
|
2557
2623
|
const params = new URLSearchParams({ mode: "iframe" });
|
|
2624
|
+
appendParentOriginParam(params);
|
|
2558
2625
|
this.appendTelemetryParams(params, telemetry);
|
|
2559
2626
|
const themeParams = this.getThemeParams();
|
|
2560
2627
|
if (themeParams) {
|
|
@@ -2671,6 +2738,7 @@ var OneAuthClient = class {
|
|
|
2671
2738
|
batchIntents: prepareResponse.intents,
|
|
2672
2739
|
batchFailedIntents: prepareResponse.failedIntents,
|
|
2673
2740
|
challenge: prepareResponse.challenge,
|
|
2741
|
+
binding: prepareResponse.binding,
|
|
2674
2742
|
username: options.username,
|
|
2675
2743
|
accountAddress: prepareResponse.accountAddress,
|
|
2676
2744
|
userId: prepareResponse.userId,
|
|
@@ -2714,6 +2782,7 @@ var OneAuthClient = class {
|
|
|
2714
2782
|
batchIntents: prepareResponse.intents,
|
|
2715
2783
|
batchFailedIntents: prepareResponse.failedIntents,
|
|
2716
2784
|
challenge: prepareResponse.challenge,
|
|
2785
|
+
binding: prepareResponse.binding,
|
|
2717
2786
|
username: options.username,
|
|
2718
2787
|
accountAddress: prepareResponse.accountAddress,
|
|
2719
2788
|
userId: prepareResponse.userId,
|
|
@@ -2781,6 +2850,7 @@ var OneAuthClient = class {
|
|
|
2781
2850
|
batchIntents: refreshed.intents,
|
|
2782
2851
|
batchFailedIntents: refreshed.failedIntents,
|
|
2783
2852
|
challenge: refreshed.challenge,
|
|
2853
|
+
binding: refreshed.binding,
|
|
2784
2854
|
expiresAt: refreshed.expiresAt,
|
|
2785
2855
|
auth: refreshedAuth
|
|
2786
2856
|
};
|
|
@@ -2788,6 +2858,7 @@ var OneAuthClient = class {
|
|
|
2788
2858
|
type: "PASSKEY_REFRESH_COMPLETE",
|
|
2789
2859
|
batchIntents: refreshed.intents,
|
|
2790
2860
|
challenge: refreshed.challenge,
|
|
2861
|
+
binding: refreshed.binding,
|
|
2791
2862
|
expiresAt: refreshed.expiresAt,
|
|
2792
2863
|
auth: refreshedAuth
|
|
2793
2864
|
}, dialogOrigin);
|
|
@@ -3216,6 +3287,82 @@ var OneAuthClient = class {
|
|
|
3216
3287
|
} catch {
|
|
3217
3288
|
}
|
|
3218
3289
|
}
|
|
3290
|
+
/**
|
|
3291
|
+
* Warm the dialog ahead of the first user interaction.
|
|
3292
|
+
*
|
|
3293
|
+
* `preconnect` (run in the constructor) only warms DNS/TLS. This goes
|
|
3294
|
+
* further: it loads the dialog into a hidden, off-screen iframe so the
|
|
3295
|
+
* browser downloads and parses the dialog HTML + JS bundle and the font, and
|
|
3296
|
+
* keeps the cross-origin connection alive. When the user later opens a real
|
|
3297
|
+
* auth/sign dialog, the fresh iframe serves those bytes from cache over the
|
|
3298
|
+
* warm connection and paints far sooner — so the SDK preload overlay is shown
|
|
3299
|
+
* only briefly (or imperceptibly) instead of covering a full cold load.
|
|
3300
|
+
*
|
|
3301
|
+
* It loads a dedicated `/dialog/warm` route, NOT a real flow route. That
|
|
3302
|
+
* matters for two reasons:
|
|
3303
|
+
* - **No side effects.** The real `/dialog/auth` route runs the signup
|
|
3304
|
+
* flow on mount (identity probe → `POST /api/auth/register?step=start`),
|
|
3305
|
+
* which writes an `AuthChallenge` row and counts against the register
|
|
3306
|
+
* rate limiter. Warming must never create backend auth state for a user
|
|
3307
|
+
* who hasn't acted, so the warm route renders nothing and runs no flow.
|
|
3308
|
+
* - **No message cross-talk.** The warm route posts no `PASSKEY_READY` /
|
|
3309
|
+
* `PASSKEY_RENDERED`, so a slow warm can never satisfy a visible modal's
|
|
3310
|
+
* readiness listener and drive it to `PASSKEY_INIT` at the wrong moment.
|
|
3311
|
+
* The warm route still pulls the shared Next.js framework + main + dialog
|
|
3312
|
+
* layout chunks (the bulk of every flow's bundle), so the real open is fast.
|
|
3313
|
+
*
|
|
3314
|
+
* Best called on a *likely-intent* signal — `pointerenter`/`focus` of your
|
|
3315
|
+
* "Sign in" / "Pay" button — rather than on page load, so visitors who never
|
|
3316
|
+
* authenticate don't pay for a cross-origin iframe. Pass `prewarm: true` in
|
|
3317
|
+
* the client config to have the SDK schedule this once on an idle callback.
|
|
3318
|
+
*
|
|
3319
|
+
* Idempotent: repeated calls return the same in-flight/settled promise.
|
|
3320
|
+
* Resolves `true` once the hidden iframe's document has loaded, `false` on
|
|
3321
|
+
* timeout or failure. Never throws and never blocks a real dialog open — a
|
|
3322
|
+
* failed prewarm just means the next open does a normal (cold) load.
|
|
3323
|
+
*
|
|
3324
|
+
* @returns Whether the dialog became warm.
|
|
3325
|
+
*/
|
|
3326
|
+
async prewarm() {
|
|
3327
|
+
if (typeof document === "undefined") return false;
|
|
3328
|
+
if (this.prewarmState) return this.prewarmState.ready;
|
|
3329
|
+
const warmUrl = `${this.getDialogUrl()}/dialog/warm`;
|
|
3330
|
+
const iframe = document.createElement("iframe");
|
|
3331
|
+
iframe.setAttribute("aria-hidden", "true");
|
|
3332
|
+
iframe.setAttribute("tabindex", "-1");
|
|
3333
|
+
iframe.title = "1auth dialog prewarm";
|
|
3334
|
+
iframe.style.cssText = "position:fixed;left:-9999px;top:0;width:1px;height:1px;opacity:0;border:0;pointer-events:none;";
|
|
3335
|
+
const ready = new Promise((resolve) => {
|
|
3336
|
+
let settled = false;
|
|
3337
|
+
const finish = (value) => {
|
|
3338
|
+
if (settled) return;
|
|
3339
|
+
settled = true;
|
|
3340
|
+
clearTimeout(timer);
|
|
3341
|
+
resolve(value);
|
|
3342
|
+
};
|
|
3343
|
+
iframe.onload = () => finish(true);
|
|
3344
|
+
iframe.onerror = () => finish(false);
|
|
3345
|
+
const timer = setTimeout(() => finish(false), 1e4);
|
|
3346
|
+
});
|
|
3347
|
+
iframe.src = warmUrl;
|
|
3348
|
+
document.body.appendChild(iframe);
|
|
3349
|
+
this.prewarmState = { iframe, ready };
|
|
3350
|
+
return ready;
|
|
3351
|
+
}
|
|
3352
|
+
/**
|
|
3353
|
+
* Tear down the hidden prewarm iframe created by {@link prewarm}.
|
|
3354
|
+
*
|
|
3355
|
+
* The HTTP cache that prewarm populated survives teardown, so a subsequent
|
|
3356
|
+
* open is still bundle-warm; this only releases the parked frame (and its
|
|
3357
|
+
* keep-alive connection). Call it when auth is no longer likely on the
|
|
3358
|
+
* current view. Safe to call when nothing is warmed.
|
|
3359
|
+
*/
|
|
3360
|
+
destroyPrewarm() {
|
|
3361
|
+
const state = this.prewarmState;
|
|
3362
|
+
if (!state) return;
|
|
3363
|
+
this.prewarmState = null;
|
|
3364
|
+
state.iframe.remove();
|
|
3365
|
+
}
|
|
3219
3366
|
/**
|
|
3220
3367
|
* Wait for the dialog iframe to signal ready, but defer sending `PASSKEY_INIT`
|
|
3221
3368
|
* until the caller decides the time is right.
|
|
@@ -3598,10 +3745,15 @@ var OneAuthClient = class {
|
|
|
3598
3745
|
return { ok: true, dialog: dialog2, iframe: iframe2 };
|
|
3599
3746
|
}
|
|
3600
3747
|
const dialogUrl = this.getDialogUrl();
|
|
3748
|
+
const params = new URLSearchParams({ mode: "iframe" });
|
|
3749
|
+
appendParentOriginParam(params);
|
|
3601
3750
|
const themeParams = this.getThemeParams(theme);
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3751
|
+
if (themeParams) {
|
|
3752
|
+
new URLSearchParams(themeParams).forEach((value, key) => {
|
|
3753
|
+
params.set(key, value);
|
|
3754
|
+
});
|
|
3755
|
+
}
|
|
3756
|
+
const signingUrl = `${dialogUrl}/dialog/sign-eoa?${params.toString()}`;
|
|
3605
3757
|
const { dialog, iframe, destroy } = this.createModalDialog(signingUrl, {
|
|
3606
3758
|
persistent: true
|
|
3607
3759
|
});
|
|
@@ -3706,6 +3858,7 @@ var OneAuthClient = class {
|
|
|
3706
3858
|
});
|
|
3707
3859
|
const dialogUrl = this.getDialogUrl();
|
|
3708
3860
|
const params = new URLSearchParams({ mode: "iframe" });
|
|
3861
|
+
appendParentOriginParam(params);
|
|
3709
3862
|
this.appendTelemetryParams(params, telemetry);
|
|
3710
3863
|
const themeParams = this.getThemeParams(options?.theme);
|
|
3711
3864
|
if (themeParams) {
|
|
@@ -3848,6 +4001,7 @@ var OneAuthClient = class {
|
|
|
3848
4001
|
});
|
|
3849
4002
|
const dialogUrl = this.getDialogUrl();
|
|
3850
4003
|
const params = new URLSearchParams({ mode: "iframe" });
|
|
4004
|
+
appendParentOriginParam(params);
|
|
3851
4005
|
this.appendTelemetryParams(params, telemetry);
|
|
3852
4006
|
const themeParams = this.getThemeParams(options?.theme);
|
|
3853
4007
|
if (themeParams) {
|
|
@@ -4301,17 +4455,17 @@ var OneAuthClient = class {
|
|
|
4301
4455
|
/**
|
|
4302
4456
|
* Create and open a full-viewport `<dialog>` containing a passkey iframe.
|
|
4303
4457
|
*
|
|
4304
|
-
* The SDK owns
|
|
4305
|
-
*
|
|
4306
|
-
*
|
|
4307
|
-
*
|
|
4458
|
+
* The SDK owns the browser `<dialog>` plus a minimal generic preload shell
|
|
4459
|
+
* that appears immediately on click. The passkey iframe owns all branded and
|
|
4460
|
+
* origin-specific UI (TitleBar, trust icon, action cards); the shell is
|
|
4461
|
+
* removed as soon as the iframe reports that its centered card has painted.
|
|
4308
4462
|
*
|
|
4309
4463
|
* Lifecycle:
|
|
4310
|
-
* 1. A themed
|
|
4311
|
-
* iframe loads
|
|
4312
|
-
*
|
|
4313
|
-
* 2. When the iframe sends `PASSKEY_RENDERED`, the overlay
|
|
4314
|
-
* the iframe becomes fully visible.
|
|
4464
|
+
* 1. A themed generic preload shell is injected and shown immediately
|
|
4465
|
+
* while the iframe loads. It intentionally contains no TitleBar or
|
|
4466
|
+
* origin chrome so that UI has a single implementation in apps/passkey.
|
|
4467
|
+
* 2. When the iframe sends `PASSKEY_RENDERED`, the overlay is removed and
|
|
4468
|
+
* the iframe becomes fully visible in the same frame.
|
|
4315
4469
|
* 3. The returned `cleanup` function tears down all event listeners,
|
|
4316
4470
|
* disconnects the MutationObserver, closes the `<dialog>`, and removes
|
|
4317
4471
|
* it from the DOM. It is idempotent — safe to call multiple times.
|
|
@@ -4333,12 +4487,10 @@ var OneAuthClient = class {
|
|
|
4333
4487
|
const dialogUrl = this.getDialogUrl();
|
|
4334
4488
|
const hostUrl = new URL(dialogUrl);
|
|
4335
4489
|
const urlParams = new URL(url, window.location.href).searchParams;
|
|
4490
|
+
const { background: backdropBackground, blur: backdropBlur } = resolveBackdropStyle(urlParams);
|
|
4336
4491
|
const themeMode = urlParams.get("theme") || "light";
|
|
4337
4492
|
const isDark = themeMode === "dark" || themeMode !== "light" && window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
4338
4493
|
const theme = isDark ? DARK_TOKENS : LIGHT_TOKENS;
|
|
4339
|
-
const { bgPrimary, borderColor, textPrimary, textSecondary } = theme;
|
|
4340
|
-
const textFooter = FOOTER_TEXT_COLOR;
|
|
4341
|
-
const spinnerColor = BRAND_PURPLE;
|
|
4342
4494
|
const dialog = document.createElement("dialog");
|
|
4343
4495
|
dialog.dataset.passkey = "";
|
|
4344
4496
|
if (options?.hidden) {
|
|
@@ -4349,16 +4501,6 @@ var OneAuthClient = class {
|
|
|
4349
4501
|
document.body.appendChild(dialog);
|
|
4350
4502
|
const style = document.createElement("style");
|
|
4351
4503
|
style.textContent = `
|
|
4352
|
-
/* Load Inter so the overlay's title/subtitle widths match the
|
|
4353
|
-
iframe (which loads Inter via next/font). Without this, host
|
|
4354
|
-
pages on Arial / system-ui produce wider text that wraps to two
|
|
4355
|
-
lines and breaks the visual match with the Figma. font-display:
|
|
4356
|
-
swap renders immediately with a fallback and swaps when Inter
|
|
4357
|
-
is ready \u2014 usually well before PASSKEY_RENDERED fires, but the
|
|
4358
|
-
overlay is short-lived either way so a single-frame swap is
|
|
4359
|
-
acceptable. */
|
|
4360
|
-
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@500;700&display=swap');
|
|
4361
|
-
|
|
4362
4504
|
dialog[data-passkey] {
|
|
4363
4505
|
position: fixed;
|
|
4364
4506
|
top: 0;
|
|
@@ -4396,103 +4538,143 @@ var OneAuthClient = class {
|
|
|
4396
4538
|
backdrop-filter: none;
|
|
4397
4539
|
-webkit-backdrop-filter: none;
|
|
4398
4540
|
}
|
|
4399
|
-
dialog[data-passkey] iframe {
|
|
4400
|
-
position: fixed;
|
|
4401
|
-
top: 0;
|
|
4402
|
-
left: 0;
|
|
4403
|
-
width: 100%;
|
|
4404
|
-
height: 100%;
|
|
4405
|
-
border: 0;
|
|
4406
|
-
background-color: transparent;
|
|
4407
|
-
color-scheme: normal;
|
|
4408
|
-
pointer-events: auto;
|
|
4409
|
-
backdrop-filter: blur(8px);
|
|
4410
|
-
-webkit-backdrop-filter: blur(8px);
|
|
4411
|
-
}
|
|
4412
4541
|
dialog[data-passkey] [data-passkey-overlay] {
|
|
4413
4542
|
position: fixed;
|
|
4414
|
-
|
|
4415
|
-
left: 0;
|
|
4416
|
-
width: 100%;
|
|
4417
|
-
height: 100%;
|
|
4543
|
+
inset: 0;
|
|
4418
4544
|
display: flex;
|
|
4419
4545
|
align-items: center;
|
|
4420
4546
|
justify-content: center;
|
|
4421
|
-
background:
|
|
4422
|
-
backdrop-filter: blur(
|
|
4423
|
-
-webkit-backdrop-filter: blur(
|
|
4547
|
+
background: ${backdropBackground};
|
|
4548
|
+
backdrop-filter: blur(${backdropBlur}px);
|
|
4549
|
+
-webkit-backdrop-filter: blur(${backdropBlur}px);
|
|
4424
4550
|
z-index: 1;
|
|
4425
|
-
/* Purely a visual loading screen \u2014 never intercept clicks.
|
|
4426
|
-
If the iframe's X button or backdrop-dismiss area happens to
|
|
4427
|
-
be reachable while the overlay is still painting (slow CI
|
|
4428
|
-
runners, redirect remounts), the click goes straight through
|
|
4429
|
-
instead of being trapped by the SDK preload. The previous
|
|
4430
|
-
rAF-deferred display:none lost this race in GitHub Actions
|
|
4431
|
-
\u2014 dialog-close.spec.ts repeatedly hit
|
|
4432
|
-
"<div data-passkey-overlay> intercepts pointer events". */
|
|
4433
4551
|
pointer-events: none;
|
|
4434
|
-
animation: _1auth-backdrop-in 0.2s ease-out;
|
|
4435
4552
|
}
|
|
4436
4553
|
dialog[data-passkey][data-passkey-hidden] [data-passkey-overlay] {
|
|
4437
4554
|
display: none;
|
|
4438
4555
|
}
|
|
4439
|
-
dialog[data-passkey] [data-passkey-card] {
|
|
4556
|
+
dialog[data-passkey] [data-passkey-preload-card] {
|
|
4440
4557
|
width: ${LOADING_MODAL_WIDTH}px;
|
|
4558
|
+
max-width: 100%;
|
|
4559
|
+
overflow: hidden;
|
|
4560
|
+
border-radius: ${LOADING_MODAL_RADIUS}px;
|
|
4561
|
+
background: ${theme.bgPrimary};
|
|
4562
|
+
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.24), 0 2px 12px rgba(0, 0, 0, 0.12);
|
|
4563
|
+
font-family: ${LOADING_FONT_FAMILY};
|
|
4564
|
+
line-height: ${LOADING_LINE_HEIGHT};
|
|
4565
|
+
-webkit-font-smoothing: antialiased;
|
|
4566
|
+
-moz-osx-font-smoothing: grayscale;
|
|
4567
|
+
}
|
|
4568
|
+
dialog[data-passkey] [data-passkey-preload-body] {
|
|
4441
4569
|
box-sizing: border-box;
|
|
4570
|
+
display: flex;
|
|
4571
|
+
width: 100%;
|
|
4572
|
+
flex-direction: column;
|
|
4573
|
+
align-items: center;
|
|
4574
|
+
gap: ${LOADING_BODY_GAP}px;
|
|
4442
4575
|
padding: ${LOADING_MODAL_PADDING}px;
|
|
4443
4576
|
border-radius: ${LOADING_MODAL_RADIUS}px;
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4577
|
+
background: ${theme.bgPrimary};
|
|
4578
|
+
}
|
|
4579
|
+
dialog[data-passkey] [data-passkey-preload-spinner-wrap] {
|
|
4580
|
+
display: flex;
|
|
4581
|
+
align-items: center;
|
|
4582
|
+
padding: ${LOADING_ICON_PADDING}px;
|
|
4583
|
+
}
|
|
4584
|
+
dialog[data-passkey] [data-passkey-preload-spinner] {
|
|
4585
|
+
position: relative;
|
|
4586
|
+
width: ${SPINNER_SIZE}px;
|
|
4587
|
+
height: ${SPINNER_SIZE}px;
|
|
4588
|
+
}
|
|
4589
|
+
dialog[data-passkey] [data-passkey-preload-spinner] svg {
|
|
4590
|
+
position: absolute;
|
|
4591
|
+
inset: 0;
|
|
4592
|
+
width: 100%;
|
|
4593
|
+
height: 100%;
|
|
4594
|
+
color: ${BRAND_PURPLE};
|
|
4595
|
+
animation: _1auth-spin ${SPINNER_SPIN_DURATION_MS}ms linear infinite;
|
|
4596
|
+
}
|
|
4597
|
+
dialog[data-passkey] [data-passkey-preload-copy] {
|
|
4448
4598
|
display: flex;
|
|
4599
|
+
width: 100%;
|
|
4449
4600
|
flex-direction: column;
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
4601
|
+
align-items: center;
|
|
4602
|
+
gap: ${LOADING_TITLE_BLOCK_GAP}px;
|
|
4603
|
+
text-align: center;
|
|
4604
|
+
}
|
|
4605
|
+
dialog[data-passkey] [data-passkey-preload-title] {
|
|
4606
|
+
margin: 0;
|
|
4607
|
+
color: ${theme.textPrimary};
|
|
4608
|
+
font-size: ${LOADING_TITLE_FONT_SIZE}px;
|
|
4609
|
+
font-weight: ${LOADING_TITLE_FONT_WEIGHT};
|
|
4456
4610
|
line-height: ${LOADING_LINE_HEIGHT};
|
|
4457
|
-
-webkit-font-smoothing: antialiased;
|
|
4458
|
-
-moz-osx-font-smoothing: grayscale;
|
|
4459
4611
|
}
|
|
4460
|
-
|
|
4612
|
+
dialog[data-passkey] [data-passkey-preload-subtitle] {
|
|
4613
|
+
margin: 0;
|
|
4614
|
+
color: ${theme.textSecondary};
|
|
4615
|
+
font-size: ${LOADING_SUBTITLE_FONT_SIZE}px;
|
|
4616
|
+
font-weight: ${LOADING_SUBTITLE_FONT_WEIGHT};
|
|
4617
|
+
line-height: ${LOADING_LINE_HEIGHT};
|
|
4618
|
+
}
|
|
4619
|
+
@media (max-width: 639px) {
|
|
4461
4620
|
dialog[data-passkey] [data-passkey-overlay] {
|
|
4462
4621
|
align-items: flex-end;
|
|
4463
4622
|
}
|
|
4464
|
-
dialog[data-passkey] [data-passkey-card] {
|
|
4623
|
+
dialog[data-passkey] [data-passkey-preload-card] {
|
|
4465
4624
|
width: 100%;
|
|
4466
|
-
border-bottom-left-radius: 0;
|
|
4467
4625
|
border-bottom-right-radius: 0;
|
|
4626
|
+
border-bottom-left-radius: 0;
|
|
4627
|
+
}
|
|
4628
|
+
dialog[data-passkey] [data-passkey-preload-body] {
|
|
4468
4629
|
padding-bottom: calc(${LOADING_MODAL_PADDING}px + env(safe-area-inset-bottom));
|
|
4469
|
-
animation: _1auth-card-slide 0.3s cubic-bezier(0.32, 0.72, 0, 1);
|
|
4470
4630
|
}
|
|
4471
4631
|
}
|
|
4472
|
-
@keyframes _1auth-backdrop-in {
|
|
4473
|
-
from { opacity: 0; } to { opacity: 1; }
|
|
4474
|
-
}
|
|
4475
|
-
@keyframes _1auth-card-in {
|
|
4476
|
-
from { opacity: 0; transform: scale(0.96) translateY(8px); }
|
|
4477
|
-
to { opacity: 1; transform: scale(1) translateY(0); }
|
|
4478
|
-
}
|
|
4479
|
-
@keyframes _1auth-card-slide {
|
|
4480
|
-
from { transform: translate3d(0, 100%, 0); }
|
|
4481
|
-
to { transform: translate3d(0, 0, 0); }
|
|
4482
|
-
}
|
|
4483
4632
|
@keyframes _1auth-spin {
|
|
4484
4633
|
from { transform: rotate(0deg); }
|
|
4485
4634
|
to { transform: rotate(360deg); }
|
|
4486
4635
|
}
|
|
4636
|
+
dialog[data-passkey] iframe {
|
|
4637
|
+
position: fixed;
|
|
4638
|
+
top: 0;
|
|
4639
|
+
left: 0;
|
|
4640
|
+
width: 100%;
|
|
4641
|
+
height: 100%;
|
|
4642
|
+
border: 0;
|
|
4643
|
+
background-color: transparent;
|
|
4644
|
+
color-scheme: normal;
|
|
4645
|
+
pointer-events: auto;
|
|
4646
|
+
backdrop-filter: blur(${backdropBlur}px);
|
|
4647
|
+
-webkit-backdrop-filter: blur(${backdropBlur}px);
|
|
4648
|
+
transition: none;
|
|
4649
|
+
}
|
|
4487
4650
|
`;
|
|
4488
4651
|
dialog.appendChild(style);
|
|
4489
4652
|
const overlay = document.createElement("div");
|
|
4490
4653
|
overlay.dataset.passkeyOverlay = "";
|
|
4654
|
+
const preloadCard = document.createElement("div");
|
|
4655
|
+
preloadCard.dataset.passkeyPreloadCard = "";
|
|
4656
|
+
const preloadBody = document.createElement("div");
|
|
4657
|
+
preloadBody.dataset.passkeyPreloadBody = "";
|
|
4658
|
+
const spinnerWrap = document.createElement("div");
|
|
4659
|
+
spinnerWrap.dataset.passkeyPreloadSpinnerWrap = "";
|
|
4660
|
+
const spinner = document.createElement("div");
|
|
4661
|
+
spinner.dataset.passkeyPreloadSpinner = "";
|
|
4491
4662
|
const spinnerCenter = SPINNER_SIZE / 2;
|
|
4492
4663
|
const spinnerGap = SPINNER_CIRCUMFERENCE - SPINNER_ARC;
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4664
|
+
spinner.innerHTML = `<svg viewBox="0 0 ${SPINNER_SIZE} ${SPINNER_SIZE}" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><circle cx="${spinnerCenter}" cy="${spinnerCenter}" r="${SPINNER_RADIUS}" stroke="currentColor" opacity="0.3" stroke-width="${SPINNER_STROKE}"/><circle cx="${spinnerCenter}" cy="${spinnerCenter}" r="${SPINNER_RADIUS}" stroke="currentColor" stroke-width="${SPINNER_STROKE}" stroke-linecap="round" stroke-dasharray="${SPINNER_ARC} ${spinnerGap}" transform="rotate(-90 ${spinnerCenter} ${spinnerCenter})"/></svg>`;
|
|
4665
|
+
spinnerWrap.appendChild(spinner);
|
|
4666
|
+
const preloadCopy = document.createElement("div");
|
|
4667
|
+
preloadCopy.dataset.passkeyPreloadCopy = "";
|
|
4668
|
+
const preloadTitle = document.createElement("p");
|
|
4669
|
+
preloadTitle.dataset.passkeyPreloadTitle = "";
|
|
4670
|
+
preloadTitle.textContent = LOADING_TITLE;
|
|
4671
|
+
const preloadSubtitle = document.createElement("p");
|
|
4672
|
+
preloadSubtitle.dataset.passkeyPreloadSubtitle = "";
|
|
4673
|
+
preloadSubtitle.textContent = LOADING_SUBTITLE;
|
|
4674
|
+
preloadCopy.append(preloadTitle, preloadSubtitle);
|
|
4675
|
+
preloadBody.append(spinnerWrap, preloadCopy);
|
|
4676
|
+
preloadCard.appendChild(preloadBody);
|
|
4677
|
+
overlay.appendChild(preloadCard);
|
|
4496
4678
|
dialog.appendChild(overlay);
|
|
4497
4679
|
const iframe = document.createElement("iframe");
|
|
4498
4680
|
iframe.setAttribute(
|
|
@@ -4512,21 +4694,23 @@ var OneAuthClient = class {
|
|
|
4512
4694
|
);
|
|
4513
4695
|
iframe.setAttribute("title", "Passkey");
|
|
4514
4696
|
iframe.style.opacity = "0";
|
|
4515
|
-
let
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4697
|
+
let revealed = false;
|
|
4698
|
+
let readyFailsafe;
|
|
4699
|
+
const revealIframe = () => {
|
|
4700
|
+
if (revealed) return;
|
|
4701
|
+
revealed = true;
|
|
4702
|
+
clearTimeout(readyFailsafe);
|
|
4519
4703
|
iframe.style.opacity = "1";
|
|
4520
|
-
overlay.style.
|
|
4521
|
-
requestAnimationFrame(() => {
|
|
4522
|
-
overlay.style.display = "none";
|
|
4523
|
-
});
|
|
4704
|
+
overlay.style.display = "none";
|
|
4524
4705
|
};
|
|
4525
|
-
const
|
|
4706
|
+
const revealFailsafe = setTimeout(revealIframe, 8e3);
|
|
4526
4707
|
const handleMessage = (event) => {
|
|
4527
4708
|
if (event.origin !== hostUrl.origin) return;
|
|
4528
|
-
if (event.
|
|
4529
|
-
|
|
4709
|
+
if (event.source !== iframe.contentWindow) return;
|
|
4710
|
+
if (event.data?.type === "PASSKEY_RENDERED") {
|
|
4711
|
+
revealIframe();
|
|
4712
|
+
} else if (event.data?.type === "PASSKEY_READY" && !revealed && readyFailsafe === void 0) {
|
|
4713
|
+
readyFailsafe = setTimeout(revealIframe, 1e3);
|
|
4530
4714
|
}
|
|
4531
4715
|
if (event.data?.type === "PASSKEY_DISCONNECT") {
|
|
4532
4716
|
localStorage.removeItem("1auth-user");
|
|
@@ -4554,7 +4738,13 @@ var OneAuthClient = class {
|
|
|
4554
4738
|
document.addEventListener("keydown", handleEscape);
|
|
4555
4739
|
const reveal = () => {
|
|
4556
4740
|
delete dialog.dataset.passkeyHidden;
|
|
4741
|
+
if (!revealed) {
|
|
4742
|
+
revealed = true;
|
|
4743
|
+
clearTimeout(readyFailsafe);
|
|
4744
|
+
clearTimeout(revealFailsafe);
|
|
4745
|
+
}
|
|
4557
4746
|
iframe.style.opacity = "1";
|
|
4747
|
+
overlay.style.display = "none";
|
|
4558
4748
|
};
|
|
4559
4749
|
if (options?.hidden) {
|
|
4560
4750
|
dialog.show();
|
|
@@ -4565,7 +4755,8 @@ var OneAuthClient = class {
|
|
|
4565
4755
|
const destroy = () => {
|
|
4566
4756
|
if (cleanedUp) return;
|
|
4567
4757
|
cleanedUp = true;
|
|
4568
|
-
clearTimeout(
|
|
4758
|
+
clearTimeout(revealFailsafe);
|
|
4759
|
+
clearTimeout(readyFailsafe);
|
|
4569
4760
|
inertObserver.disconnect();
|
|
4570
4761
|
viewportInfoCleanup();
|
|
4571
4762
|
window.removeEventListener("message", handleMessage);
|
|
@@ -4871,19 +5062,20 @@ var OneAuthClient = class {
|
|
|
4871
5062
|
return;
|
|
4872
5063
|
}
|
|
4873
5064
|
if (data?.type === "PASSKEY_GRANT_PERMISSION_RESULT") {
|
|
4874
|
-
teardown();
|
|
4875
|
-
cleanup();
|
|
4876
5065
|
if (data.success) {
|
|
5066
|
+
teardown();
|
|
4877
5067
|
resolve({ success: true, ...data.data ?? {} });
|
|
4878
|
-
|
|
4879
|
-
resolve({
|
|
4880
|
-
success: false,
|
|
4881
|
-
error: data.error ?? data.data?.error ?? {
|
|
4882
|
-
code: "GRANT_PERMISSION_FAILED",
|
|
4883
|
-
message: "Permission grant failed"
|
|
4884
|
-
}
|
|
4885
|
-
});
|
|
5068
|
+
return;
|
|
4886
5069
|
}
|
|
5070
|
+
teardown();
|
|
5071
|
+
cleanup();
|
|
5072
|
+
resolve({
|
|
5073
|
+
success: false,
|
|
5074
|
+
error: data.error ?? data.data?.error ?? {
|
|
5075
|
+
code: "GRANT_PERMISSION_FAILED",
|
|
5076
|
+
message: "Permission grant failed"
|
|
5077
|
+
}
|
|
5078
|
+
});
|
|
4887
5079
|
} else if (data?.type === "PASSKEY_CLOSE") {
|
|
4888
5080
|
teardown();
|
|
4889
5081
|
cleanup();
|