@lumiapassport/ui-kit 1.15.10 → 1.15.11
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/iframe/index.html +1 -1
- package/dist/iframe/main.js +1 -1
- package/dist/index.cjs +107 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +108 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -101,7 +101,7 @@ function getServiceUrls() {
|
|
|
101
101
|
}
|
|
102
102
|
function getIframeUrl() {
|
|
103
103
|
const config = DEFAULT_LUMIA_PASSPORT_CONFIG;
|
|
104
|
-
const buildIframeUrl = "
|
|
104
|
+
const buildIframeUrl = "http://localhost:5173/iframe/index.html";
|
|
105
105
|
const iframeUrl = buildIframeUrl || config.services.iframeUrl || "https://auth.lumiapassport.com";
|
|
106
106
|
return iframeUrl;
|
|
107
107
|
}
|
|
@@ -541,6 +541,15 @@ var init_site = __esm({
|
|
|
541
541
|
});
|
|
542
542
|
|
|
543
543
|
// src/internal/auth/passkey.ts
|
|
544
|
+
var passkey_exports = {};
|
|
545
|
+
__export(passkey_exports, {
|
|
546
|
+
authenticateWithPasskey: () => authenticateWithPasskey,
|
|
547
|
+
createPasskeyHelpers: () => createPasskeyHelpers,
|
|
548
|
+
hasAvailablePasskeys: () => hasAvailablePasskeys,
|
|
549
|
+
isWebAuthnSupported: () => isWebAuthnSupported,
|
|
550
|
+
registerPasskey: () => registerPasskey,
|
|
551
|
+
resetWebAuthnFlags: () => resetWebAuthnFlags
|
|
552
|
+
});
|
|
544
553
|
function setGlobalConditionalUI(active) {
|
|
545
554
|
if (typeof window !== "undefined") window.__LUMIA_CONDITIONAL_UI_ACTIVE__ = active;
|
|
546
555
|
}
|
|
@@ -2233,6 +2242,12 @@ var init_email = __esm({
|
|
|
2233
2242
|
});
|
|
2234
2243
|
|
|
2235
2244
|
// src/internal/auth/providers/passkey.ts
|
|
2245
|
+
var passkey_exports2 = {};
|
|
2246
|
+
__export(passkey_exports2, {
|
|
2247
|
+
beginPasskeyLinking: () => beginPasskeyLinking,
|
|
2248
|
+
completePasskeyLinking: () => completePasskeyLinking,
|
|
2249
|
+
linkPasskeyWithWebAuthn: () => linkPasskeyWithWebAuthn
|
|
2250
|
+
});
|
|
2236
2251
|
async function completePasskeyLinking(payload) {
|
|
2237
2252
|
const hasValidToken = await ensureValidToken();
|
|
2238
2253
|
if (!hasValidToken) throw new Error("No authentication token available");
|
|
@@ -2311,8 +2326,8 @@ async function linkPasskeyWithWebAuthn(optionsOverride) {
|
|
|
2311
2326
|
}
|
|
2312
2327
|
try {
|
|
2313
2328
|
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
2314
|
-
const friendlyDisplay = `Lumia
|
|
2315
|
-
const friendlyName = `lumia-
|
|
2329
|
+
const friendlyDisplay = `Lumia Passport (${ts})`;
|
|
2330
|
+
const friendlyName = `lumia-passport.${ts}`;
|
|
2316
2331
|
const originalUser = publicKeyOptions.user;
|
|
2317
2332
|
publicKeyOptions = {
|
|
2318
2333
|
...publicKeyOptions,
|
|
@@ -2347,6 +2362,8 @@ async function linkPasskeyWithWebAuthn(optionsOverride) {
|
|
|
2347
2362
|
const attestationPayload = credentialToAttestationPayload(credential);
|
|
2348
2363
|
const cid = challengeId || "local-" + Date.now();
|
|
2349
2364
|
await completePasskeyLinking({ challengeId: cid, credential: attestationPayload });
|
|
2365
|
+
const rawIdB64 = btoa(String.fromCharCode(...new Uint8Array(credential.rawId)));
|
|
2366
|
+
return { credentialId: credential.id, rawId: rawIdB64 };
|
|
2350
2367
|
}
|
|
2351
2368
|
var init_passkey2 = __esm({
|
|
2352
2369
|
"src/internal/auth/providers/passkey.ts"() {
|
|
@@ -5501,7 +5518,7 @@ function Header() {
|
|
|
5501
5518
|
// package.json
|
|
5502
5519
|
var package_default = {
|
|
5503
5520
|
name: "@lumiapassport/ui-kit",
|
|
5504
|
-
version: "1.15.
|
|
5521
|
+
version: "1.15.11",
|
|
5505
5522
|
description: "React UI components and hooks for Lumia Passport authentication and Account Abstraction",
|
|
5506
5523
|
type: "module",
|
|
5507
5524
|
main: "./dist/index.cjs",
|
|
@@ -8407,6 +8424,7 @@ var useRestoreStore = create4((set) => ({
|
|
|
8407
8424
|
restoreFile: null,
|
|
8408
8425
|
checkingBackup: false,
|
|
8409
8426
|
hasServerBackup: false,
|
|
8427
|
+
isCreatingPasskey: false,
|
|
8410
8428
|
selectedCloudProvider: null,
|
|
8411
8429
|
error: null,
|
|
8412
8430
|
success: null,
|
|
@@ -8418,6 +8436,7 @@ var useRestoreStore = create4((set) => ({
|
|
|
8418
8436
|
setRestoreFile: (restoreFile) => set({ restoreFile }),
|
|
8419
8437
|
setCheckingBackup: (checkingBackup) => set({ checkingBackup }),
|
|
8420
8438
|
setHasServerBackup: (hasServerBackup) => set({ hasServerBackup }),
|
|
8439
|
+
setIsCreatingPasskey: (isCreatingPasskey) => set({ isCreatingPasskey }),
|
|
8421
8440
|
setSelectedCloudProvider: (providerId) => set({ selectedCloudProvider: providerId }),
|
|
8422
8441
|
setError: (error) => set({ error }),
|
|
8423
8442
|
setSuccess: (success) => set({ success })
|
|
@@ -8542,7 +8561,7 @@ function useCreateBackup() {
|
|
|
8542
8561
|
const address = useLumiaPassportSession((st) => st.address);
|
|
8543
8562
|
const hasServerVault = useLumiaPassportSession((st) => st.hasServerVault);
|
|
8544
8563
|
const setIsDialogForced = useLayoutStore((st) => st.setIsDialogForced);
|
|
8545
|
-
const { usePasskey, restorePassword, selectedCloudProvider, setSuccess, setError, setMethod } = useRestoreStore();
|
|
8564
|
+
const { usePasskey, restorePassword, selectedCloudProvider, setSuccess, setError, setMethod, setIsCreatingPasskey } = useRestoreStore();
|
|
8546
8565
|
useEffect15(() => {
|
|
8547
8566
|
if (!hasServerVault) {
|
|
8548
8567
|
setMethod("server");
|
|
@@ -8561,12 +8580,13 @@ function useCreateBackup() {
|
|
|
8561
8580
|
if (!usePasskey && !restorePassword) {
|
|
8562
8581
|
throw new Error("Please provide a password for the backup");
|
|
8563
8582
|
}
|
|
8583
|
+
const password = !usePasskey ? restorePassword : void 0;
|
|
8564
8584
|
const navigateToMainMenu = jwt.isNewUser || !hasServerVault;
|
|
8565
|
-
console.log("[BACKUP STATUS] is new user:", jwt.isNewUser, !hasServerVault);
|
|
8585
|
+
console.log("[BACKUP STATUS] is new user:", jwt.isNewUser, !hasServerVault, "usePasskey:", usePasskey);
|
|
8566
8586
|
return {
|
|
8567
8587
|
response: await iframeManager.createBackup(
|
|
8568
8588
|
passportUserId,
|
|
8569
|
-
{ method: "server", password
|
|
8589
|
+
{ method: "server", password },
|
|
8570
8590
|
jwt.accessToken
|
|
8571
8591
|
),
|
|
8572
8592
|
navigateToMainMenu
|
|
@@ -8590,7 +8610,11 @@ function useCreateBackup() {
|
|
|
8590
8610
|
setIsDialogForced(false);
|
|
8591
8611
|
},
|
|
8592
8612
|
onError: async (error) => {
|
|
8593
|
-
|
|
8613
|
+
if (error?.name === "NotAllowedError" || error?.message?.includes("timed out or was not allowed")) {
|
|
8614
|
+
setError("Passkey selection was cancelled. Please try again or create a new passkey.");
|
|
8615
|
+
} else {
|
|
8616
|
+
setError(error?.message || "Backup creation failed");
|
|
8617
|
+
}
|
|
8594
8618
|
qc.invalidateQueries({ queryKey: [CHECK_BACKUP_QUERY_KEY, address] });
|
|
8595
8619
|
}
|
|
8596
8620
|
});
|
|
@@ -8628,6 +8652,31 @@ function useCreateBackup() {
|
|
|
8628
8652
|
qc.invalidateQueries({ queryKey: [CHECK_BACKUP_QUERY_KEY, address] });
|
|
8629
8653
|
}
|
|
8630
8654
|
});
|
|
8655
|
+
const { mutate: createPasskey, isPending: isPasskeyCreating } = useMutation7({
|
|
8656
|
+
mutationFn: async () => {
|
|
8657
|
+
setIsCreatingPasskey(true);
|
|
8658
|
+
const { linkPasskeyWithWebAuthn: linkPasskeyWithWebAuthn2 } = await Promise.resolve().then(() => (init_passkey2(), passkey_exports2));
|
|
8659
|
+
const { createPasskeyHelpers: createPasskeyHelpers2 } = await Promise.resolve().then(() => (init_passkey(), passkey_exports));
|
|
8660
|
+
const { credentialId, rawId } = await linkPasskeyWithWebAuthn2();
|
|
8661
|
+
const helpers = createPasskeyHelpers2(passportUserId);
|
|
8662
|
+
helpers.setCredId(credentialId);
|
|
8663
|
+
helpers.setRawId(rawId);
|
|
8664
|
+
return { credentialId, rawId };
|
|
8665
|
+
},
|
|
8666
|
+
onSuccess: async () => {
|
|
8667
|
+
setIsCreatingPasskey(false);
|
|
8668
|
+
setError(null);
|
|
8669
|
+
setSuccess("Passkey created successfully. You can now create a backup.");
|
|
8670
|
+
},
|
|
8671
|
+
onError: async (error) => {
|
|
8672
|
+
setIsCreatingPasskey(false);
|
|
8673
|
+
if (error.name === "NotAllowedError") {
|
|
8674
|
+
setError("Passkey creation cancelled. Please try again.");
|
|
8675
|
+
} else {
|
|
8676
|
+
setError(error?.message || "Failed to create passkey");
|
|
8677
|
+
}
|
|
8678
|
+
}
|
|
8679
|
+
});
|
|
8631
8680
|
const { mutate: createCloudBackup, isPending: isCloudBackupCreating } = useMutation7({
|
|
8632
8681
|
mutationFn: async () => {
|
|
8633
8682
|
const iframeManager = getIframeManager();
|
|
@@ -8674,7 +8723,9 @@ function useCreateBackup() {
|
|
|
8674
8723
|
isCloudBackupCreating,
|
|
8675
8724
|
createCloudBackup,
|
|
8676
8725
|
isLocalBackupCreating,
|
|
8677
|
-
createLocalBackup
|
|
8726
|
+
createLocalBackup,
|
|
8727
|
+
isPasskeyCreating,
|
|
8728
|
+
createPasskey
|
|
8678
8729
|
};
|
|
8679
8730
|
}
|
|
8680
8731
|
|
|
@@ -8891,7 +8942,7 @@ function MethodSelector(props) {
|
|
|
8891
8942
|
import { AlertCircle, FileUp as FileUp2, Upload, User } from "lucide-react";
|
|
8892
8943
|
|
|
8893
8944
|
// src/internal/components/KeyshareRestoreMenu/components/PasswordPasskey.tsx
|
|
8894
|
-
import { ChevronRight as ChevronRight2, Eye, EyeOff, Info as Info2, Key as Key4, Loader as Loader8 } from "lucide-react";
|
|
8945
|
+
import { ChevronRight as ChevronRight2, Eye, EyeOff, Info as Info2, Key as Key4, Loader as Loader8, Plus } from "lucide-react";
|
|
8895
8946
|
import { useRef as useRef12 } from "react";
|
|
8896
8947
|
import { Fragment as Fragment9, jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
8897
8948
|
function PasswordPasskey(props) {
|
|
@@ -8902,7 +8953,8 @@ function PasswordPasskey(props) {
|
|
|
8902
8953
|
isLoading,
|
|
8903
8954
|
disabled,
|
|
8904
8955
|
isEncryptionMethod,
|
|
8905
|
-
actionHandler
|
|
8956
|
+
actionHandler,
|
|
8957
|
+
onCreatePasskey
|
|
8906
8958
|
} = props;
|
|
8907
8959
|
const hasServerVault = useLumiaPassportSession((st) => st.hasServerVault);
|
|
8908
8960
|
const actionRef = useRef12(null);
|
|
@@ -8911,6 +8963,7 @@ function PasswordPasskey(props) {
|
|
|
8911
8963
|
restorePassword,
|
|
8912
8964
|
usePasskey,
|
|
8913
8965
|
error,
|
|
8966
|
+
isCreatingPasskey,
|
|
8914
8967
|
setRestorePassword,
|
|
8915
8968
|
setShowPassword,
|
|
8916
8969
|
setUsePasskey,
|
|
@@ -9007,22 +9060,41 @@ function PasswordPasskey(props) {
|
|
|
9007
9060
|
children: isLoading ? /* @__PURE__ */ jsx39(Loader8, { className: "animate-spin h-4 w-4" }) : /* @__PURE__ */ jsx39(ChevronRight2, { className: "h-4 w-4" })
|
|
9008
9061
|
}
|
|
9009
9062
|
)
|
|
9010
|
-
] }) : /* @__PURE__ */ jsxs32(
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
isLoading ? /* @__PURE__ */
|
|
9022
|
-
|
|
9023
|
-
|
|
9024
|
-
|
|
9025
|
-
|
|
9063
|
+
] }) : /* @__PURE__ */ jsxs32("div", { className: "w-full flex flex-col gap-[var(--l-pass-gap)]", children: [
|
|
9064
|
+
/* @__PURE__ */ jsx39(
|
|
9065
|
+
Button,
|
|
9066
|
+
{
|
|
9067
|
+
ref: actionRef,
|
|
9068
|
+
size: "large",
|
|
9069
|
+
variant: "default",
|
|
9070
|
+
title: actionCaption,
|
|
9071
|
+
onClick: actionHandler,
|
|
9072
|
+
disabled: isLoading || disabled || !usePasskey && !restorePassword,
|
|
9073
|
+
className: "w-full",
|
|
9074
|
+
children: isLoading ? /* @__PURE__ */ jsxs32(Fragment9, { children: [
|
|
9075
|
+
/* @__PURE__ */ jsx39(Loader8, { className: "animate-spin h-4 w-4" }),
|
|
9076
|
+
isCreatingPasskey && /* @__PURE__ */ jsx39("span", { children: "Creating Passkey..." })
|
|
9077
|
+
] }) : /* @__PURE__ */ jsxs32(Fragment9, { children: [
|
|
9078
|
+
/* @__PURE__ */ jsx39(ActionIcon, { className: "h-4 w-4" }),
|
|
9079
|
+
/* @__PURE__ */ jsx39("span", { children: actionCaption })
|
|
9080
|
+
] })
|
|
9081
|
+
}
|
|
9082
|
+
),
|
|
9083
|
+
mode === "backup" && onCreatePasskey && /* @__PURE__ */ jsxs32(
|
|
9084
|
+
Button,
|
|
9085
|
+
{
|
|
9086
|
+
size: "medium",
|
|
9087
|
+
variant: "outline",
|
|
9088
|
+
onClick: onCreatePasskey,
|
|
9089
|
+
disabled: isLoading || disabled,
|
|
9090
|
+
className: "w-full",
|
|
9091
|
+
children: [
|
|
9092
|
+
/* @__PURE__ */ jsx39(Plus, { className: "h-4 w-4" }),
|
|
9093
|
+
/* @__PURE__ */ jsx39("span", { children: "Create new Passkey" })
|
|
9094
|
+
]
|
|
9095
|
+
}
|
|
9096
|
+
)
|
|
9097
|
+
] }),
|
|
9026
9098
|
!isEncryptionMethod && !!usePasskey && /* @__PURE__ */ jsx39(Highlight, { type: "info", className: "w-full flex flex-col gap-[var(--l-pass-gap)] text-[10px]", children: mode === "backup" && /* @__PURE__ */ jsxs32("div", { className: "flex gap-[var(--l-pass-gap)]", children: [
|
|
9027
9099
|
/* @__PURE__ */ jsx39(Info2, { className: "h-4 w-4 flex-shrink-0" }),
|
|
9028
9100
|
/* @__PURE__ */ jsxs32("span", { className: "text-[var(--l-pass-fg-muted)] block flex-1", children: [
|
|
@@ -9176,7 +9248,7 @@ import { Download, Key as Key5, Upload as Upload2 } from "lucide-react";
|
|
|
9176
9248
|
import { useEffect as useEffect17 } from "react";
|
|
9177
9249
|
import { Fragment as Fragment12, jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
9178
9250
|
function Server(props) {
|
|
9179
|
-
const { isLoading, mode = "restore", serverHandler } = props;
|
|
9251
|
+
const { isLoading, mode = "restore", serverHandler, createPasskeyHandler } = props;
|
|
9180
9252
|
const qc = useQueryClient6();
|
|
9181
9253
|
const address = useLumiaPassportSession((st) => st.address);
|
|
9182
9254
|
const setUsePasskey = useRestoreStore((st) => st.setUsePasskey);
|
|
@@ -9195,7 +9267,8 @@ function Server(props) {
|
|
|
9195
9267
|
isLoading,
|
|
9196
9268
|
actionCaption: mode === "backup" ? "Create Vault Backup" : "Restore from Vault",
|
|
9197
9269
|
actionIcon: mode === "backup" ? Upload2 : Download,
|
|
9198
|
-
actionHandler: () => serverHandler()
|
|
9270
|
+
actionHandler: () => serverHandler(),
|
|
9271
|
+
onCreatePasskey: createPasskeyHandler
|
|
9199
9272
|
}
|
|
9200
9273
|
),
|
|
9201
9274
|
!!serverRecoveryStatus?.created?.at && /* @__PURE__ */ jsxs35(Highlight, { type: "success", className: "flex gap-[var(--l-pass-gap)]", children: [
|
|
@@ -9657,7 +9730,9 @@ function KeyshareBackupMenu() {
|
|
|
9657
9730
|
isCloudBackupCreating,
|
|
9658
9731
|
createCloudBackup,
|
|
9659
9732
|
isLocalBackupCreating,
|
|
9660
|
-
createLocalBackup
|
|
9733
|
+
createLocalBackup,
|
|
9734
|
+
isPasskeyCreating,
|
|
9735
|
+
createPasskey
|
|
9661
9736
|
} = useCreateBackup();
|
|
9662
9737
|
const BackupComponent = !!currentBackupMethod ? COMPONENTS[currentBackupMethod] : null;
|
|
9663
9738
|
return /* @__PURE__ */ jsx46(
|
|
@@ -9719,10 +9794,11 @@ function KeyshareBackupMenu() {
|
|
|
9719
9794
|
BackupComponent,
|
|
9720
9795
|
{
|
|
9721
9796
|
mode: "backup",
|
|
9722
|
-
isLoading: isPasswordBackupCreating || isCloudBackupCreating || isLocalBackupCreating,
|
|
9797
|
+
isLoading: isPasswordBackupCreating || isCloudBackupCreating || isLocalBackupCreating || isPasskeyCreating,
|
|
9723
9798
|
fileHandler: createLocalBackup,
|
|
9724
9799
|
serverHandler: createPasswordBackup,
|
|
9725
|
-
cloudHandler: createCloudBackup
|
|
9800
|
+
cloudHandler: createCloudBackup,
|
|
9801
|
+
createPasskeyHandler: createPasskey
|
|
9726
9802
|
}
|
|
9727
9803
|
) }),
|
|
9728
9804
|
!isRecoveryLoading && !currentBackupMethod && !hasRecoveryData && /* @__PURE__ */ jsxs39(Highlight, { type: "warning", className: "flex gap-[var(--l-pass-gap)]", children: [
|