@passflow/react 0.2.8 → 0.2.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/dist/index.cjs.js +4 -4
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.es.js +440 -6
  4. package/dist/index.es.js.map +1 -1
  5. package/dist/src/components/flow/two-factor-verify/index.d.ts +1 -0
  6. package/dist/src/components/flow/two-factor-verify/index.d.ts.map +1 -1
  7. package/dist/src/components/form/index.d.ts +1 -0
  8. package/dist/src/components/form/index.d.ts.map +1 -1
  9. package/dist/src/components/form/two-factor-challenge/index.d.ts +10 -0
  10. package/dist/src/components/form/two-factor-challenge/index.d.ts.map +1 -0
  11. package/dist/src/components/form/two-factor-challenge/method-selector.d.ts +12 -0
  12. package/dist/src/components/form/two-factor-challenge/method-selector.d.ts.map +1 -0
  13. package/dist/src/components/form/two-factor-challenge/otp-input.d.ts +12 -0
  14. package/dist/src/components/form/two-factor-challenge/otp-input.d.ts.map +1 -0
  15. package/dist/src/context/auth-context.d.ts +10 -1
  16. package/dist/src/context/auth-context.d.ts.map +1 -1
  17. package/dist/src/hooks/index.d.ts +3 -0
  18. package/dist/src/hooks/index.d.ts.map +1 -1
  19. package/dist/src/hooks/use-session-expired.d.ts +49 -0
  20. package/dist/src/hooks/use-session-expired.d.ts.map +1 -0
  21. package/dist/src/hooks/use-two-factor-challenge.d.ts +16 -0
  22. package/dist/src/hooks/use-two-factor-challenge.d.ts.map +1 -0
  23. package/dist/src/hooks/use-two-factor-methods.d.ts +14 -0
  24. package/dist/src/hooks/use-two-factor-methods.d.ts.map +1 -0
  25. package/dist/src/types/index.d.ts +18 -0
  26. package/dist/src/types/index.d.ts.map +1 -1
  27. package/package.json +2 -2
package/dist/index.es.js CHANGED
@@ -6,6 +6,8 @@ import clsx from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import * as React from 'react';
8
8
  import { useState, useEffect, forwardRef, createContext, useCallback, useContext, useRef, useLayoutEffect, useMemo, useReducer } from 'react';
9
+ import { PassflowEvent, parseToken, Passflow } from '@passflow/core';
10
+ export * from '@passflow/core';
9
11
  import queryString from 'query-string';
10
12
  import { getCountryForTimezone } from 'countries-and-timezones';
11
13
  import { usePhoneInput, defaultCountries, parseCountry, FlagImage } from 'react-international-phone';
@@ -16,11 +18,9 @@ import { HelmetProvider, Helmet } from 'react-helmet-async';
16
18
  import { ErrorBoundary } from 'react-error-boundary';
17
19
  import { phone as phone$1 } from 'phone';
18
20
  import { useForm, Controller } from 'react-hook-form';
19
- import { parseToken, Passflow } from '@passflow/core';
20
- export * from '@passflow/core';
21
21
  import 'react-dom';
22
22
 
23
- const version = "0.2.8";
23
+ const version = "0.2.10";
24
24
 
