@camstack/addon-auth 1.1.1 → 1.1.3
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/{dist-JmuFs-U5.mjs → dist-mmJDfwXE.js} +335 -8
- package/dist/{dist-CXCR7sEk.js → dist-suALViLT.mjs} +276 -37
- package/dist/magic-link/auth-magic-link.addon.js +104 -30
- package/dist/magic-link/auth-magic-link.addon.mjs +104 -30
- package/dist/oidc/auth-oidc.addon.js +36 -8
- package/dist/oidc/auth-oidc.addon.mjs +36 -8
- package/dist/webauthn/_stub.js +568 -0
- package/dist/webauthn/_virtual_mf-localSharedImportMap___mfe_internal__addon_auth_webauthn_widgets-Bg_T1-iY.mjs +156 -0
- package/dist/webauthn/_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-EnxrfqY5.mjs +26 -0
- package/dist/webauthn/_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CQ-aEQ9b.mjs +26 -0
- package/dist/webauthn/_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare__react__loadShare__.js-BIIa6vDX.mjs +26 -0
- package/dist/webauthn/_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-BL2etuqg.mjs +26 -0
- package/dist/webauthn/auth-webauthn.addon.js +141 -5
- package/dist/webauthn/auth-webauthn.addon.mjs +136 -37
- package/dist/webauthn/dist-CYZr2fwk.mjs +2726 -0
- package/dist/webauthn/hostInit-Boe91Eeg.mjs +129 -0
- package/dist/webauthn/remoteEntry.js +134 -0
- package/dist/webauthn/remoteEntry.ssr.js +33 -0
- package/dist/webauthn/virtualExposes-Ckj56FAf.mjs +27 -0
- package/dist/webauthn/virtual_mf-exposes-ssr___mfe_internal__addon_auth_webauthn_widgets__remoteEntry_js-C5AzEzK5.mjs +10 -0
- package/package.json +30 -5
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
import { n as e, r as t, t as n } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare__react__loadShare__.js-BIIa6vDX.mjs";
|
|
2
|
+
import { n as r, t as i } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_tanstack_mf_1_react_mf_2_query__loadShare__.js-CQ-aEQ9b.mjs";
|
|
3
|
+
import { t as a } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-EnxrfqY5.mjs";
|
|
4
|
+
import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_auth_webauthn_widgets__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-BL2etuqg.mjs";
|
|
5
|
+
//#region ../../node_modules/lucide-react/dist/esm/shared/src/utils.js
|
|
6
|
+
var l = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), u = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), d = (e) => {
|
|
7
|
+
let t = u(e);
|
|
8
|
+
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
9
|
+
}, f = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), p = (e) => {
|
|
10
|
+
for (let t in e) if (t.startsWith("aria-") || t === "role" || t === "title") return !0;
|
|
11
|
+
}, m = {
|
|
12
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
13
|
+
width: 24,
|
|
14
|
+
height: 24,
|
|
15
|
+
viewBox: "0 0 24 24",
|
|
16
|
+
fill: "none",
|
|
17
|
+
stroke: "currentColor",
|
|
18
|
+
strokeWidth: 2,
|
|
19
|
+
strokeLinecap: "round",
|
|
20
|
+
strokeLinejoin: "round"
|
|
21
|
+
}, h = e(({ color: e = "currentColor", size: t = 24, strokeWidth: r = 2, absoluteStrokeWidth: i, className: a = "", children: o, iconNode: s, ...c }, l) => n("svg", {
|
|
22
|
+
ref: l,
|
|
23
|
+
...m,
|
|
24
|
+
width: t,
|
|
25
|
+
height: t,
|
|
26
|
+
stroke: e,
|
|
27
|
+
strokeWidth: i ? Number(r) * 24 / Number(t) : r,
|
|
28
|
+
className: f("lucide", a),
|
|
29
|
+
...!o && !p(c) && { "aria-hidden": "true" },
|
|
30
|
+
...c
|
|
31
|
+
}, [...s.map(([e, t]) => n(e, t)), ...Array.isArray(o) ? o : [o]])), g = (t, r) => {
|
|
32
|
+
let i = e(({ className: e, ...i }, a) => n(h, {
|
|
33
|
+
ref: a,
|
|
34
|
+
iconNode: r,
|
|
35
|
+
className: f(`lucide-${l(d(t))}`, `lucide-${t}`, e),
|
|
36
|
+
...i
|
|
37
|
+
}));
|
|
38
|
+
return i.displayName = d(t), i;
|
|
39
|
+
}, _ = g("circle-alert", [
|
|
40
|
+
["circle", {
|
|
41
|
+
cx: "12",
|
|
42
|
+
cy: "12",
|
|
43
|
+
r: "10",
|
|
44
|
+
key: "1mglay"
|
|
45
|
+
}],
|
|
46
|
+
["line", {
|
|
47
|
+
x1: "12",
|
|
48
|
+
x2: "12",
|
|
49
|
+
y1: "8",
|
|
50
|
+
y2: "12",
|
|
51
|
+
key: "1pkeuh"
|
|
52
|
+
}],
|
|
53
|
+
["line", {
|
|
54
|
+
x1: "12",
|
|
55
|
+
x2: "12.01",
|
|
56
|
+
y1: "16",
|
|
57
|
+
y2: "16",
|
|
58
|
+
key: "4dfq90"
|
|
59
|
+
}]
|
|
60
|
+
]), v = g("fingerprint", [
|
|
61
|
+
["path", {
|
|
62
|
+
d: "M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4",
|
|
63
|
+
key: "1nerag"
|
|
64
|
+
}],
|
|
65
|
+
["path", {
|
|
66
|
+
d: "M14 13.12c0 2.38 0 6.38-1 8.88",
|
|
67
|
+
key: "o46ks0"
|
|
68
|
+
}],
|
|
69
|
+
["path", {
|
|
70
|
+
d: "M17.29 21.02c.12-.6.43-2.3.5-3.02",
|
|
71
|
+
key: "ptglia"
|
|
72
|
+
}],
|
|
73
|
+
["path", {
|
|
74
|
+
d: "M2 12a10 10 0 0 1 18-6",
|
|
75
|
+
key: "ydlgp0"
|
|
76
|
+
}],
|
|
77
|
+
["path", {
|
|
78
|
+
d: "M2 16h.01",
|
|
79
|
+
key: "1gqxmh"
|
|
80
|
+
}],
|
|
81
|
+
["path", {
|
|
82
|
+
d: "M21.8 16c.2-2 .131-5.354 0-6",
|
|
83
|
+
key: "drycrb"
|
|
84
|
+
}],
|
|
85
|
+
["path", {
|
|
86
|
+
d: "M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2",
|
|
87
|
+
key: "1tidbn"
|
|
88
|
+
}],
|
|
89
|
+
["path", {
|
|
90
|
+
d: "M8.65 22c.21-.66.45-1.32.57-2",
|
|
91
|
+
key: "13wd9y"
|
|
92
|
+
}],
|
|
93
|
+
["path", {
|
|
94
|
+
d: "M9 6.8a6 6 0 0 1 9 5.2v2",
|
|
95
|
+
key: "1fr1j5"
|
|
96
|
+
}]
|
|
97
|
+
]), y = g("key-round", [["path", {
|
|
98
|
+
d: "M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",
|
|
99
|
+
key: "1s6t7t"
|
|
100
|
+
}], ["circle", {
|
|
101
|
+
cx: "16.5",
|
|
102
|
+
cy: "7.5",
|
|
103
|
+
r: ".5",
|
|
104
|
+
fill: "currentColor",
|
|
105
|
+
key: "w0ekpg"
|
|
106
|
+
}]]), b = g("loader-circle", [["path", {
|
|
107
|
+
d: "M21 12a9 9 0 1 1-6.219-8.56",
|
|
108
|
+
key: "13zald"
|
|
109
|
+
}]]), x = g("trash-2", [
|
|
110
|
+
["path", {
|
|
111
|
+
d: "M3 6h18",
|
|
112
|
+
key: "d0wm0j"
|
|
113
|
+
}],
|
|
114
|
+
["path", {
|
|
115
|
+
d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",
|
|
116
|
+
key: "4alrt4"
|
|
117
|
+
}],
|
|
118
|
+
["path", {
|
|
119
|
+
d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",
|
|
120
|
+
key: "v07s0e"
|
|
121
|
+
}],
|
|
122
|
+
["line", {
|
|
123
|
+
x1: "10",
|
|
124
|
+
x2: "10",
|
|
125
|
+
y1: "11",
|
|
126
|
+
y2: "17",
|
|
127
|
+
key: "1uufr5"
|
|
128
|
+
}],
|
|
129
|
+
["line", {
|
|
130
|
+
x1: "14",
|
|
131
|
+
x2: "14",
|
|
132
|
+
y1: "11",
|
|
133
|
+
y2: "17",
|
|
134
|
+
key: "xtxkd"
|
|
135
|
+
}]
|
|
136
|
+
]);
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region ../../node_modules/@simplewebauthn/browser/dist/bundle/index.js
|
|
139
|
+
function S(e) {
|
|
140
|
+
let t = new Uint8Array(e), n = "";
|
|
141
|
+
for (let e of t) n += String.fromCharCode(e);
|
|
142
|
+
return btoa(n).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
143
|
+
}
|
|
144
|
+
function C(e) {
|
|
145
|
+
let t = e.replace(/-/g, "+").replace(/_/g, "/"), n = (4 - t.length % 4) % 4, r = t.padEnd(t.length + n, "="), i = atob(r), a = new ArrayBuffer(i.length), o = new Uint8Array(a);
|
|
146
|
+
for (let e = 0; e < i.length; e++) o[e] = i.charCodeAt(e);
|
|
147
|
+
return a;
|
|
148
|
+
}
|
|
149
|
+
function w() {
|
|
150
|
+
return window?.PublicKeyCredential !== void 0 && typeof window.PublicKeyCredential == "function";
|
|
151
|
+
}
|
|
152
|
+
function T(e) {
|
|
153
|
+
let { id: t } = e;
|
|
154
|
+
return {
|
|
155
|
+
...e,
|
|
156
|
+
id: C(t),
|
|
157
|
+
transports: e.transports
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function E(e) {
|
|
161
|
+
return e === "localhost" || /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i.test(e);
|
|
162
|
+
}
|
|
163
|
+
var D = class extends Error {
|
|
164
|
+
constructor({ message: e, code: t, cause: n, name: r }) {
|
|
165
|
+
super(e, { cause: n }), this.name = r ?? n.name, this.code = t;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
function O({ error: e, options: t }) {
|
|
169
|
+
let { publicKey: n } = t;
|
|
170
|
+
if (!n) throw Error("options was missing required publicKey property");
|
|
171
|
+
if (e.name === "AbortError") {
|
|
172
|
+
if (t.signal instanceof AbortSignal) return new D({
|
|
173
|
+
message: "Registration ceremony was sent an abort signal",
|
|
174
|
+
code: "ERROR_CEREMONY_ABORTED",
|
|
175
|
+
cause: e
|
|
176
|
+
});
|
|
177
|
+
} else if (e.name === "ConstraintError") {
|
|
178
|
+
if (n.authenticatorSelection?.requireResidentKey === !0) return new D({
|
|
179
|
+
message: "Discoverable credentials were required but no available authenticator supported it",
|
|
180
|
+
code: "ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT",
|
|
181
|
+
cause: e
|
|
182
|
+
});
|
|
183
|
+
if (t.mediation === "conditional" && n.authenticatorSelection?.userVerification === "required") return new D({
|
|
184
|
+
message: "User verification was required during automatic registration but it could not be performed",
|
|
185
|
+
code: "ERROR_AUTO_REGISTER_USER_VERIFICATION_FAILURE",
|
|
186
|
+
cause: e
|
|
187
|
+
});
|
|
188
|
+
if (n.authenticatorSelection?.userVerification === "required") return new D({
|
|
189
|
+
message: "User verification was required but no available authenticator supported it",
|
|
190
|
+
code: "ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT",
|
|
191
|
+
cause: e
|
|
192
|
+
});
|
|
193
|
+
} else if (e.name === "InvalidStateError") return new D({
|
|
194
|
+
message: "The authenticator was previously registered",
|
|
195
|
+
code: "ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED",
|
|
196
|
+
cause: e
|
|
197
|
+
});
|
|
198
|
+
else if (e.name === "NotAllowedError") return new D({
|
|
199
|
+
message: e.message,
|
|
200
|
+
code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
|
|
201
|
+
cause: e
|
|
202
|
+
});
|
|
203
|
+
else if (e.name === "NotSupportedError") return n.pubKeyCredParams.filter((e) => e.type === "public-key").length === 0 ? new D({
|
|
204
|
+
message: "No entry in pubKeyCredParams was of type \"public-key\"",
|
|
205
|
+
code: "ERROR_MALFORMED_PUBKEYCREDPARAMS",
|
|
206
|
+
cause: e
|
|
207
|
+
}) : new D({
|
|
208
|
+
message: "No available authenticator supported any of the specified pubKeyCredParams algorithms",
|
|
209
|
+
code: "ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG",
|
|
210
|
+
cause: e
|
|
211
|
+
});
|
|
212
|
+
else if (e.name === "SecurityError") {
|
|
213
|
+
let t = window.location.hostname;
|
|
214
|
+
if (!E(t)) return new D({
|
|
215
|
+
message: `${window.location.hostname} is an invalid domain`,
|
|
216
|
+
code: "ERROR_INVALID_DOMAIN",
|
|
217
|
+
cause: e
|
|
218
|
+
});
|
|
219
|
+
if (n.rp.id !== t) return new D({
|
|
220
|
+
message: `The RP ID "${n.rp.id}" is invalid for this domain`,
|
|
221
|
+
code: "ERROR_INVALID_RP_ID",
|
|
222
|
+
cause: e
|
|
223
|
+
});
|
|
224
|
+
} else if (e.name === "TypeError") {
|
|
225
|
+
if (n.user.id.byteLength < 1 || n.user.id.byteLength > 64) return new D({
|
|
226
|
+
message: "User ID was not between 1 and 64 characters",
|
|
227
|
+
code: "ERROR_INVALID_USER_ID_LENGTH",
|
|
228
|
+
cause: e
|
|
229
|
+
});
|
|
230
|
+
} else if (e.name === "UnknownError") return new D({
|
|
231
|
+
message: "The authenticator was unable to process the specified options, or could not create a new credential",
|
|
232
|
+
code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
|
|
233
|
+
cause: e
|
|
234
|
+
});
|
|
235
|
+
return e;
|
|
236
|
+
}
|
|
237
|
+
var k = new class {
|
|
238
|
+
createNewAbortSignal() {
|
|
239
|
+
if (this.controller) {
|
|
240
|
+
let e = /* @__PURE__ */ Error("Cancelling existing WebAuthn API call for new one");
|
|
241
|
+
e.name = "AbortError", this.controller.abort(e);
|
|
242
|
+
}
|
|
243
|
+
let e = new AbortController();
|
|
244
|
+
return this.controller = e, e.signal;
|
|
245
|
+
}
|
|
246
|
+
cancelCeremony() {
|
|
247
|
+
if (this.controller) {
|
|
248
|
+
let e = /* @__PURE__ */ Error("Manually cancelling existing WebAuthn API call");
|
|
249
|
+
e.name = "AbortError", this.controller.abort(e), this.controller = void 0;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}(), A = ["cross-platform", "platform"];
|
|
253
|
+
function j(e) {
|
|
254
|
+
if (e && !(A.indexOf(e) < 0)) return e;
|
|
255
|
+
}
|
|
256
|
+
async function M(e) {
|
|
257
|
+
let { optionsJSON: t, useAutoRegister: n = !1 } = e;
|
|
258
|
+
if (!w()) throw Error("WebAuthn is not supported in this browser");
|
|
259
|
+
let r = {
|
|
260
|
+
...t,
|
|
261
|
+
challenge: C(t.challenge),
|
|
262
|
+
user: {
|
|
263
|
+
...t.user,
|
|
264
|
+
id: C(t.user.id)
|
|
265
|
+
},
|
|
266
|
+
excludeCredentials: t.excludeCredentials?.map(T)
|
|
267
|
+
}, i = {};
|
|
268
|
+
n && (i.mediation = "conditional"), i.publicKey = r, i.signal = k.createNewAbortSignal();
|
|
269
|
+
let a;
|
|
270
|
+
try {
|
|
271
|
+
a = await navigator.credentials.create(i);
|
|
272
|
+
} catch (e) {
|
|
273
|
+
throw O({
|
|
274
|
+
error: e,
|
|
275
|
+
options: i
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (!a) throw Error("Registration was not completed");
|
|
279
|
+
let { id: o, rawId: s, response: c, type: l } = a, u;
|
|
280
|
+
typeof c.getTransports == "function" && (u = c.getTransports());
|
|
281
|
+
let d;
|
|
282
|
+
if (typeof c.getPublicKeyAlgorithm == "function") try {
|
|
283
|
+
d = c.getPublicKeyAlgorithm();
|
|
284
|
+
} catch (e) {
|
|
285
|
+
N("getPublicKeyAlgorithm()", e);
|
|
286
|
+
}
|
|
287
|
+
let f;
|
|
288
|
+
if (typeof c.getPublicKey == "function") try {
|
|
289
|
+
let e = c.getPublicKey();
|
|
290
|
+
e !== null && (f = S(e));
|
|
291
|
+
} catch (e) {
|
|
292
|
+
N("getPublicKey()", e);
|
|
293
|
+
}
|
|
294
|
+
let p;
|
|
295
|
+
if (typeof c.getAuthenticatorData == "function") try {
|
|
296
|
+
p = S(c.getAuthenticatorData());
|
|
297
|
+
} catch (e) {
|
|
298
|
+
N("getAuthenticatorData()", e);
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
id: o,
|
|
302
|
+
rawId: S(s),
|
|
303
|
+
response: {
|
|
304
|
+
attestationObject: S(c.attestationObject),
|
|
305
|
+
clientDataJSON: S(c.clientDataJSON),
|
|
306
|
+
transports: u,
|
|
307
|
+
publicKeyAlgorithm: d,
|
|
308
|
+
publicKey: f,
|
|
309
|
+
authenticatorData: p
|
|
310
|
+
},
|
|
311
|
+
type: l,
|
|
312
|
+
clientExtensionResults: a.getClientExtensionResults(),
|
|
313
|
+
authenticatorAttachment: j(a.authenticatorAttachment)
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function N(e, t) {
|
|
317
|
+
console.warn(`The browser extension that intercepted this WebAuthn API call incorrectly implemented ${e}. You should report this error to them.\n`, t);
|
|
318
|
+
}
|
|
319
|
+
function P() {
|
|
320
|
+
if (!w()) return new Promise((e) => e(!1));
|
|
321
|
+
let e = window.PublicKeyCredential;
|
|
322
|
+
return e.isConditionalMediationAvailable === void 0 ? new Promise((e) => e(!1)) : e.isConditionalMediationAvailable();
|
|
323
|
+
}
|
|
324
|
+
function F({ error: e, options: t }) {
|
|
325
|
+
let { publicKey: n } = t;
|
|
326
|
+
if (!n) throw Error("options was missing required publicKey property");
|
|
327
|
+
if (e.name === "AbortError") {
|
|
328
|
+
if (t.signal instanceof AbortSignal) return new D({
|
|
329
|
+
message: "Authentication ceremony was sent an abort signal",
|
|
330
|
+
code: "ERROR_CEREMONY_ABORTED",
|
|
331
|
+
cause: e
|
|
332
|
+
});
|
|
333
|
+
} else if (e.name === "NotAllowedError") return new D({
|
|
334
|
+
message: e.message,
|
|
335
|
+
code: "ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY",
|
|
336
|
+
cause: e
|
|
337
|
+
});
|
|
338
|
+
else if (e.name === "SecurityError") {
|
|
339
|
+
let t = window.location.hostname;
|
|
340
|
+
if (!E(t)) return new D({
|
|
341
|
+
message: `${window.location.hostname} is an invalid domain`,
|
|
342
|
+
code: "ERROR_INVALID_DOMAIN",
|
|
343
|
+
cause: e
|
|
344
|
+
});
|
|
345
|
+
if (n.rpId !== t) return new D({
|
|
346
|
+
message: `The RP ID "${n.rpId}" is invalid for this domain`,
|
|
347
|
+
code: "ERROR_INVALID_RP_ID",
|
|
348
|
+
cause: e
|
|
349
|
+
});
|
|
350
|
+
} else if (e.name === "UnknownError") return new D({
|
|
351
|
+
message: "The authenticator was unable to process the specified options, or could not create a new assertion signature",
|
|
352
|
+
code: "ERROR_AUTHENTICATOR_GENERAL_ERROR",
|
|
353
|
+
cause: e
|
|
354
|
+
});
|
|
355
|
+
return e;
|
|
356
|
+
}
|
|
357
|
+
async function I(e) {
|
|
358
|
+
let { optionsJSON: t, useBrowserAutofill: n = !1, verifyBrowserAutofillInput: r = !0 } = e;
|
|
359
|
+
if (!w()) throw Error("WebAuthn is not supported in this browser");
|
|
360
|
+
let i;
|
|
361
|
+
t.allowCredentials?.length !== 0 && (i = t.allowCredentials?.map(T));
|
|
362
|
+
let a = {
|
|
363
|
+
...t,
|
|
364
|
+
challenge: C(t.challenge),
|
|
365
|
+
allowCredentials: i
|
|
366
|
+
}, o = {};
|
|
367
|
+
if (n) {
|
|
368
|
+
if (!await P()) throw Error("Browser does not support WebAuthn autofill");
|
|
369
|
+
if (document.querySelectorAll("input[autocomplete$='webauthn']").length < 1 && r) throw Error("No <input> with \"webauthn\" as the only or last value in its `autocomplete` attribute was detected");
|
|
370
|
+
o.mediation = "conditional", a.allowCredentials = [];
|
|
371
|
+
}
|
|
372
|
+
o.publicKey = a, o.signal = k.createNewAbortSignal();
|
|
373
|
+
let s;
|
|
374
|
+
try {
|
|
375
|
+
s = await navigator.credentials.get(o);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
throw F({
|
|
378
|
+
error: e,
|
|
379
|
+
options: o
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
if (!s) throw Error("Authentication was not completed");
|
|
383
|
+
let { id: c, rawId: l, response: u, type: d } = s, f;
|
|
384
|
+
return u.userHandle && (f = S(u.userHandle)), {
|
|
385
|
+
id: c,
|
|
386
|
+
rawId: S(l),
|
|
387
|
+
response: {
|
|
388
|
+
authenticatorData: S(u.authenticatorData),
|
|
389
|
+
clientDataJSON: S(u.clientDataJSON),
|
|
390
|
+
signature: S(u.signature),
|
|
391
|
+
userHandle: f
|
|
392
|
+
},
|
|
393
|
+
type: d,
|
|
394
|
+
clientExtensionResults: s.getClientExtensionResults(),
|
|
395
|
+
authenticatorAttachment: j(s.authenticatorAttachment)
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/webauthn/widgets/passkey-ceremony.ts
|
|
400
|
+
function L() {
|
|
401
|
+
return w();
|
|
402
|
+
}
|
|
403
|
+
async function R(e) {
|
|
404
|
+
let t = await I({ optionsJSON: e });
|
|
405
|
+
return Object.fromEntries(Object.entries(t));
|
|
406
|
+
}
|
|
407
|
+
async function z(e) {
|
|
408
|
+
let t = await M({ optionsJSON: e });
|
|
409
|
+
return Object.fromEntries(Object.entries(t));
|
|
410
|
+
}
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region src/webauthn/widgets/PasskeyEnrollment.tsx
|
|
413
|
+
function B(e) {
|
|
414
|
+
let n = a(), l = r({
|
|
415
|
+
queryKey: ["auth", "listOwnPasskeys"],
|
|
416
|
+
queryFn: () => n.listOwnPasskeys()
|
|
417
|
+
}), u = l.data ?? [], [d, f] = t(""), [p, m] = t(!1), [h, g] = t(null), S = async () => {
|
|
418
|
+
g(null), m(!0);
|
|
419
|
+
try {
|
|
420
|
+
let e = await z((await n.beginOwnPasskeyRegistration()).optionsJSON);
|
|
421
|
+
await n.finishOwnPasskeyRegistration({
|
|
422
|
+
response: e,
|
|
423
|
+
label: d.trim() || "Unnamed device"
|
|
424
|
+
}), f(""), l.refetch();
|
|
425
|
+
} catch (e) {
|
|
426
|
+
g(e instanceof Error ? e.message : "Passkey enrollment failed");
|
|
427
|
+
} finally {
|
|
428
|
+
m(!1);
|
|
429
|
+
}
|
|
430
|
+
}, C = i({
|
|
431
|
+
mutationFn: (e) => n.removeOwnPasskey({ credentialId: e }),
|
|
432
|
+
onSuccess: () => {
|
|
433
|
+
g(null), l.refetch();
|
|
434
|
+
},
|
|
435
|
+
onError: (e) => g(e instanceof Error ? e.message : "Remove failed")
|
|
436
|
+
});
|
|
437
|
+
return /* @__PURE__ */ s("div", {
|
|
438
|
+
className: "rounded-lg border border-border bg-surface overflow-hidden",
|
|
439
|
+
children: [/* @__PURE__ */ s("div", {
|
|
440
|
+
className: "px-4 py-2.5 border-b border-border flex items-center gap-2",
|
|
441
|
+
children: [/* @__PURE__ */ o(v, { className: "h-3.5 w-3.5 text-foreground-subtle" }), /* @__PURE__ */ o("div", {
|
|
442
|
+
className: "text-xs font-semibold text-foreground",
|
|
443
|
+
children: "Passkeys"
|
|
444
|
+
})]
|
|
445
|
+
}), /* @__PURE__ */ s("div", {
|
|
446
|
+
className: "p-4 space-y-3",
|
|
447
|
+
children: [
|
|
448
|
+
/* @__PURE__ */ o("div", {
|
|
449
|
+
className: "text-xs text-foreground-subtle",
|
|
450
|
+
children: "Add a passkey (Touch ID, Windows Hello, or a security key) as a phishing-resistant second factor. You'll be prompted for it at every login."
|
|
451
|
+
}),
|
|
452
|
+
l.isLoading ? /* @__PURE__ */ s("div", {
|
|
453
|
+
className: "flex items-center gap-2 text-xs text-foreground-subtle",
|
|
454
|
+
children: [/* @__PURE__ */ o(b, { className: "h-3.5 w-3.5 animate-spin" }), "Loading passkeys…"]
|
|
455
|
+
}) : u.length > 0 ? /* @__PURE__ */ o("ul", {
|
|
456
|
+
className: "divide-y divide-border rounded-md border border-border",
|
|
457
|
+
children: u.map((e) => /* @__PURE__ */ s("li", {
|
|
458
|
+
className: "flex items-center gap-3 px-3 py-2 text-xs",
|
|
459
|
+
children: [
|
|
460
|
+
/* @__PURE__ */ o(y, { className: "h-3.5 w-3.5 text-foreground-subtle shrink-0" }),
|
|
461
|
+
/* @__PURE__ */ s("div", {
|
|
462
|
+
className: "flex-1 min-w-0",
|
|
463
|
+
children: [/* @__PURE__ */ o("div", {
|
|
464
|
+
className: "font-medium text-foreground truncate",
|
|
465
|
+
children: e.label
|
|
466
|
+
}), /* @__PURE__ */ s("div", {
|
|
467
|
+
className: "text-[10px] text-foreground-subtle",
|
|
468
|
+
children: [
|
|
469
|
+
"Added ",
|
|
470
|
+
new Date(e.createdAt).toLocaleDateString(),
|
|
471
|
+
e.lastUsedAt ? ` · last used ${new Date(e.lastUsedAt).toLocaleDateString()}` : " · never used"
|
|
472
|
+
]
|
|
473
|
+
})]
|
|
474
|
+
}),
|
|
475
|
+
/* @__PURE__ */ s("button", {
|
|
476
|
+
onClick: () => C.mutate(e.credentialId),
|
|
477
|
+
disabled: C.isPending,
|
|
478
|
+
className: "inline-flex items-center gap-1 rounded px-2 py-1 text-[11px] text-danger hover:bg-danger/10 disabled:opacity-50",
|
|
479
|
+
children: [/* @__PURE__ */ o(x, { className: "h-3 w-3" }), "Remove"]
|
|
480
|
+
})
|
|
481
|
+
]
|
|
482
|
+
}, e.credentialId))
|
|
483
|
+
}) : /* @__PURE__ */ o("div", {
|
|
484
|
+
className: "text-[11px] text-foreground-subtle",
|
|
485
|
+
children: "No passkeys enrolled yet."
|
|
486
|
+
}),
|
|
487
|
+
h && /* @__PURE__ */ s("div", {
|
|
488
|
+
className: "text-[11px] text-danger flex items-center gap-1",
|
|
489
|
+
children: [/* @__PURE__ */ o(_, { className: "h-3 w-3" }), h]
|
|
490
|
+
}),
|
|
491
|
+
/* @__PURE__ */ s("div", {
|
|
492
|
+
className: "flex items-end gap-2",
|
|
493
|
+
children: [/* @__PURE__ */ s("div", {
|
|
494
|
+
className: "flex-1 space-y-1",
|
|
495
|
+
children: [/* @__PURE__ */ o("label", {
|
|
496
|
+
className: "text-[10px] uppercase tracking-wide text-foreground-subtle",
|
|
497
|
+
children: "Passkey name"
|
|
498
|
+
}), /* @__PURE__ */ o("input", {
|
|
499
|
+
type: "text",
|
|
500
|
+
value: d,
|
|
501
|
+
onChange: (e) => f(e.target.value),
|
|
502
|
+
placeholder: "e.g. MacBook Touch ID",
|
|
503
|
+
className: "w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-primary"
|
|
504
|
+
})]
|
|
505
|
+
}), /* @__PURE__ */ o("button", {
|
|
506
|
+
onClick: S,
|
|
507
|
+
disabled: p,
|
|
508
|
+
className: "inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-2 text-xs font-semibold text-primary-foreground hover:opacity-90 disabled:opacity-50",
|
|
509
|
+
children: p ? /* @__PURE__ */ s(c, { children: [/* @__PURE__ */ o(b, { className: "h-3.5 w-3.5 animate-spin" }), "Enrolling…"] }) : /* @__PURE__ */ s(c, { children: [/* @__PURE__ */ o(v, { className: "h-3.5 w-3.5" }), "Add passkey"] })
|
|
510
|
+
})]
|
|
511
|
+
})
|
|
512
|
+
]
|
|
513
|
+
})]
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
//#endregion
|
|
517
|
+
//#region src/webauthn/widgets/PasskeyLogin.tsx
|
|
518
|
+
function V(e) {
|
|
519
|
+
if (!e) return null;
|
|
520
|
+
let t = e.challengeToken, n = e.onComplete, r = e.onError;
|
|
521
|
+
return typeof t != "string" || typeof n != "function" ? null : {
|
|
522
|
+
challengeToken: t,
|
|
523
|
+
onComplete: n,
|
|
524
|
+
onError: typeof r == "function" ? r : void 0
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
function H(e) {
|
|
528
|
+
let n = a(), r = V(e.config), [i, c] = t(!1), [l, u] = t(null);
|
|
529
|
+
return r ? L() ? /* @__PURE__ */ s("div", {
|
|
530
|
+
className: "space-y-2",
|
|
531
|
+
children: [/* @__PURE__ */ s("button", {
|
|
532
|
+
type: "button",
|
|
533
|
+
"data-testid": "login-passkey",
|
|
534
|
+
onClick: async () => {
|
|
535
|
+
u(null), c(!0);
|
|
536
|
+
try {
|
|
537
|
+
let e = await R((await n.loginBeginPasskey(r.challengeToken)).optionsJSON), t = await n.loginVerifyPasskey(r.challengeToken, e);
|
|
538
|
+
r.onComplete(t.token);
|
|
539
|
+
} catch (e) {
|
|
540
|
+
let t = e instanceof Error ? e.message : "Passkey verification failed";
|
|
541
|
+
u(t), r.onError?.(t);
|
|
542
|
+
} finally {
|
|
543
|
+
c(!1);
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
disabled: i,
|
|
547
|
+
className: "w-full flex items-center justify-center gap-2 rounded-lg border border-border bg-background px-4 py-2.5 text-sm font-semibold text-foreground hover:bg-surface-hover disabled:opacity-50 transition-all",
|
|
548
|
+
children: [i ? /* @__PURE__ */ o(b, { className: "h-4 w-4 animate-spin text-primary" }) : /* @__PURE__ */ o(v, { className: "h-4 w-4 text-primary" }), "Use a passkey"]
|
|
549
|
+
}), l && /* @__PURE__ */ o("div", {
|
|
550
|
+
className: "rounded-md bg-danger/10 border border-danger/20 px-3 py-2 text-xs text-danger",
|
|
551
|
+
children: l
|
|
552
|
+
})]
|
|
553
|
+
}) : /* @__PURE__ */ o("div", {
|
|
554
|
+
className: "rounded-lg border border-border bg-surface px-3 py-2 text-xs text-foreground-subtle",
|
|
555
|
+
children: "This browser does not support passkeys."
|
|
556
|
+
}) : /* @__PURE__ */ o("div", {
|
|
557
|
+
className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning",
|
|
558
|
+
children: "Passkey login widget requires a challengeToken + onComplete callback."
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
//#endregion
|
|
562
|
+
//#region src/webauthn/widgets/index.tsx
|
|
563
|
+
var U = {
|
|
564
|
+
"passkey-enrollment": B,
|
|
565
|
+
"passkey-login": H
|
|
566
|
+
};
|
|
567
|
+
//#endregion
|
|
568
|
+
export { U as default };
|