@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 CHANGED
@@ -404,7 +404,8 @@ interface UniversalSecurityPageProps {
404
404
  onVerifyAndDisable2FA?: (otp: string) => Promise<{
405
405
  success: boolean;
406
406
  }>;
407
- onEnablePasskey?: () => Promise<{
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
- onEnablePasskey?: () => Promise<{
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
- onEnablePasskey,
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
- await navigator.clipboard.writeText(secret);
2718
- import_react_hot_toast8.default.success("Secret copied to clipboard");
2719
- } catch {
2720
- import_react_hot_toast8.default.error("Failed to copy");
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 (!onEnablePasskey) return;
2807
+ if (!onRequestPasskeySetup || !onVerifyAndEnablePasskey) return;
2788
2808
  setIsSubmitting(true);
2789
2809
  try {
2790
- const res = await onEnablePasskey();
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 failed or was canceled");
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-8", autoComplete: "off", onSubmit: (e) => {
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 items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-[13px] tracking-wide transition-colors"
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("div", { className: "w-16 h-16 bg-neutral-100 rounded-full flex items-center justify-center mx-auto mb-4 text-black" }, /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons16.Key01Icon, size: 28 })), /* @__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(
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
- onEnablePasskey,
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
- await navigator.clipboard.writeText(secret);
2705
- toast7.success("Secret copied to clipboard");
2706
- } catch {
2707
- toast7.error("Failed to copy");
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 (!onEnablePasskey) return;
2795
+ if (!onRequestPasskeySetup || !onVerifyAndEnablePasskey) return;
2775
2796
  setIsSubmitting(true);
2776
2797
  try {
2777
- const res = await onEnablePasskey();
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 failed or was canceled");
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-8", autoComplete: "off", onSubmit: (e) => {
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 items-center justify-center py-2.5 rounded-full border border-neutral-200 text-black hover:bg-neutral-50 outline-none text-[13px] tracking-wide transition-colors"
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("div", { className: "w-16 h-16 bg-neutral-100 rounded-full flex items-center justify-center mx-auto mb-4 text-black" }, /* @__PURE__ */ React27.createElement(HugeiconsIcon19, { icon: Key01Icon, size: 28 })), /* @__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(
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.1",
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",