25
25
  window.passflowReactAppVersion = () => {
26
26
  console.log(`App Version: ${version}`);
@@ -787,9 +787,27 @@ const NavigationContext$1 = createContext({
787
787
  });
788
788
 
789
789
  const AuthContext = createContext(void 0);
790
- const AuthProvider = ({ children }) => {
790
+ const AuthProvider = ({ children, onSessionExpired }) => {
791
791
  const passflow = usePassflow();
792
792
  const [isLoading, setIsLoading] = useState(false);
793
+ const [isSessionExpired, setIsSessionExpired] = useState(false);
794
+ useEffect(() => {
795
+ const subscriber = {
796
+ onAuthChange: (eventType, payload) => {
797
+ if (eventType === PassflowEvent.SessionExpired) {
798
+ const reason = payload?.reason ?? "refresh_failed";
799
+ setIsSessionExpired(true);
800
+ onSessionExpired?.(reason);
801
+ } else if (eventType === PassflowEvent.SignIn || eventType === PassflowEvent.Register) {
802
+ setIsSessionExpired(false);
803
+ }
804
+ }
805
+ };
806
+ passflow.subscribe(subscriber, [PassflowEvent.SessionExpired, PassflowEvent.SignIn, PassflowEvent.Register]);
807
+ return () => {
808
+ passflow.unsubscribe(subscriber);
809
+ };
810
+ }, [passflow, onSessionExpired]);
793
811
  const isAuthenticated = useCallback(() => passflow.isAuthenticated(), [passflow]);
794
812
  const getTokens = useCallback(
795
813
  async (doRefresh) => {
@@ -819,6 +837,7 @@ const AuthProvider = ({ children }) => {
819
837
  isAuthenticated,
820
838
  logout,
821
839
  isLoading,
840
+ isSessionExpired,
822
841
  getTokens
823
842
  };
824
843
  return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
@@ -1789,6 +1808,178 @@ const useTwoFactorSetupMagicLink = (token) => {
1789
1808
  };
1790
1809
  };
1791
1810
 
1811
+ const useTwoFactorChallenge = () => {
1812
+ const passflow = usePassflow();
1813
+ const [challenge, setChallenge] = useState(null);
1814
+ const [selectedMethod, setSelectedMethod] = useState(null);
1815
+ const [isLoading, setIsLoading] = useState(false);
1816
+ const [error, setError] = useState(null);
1817
+ const requestChallenge = useCallback(
1818
+ async (firstFactorMethod) => {
1819
+ setIsLoading(true);
1820
+ setError(null);
1821
+ try {
1822
+ const response = await passflow.twoFactor.requestChallenge({
1823
+ first_factor_method: firstFactorMethod
1824
+ });
1825
+ setChallenge(response);
1826
+ setSelectedMethod(response.method);
1827
+ } catch (e) {
1828
+ setError(e);
1829
+ setChallenge(null);
1830
+ } finally {
1831
+ setIsLoading(false);
1832
+ }
1833
+ },
1834
+ [passflow]
1835
+ );
1836
+ const verify = useCallback(
1837
+ async (response, trustDevice = false) => {
1838
+ if (!challenge?.challenge_id) {
1839
+ setError(new Error("No active challenge session"));
1840
+ return null;
1841
+ }
1842
+ setIsLoading(true);
1843
+ setError(null);
1844
+ try {
1845
+ const result = await passflow.twoFactor.verifyV2({
1846
+ challenge_id: challenge.challenge_id,
1847
+ method: selectedMethod || challenge.method,
1848
+ response,
1849
+ trust_device: trustDevice
1850
+ });
1851
+ return result;
1852
+ } catch (e) {
1853
+ setError(e);
1854
+ return null;
1855
+ } finally {
1856
+ setIsLoading(false);
1857
+ }
1858
+ },
1859
+ [passflow, challenge, selectedMethod]
1860
+ );
1861
+ const switchMethod = useCallback(
1862
+ async (method) => {
1863
+ if (!challenge?.challenge_id) {
1864
+ setError(new Error("No active challenge session"));
1865
+ return;
1866
+ }
1867
+ setIsLoading(true);
1868
+ setError(null);
1869
+ try {
1870
+ const response = await passflow.twoFactor.switchToAlternative({
1871
+ challenge_id: challenge.challenge_id,
1872
+ method
1873
+ });
1874
+ setChallenge(response);
1875
+ setSelectedMethod(method);
1876
+ } catch (e) {
1877
+ setError(e);
1878
+ } finally {
1879
+ setIsLoading(false);
1880
+ }
1881
+ },
1882
+ [passflow, challenge]
1883
+ );
1884
+ const reset = useCallback(() => {
1885
+ setChallenge(null);
1886
+ setSelectedMethod(null);
1887
+ setError(null);
1888
+ setIsLoading(false);
1889
+ }, []);
1890
+ return {
1891
+ challenge,
1892
+ isLoading,
1893
+ error,
1894
+ requestChallenge,
1895
+ verify,
1896
+ switchMethod,
1897
+ selectedMethod,
1898
+ reset
1899
+ };
1900
+ };
1901
+
1902
+ const useTwoFactorMethods = () => {
1903
+ const passflow = usePassflow();
1904
+ const [availableMethods, setAvailableMethods] = useState([]);
1905
+ const [registeredMethods, setRegisteredMethods] = useState([]);
1906
+ const [isLoading, setIsLoading] = useState(false);
1907
+ const [error, setError] = useState(null);
1908
+ const refresh = useCallback(async () => {
1909
+ setIsLoading(true);
1910
+ setError(null);
1911
+ try {
1912
+ const methods = await passflow.twoFactor.getRegisteredMethods();
1913
+ setRegisteredMethods(methods);
1914
+ const available = methods.map((m) => m.method);
1915
+ setAvailableMethods(available);
1916
+ } catch (e) {
1917
+ setError(e);
1918
+ setRegisteredMethods([]);
1919
+ setAvailableMethods([]);
1920
+ } finally {
1921
+ setIsLoading(false);
1922
+ }
1923
+ }, [passflow]);
1924
+ const removeMethod = useCallback(
1925
+ async (methodId) => {
1926
+ setIsLoading(true);
1927
+ setError(null);
1928
+ try {
1929
+ await passflow.twoFactor.removeMethod?.(methodId);
1930
+ await refresh();
1931
+ } catch (e) {
1932
+ setError(e);
1933
+ } finally {
1934
+ setIsLoading(false);
1935
+ }
1936
+ },
1937
+ [passflow, refresh]
1938
+ );
1939
+ return {
1940
+ availableMethods,
1941
+ registeredMethods,
1942
+ isLoading,
1943
+ error,
1944
+ refresh,
1945
+ removeMethod
1946
+ };
1947
+ };
1948
+
1949
+ function useSessionExpired(options) {
1950
+ const passflow = usePassflow();
1951
+ const [isSessionExpired, setIsSessionExpired] = useState(false);
1952
+ const [expiredReason, setExpiredReason] = useState(null);
1953
+ useEffect(() => {
1954
+ const subscriber = {
1955
+ onAuthChange: (eventType, payload) => {
1956
+ if (eventType === PassflowEvent.SessionExpired) {
1957
+ const reason = payload?.reason ?? "refresh_failed";
1958
+ setIsSessionExpired(true);
1959
+ setExpiredReason(reason);
1960
+ options?.onSessionExpired?.(reason);
1961
+ } else if (eventType === PassflowEvent.SignIn || eventType === PassflowEvent.Register) {
1962
+ setIsSessionExpired(false);
1963
+ setExpiredReason(null);
1964
+ }
1965
+ }
1966
+ };
1967
+ passflow.subscribe(subscriber, [PassflowEvent.SessionExpired, PassflowEvent.SignIn, PassflowEvent.Register]);
1968
+ return () => {
1969
+ passflow.unsubscribe(subscriber);
1970
+ };
1971
+ }, [passflow, options?.onSessionExpired]);
1972
+ const resetSessionExpired = () => {
1973
+ setIsSessionExpired(false);
1974
+ setExpiredReason(null);
1975
+ };
1976
+ return {
1977
+ isSessionExpired,
1978
+ expiredReason,
1979
+ resetSessionExpired
1980
+ };
1981
+ }
1982
+
1792
1983
  const FieldPhone = ({ id, onChange, isError = false, className = "" }) => {
1793
1984
  const [show, setShow] = useState(false);
1794
1985
  const [filterValue, setFilterValue] = useState("");
@@ -2190,6 +2381,245 @@ const TwoFactorSetupFlow = ({
2190
2381
  return /* @__PURE__ */ jsx(TwoFactorSetupForm, { onComplete: handleSetupComplete, onCancel: handleCancel });
2191
2382
  };
2192
2383
 
2384
+ const methodLabels = {
2385
+ totp: "Authenticator App",
2386
+ email_otp: "Email Code",
2387
+ sms_otp: "SMS Code",
2388
+ passkey: "Passkey",
2389
+ recovery_codes: "Recovery Code",
2390
+ push_fcm: "Push Notification (FCM)",
2391
+ push_webpush: "Push Notification (Web)"
2392
+ };
2393
+ const methodIcons = {
2394
+ totp: "📱",
2395
+ email_otp: "✉️",
2396
+ sms_otp: "💬",
2397
+ passkey: "🔑",
2398
+ recovery_codes: "🔒",
2399
+ push_fcm: "🔔",
2400
+ push_webpush: "🔔"
2401
+ };
2402
+ const MethodSelector = ({
2403
+ availableMethods,
2404
+ currentMethod,
2405
+ onSelectMethod,
2406
+ isOpen,
2407
+ onClose
2408
+ }) => {
2409
+ const handleSelect = (method) => {
2410
+ onSelectMethod(method);
2411
+ onClose();
2412
+ };
2413
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
2414
+ /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: "pf-dialog-overlay" }),
2415
+ /* @__PURE__ */ jsxs(DialogPrimitive.Content, { className: "pf-dialog-content pf-method-selector-dialog", children: [
2416
+ /* @__PURE__ */ jsx(DialogPrimitive.Title, { className: "pf-dialog-title", children: "Choose Verification Method" }),
2417
+ /* @__PURE__ */ jsx(DialogPrimitive.Description, { className: "pf-dialog-description", children: "Select an alternative method to verify your identity" }),
2418
+ /* @__PURE__ */ jsx("div", { className: "pf-method-selector-list", children: availableMethods.map((method) => /* @__PURE__ */ jsxs(
2419
+ "button",
2420
+ {
2421
+ type: "button",
2422
+ className: `pf-method-selector-item ${method === currentMethod ? "pf-method-selector-item-active" : ""}`,
2423
+ onClick: () => handleSelect(method),
2424
+ disabled: method === currentMethod,
2425
+ children: [
2426
+ /* @__PURE__ */ jsx("span", { className: "pf-method-icon", children: methodIcons[method] || "🔐" }),
2427
+ /* @__PURE__ */ jsx("span", { className: "pf-method-label", children: methodLabels[method] || method }),
2428
+ method === currentMethod && /* @__PURE__ */ jsx("span", { className: "pf-method-current-badge", children: "Current" })
2429
+ ]
2430
+ },
2431
+ method
2432
+ )) }),
2433
+ /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", className: "pf-dialog-close", "aria-label": "Close", children: "×" }) })
2434
+ ] })
2435
+ ] }) });
2436
+ };
2437
+
2438
+ const OtpInputComponent = ({
2439
+ value,
2440
+ onChange,
2441
+ numInputs = 6,
2442
+ error,
2443
+ disabled = false,
2444
+ autoFocus = true
2445
+ }) => {
2446
+ const containerRef = useRef(null);
2447
+ useEffect(() => {
2448
+ if (autoFocus && containerRef.current) {
2449
+ const firstInput = containerRef.current.querySelector("input");
2450
+ if (firstInput) {
2451
+ firstInput.focus();
2452
+ }
2453
+ }
2454
+ }, [autoFocus]);
2455
+ return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "pf-otp-input-container", children: [
2456
+ /* @__PURE__ */ jsx(
2457
+ OtpInput,
2458
+ {
2459
+ value,
2460
+ onChange,
2461
+ numInputs,
2462
+ renderSeparator: /* @__PURE__ */ jsx("span", { className: "pf-otp-separator" }),
2463
+ renderInput: (props) => /* @__PURE__ */ jsx(
2464
+ "input",
2465
+ {
2466
+ ...props,
2467
+ className: `pf-otp-input ${error ? "pf-otp-input-error" : ""} ${disabled ? "pf-otp-input-disabled" : ""}`,
2468
+ disabled
2469
+ }
2470
+ ),
2471
+ inputType: "tel",
2472
+ shouldAutoFocus: autoFocus
2473
+ }
2474
+ ),
2475
+ error && /* @__PURE__ */ jsx("div", { className: "pf-otp-error", children: error })
2476
+ ] });
2477
+ };
2478
+
2479
+ const TwoFactorChallenge = ({
2480
+ firstFactorMethod,
2481
+ onSuccess,
2482
+ onError,
2483
+ trustDevice = false
2484
+ }) => {
2485
+ const { challenge, isLoading, error, requestChallenge, verify, switchMethod, selectedMethod } = useTwoFactorChallenge();
2486
+ const [otpValue, setOtpValue] = useState("");
2487
+ const [isMethodSelectorOpen, setIsMethodSelectorOpen] = useState(false);
2488
+ useEffect(() => {
2489
+ requestChallenge(firstFactorMethod);
2490
+ }, [requestChallenge, firstFactorMethod]);
2491
+ useEffect(() => {
2492
+ if (error && onError) {
2493
+ onError(error);
2494
+ }
2495
+ }, [error, onError]);
2496
+ const handleVerify = async () => {
2497
+ if (!otpValue) {
2498
+ return;
2499
+ }
2500
+ const result = await verify(otpValue, trustDevice);
2501
+ if (result) {
2502
+ onSuccess?.();
2503
+ }
2504
+ };
2505
+ const handleSwitchMethod = async (method) => {
2506
+ setOtpValue("");
2507
+ await switchMethod(method);
2508
+ };
2509
+ const handleOtpChange = (value) => {
2510
+ setOtpValue(value);
2511
+ if (value.length === 6) {
2512
+ setTimeout(() => {
2513
+ verify(value, trustDevice).then((result) => {
2514
+ if (result) {
2515
+ onSuccess?.();
2516
+ }
2517
+ });
2518
+ }, 100);
2519
+ }
2520
+ };
2521
+ if (!challenge) {
2522
+ return /* @__PURE__ */ jsx("div", { className: "pf-two-factor-challenge pf-loading", children: /* @__PURE__ */ jsx("p", { children: "Loading challenge..." }) });
2523
+ }
2524
+ const currentMethod = selectedMethod || challenge.method;
2525
+ const availableMethods = [challenge.method, ...challenge.alternative_methods || []];
2526
+ const renderChallengeInput = () => {
2527
+ switch (currentMethod) {
2528
+ case "totp":
2529
+ case "email_otp":
2530
+ case "sms_otp":
2531
+ return /* @__PURE__ */ jsxs("div", { className: "pf-challenge-input-wrapper", children: [
2532
+ /* @__PURE__ */ jsx(
2533
+ OtpInputComponent,
2534
+ {
2535
+ value: otpValue,
2536
+ onChange: handleOtpChange,
2537
+ numInputs: 6,
2538
+ error: error?.message,
2539
+ disabled: isLoading,
2540
+ autoFocus: true
2541
+ }
2542
+ ),
2543
+ currentMethod === "email_otp" && challenge.code_sent_to && /* @__PURE__ */ jsxs("p", { className: "pf-challenge-hint", children: [
2544
+ "Code sent to ",
2545
+ challenge.code_sent_to
2546
+ ] }),
2547
+ currentMethod === "sms_otp" && challenge.code_sent_to && /* @__PURE__ */ jsxs("p", { className: "pf-challenge-hint", children: [
2548
+ "Code sent to ",
2549
+ challenge.code_sent_to
2550
+ ] }),
2551
+ /* @__PURE__ */ jsx(
2552
+ "button",
2553
+ {
2554
+ type: "button",
2555
+ onClick: handleVerify,
2556
+ disabled: isLoading || otpValue.length !== 6,
2557
+ className: "pf-button pf-button-primary",
2558
+ children: isLoading ? "Verifying..." : "Verify"
2559
+ }
2560
+ )
2561
+ ] });
2562
+ case "passkey":
2563
+ return /* @__PURE__ */ jsx("div", { className: "pf-challenge-input-wrapper", children: /* @__PURE__ */ jsx("button", { type: "button", onClick: handleVerify, disabled: isLoading, className: "pf-button pf-button-primary", children: isLoading ? "Verifying..." : "Use Passkey" }) });
2564
+ case "recovery_codes":
2565
+ return /* @__PURE__ */ jsxs("div", { className: "pf-challenge-input-wrapper", children: [
2566
+ /* @__PURE__ */ jsx(
2567
+ "input",
2568
+ {
2569
+ type: "text",
2570
+ value: otpValue,
2571
+ onChange: (e) => setOtpValue(e.target.value),
2572
+ placeholder: "Enter recovery code",
2573
+ disabled: isLoading,
2574
+ className: "pf-input"
2575
+ }
2576
+ ),
2577
+ /* @__PURE__ */ jsx(
2578
+ "button",
2579
+ {
2580
+ type: "button",
2581
+ onClick: handleVerify,
2582
+ disabled: isLoading || !otpValue,
2583
+ className: "pf-button pf-button-primary",
2584
+ children: isLoading ? "Verifying..." : "Verify"
2585
+ }
2586
+ )
2587
+ ] });
2588
+ default:
2589
+ return /* @__PURE__ */ jsxs("p", { children: [
2590
+ "Unsupported method: ",
2591
+ currentMethod
2592
+ ] });
2593
+ }
2594
+ };
2595
+ return /* @__PURE__ */ jsxs("div", { className: "pf-two-factor-challenge", children: [
2596
+ /* @__PURE__ */ jsxs("div", { className: "pf-challenge-method-info", children: [
2597
+ /* @__PURE__ */ jsx("h3", { children: "Two-Factor Authentication" }),
2598
+ /* @__PURE__ */ jsx("p", { children: "Enter the verification code" })
2599
+ ] }),
2600
+ renderChallengeInput(),
2601
+ availableMethods.length > 1 && /* @__PURE__ */ jsx(
2602
+ "button",
2603
+ {
2604
+ type: "button",
2605
+ onClick: () => setIsMethodSelectorOpen(true),
2606
+ className: "pf-button pf-button-secondary pf-button-switch-method",
2607
+ children: "Use different method"
2608
+ }
2609
+ ),
2610
+ /* @__PURE__ */ jsx(
2611
+ MethodSelector,
2612
+ {
2613
+ availableMethods,
2614
+ currentMethod,
2615
+ onSelectMethod: handleSwitchMethod,
2616
+ isOpen: isMethodSelectorOpen,
2617
+ onClose: () => setIsMethodSelectorOpen(false)
2618
+ }
2619
+ )
2620
+ ] });
2621
+ };
2622
+
2193
2623
  const TwoFactorVerifyForm = ({
2194
2624
  onSuccess,
2195
2625
  onUseRecovery,
@@ -2477,7 +2907,8 @@ const TwoFactorRecoveryForm = ({
2477
2907
  const TwoFactorVerifyFlow = ({
2478
2908
  successAuthRedirect,
2479
2909
  signInPath = routes.signin.path,
2480
- twoFactorSetupPath = routes.two_factor_setup?.path
2910
+ twoFactorSetupPath = routes.two_factor_setup?.path,
2911
+ useV2Flow = false
2481
2912
  }) => {
2482
2913
  const [mode, setMode] = useState("verify");
2483
2914
  const [shouldBlockRender, setShouldBlockRender] = useState(false);
@@ -2530,6 +2961,9 @@ const TwoFactorVerifyFlow = ({
2530
2961
  if (!passflow.isTwoFactorVerificationRequired() && TwoFactorLoopPrevention.canRedirect()) {
2531
2962
  return null;
2532
2963
  }
2964
+ if (useV2Flow) {
2965
+ return /* @__PURE__ */ jsx(TwoFactorChallenge, { onSuccess: handleSuccess });
2966
+ }
2533
2967
  return /* @__PURE__ */ jsx(Fragment, { children: mode === "verify" ? /* @__PURE__ */ jsx(
2534
2968
  TwoFactorVerifyForm,
2535
2969
  {
@@ -6408,5 +6842,5 @@ const PassflowProvider = ({
6408
6842
  return /* @__PURE__ */ jsx(PassflowContext.Provider, { value: passflowValue, children: /* @__PURE__ */ jsx(NavigationContext$1.Provider, { value: navigationValue, children: /* @__PURE__ */ jsx(AuthProvider, { children }) }) });
6409
6843
  };
6410
6844
 
6411
- export { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, FieldPassword, FieldPhone, FieldText, ForgotPassword, ForgotPasswordSuccess, Icon, InvitationJoin, Link, PassflowFlow, PassflowProvider, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProvidersBox, ResetPassword, SignIn, SignInForm, SignUp, SignUpForm, Switch, TwoFactorRecoveryForm, TwoFactorSetupForm, TwoFactorSetupMagicLinkFlow, TwoFactorVerifyForm, VerifyChallengeMagicLink, VerifyChallengeOTP, Wrapper, useAppSettings, useAuth, useAuthCloudRedirect, useForgotPassword, useJoinInvite, useLogout, useNavigation, useOutsideClick, usePassflow, usePasswordlessComplete, useProvider, useResetPassword, useSignIn, useSignUp, useTwoFactorManage, useTwoFactorSetup, useTwoFactorSetupMagicLink, useTwoFactorStatus, useTwoFactorVerify, useUserPasskeys };
6845
+ export { Button, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, FieldPassword, FieldPhone, FieldText, ForgotPassword, ForgotPasswordSuccess, Icon, InvitationJoin, Link, PassflowFlow, PassflowProvider, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, ProvidersBox, ResetPassword, SignIn, SignInForm, SignUp, SignUpForm, Switch, TwoFactorChallenge, TwoFactorRecoveryForm, TwoFactorSetupForm, TwoFactorSetupMagicLinkFlow, TwoFactorVerifyForm, VerifyChallengeMagicLink, VerifyChallengeOTP, Wrapper, useAppSettings, useAuth, useAuthCloudRedirect, useForgotPassword, useJoinInvite, useLogout, useNavigation, useOutsideClick, usePassflow, usePasswordlessComplete, useProvider, useResetPassword, useSessionExpired, useSignIn, useSignUp, useTwoFactorChallenge, useTwoFactorManage, useTwoFactorMethods, useTwoFactorSetup, useTwoFactorSetupMagicLink, useTwoFactorStatus, useTwoFactorVerify, useUserPasskeys };
6412
6846
  //# sourceMappingURL=index.es.js.map