@retinalabsllc/zairusjs 10.0.1 → 10.0.9
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/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +46 -12
- package/dist/index.mjs +47 -12
- package/package.json +3 -1
package/dist/index.d.mts
CHANGED
|
@@ -404,7 +404,8 @@ interface UniversalSecurityPageProps {
|
|
|
404
404
|
onVerifyAndDisable2FA?: (otp: string) => Promise<{
|
|
405
405
|
success: boolean;
|
|
406
406
|
}>;
|
|
407
|
-
|
|
407
|
+
onRequestPasskeySetup?: () => Promise<any>;
|
|
408
|
+
onVerifyAndEnablePasskey?: (credential: any) => Promise<{
|
|
408
409
|
success: boolean;
|
|
409
410
|
}>;
|
|
410
411
|
onDisablePasskey?: () => Promise<{
|
package/dist/index.d.ts
CHANGED
|
@@ -404,7 +404,8 @@ interface UniversalSecurityPageProps {
|
|
|
404
404
|
onVerifyAndDisable2FA?: (otp: string) => Promise<{
|
|
405
405
|
success: boolean;
|
|
406
406
|
}>;
|
|
407
|
-
|
|
407
|
+
onRequestPasskeySetup?: () => Promise<any>;
|
|
408
|
+
onVerifyAndEnablePasskey?: (credential: any) => Promise<{
|
|
408
409
|
success: boolean;
|
|
409
410
|
}>;
|
|
410
411
|
onDisablePasskey?: () => Promise<{
|
package/dist/index.js
CHANGED
|
@@ -2665,6 +2665,7 @@ var import_react45 = __toESM(require("react"));
|
|
|
2665
2665
|
var import_react_hot_toast8 = __toESM(require("react-hot-toast"));
|
|
2666
2666
|
var import_react46 = require("@hugeicons/react");
|
|
2667
2667
|
var import_core_free_icons16 = require("@hugeicons/core-free-icons");
|
|
2668
|
+
var import_browser = require("@simplewebauthn/browser");
|
|
2668
2669
|
var UniversalSecurityPage = ({
|
|
2669
2670
|
has2FA,
|
|
2670
2671
|
hasPasskey,
|
|
@@ -2675,7 +2676,8 @@ var UniversalSecurityPage = ({
|
|
|
2675
2676
|
onRequest2FASetup,
|
|
2676
2677
|
onVerifyAndEnable2FA,
|
|
2677
2678
|
onVerifyAndDisable2FA,
|
|
2678
|
-
|
|
2679
|
+
onRequestPasskeySetup,
|
|
2680
|
+
onVerifyAndEnablePasskey,
|
|
2679
2681
|
onDisablePasskey
|
|
2680
2682
|
}) => {
|
|
2681
2683
|
const [show2FASetupModal, setShow2FASetupModal] = (0, import_react45.useState)(false);
|
|
@@ -2714,10 +2716,28 @@ var UniversalSecurityPage = ({
|
|
|
2714
2716
|
};
|
|
2715
2717
|
const handleCopySecret = async (secret) => {
|
|
2716
2718
|
try {
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2719
|
+
if (navigator?.clipboard?.writeText && window.isSecureContext) {
|
|
2720
|
+
await navigator.clipboard.writeText(secret);
|
|
2721
|
+
import_react_hot_toast8.default.success("Secret copied to clipboard");
|
|
2722
|
+
} else {
|
|
2723
|
+
throw new Error("Clipboard API not available");
|
|
2724
|
+
}
|
|
2725
|
+
} catch (e) {
|
|
2726
|
+
try {
|
|
2727
|
+
const textArea = document.createElement("textarea");
|
|
2728
|
+
textArea.value = secret;
|
|
2729
|
+
textArea.style.position = "fixed";
|
|
2730
|
+
textArea.style.left = "-999999px";
|
|
2731
|
+
textArea.style.top = "-999999px";
|
|
2732
|
+
document.body.appendChild(textArea);
|
|
2733
|
+
textArea.focus();
|
|
2734
|
+
textArea.select();
|
|
2735
|
+
document.execCommand("copy");
|
|
2736
|
+
textArea.remove();
|
|
2737
|
+
import_react_hot_toast8.default.success("Secret copied to clipboard");
|
|
2738
|
+
} catch (err) {
|
|
2739
|
+
import_react_hot_toast8.default.error("Unable to copy. Please manually copy the key.");
|
|
2740
|
+
}
|
|
2721
2741
|
}
|
|
2722
2742
|
};
|
|
2723
2743
|
const handleToggle2FA = async () => {
|
|
@@ -2784,16 +2804,28 @@ var UniversalSecurityPage = ({
|
|
|
2784
2804
|
}
|
|
2785
2805
|
};
|
|
2786
2806
|
const submitEnablePasskey = async () => {
|
|
2787
|
-
if (!
|
|
2807
|
+
if (!onRequestPasskeySetup || !onVerifyAndEnablePasskey) return;
|
|
2788
2808
|
setIsSubmitting(true);
|
|
2789
2809
|
try {
|
|
2790
|
-
const
|
|
2810
|
+
const options = await onRequestPasskeySetup();
|
|
2811
|
+
let credentialResponse;
|
|
2812
|
+
try {
|
|
2813
|
+
credentialResponse = await (0, import_browser.startRegistration)({ optionsJSON: options });
|
|
2814
|
+
} catch (err) {
|
|
2815
|
+
if (err.name === "NotAllowedError") {
|
|
2816
|
+
throw new Error("Passkey setup was canceled or is not supported on this device.");
|
|
2817
|
+
}
|
|
2818
|
+
throw err;
|
|
2819
|
+
}
|
|
2820
|
+
const res = await onVerifyAndEnablePasskey(credentialResponse);
|
|
2791
2821
|
if (res.success) {
|
|
2792
2822
|
import_react_hot_toast8.default.success("Passkey Created Successfully");
|
|
2793
2823
|
setShowPasskeyModal(false);
|
|
2824
|
+
} else {
|
|
2825
|
+
import_react_hot_toast8.default.error("Failed to verify device passkey.");
|
|
2794
2826
|
}
|
|
2795
2827
|
} catch (error) {
|
|
2796
|
-
import_react_hot_toast8.default.error("Passkey setup
|
|
2828
|
+
import_react_hot_toast8.default.error(error.message || "Passkey setup interrupted.");
|
|
2797
2829
|
} finally {
|
|
2798
2830
|
setIsSubmitting(false);
|
|
2799
2831
|
}
|
|
@@ -2829,10 +2861,10 @@ var UniversalSecurityPage = ({
|
|
|
2829
2861
|
toggleLoading: isPasskeyLoading,
|
|
2830
2862
|
isLast: true
|
|
2831
2863
|
}
|
|
2832
|
-
))), show2FASetupModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ import_react45.default.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ import_react45.default.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ import_react45.default.createElement("form", { className: "space-y-
|
|
2864
|
+
))), show2FASetupModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ import_react45.default.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ import_react45.default.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ import_react45.default.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
|
|
2833
2865
|
e.preventDefault();
|
|
2834
2866
|
submitEnable2FA(otp.join(""));
|
|
2835
|
-
} }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ import_react45.default.createElement(
|
|
2867
|
+
} }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex justify-between gap-2 pb-6", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ import_react45.default.createElement(
|
|
2836
2868
|
"input",
|
|
2837
2869
|
{
|
|
2838
2870
|
key: index,
|
|
@@ -2863,9 +2895,11 @@ var UniversalSecurityPage = ({
|
|
|
2863
2895
|
), /* @__PURE__ */ import_react45.default.createElement(
|
|
2864
2896
|
"button",
|
|
2865
2897
|
{
|
|
2898
|
+
type: "button",
|
|
2866
2899
|
onClick: () => handleCopySecret(twoFaSecret),
|
|
2867
|
-
className: "w-full flex
|
|
2900
|
+
className: "w-full flex items-center justify-center py-3 rounded-full bg-neutral-100 text-black hover:bg-neutral-200 outline-none text-[13px] font-medium tracking-wide transition-colors mt-3"
|
|
2868
2901
|
},
|
|
2902
|
+
/* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.Copy01Icon, size: 16, className: "mr-2" }),
|
|
2869
2903
|
"Copy Secret Key"
|
|
2870
2904
|
))))), show2FADisableModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FADisableModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Disable 2FA"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShow2FADisableModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "p-6" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the code from your authenticator app to disable 2FA.")), /* @__PURE__ */ import_react45.default.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
2871
2905
|
e.preventDefault();
|
|
@@ -2898,7 +2932,7 @@ var UniversalSecurityPage = ({
|
|
|
2898
2932
|
className: "w-full py-3.5"
|
|
2899
2933
|
},
|
|
2900
2934
|
"Verify & Disable"
|
|
2901
|
-
))))), showPasskeyModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 border-b border-neutral-50" }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ import_react45.default.createElement("
|
|
2935
|
+
))))), showPasskeyModal && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 border-b border-neutral-50" }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ import_react45.default.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.CancelCircleIcon, size: 18 }))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ import_react45.default.createElement("h2", { className: "text-lg text-black mb-2 tracking-tight" }, "Simplify your Sign In"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ import_react45.default.createElement(
|
|
2902
2936
|
ThreeDActionButton,
|
|
2903
2937
|
{
|
|
2904
2938
|
onClick: submitEnablePasskey,
|
package/dist/index.mjs
CHANGED
|
@@ -2647,11 +2647,13 @@ import { HugeiconsIcon as HugeiconsIcon19 } from "@hugeicons/react";
|
|
|
2647
2647
|
import {
|
|
2648
2648
|
CancelCircleIcon as CancelCircleIcon6,
|
|
2649
2649
|
Loading03Icon as Loading03Icon10,
|
|
2650
|
+
Copy01Icon as Copy01Icon3,
|
|
2650
2651
|
ArrowLeft01Icon as ArrowLeft01Icon5,
|
|
2651
2652
|
Shield02Icon,
|
|
2652
2653
|
Key01Icon,
|
|
2653
2654
|
ArrowRight01Icon as ArrowRight01Icon4
|
|
2654
2655
|
} from "@hugeicons/core-free-icons";
|
|
2656
|
+
import { startRegistration } from "@simplewebauthn/browser";
|
|
2655
2657
|
var UniversalSecurityPage = ({
|
|
2656
2658
|
has2FA,
|
|
2657
2659
|
hasPasskey,
|
|
@@ -2662,7 +2664,8 @@ var UniversalSecurityPage = ({
|
|
|
2662
2664
|
onRequest2FASetup,
|
|
2663
2665
|
onVerifyAndEnable2FA,
|
|
2664
2666
|
onVerifyAndDisable2FA,
|
|
2665
|
-
|
|
2667
|
+
onRequestPasskeySetup,
|
|
2668
|
+
onVerifyAndEnablePasskey,
|
|
2666
2669
|
onDisablePasskey
|
|
2667
2670
|
}) => {
|
|
2668
2671
|
const [show2FASetupModal, setShow2FASetupModal] = useState18(false);
|
|
@@ -2701,10 +2704,28 @@ var UniversalSecurityPage = ({
|
|
|
2701
2704
|
};
|
|
2702
2705
|
const handleCopySecret = async (secret) => {
|
|
2703
2706
|
try {
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2707
|
+
if (navigator?.clipboard?.writeText && window.isSecureContext) {
|
|
2708
|
+
await navigator.clipboard.writeText(secret);
|
|
2709
|
+
toast7.success("Secret copied to clipboard");
|
|
2710
|
+
} else {
|
|
2711
|
+
throw new Error("Clipboard API not available");
|
|
2712
|
+
}
|
|
2713
|
+
} catch (e) {
|
|
2714
|
+
try {
|
|
2715
|
+
const textArea = document.createElement("textarea");
|
|
2716
|
+
textArea.value = secret;
|
|
2717
|
+
textArea.style.position = "fixed";
|
|
2718
|
+
textArea.style.left = "-999999px";
|
|
2719
|
+
textArea.style.top = "-999999px";
|
|
2720
|
+
document.body.appendChild(textArea);
|
|
2721
|
+
textArea.focus();
|
|
2722
|
+
textArea.select();
|
|
2723
|
+
document.execCommand("copy");
|
|
2724
|
+
textArea.remove();
|
|
2725
|
+
toast7.success("Secret copied to clipboard");
|
|
2726
|
+
} catch (err) {
|
|
2727
|
+
toast7.error("Unable to copy. Please manually copy the key.");
|
|
2728
|
+
}
|
|
2708
2729
|
}
|
|
2709
2730
|
};
|
|
2710
2731
|
const handleToggle2FA = async () => {
|
|
@@ -2771,16 +2792,28 @@ var UniversalSecurityPage = ({
|
|
|
2771
2792
|
}
|
|
2772
2793
|
};
|
|
2773
2794
|
const submitEnablePasskey = async () => {
|
|
2774
|
-
if (!
|
|
2795
|
+
if (!onRequestPasskeySetup || !onVerifyAndEnablePasskey) return;
|
|
2775
2796
|
setIsSubmitting(true);
|
|
2776
2797
|
try {
|
|
2777
|
-
const
|
|
2798
|
+
const options = await onRequestPasskeySetup();
|
|
2799
|
+
let credentialResponse;
|
|
2800
|
+
try {
|
|
2801
|
+
credentialResponse = await startRegistration({ optionsJSON: options });
|
|
2802
|
+
} catch (err) {
|
|
2803
|
+
if (err.name === "NotAllowedError") {
|
|
2804
|
+
throw new Error("Passkey setup was canceled or is not supported on this device.");
|
|
2805
|
+
}
|
|
2806
|
+
throw err;
|
|
2807
|
+
}
|
|
2808
|
+
const res = await onVerifyAndEnablePasskey(credentialResponse);
|
|
2778
2809
|
if (res.success) {
|
|
2779
2810
|
toast7.success("Passkey Created Successfully");
|
|
2780
2811
|
setShowPasskeyModal(false);
|
|
2812
|
+
} else {
|
|
2813
|
+
toast7.error("Failed to verify device passkey.");
|
|
2781
2814
|
}
|
|
2782
2815
|
} catch (error) {
|
|
2783
|
-
toast7.error("Passkey setup
|
|
2816
|
+
toast7.error(error.message || "Passkey setup interrupted.");
|
|
2784
2817
|
} finally {
|
|
2785
2818
|
setIsSubmitting(false);
|
|
2786
2819
|
}
|
|
@@ -2816,10 +2849,10 @@ var UniversalSecurityPage = ({
|
|
|
2816
2849
|
toggleLoading: isPasskeyLoading,
|
|
2817
2850
|
isLast: true
|
|
2818
2851
|
}
|
|
2819
|
-
))), show2FASetupModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ React27.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ React27.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ React27.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ React27.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ React27.createElement("form", { className: "space-y-
|
|
2852
|
+
))), show2FASetupModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FASetupModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200 max-h-[90vh]" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable 2FA"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShow2FASetupModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "flex-1 overflow-y-auto custom-scrollbar p-6 pt-2" }, /* @__PURE__ */ React27.createElement("div", { className: "w-full flex justify-center mb-6 mix-blend-multiply" }, twoFaQr ? /* @__PURE__ */ React27.createElement("img", { src: twoFaQr, alt: "2FA QR Code", className: "w-40 h-40 object-contain rounded-xl border border-neutral-100 p-2" }) : /* @__PURE__ */ React27.createElement("div", { className: "w-40 h-40 bg-neutral-100 rounded-xl flex items-center justify-center animate-pulse" })), /* @__PURE__ */ React27.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the 6-digit code from your app")), /* @__PURE__ */ React27.createElement("form", { className: "space-y-4", autoComplete: "off", onSubmit: (e) => {
|
|
2820
2853
|
e.preventDefault();
|
|
2821
2854
|
submitEnable2FA(otp.join(""));
|
|
2822
|
-
} }, /* @__PURE__ */ React27.createElement("div", { className: "flex justify-between gap-2", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React27.createElement(
|
|
2855
|
+
} }, /* @__PURE__ */ React27.createElement("div", { className: "flex justify-between gap-2 pb-6", onPaste: handlePaste }, otp.map((digit, index) => /* @__PURE__ */ React27.createElement(
|
|
2823
2856
|
"input",
|
|
2824
2857
|
{
|
|
2825
2858
|
key: index,
|
|
@@ -2850,9 +2883,11 @@ var UniversalSecurityPage = ({
|
|
|
2850
2883
|
), /* @__PURE__ */ React27.createElement(
|
|
2851
2884
|
"button",
|
|
2852
2885
|
{
|
|
2886
|
+
type: "button",
|
|
2853
2887
|
onClick: () => handleCopySecret(twoFaSecret),
|
|
2854
|
-
className: "w-full flex
|
|
2888
|
+
className: "w-full flex items-center justify-center py-3 rounded-full bg-neutral-100 text-black hover:bg-neutral-200 outline-none text-[13px] font-medium tracking-wide transition-colors mt-3"
|
|
2855
2889
|
},
|
|
2890
|
+
/* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: Copy01Icon3, size: 16, className: "mr-2" }),
|
|
2856
2891
|
"Copy Secret Key"
|
|
2857
2892
|
))))), show2FADisableModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShow2FADisableModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 " }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Disable 2FA"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShow2FADisableModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "p-6" }, /* @__PURE__ */ React27.createElement("div", { className: "text-center mb-8 mt-2" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-xl text-black mb-2 tracking-tight" }, "Security Check"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500" }, "Enter the code from your authenticator app to disable 2FA.")), /* @__PURE__ */ React27.createElement("form", { className: "space-y-8", autoComplete: "off", onSubmit: (e) => {
|
|
2858
2893
|
e.preventDefault();
|
|
@@ -2885,7 +2920,7 @@ var UniversalSecurityPage = ({
|
|
|
2885
2920
|
className: "w-full py-3.5"
|
|
2886
2921
|
},
|
|
2887
2922
|
"Verify & Disable"
|
|
2888
|
-
))))), showPasskeyModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 border-b border-neutral-50" }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ React27.createElement("
|
|
2923
|
+
))))), showPasskeyModal && /* @__PURE__ */ React27.createElement("div", { className: "fixed inset-0 z-120 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ React27.createElement("div", { className: "absolute inset-0 bg-black/40 ", onClick: () => !isSubmitting && setShowPasskeyModal(false) }), /* @__PURE__ */ React27.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ React27.createElement("div", { className: "flex items-center justify-between p-5 shrink-0 border-b border-neutral-50" }, /* @__PURE__ */ React27.createElement("h3", { className: "text-[15px] text-black tracking-tight" }, "Enable Passkey"), /* @__PURE__ */ React27.createElement("button", { onClick: () => !isSubmitting && setShowPasskeyModal(false), className: "text-neutral-400 hover:text-black transition-colors outline-none" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: CancelCircleIcon6, size: 18 }))), /* @__PURE__ */ React27.createElement("div", { className: "p-6 text-center" }, /* @__PURE__ */ React27.createElement("h2", { className: "text-lg text-black mb-2 tracking-tight" }, "Simplify your Sign In"), /* @__PURE__ */ React27.createElement("p", { className: "text-[13px] text-neutral-500 mb-8 leading-relaxed" }, "Use your device's biometrics (Face ID, Touch ID, or PIN) to securely sign into your account without needing a password."), /* @__PURE__ */ React27.createElement(
|
|
2889
2924
|
ThreeDActionButton,
|
|
2890
2925
|
{
|
|
2891
2926
|
onClick: submitEnablePasskey,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@retinalabsllc/zairusjs",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.9",
|
|
4
4
|
"description": "A perceptive, Ai data driven Next.js UI component library.",
|
|
5
5
|
"author": "Retina Labs Company",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@hugeicons/core-free-icons": "^1.1.0",
|
|
41
41
|
"@hugeicons/react": "^1.1.1",
|
|
42
|
+
"@simplewebauthn/browser": "^13.3.0",
|
|
43
|
+
"@simplewebauthn/server": "^13.3.2",
|
|
42
44
|
"clsx": "^2.1.1",
|
|
43
45
|
"react-google-recaptcha-v3": "^1.11.0",
|
|
44
46
|
"react-hot-toast": "^2.6.0",
|