@burdenoff/microfe-auth 2026.925.1 → 2026.1005.1

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 (159) hide show
  1. package/dist/auth/AuthRoot.d.ts +0 -1
  2. package/dist/auth/AuthRoot.js.map +1 -1
  3. package/dist/auth/AuthRoutes.d.ts +1 -1
  4. package/dist/auth/AuthRoutes.js.map +1 -1
  5. package/dist/auth/components/AuthIcons.d.ts +12 -13
  6. package/dist/auth/components/AuthIcons.js.map +1 -1
  7. package/dist/auth/components/AuthLayout.d.ts +1 -2
  8. package/dist/auth/components/AuthLayout.js.map +1 -1
  9. package/dist/auth/components/CaptchaV2.d.ts +1 -1
  10. package/dist/auth/components/CaptchaV2.js +2 -2
  11. package/dist/auth/components/CaptchaV2.js.map +1 -1
  12. package/dist/auth/components/ConfirmActionDialog.d.ts +1 -1
  13. package/dist/auth/components/ConfirmActionDialog.js.map +1 -1
  14. package/dist/auth/components/profile/UserProfileMenu.d.ts +1 -1
  15. package/dist/auth/components/profile/UserProfileMenu.js.map +1 -1
  16. package/dist/auth/components/workspace/WorkspaceSelector.d.ts +1 -2
  17. package/dist/auth/components/workspace/WorkspaceSelector.js.map +1 -1
  18. package/dist/auth/constants/permissions.js.map +1 -1
  19. package/dist/auth/hooks/useAccountOperations.d.ts +0 -1
  20. package/dist/auth/hooks/useAccountOperations.js.map +1 -1
  21. package/dist/auth/hooks/useActiveContextBootstrapMirror.js.map +1 -1
  22. package/dist/auth/hooks/useApiKeyOperations.d.ts +1 -2
  23. package/dist/auth/hooks/useAppOperations.d.ts +1 -2
  24. package/dist/auth/hooks/useAuthOperations.d.ts +0 -1
  25. package/dist/auth/hooks/useAuthOperations.js.map +1 -1
  26. package/dist/auth/hooks/useAuthPermissions.js.map +1 -1
  27. package/dist/auth/hooks/useCaptchaV3.js +1 -1
  28. package/dist/auth/hooks/useCaptchaV3.js.map +1 -1
  29. package/dist/auth/hooks/useContextSwitcherData.d.ts +1 -1
  30. package/dist/auth/hooks/useContextSwitcherData.js +356 -234
  31. package/dist/auth/hooks/useContextSwitcherData.js.map +1 -1
  32. package/dist/auth/hooks/useDelegationOperations.d.ts +0 -1
  33. package/dist/auth/hooks/useMfaOperations.d.ts +0 -1
  34. package/dist/auth/hooks/useMfaOperations.js.map +1 -1
  35. package/dist/auth/hooks/useMyWorkspaces.d.ts +0 -1
  36. package/dist/auth/hooks/useMyWorkspaces.js.map +1 -1
  37. package/dist/auth/hooks/useOAuthOperations.d.ts +0 -1
  38. package/dist/auth/hooks/useOAuthOperations.js +2 -2
  39. package/dist/auth/hooks/useOAuthOperations.js.map +1 -1
  40. package/dist/auth/hooks/usePasswordOperations.d.ts +0 -1
  41. package/dist/auth/hooks/usePasswordOperations.js.map +1 -1
  42. package/dist/auth/hooks/useSessionOperations.d.ts +0 -1
  43. package/dist/auth/hooks/useSessionOperations.js.map +1 -1
  44. package/dist/auth/hooks/useSignupCaptcha.js +1 -1
  45. package/dist/auth/hooks/useSignupCaptcha.js.map +1 -1
  46. package/dist/auth/hooks/useSsoOperations.d.ts +0 -1
  47. package/dist/auth/hooks/useSsoOperations.js.map +1 -1
  48. package/dist/auth/hooks/useTokenRefresh.js.map +1 -1
  49. package/dist/auth/hooks/useUserOperations.d.ts +0 -1
  50. package/dist/auth/hooks/useUserOperations.js.map +1 -1
  51. package/dist/auth/hooks/useWorkspaceOperations.d.ts +0 -1
  52. package/dist/auth/hooks/useWorkspaceOperations.js.map +1 -1
  53. package/dist/auth/hooks/useWorkspaceToken.js.map +1 -1
  54. package/dist/auth/pages/AuditLogPage.d.ts +1 -1
  55. package/dist/auth/pages/AuditLogPage.js.map +1 -1
  56. package/dist/auth/pages/EmailVerifyPage.d.ts +1 -1
  57. package/dist/auth/pages/EmailVerifyPage.js.map +1 -1
  58. package/dist/auth/pages/LoginPage.d.ts +1 -1
  59. package/dist/auth/pages/LoginPage.js.map +1 -1
  60. package/dist/auth/pages/MagicLinkPage.d.ts +1 -1
  61. package/dist/auth/pages/MagicLinkPage.js.map +1 -1
  62. package/dist/auth/pages/MfaSetupPage.d.ts +1 -1
  63. package/dist/auth/pages/MfaSetupPage.js +88 -88
  64. package/dist/auth/pages/MfaSetupPage.js.map +1 -1
  65. package/dist/auth/pages/MfaVerifyPage.d.ts +1 -1
  66. package/dist/auth/pages/MfaVerifyPage.js.map +1 -1
  67. package/dist/auth/pages/OAuthCallbackPage.d.ts +1 -1
  68. package/dist/auth/pages/OAuthCallbackPage.js.map +1 -1
  69. package/dist/auth/pages/PasswordResetPage.d.ts +1 -1
  70. package/dist/auth/pages/PasswordResetPage.js.map +1 -1
  71. package/dist/auth/pages/ReactivatePage.d.ts +1 -1
  72. package/dist/auth/pages/ReactivatePage.js.map +1 -1
  73. package/dist/auth/pages/RegisterPage.d.ts +1 -1
  74. package/dist/auth/pages/RegisterPage.js.map +1 -1
  75. package/dist/auth/pages/SSOClearPage.d.ts +1 -1
  76. package/dist/auth/pages/SSOClearPage.js.map +1 -1
  77. package/dist/auth/pages/SSODepositPage.d.ts +1 -1
  78. package/dist/auth/pages/SSODepositPage.js.map +1 -1
  79. package/dist/auth/pages/SSORelayCallbackPage.d.ts +1 -1
  80. package/dist/auth/pages/SSORelayCallbackPage.js.map +1 -1
  81. package/dist/auth/pages/SSORelayPage.d.ts +1 -1
  82. package/dist/auth/pages/SSORelayPage.js.map +1 -1
  83. package/dist/auth/pages/SecurityPage.d.ts +1 -1
  84. package/dist/auth/pages/SecurityPage.js.map +1 -1
  85. package/dist/auth/pages/SessionBridgePage.d.ts +1 -1
  86. package/dist/auth/pages/SessionBridgePage.js.map +1 -1
  87. package/dist/auth/pages/SessionsPage.d.ts +1 -1
  88. package/dist/auth/pages/SessionsPage.js.map +1 -1
  89. package/dist/auth/pages/SsoCallbackPage.d.ts +1 -1
  90. package/dist/auth/pages/SsoCallbackPage.js.map +1 -1
  91. package/dist/auth/pages/SsoConfigPage.d.ts +1 -1
  92. package/dist/auth/pages/SsoConfigPage.js.map +1 -1
  93. package/dist/auth/pages/SsoLoginPage.d.ts +1 -1
  94. package/dist/auth/pages/SsoLoginPage.js.map +1 -1
  95. package/dist/auth/pages/UserDetailsPage.d.ts +1 -1
  96. package/dist/auth/pages/UserDetailsPage.js.map +1 -1
  97. package/dist/auth/pages/UserProfilePage.d.ts +1 -1
  98. package/dist/auth/pages/UserProfilePage.js.map +1 -1
  99. package/dist/auth/pages/UsersPage.d.ts +1 -1
  100. package/dist/auth/pages/UsersPage.js.map +1 -1
  101. package/dist/auth/providers/AuthProvider.d.ts +0 -1
  102. package/dist/auth/providers/AuthProvider.js.map +1 -1
  103. package/dist/auth/providers/CaptchaProvider.d.ts +1 -2
  104. package/dist/auth/providers/CaptchaProvider.js +2 -2
  105. package/dist/auth/providers/CaptchaProvider.js.map +1 -1
  106. package/dist/auth/store/authStore.d.ts +0 -1
  107. package/dist/auth/store/authStore.js.map +1 -1
  108. package/dist/auth/types/index.d.ts +0 -1
  109. package/dist/auth/utils/captchaConfig.js.map +1 -1
  110. package/dist/auth/utils/formatters.js.map +1 -1
  111. package/dist/auth/utils/gatewayBaseUrls.js.map +1 -1
  112. package/dist/auth/utils/legalUrls.js.map +1 -1
  113. package/dist/auth/utils/redirect.js.map +1 -1
  114. package/dist/auth/utils/ssoOrigins.js.map +1 -1
  115. package/dist/auth/utils/validation.d.ts +0 -1
  116. package/dist/auth/utils/validation.js.map +1 -1
  117. package/dist/dev/main.d.ts +0 -1
  118. package/dist/generated/global-operations.js.map +1 -1
  119. package/dist/generated/wspace-operations.js.map +1 -1
  120. package/dist/index.d.ts +0 -1
  121. package/dist/shared/hooks/useTr.js.map +1 -1
  122. package/dist/shared/types/index.d.ts +0 -1
  123. package/dist/translations/en.js.map +1 -1
  124. package/package.json +27 -20
  125. package/dist/_virtual/_rolldown/runtime.js +0 -13
  126. package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js +0 -70
  127. package/dist/node_modules/hoist-non-react-statics/dist/hoist-non-react-statics.cjs.js.map +0 -1
  128. package/dist/node_modules/object-assign/index.js +0 -41
  129. package/dist/node_modules/object-assign/index.js.map +0 -1
  130. package/dist/node_modules/prop-types/checkPropTypes.js +0 -46
  131. package/dist/node_modules/prop-types/checkPropTypes.js.map +0 -1
  132. package/dist/node_modules/prop-types/factoryWithThrowingShims.js +0 -49
  133. package/dist/node_modules/prop-types/factoryWithThrowingShims.js.map +0 -1
  134. package/dist/node_modules/prop-types/factoryWithTypeCheckers.js +0 -272
  135. package/dist/node_modules/prop-types/factoryWithTypeCheckers.js.map +0 -1
  136. package/dist/node_modules/prop-types/index.js +0 -16
  137. package/dist/node_modules/prop-types/index.js.map +0 -1
  138. package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js +0 -10
  139. package/dist/node_modules/prop-types/lib/ReactPropTypesSecret.js.map +0 -1
  140. package/dist/node_modules/prop-types/lib/has.js +0 -10
  141. package/dist/node_modules/prop-types/lib/has.js.map +0 -1
  142. package/dist/node_modules/qrcode.react/lib/esm/index.js +0 -959
  143. package/dist/node_modules/qrcode.react/lib/esm/index.js.map +0 -1
  144. package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js +0 -114
  145. package/dist/node_modules/react-async-script/lib/esm/async-script-loader.js.map +0 -1
  146. package/dist/node_modules/react-google-recaptcha/lib/esm/index.js +0 -8
  147. package/dist/node_modules/react-google-recaptcha/lib/esm/index.js.map +0 -1
  148. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js +0 -20
  149. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha-wrapper.js.map +0 -1
  150. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js +0 -148
  151. package/dist/node_modules/react-google-recaptcha/lib/esm/recaptcha.js.map +0 -1
  152. package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js +0 -445
  153. package/dist/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.esm.js.map +0 -1
  154. package/dist/node_modules/react-is/cjs/react-is.development.js +0 -84
  155. package/dist/node_modules/react-is/cjs/react-is.development.js.map +0 -1
  156. package/dist/node_modules/react-is/cjs/react-is.production.min.js +0 -64
  157. package/dist/node_modules/react-is/cjs/react-is.production.min.js.map +0 -1
  158. package/dist/node_modules/react-is/index.js +0 -12
  159. package/dist/node_modules/react-is/index.js.map +0 -1
@@ -3,26 +3,26 @@ import { useTr as t } from "../../shared/hooks/useTr.js";
3
3
  import { AlertIcon as n, SpinnerIcon as r } from "../components/AuthIcons.js";
4
4
  import { useMfaOperations as i } from "../hooks/useMfaOperations.js";
5
5
  import { ConfirmActionDialog as a } from "../components/ConfirmActionDialog.js";
6
- import { QRCodeSVG as o } from "../../node_modules/qrcode.react/lib/esm/index.js";
7
- import { nativeCopyText as s, nativeImpact as c, nativeNotify as l } from "../../utils/nativeBridge.js";
8
- import { useState as u } from "react";
9
- import { useNavigate as d } from "react-router";
10
- import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
11
- import { Button as h } from "@burdenoff/fe-libs/button";
12
- import { NextSteps as g, PagePurpose as _ } from "@burdenoff/fe-libs/ui";
6
+ import { nativeCopyText as o, nativeImpact as s, nativeNotify as c } from "../../utils/nativeBridge.js";
7
+ import { useState as l } from "react";
8
+ import { useNavigate as u } from "react-router";
9
+ import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
10
+ import { Button as m } from "@burdenoff/fe-libs/button";
11
+ import { NextSteps as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
12
+ import { QRCodeSVG as _ } from "qrcode.react";
13
13
  //#region src/auth/pages/MfaSetupPage.tsx
14
14
  function v() {
15
- let v = t(), y = d(), { setupMFA: b, enableMFA: x, disableMFA: S, isLoading: C } = i(), w = e((e) => e.user), T = e((e) => e.isAuthenticated), [E, D] = u(null), [O, k] = u(""), [A, j] = u(null), [M, N] = u(null), [P, F] = u(!1), [I, L] = u(!1), R = async (e) => {
15
+ let v = t(), y = u(), { setupMFA: b, enableMFA: x, disableMFA: S, isLoading: C } = i(), w = e((e) => e.user), T = e((e) => e.isAuthenticated), [E, D] = l(null), [O, k] = l(""), [A, j] = l(null), [M, N] = l(null), [P, F] = l(!1), [I, L] = l(!1), R = async (e) => {
16
16
  try {
17
17
  j(null), N(null), D(await b(e));
18
18
  } catch (e) {
19
19
  console.error("Failed to setup MFA:", e), j(e instanceof Error ? e.message : "Failed to setup MFA. Please try again.");
20
20
  }
21
21
  };
22
- return T ? /* @__PURE__ */ m("div", {
22
+ return T ? /* @__PURE__ */ p("div", {
23
23
  className: "max-w-2xl mx-auto p-6",
24
24
  children: [
25
- /* @__PURE__ */ p(a, {
25
+ /* @__PURE__ */ f(a, {
26
26
  open: I,
27
27
  onOpenChange: L,
28
28
  title: v("auth.mfaSetup.disableTitle", "Disable two-factor authentication?"),
@@ -38,52 +38,52 @@ function v() {
38
38
  }
39
39
  }
40
40
  }),
41
- /* @__PURE__ */ m("div", {
41
+ /* @__PURE__ */ p("div", {
42
42
  className: "mb-8",
43
43
  children: [
44
- /* @__PURE__ */ p("h1", {
44
+ /* @__PURE__ */ f("h1", {
45
45
  className: "text-3xl font-semibold text-[var(--color-text-primary)]",
46
46
  children: v("auth.mfaSetup.title", "Two-Factor Authentication")
47
47
  }),
48
- /* @__PURE__ */ p("p", {
48
+ /* @__PURE__ */ f("p", {
49
49
  className: "text-[var(--color-text-secondary)] mt-2",
50
50
  children: v("auth.mfaSetup.subtitle", "Add an extra layer of security to your account")
51
51
  }),
52
- /* @__PURE__ */ p(_, {
52
+ /* @__PURE__ */ f(g, {
53
53
  className: "mt-3",
54
54
  children: v("auth.mfaSetup.purpose", "Two-factor authentication (2FA) asks for a one-time code from an authenticator app at sign-in, so your account stays safe even if your password leaks. Set it up here and keep your backup codes somewhere safe.")
55
55
  })
56
56
  ]
57
57
  }),
58
- M && /* @__PURE__ */ p("div", {
58
+ M && /* @__PURE__ */ f("div", {
59
59
  className: "mb-6 p-4 rounded-xl bg-[var(--color-status-success-bg-subtle)] border border-[var(--color-status-success-border)]",
60
- children: /* @__PURE__ */ m("div", {
60
+ children: /* @__PURE__ */ p("div", {
61
61
  className: "flex items-center gap-3",
62
- children: [/* @__PURE__ */ p("svg", {
62
+ children: [/* @__PURE__ */ f("svg", {
63
63
  className: "size-5 text-[var(--color-status-success-text)]",
64
64
  fill: "none",
65
65
  viewBox: "0 0 24 24",
66
66
  stroke: "currentColor",
67
- children: /* @__PURE__ */ p("path", {
67
+ children: /* @__PURE__ */ f("path", {
68
68
  strokeLinecap: "round",
69
69
  strokeLinejoin: "round",
70
70
  strokeWidth: 2,
71
71
  d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
72
72
  })
73
- }), /* @__PURE__ */ p("p", {
73
+ }), /* @__PURE__ */ f("p", {
74
74
  className: "text-[var(--color-status-success-text)]",
75
75
  children: M
76
76
  })]
77
77
  })
78
78
  }),
79
- A && /* @__PURE__ */ m("div", {
79
+ A && /* @__PURE__ */ p("div", {
80
80
  className: "mb-6 flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]",
81
- children: [/* @__PURE__ */ p(n, { className: "size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5" }), /* @__PURE__ */ m("div", {
81
+ children: [/* @__PURE__ */ f(n, { className: "size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5" }), /* @__PURE__ */ p("div", {
82
82
  className: "flex-1",
83
- children: [/* @__PURE__ */ p("p", {
83
+ children: [/* @__PURE__ */ f("p", {
84
84
  className: "text-sm text-[var(--color-status-error-text)]",
85
85
  children: A
86
- }), /* @__PURE__ */ p("button", {
86
+ }), /* @__PURE__ */ f("button", {
87
87
  type: "button",
88
88
  onClick: () => j(null),
89
89
  className: "mt-2 text-sm text-[var(--color-status-error-text)] hover:underline transition-colors duration-200",
@@ -91,39 +91,39 @@ function v() {
91
91
  })]
92
92
  })]
93
93
  }),
94
- E ? /* @__PURE__ */ m("div", {
94
+ E ? /* @__PURE__ */ p("div", {
95
95
  className: "p-6 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-sm",
96
- children: [/* @__PURE__ */ m("div", {
96
+ children: [/* @__PURE__ */ p("div", {
97
97
  className: "flex items-center gap-3 mb-6",
98
- children: [/* @__PURE__ */ p("div", {
98
+ children: [/* @__PURE__ */ f("div", {
99
99
  className: "size-10 rounded-full bg-[var(--color-bg-accent)] flex items-center justify-center",
100
- children: /* @__PURE__ */ p("svg", {
100
+ children: /* @__PURE__ */ f("svg", {
101
101
  className: "size-5 text-[var(--color-text-link)]",
102
102
  fill: "none",
103
103
  viewBox: "0 0 24 24",
104
104
  stroke: "currentColor",
105
- children: /* @__PURE__ */ p("path", {
105
+ children: /* @__PURE__ */ f("path", {
106
106
  strokeLinecap: "round",
107
107
  strokeLinejoin: "round",
108
108
  strokeWidth: 2,
109
109
  d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
110
110
  })
111
111
  })
112
- }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h2", {
112
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h2", {
113
113
  className: "text-xl font-semibold text-[var(--color-text-primary)]",
114
114
  children: v("auth.mfaSetup.setupAuthApp", "Setup Authenticator App")
115
- }), /* @__PURE__ */ p("p", {
115
+ }), /* @__PURE__ */ f("p", {
116
116
  className: "text-sm text-[var(--color-text-secondary)]",
117
117
  children: v("auth.mfaSetup.scanQr", "Scan the QR code with your authenticator app")
118
118
  })] })]
119
- }), /* @__PURE__ */ m("div", {
119
+ }), /* @__PURE__ */ p("div", {
120
120
  className: "space-y-6",
121
121
  children: [
122
- E.qrCode && /* @__PURE__ */ p("div", {
122
+ E.qrCode && /* @__PURE__ */ f("div", {
123
123
  className: "flex justify-center",
124
- children: /* @__PURE__ */ p("div", {
124
+ children: /* @__PURE__ */ f("div", {
125
125
  className: "p-4 bg-[var(--color-bg-surface)] rounded-xl border border-[var(--color-border-default)]",
126
- children: /* @__PURE__ */ p(o, {
126
+ children: /* @__PURE__ */ f(_, {
127
127
  value: E.qrCode,
128
128
  size: 192,
129
129
  level: "M",
@@ -132,40 +132,40 @@ function v() {
132
132
  })
133
133
  })
134
134
  }),
135
- E.secret && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("p", {
135
+ E.secret && /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("p", {
136
136
  className: "text-sm text-[var(--color-text-secondary)] mb-2",
137
137
  children: v("auth.mfaSetup.cantScan", "Can't scan the QR code? Enter this key manually:")
138
- }), /* @__PURE__ */ p("code", {
138
+ }), /* @__PURE__ */ f("code", {
139
139
  className: "block p-3 rounded-lg bg-[var(--color-bg-muted)] text-[var(--color-text-primary)] font-mono text-sm break-all select-all",
140
140
  children: E.secret
141
141
  })] }),
142
- E.backupCodes && E.backupCodes.length > 0 && /* @__PURE__ */ m("div", {
142
+ E.backupCodes && E.backupCodes.length > 0 && /* @__PURE__ */ p("div", {
143
143
  className: "p-4 rounded-xl bg-[var(--color-status-warning-bg-subtle)] border border-[var(--color-status-warning-border)]",
144
144
  children: [
145
- /* @__PURE__ */ m("div", {
145
+ /* @__PURE__ */ p("div", {
146
146
  className: "flex items-start gap-3 mb-3",
147
- children: [/* @__PURE__ */ p("svg", {
147
+ children: [/* @__PURE__ */ f("svg", {
148
148
  className: "size-5 text-[var(--color-status-warning-text)] flex-shrink-0 mt-0.5",
149
149
  fill: "none",
150
150
  viewBox: "0 0 24 24",
151
151
  stroke: "currentColor",
152
- children: /* @__PURE__ */ p("path", {
152
+ children: /* @__PURE__ */ f("path", {
153
153
  strokeLinecap: "round",
154
154
  strokeLinejoin: "round",
155
155
  strokeWidth: 2,
156
156
  d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
157
157
  })
158
- }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h3", {
158
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h3", {
159
159
  className: "font-medium text-[var(--color-status-warning-text)]",
160
160
  children: v("auth.mfaSetup.saveBackupCodes", "Save your backup codes")
161
- }), /* @__PURE__ */ p("p", {
161
+ }), /* @__PURE__ */ f("p", {
162
162
  className: "text-sm text-[var(--color-status-warning-text)]",
163
163
  children: v("auth.mfaSetup.storeCodesSafely", "Store these codes safely. You can use them to access your account if you lose your authenticator device.")
164
164
  })] })]
165
165
  }),
166
- /* @__PURE__ */ p("div", {
166
+ /* @__PURE__ */ f("div", {
167
167
  className: "p-3 rounded-lg bg-[var(--color-bg-surface)] grid grid-cols-2 gap-2 mb-3",
168
- children: E.backupCodes.map((e, t) => /* @__PURE__ */ m("code", {
168
+ children: E.backupCodes.map((e, t) => /* @__PURE__ */ p("code", {
169
169
  className: "text-sm text-[var(--color-text-primary)] font-mono",
170
170
  children: [
171
171
  t + 1,
@@ -174,21 +174,21 @@ function v() {
174
174
  ]
175
175
  }, e))
176
176
  }),
177
- /* @__PURE__ */ p("button", {
177
+ /* @__PURE__ */ f("button", {
178
178
  type: "button",
179
179
  onClick: async () => {
180
- E?.backupCodes && (c("light"), await s(E.backupCodes.join("\n")) ? (F(!0), l("success"), setTimeout(() => F(!1), 2e3)) : l("error"));
180
+ E?.backupCodes && (s("light"), await o(E.backupCodes.join("\n")) ? (F(!0), c("success"), setTimeout(() => F(!1), 2e3)) : c("error"));
181
181
  },
182
182
  className: "text-sm font-medium text-[var(--color-status-warning-text)] hover:underline transition-colors duration-200",
183
183
  children: P ? v("auth.mfaSetup.copied", "Copied!") : v("auth.mfaSetup.copyBackupCodes", "Copy backup codes")
184
184
  })
185
185
  ]
186
186
  }),
187
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("label", {
187
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("label", {
188
188
  htmlFor: "mfa-verification-code",
189
189
  className: "block text-sm font-medium text-[var(--color-text-primary)] mb-2",
190
190
  children: v("auth.mfaSetup.enterCode", "Enter the 6-digit code from your app")
191
- }), /* @__PURE__ */ p("input", {
191
+ }), /* @__PURE__ */ f("input", {
192
192
  id: "mfa-verification-code",
193
193
  type: "text",
194
194
  inputMode: "numeric",
@@ -201,16 +201,16 @@ function v() {
201
201
  autoComplete: "one-time-code",
202
202
  className: "block w-full px-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] text-center text-2xl tracking-widest font-mono focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all duration-300"
203
203
  })] }),
204
- /* @__PURE__ */ m("div", {
204
+ /* @__PURE__ */ p("div", {
205
205
  className: "flex gap-3",
206
- children: [/* @__PURE__ */ p("button", {
206
+ children: [/* @__PURE__ */ f("button", {
207
207
  type: "button",
208
208
  onClick: () => {
209
209
  D(null), k(""), j(null);
210
210
  },
211
211
  className: "flex-1 py-3 px-4 rounded-xl border border-[var(--color-border-default)] text-[var(--color-text-secondary)] font-medium hover:bg-[var(--color-bg-muted)] transition-colors duration-200",
212
212
  children: v("auth.mfaSetup.cancel", "Cancel")
213
- }), /* @__PURE__ */ p(h, {
213
+ }), /* @__PURE__ */ f(m, {
214
214
  type: "button",
215
215
  onClick: async () => {
216
216
  if (O.length !== 6) {
@@ -227,53 +227,53 @@ function v() {
227
227
  variant: "default",
228
228
  size: "lg",
229
229
  className: "flex-1 font-semibold",
230
- children: C ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(r, { className: "size-5 animate-spin" }), /* @__PURE__ */ p("span", { children: v("auth.mfa.verifying", "Verifying...") })] }) : v("auth.mfaSetup.enable2fa", "Enable 2FA")
230
+ children: C ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(r, { className: "size-5 animate-spin" }), /* @__PURE__ */ f("span", { children: v("auth.mfa.verifying", "Verifying...") })] }) : v("auth.mfaSetup.enable2fa", "Enable 2FA")
231
231
  })]
232
232
  })
233
233
  ]
234
234
  })]
235
- }) : /* @__PURE__ */ p("div", {
235
+ }) : /* @__PURE__ */ f("div", {
236
236
  className: "p-6 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-sm",
237
- children: w?.mfaEnabled ? /* @__PURE__ */ m(f, { children: [
238
- /* @__PURE__ */ m("div", {
237
+ children: w?.mfaEnabled ? /* @__PURE__ */ p(d, { children: [
238
+ /* @__PURE__ */ p("div", {
239
239
  className: "flex items-center gap-4 mb-6",
240
- children: [/* @__PURE__ */ p("div", {
240
+ children: [/* @__PURE__ */ f("div", {
241
241
  className: "size-12 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center",
242
- children: /* @__PURE__ */ p("svg", {
242
+ children: /* @__PURE__ */ f("svg", {
243
243
  className: "size-6 text-[var(--color-status-success-text)]",
244
244
  fill: "none",
245
245
  viewBox: "0 0 24 24",
246
246
  stroke: "currentColor",
247
- children: /* @__PURE__ */ p("path", {
247
+ children: /* @__PURE__ */ f("path", {
248
248
  strokeLinecap: "round",
249
249
  strokeLinejoin: "round",
250
250
  strokeWidth: 2,
251
251
  d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
252
252
  })
253
253
  })
254
- }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h2", {
254
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h2", {
255
255
  className: "text-xl font-semibold text-[var(--color-text-primary)]",
256
256
  children: v("auth.mfaSetup.twoFactorOn", "Two-Factor Authentication is On")
257
- }), /* @__PURE__ */ p("p", {
257
+ }), /* @__PURE__ */ f("p", {
258
258
  className: "text-[var(--color-text-secondary)]",
259
259
  children: v("auth.mfaSetup.protected", "Your account is protected with an authenticator app")
260
260
  })] })]
261
261
  }),
262
- /* @__PURE__ */ p("div", {
262
+ /* @__PURE__ */ f("div", {
263
263
  className: "mb-6 p-4 rounded-lg bg-[var(--color-status-success-bg-subtle)] border border-[var(--color-status-success-border)]",
264
- children: /* @__PURE__ */ p("p", {
264
+ children: /* @__PURE__ */ f("p", {
265
265
  className: "text-sm text-[var(--color-status-success-text)]",
266
266
  children: v("auth.mfaSetup.verificationOnSignIn", "You'll be asked for a verification code from your authenticator app when signing in.")
267
267
  })
268
268
  }),
269
- /* @__PURE__ */ p("button", {
269
+ /* @__PURE__ */ f("button", {
270
270
  type: "button",
271
271
  onClick: () => L(!0),
272
272
  disabled: C,
273
273
  className: "w-full py-3 px-4 rounded-xl border border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] font-medium bg-[var(--color-bg-surface)] hover:bg-[var(--color-status-error-bg-subtle)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2",
274
- children: C ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(r, { className: "size-5 animate-spin" }), /* @__PURE__ */ p("span", { children: v("auth.mfa.disabling", "Disabling...") })] }) : v("auth.mfaSetup.disableTwoFactor", "Disable Two-Factor Authentication")
274
+ children: C ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(r, { className: "size-5 animate-spin" }), /* @__PURE__ */ f("span", { children: v("auth.mfa.disabling", "Disabling...") })] }) : v("auth.mfaSetup.disableTwoFactor", "Disable Two-Factor Authentication")
275
275
  }),
276
- /* @__PURE__ */ p(g, {
276
+ /* @__PURE__ */ f(h, {
277
277
  className: "mt-6",
278
278
  storageKey: "auth-mfa-enabled",
279
279
  steps: [
@@ -297,82 +297,82 @@ function v() {
297
297
  }
298
298
  ]
299
299
  })
300
- ] }) : /* @__PURE__ */ m(f, { children: [
301
- /* @__PURE__ */ m("div", {
300
+ ] }) : /* @__PURE__ */ p(d, { children: [
301
+ /* @__PURE__ */ p("div", {
302
302
  className: "flex items-center gap-4 mb-6",
303
- children: [/* @__PURE__ */ p("div", {
303
+ children: [/* @__PURE__ */ f("div", {
304
304
  className: "size-12 rounded-full bg-[var(--color-bg-muted)] flex items-center justify-center",
305
- children: /* @__PURE__ */ p("svg", {
305
+ children: /* @__PURE__ */ f("svg", {
306
306
  className: "size-6 text-[var(--color-text-tertiary)]",
307
307
  fill: "none",
308
308
  viewBox: "0 0 24 24",
309
309
  stroke: "currentColor",
310
- children: /* @__PURE__ */ p("path", {
310
+ children: /* @__PURE__ */ f("path", {
311
311
  strokeLinecap: "round",
312
312
  strokeLinejoin: "round",
313
313
  strokeWidth: 2,
314
314
  d: "M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z"
315
315
  })
316
316
  })
317
- }), /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h2", {
317
+ }), /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ f("h2", {
318
318
  className: "text-xl font-semibold text-[var(--color-text-primary)]",
319
319
  children: v("auth.mfaSetup.twoFactorOff", "Two-Factor Authentication is Off")
320
- }), /* @__PURE__ */ p("p", {
320
+ }), /* @__PURE__ */ f("p", {
321
321
  className: "text-[var(--color-text-secondary)]",
322
322
  children: v("auth.mfaSetup.notProtected", "Your account is not protected with 2FA")
323
323
  })] })]
324
324
  }),
325
- /* @__PURE__ */ m("div", {
325
+ /* @__PURE__ */ p("div", {
326
326
  className: "mb-6 p-4 rounded-lg bg-[var(--color-bg-accent)] border border-[var(--color-border-default)]",
327
- children: [/* @__PURE__ */ p("h3", {
327
+ children: [/* @__PURE__ */ f("h3", {
328
328
  className: "font-medium text-[var(--color-text-link)] mb-2",
329
329
  children: v("auth.mfaSetup.whyEnable", "Why enable 2FA?")
330
- }), /* @__PURE__ */ m("ul", {
330
+ }), /* @__PURE__ */ p("ul", {
331
331
  className: "text-sm text-[var(--color-text-link)] space-y-1",
332
332
  children: [
333
- /* @__PURE__ */ p("li", { children: "• Protects your account even if your password is compromised" }),
334
- /* @__PURE__ */ p("li", { children: "• Adds a second verification step during sign-in" }),
335
- /* @__PURE__ */ p("li", { children: "• Works with popular authenticator apps (Google, Authy, etc.)" })
333
+ /* @__PURE__ */ f("li", { children: "• Protects your account even if your password is compromised" }),
334
+ /* @__PURE__ */ f("li", { children: "• Adds a second verification step during sign-in" }),
335
+ /* @__PURE__ */ f("li", { children: "• Works with popular authenticator apps (Google, Authy, etc.)" })
336
336
  ]
337
337
  })]
338
338
  }),
339
- /* @__PURE__ */ p(h, {
339
+ /* @__PURE__ */ f(m, {
340
340
  type: "button",
341
341
  onClick: () => R("TOTP"),
342
342
  disabled: C,
343
343
  variant: "default",
344
344
  size: "lg",
345
345
  className: "w-full font-semibold",
346
- children: C ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(r, { className: "size-5 animate-spin" }), /* @__PURE__ */ p("span", { children: v("auth.mfa.settingUp", "Setting up...") })] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("svg", {
346
+ children: C ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(r, { className: "size-5 animate-spin" }), /* @__PURE__ */ f("span", { children: v("auth.mfa.settingUp", "Setting up...") })] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("svg", {
347
347
  className: "size-5",
348
348
  fill: "none",
349
349
  viewBox: "0 0 24 24",
350
350
  stroke: "currentColor",
351
- children: /* @__PURE__ */ p("path", {
351
+ children: /* @__PURE__ */ f("path", {
352
352
  strokeLinecap: "round",
353
353
  strokeLinejoin: "round",
354
354
  strokeWidth: 2,
355
355
  d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
356
356
  })
357
- }), /* @__PURE__ */ p("span", { children: v("auth.mfaSetup.enableTwoFactor", "Enable Two-Factor Authentication") })] })
357
+ }), /* @__PURE__ */ f("span", { children: v("auth.mfaSetup.enableTwoFactor", "Enable Two-Factor Authentication") })] })
358
358
  })
359
359
  ] })
360
360
  })
361
361
  ]
362
- }) : /* @__PURE__ */ p("div", {
362
+ }) : /* @__PURE__ */ f("div", {
363
363
  className: "max-w-2xl mx-auto p-6",
364
- children: /* @__PURE__ */ m("div", {
364
+ children: /* @__PURE__ */ p("div", {
365
365
  className: "text-center py-16 border-2 border-dashed border-border-default rounded-xl",
366
366
  children: [
367
- /* @__PURE__ */ p("div", {
367
+ /* @__PURE__ */ f("div", {
368
368
  className: "size-16 mx-auto mb-4 rounded-full bg-status-warning-bg-subtle flex items-center justify-center",
369
- children: /* @__PURE__ */ p(n, { className: "size-8 text-status-warning-text" })
369
+ children: /* @__PURE__ */ f(n, { className: "size-8 text-status-warning-text" })
370
370
  }),
371
- /* @__PURE__ */ p("h2", {
371
+ /* @__PURE__ */ f("h2", {
372
372
  className: "text-xl font-semibold text-text-primary mb-2",
373
373
  children: v("auth.mfaSetup.authRequired", "Authentication Required")
374
374
  }),
375
- /* @__PURE__ */ p("p", {
375
+ /* @__PURE__ */ f("p", {
376
376
  className: "text-text-secondary",
377
377
  children: v("auth.mfaSetup.signInToManage", "Please sign in to manage MFA settings")
378
378
  })
@@ -1 +1 @@
1
- {"version":3,"file":"MfaSetupPage.js","names":[],"sources":["../../../src/auth/pages/MfaSetupPage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useNavigate } from \"react-router\";\nimport { useTr } from \"../../shared/hooks/useTr\";\nimport { Button } from \"@burdenoff/fe-libs/button\";\nimport { PagePurpose, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { useMfaOperations } from \"../hooks/useMfaOperations\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { ConfirmActionDialog } from \"../components/ConfirmActionDialog\";\nimport { SpinnerIcon, AlertIcon } from \"../components/AuthIcons\";\nimport type { MFAMethod, MFASetupResult } from \"../types\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\n\n/**\n * MFA setup and management page with professional UI\n */\nexport function MfaSetupPage() {\n const tr = useTr();\n\n const navigate = useNavigate();\n const { setupMFA, enableMFA, disableMFA, isLoading } = useMfaOperations();\n const user = useAuthStore((state) => state.user);\n const isAuthenticated = useAuthStore((state) => state.isAuthenticated);\n const [setupData, setSetupData] = useState<MFASetupResult | null>(null);\n const [verificationCode, setVerificationCode] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [backupCodesCopied, setBackupCodesCopied] = useState(false);\n const [showDisableDialog, setShowDisableDialog] = useState(false);\n\n const handleSetupMfa = async (method: MFAMethod) => {\n try {\n setError(null);\n setSuccessMessage(null);\n const data = await setupMFA(method);\n setSetupData(data);\n } catch (err) {\n console.error(\"Failed to setup MFA:\", err);\n setError(\n err instanceof Error\n ? err.message\n : \"Failed to setup MFA. Please try again.\",\n );\n }\n };\n\n const handleVerifyAndEnable = async () => {\n if (verificationCode.length !== 6) {\n setError(tr(\"auth.mfaSetup.enter6Digit\", \"Please enter a 6-digit code\"));\n return;\n }\n\n try {\n setError(null);\n const success = await enableMFA(verificationCode);\n if (success) {\n setSetupData(null);\n setVerificationCode(\"\");\n setSuccessMessage(\n tr(\n \"auth.mfaSetup.enableSuccess\",\n \"Two-factor authentication has been enabled successfully!\",\n ),\n );\n }\n } catch (err) {\n console.error(\"Failed to verify MFA code:\", err);\n setError(\n err instanceof Error\n ? err.message\n : \"Invalid verification code. Please try again.\",\n );\n }\n };\n\n const handleDisableMfa = async () => {\n try {\n setError(null);\n setSuccessMessage(null);\n await disableMFA();\n setSuccessMessage(\n tr(\n \"auth.mfaSetup.disableSuccess\",\n \"Two-factor authentication has been disabled.\",\n ),\n );\n setShowDisableDialog(false);\n } catch (err) {\n console.error(\"Failed to disable MFA:\", err);\n setError(\n err instanceof Error\n ? err.message\n : \"Failed to disable MFA. Please try again.\",\n );\n }\n };\n\n const copyBackupCodes = async () => {\n if (setupData?.backupCodes) {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(setupData.backupCodes.join(\"\\n\"));\n if (ok) {\n setBackupCodesCopied(true);\n void nativeNotify(\"success\");\n setTimeout(() => setBackupCodesCopied(false), 2000);\n } else {\n void nativeNotify(\"error\");\n }\n }\n };\n\n const cancelSetup = () => {\n setSetupData(null);\n setVerificationCode(\"\");\n setError(null);\n };\n\n // Authentication check\n if (!isAuthenticated) {\n return (\n <div className=\"max-w-2xl mx-auto p-6\">\n <div className=\"text-center py-16 border-2 border-dashed border-border-default rounded-xl\">\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-status-warning-bg-subtle flex items-center justify-center\">\n <AlertIcon className=\"size-8 text-status-warning-text\" />\n </div>\n <h2 className=\"text-xl font-semibold text-text-primary mb-2\">\n {tr(\"auth.mfaSetup.authRequired\", \"Authentication Required\")}\n </h2>\n <p className=\"text-text-secondary\">\n {tr(\n \"auth.mfaSetup.signInToManage\",\n \"Please sign in to manage MFA settings\",\n )}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"max-w-2xl mx-auto p-6\">\n <ConfirmActionDialog\n open={showDisableDialog}\n onOpenChange={setShowDisableDialog}\n title={tr(\n \"auth.mfaSetup.disableTitle\",\n \"Disable two-factor authentication?\",\n )}\n description={tr(\n \"auth.mfaSetup.disableDesc\",\n \"Your account will become less secure and future sign-ins will only require your password until MFA is re-enabled.\",\n )}\n confirmText={tr(\"auth.mfaSetup.disableConfirm\", \"Disable MFA\")}\n variant=\"warning\"\n isPending={isLoading}\n onConfirm={handleDisableMfa}\n />\n {/* Header */}\n <div className=\"mb-8\">\n <h1 className=\"text-3xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\"auth.mfaSetup.title\", \"Two-Factor Authentication\")}\n </h1>\n <p className=\"text-[var(--color-text-secondary)] mt-2\">\n {tr(\n \"auth.mfaSetup.subtitle\",\n \"Add an extra layer of security to your account\",\n )}\n </p>\n <PagePurpose className=\"mt-3\">\n {tr(\n \"auth.mfaSetup.purpose\",\n \"Two-factor authentication (2FA) asks for a one-time code from an authenticator app at sign-in, so your account stays safe even if your password leaks. Set it up here and keep your backup codes somewhere safe.\",\n )}\n </PagePurpose>\n </div>\n\n {/* Success Message */}\n {successMessage && (\n <div className=\"mb-6 p-4 rounded-xl bg-[var(--color-status-success-bg-subtle)] border border-[var(--color-status-success-border)]\">\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"size-5 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <p className=\"text-[var(--color-status-success-text)]\">\n {successMessage}\n </p>\n </div>\n </div>\n )}\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <AlertIcon className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1\">\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n <button\n type=\"button\"\n onClick={() => setError(null)}\n className=\"mt-2 text-sm text-[var(--color-status-error-text)] hover:underline transition-colors duration-200\"\n >\n {tr(\"auth.mfaSetup.dismiss\", \"Dismiss\")}\n </button>\n </div>\n </div>\n )}\n\n {setupData ? (\n /* Setup Flow */\n <div className=\"p-6 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-sm\">\n <div className=\"flex items-center gap-3 mb-6\">\n <div className=\"size-10 rounded-full bg-[var(--color-bg-accent)] flex items-center justify-center\">\n <svg\n className=\"size-5 text-[var(--color-text-link)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <div>\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\"auth.mfaSetup.setupAuthApp\", \"Setup Authenticator App\")}\n </h2>\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.mfaSetup.scanQr\",\n \"Scan the QR code with your authenticator app\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"space-y-6\">\n {/* QR Code */}\n {setupData.qrCode && (\n <div className=\"flex justify-center\">\n <div className=\"p-4 bg-[var(--color-bg-surface)] rounded-xl border border-[var(--color-border-default)]\">\n <QRCodeSVG\n value={setupData.qrCode}\n size={192}\n level=\"M\"\n includeMargin={false}\n className=\"size-48\"\n />\n </div>\n </div>\n )}\n\n {/* Manual Secret */}\n {setupData.secret && (\n <div>\n <p className=\"text-sm text-[var(--color-text-secondary)] mb-2\">\n {tr(\n \"auth.mfaSetup.cantScan\",\n \"Can't scan the QR code? Enter this key manually:\",\n )}\n </p>\n <code className=\"block p-3 rounded-lg bg-[var(--color-bg-muted)] text-[var(--color-text-primary)] font-mono text-sm break-all select-all\">\n {setupData.secret}\n </code>\n </div>\n )}\n\n {/* Backup Codes */}\n {setupData.backupCodes && setupData.backupCodes.length > 0 && (\n <div className=\"p-4 rounded-xl bg-[var(--color-status-warning-bg-subtle)] border border-[var(--color-status-warning-border)]\">\n <div className=\"flex items-start gap-3 mb-3\">\n <svg\n className=\"size-5 text-[var(--color-status-warning-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <div>\n <h3 className=\"font-medium text-[var(--color-status-warning-text)]\">\n {tr(\n \"auth.mfaSetup.saveBackupCodes\",\n \"Save your backup codes\",\n )}\n </h3>\n <p className=\"text-sm text-[var(--color-status-warning-text)]\">\n {tr(\n \"auth.mfaSetup.storeCodesSafely\",\n \"Store these codes safely. You can use them to access your account if you lose your authenticator device.\",\n )}\n </p>\n </div>\n </div>\n <div className=\"p-3 rounded-lg bg-[var(--color-bg-surface)] grid grid-cols-2 gap-2 mb-3\">\n {setupData.backupCodes.map((code, i) => (\n <code\n key={code}\n className=\"text-sm text-[var(--color-text-primary)] font-mono\"\n >\n {i + 1}. {code}\n </code>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={copyBackupCodes}\n className=\"text-sm font-medium text-[var(--color-status-warning-text)] hover:underline transition-colors duration-200\"\n >\n {backupCodesCopied\n ? tr(\"auth.mfaSetup.copied\", \"Copied!\")\n : tr(\"auth.mfaSetup.copyBackupCodes\", \"Copy backup codes\")}\n </button>\n </div>\n )}\n\n {/* Verification Code Input */}\n <div>\n <label\n htmlFor=\"mfa-verification-code\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)] mb-2\"\n >\n {tr(\n \"auth.mfaSetup.enterCode\",\n \"Enter the 6-digit code from your app\",\n )}\n </label>\n <input\n id=\"mfa-verification-code\"\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={6}\n value={verificationCode}\n onChange={(e) =>\n setVerificationCode(e.target.value.replace(/\\D/g, \"\"))\n }\n placeholder={tr(\n \"auth.mfa.verificationCodePlaceholder\",\n \"000000\",\n )}\n aria-label={tr(\n \"auth.mfaSetup.enterCode\",\n \"Enter the 6-digit code from your app\",\n )}\n aria-required=\"true\"\n autoComplete=\"one-time-code\"\n className=\"block w-full px-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] text-center text-2xl tracking-widest font-mono focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all duration-300\"\n />\n </div>\n\n {/* Action Buttons */}\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={cancelSetup}\n className=\"flex-1 py-3 px-4 rounded-xl border border-[var(--color-border-default)] text-[var(--color-text-secondary)] font-medium hover:bg-[var(--color-bg-muted)] transition-colors duration-200\"\n >\n {tr(\"auth.mfaSetup.cancel\", \"Cancel\")}\n </button>\n <Button\n type=\"button\"\n onClick={handleVerifyAndEnable}\n disabled={isLoading || verificationCode.length !== 6}\n variant=\"default\"\n size=\"lg\"\n className=\"flex-1 font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.mfa.verifying\", \"Verifying...\")}</span>\n </>\n ) : (\n tr(\"auth.mfaSetup.enable2fa\", \"Enable 2FA\")\n )}\n </Button>\n </div>\n </div>\n </div>\n ) : (\n /* Status Display */\n <div className=\"p-6 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-sm\">\n {!user?.mfaEnabled ? (\n /* MFA Not Enabled */\n <>\n <div className=\"flex items-center gap-4 mb-6\">\n <div className=\"size-12 rounded-full bg-[var(--color-bg-muted)] flex items-center justify-center\">\n <svg\n className=\"size-6 text-[var(--color-text-tertiary)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\"\n />\n </svg>\n </div>\n <div>\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\n \"auth.mfaSetup.twoFactorOff\",\n \"Two-Factor Authentication is Off\",\n )}\n </h2>\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.mfaSetup.notProtected\",\n \"Your account is not protected with 2FA\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"mb-6 p-4 rounded-lg bg-[var(--color-bg-accent)] border border-[var(--color-border-default)]\">\n <h3 className=\"font-medium text-[var(--color-text-link)] mb-2\">\n {tr(\"auth.mfaSetup.whyEnable\", \"Why enable 2FA?\")}\n </h3>\n <ul className=\"text-sm text-[var(--color-text-link)] space-y-1\">\n <li>\n • Protects your account even if your password is compromised\n </li>\n <li>• Adds a second verification step during sign-in</li>\n <li>\n • Works with popular authenticator apps (Google, Authy,\n etc.)\n </li>\n </ul>\n </div>\n\n <Button\n type=\"button\"\n onClick={() => handleSetupMfa(\"TOTP\")}\n disabled={isLoading}\n variant=\"default\"\n size=\"lg\"\n className=\"w-full font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.mfa.settingUp\", \"Setting up...\")}</span>\n </>\n ) : (\n <>\n <svg\n className=\"size-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n <span>\n {tr(\n \"auth.mfaSetup.enableTwoFactor\",\n \"Enable Two-Factor Authentication\",\n )}\n </span>\n </>\n )}\n </Button>\n </>\n ) : (\n /* MFA Enabled */\n <>\n <div className=\"flex items-center gap-4 mb-6\">\n <div className=\"size-12 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center\">\n <svg\n className=\"size-6 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\"\n />\n </svg>\n </div>\n <div>\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\n \"auth.mfaSetup.twoFactorOn\",\n \"Two-Factor Authentication is On\",\n )}\n </h2>\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.mfaSetup.protected\",\n \"Your account is protected with an authenticator app\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"mb-6 p-4 rounded-lg bg-[var(--color-status-success-bg-subtle)] border border-[var(--color-status-success-border)]\">\n <p className=\"text-sm text-[var(--color-status-success-text)]\">\n {tr(\n \"auth.mfaSetup.verificationOnSignIn\",\n \"You'll be asked for a verification code from your authenticator app when signing in.\",\n )}\n </p>\n </div>\n\n <button\n type=\"button\"\n onClick={() => setShowDisableDialog(true)}\n disabled={isLoading}\n className=\"w-full py-3 px-4 rounded-xl border border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] font-medium bg-[var(--color-bg-surface)] hover:bg-[var(--color-status-error-bg-subtle)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.mfa.disabling\", \"Disabling...\")}</span>\n </>\n ) : (\n tr(\n \"auth.mfaSetup.disableTwoFactor\",\n \"Disable Two-Factor Authentication\",\n )\n )}\n </button>\n\n <NextSteps\n className=\"mt-6\"\n storageKey=\"auth-mfa-enabled\"\n steps={[\n {\n id: \"review-sessions\",\n label: tr(\n \"auth.mfaSetup.nextReviewSessions\",\n \"Review your active sessions\",\n ),\n description: tr(\n \"auth.mfaSetup.nextReviewSessionsDesc\",\n \"Sign out any device you no longer recognise.\",\n ),\n onClick: () => navigate(\"/auth/sessions\"),\n },\n {\n id: \"security-center\",\n label: tr(\n \"auth.mfaSetup.nextSecurityCenter\",\n \"Visit the Security Center\",\n ),\n description: tr(\n \"auth.mfaSetup.nextSecurityCenterDesc\",\n \"Check your password and account protection at a glance.\",\n ),\n onClick: () => navigate(\"/auth/security\"),\n },\n {\n id: \"update-profile\",\n label: tr(\n \"auth.mfaSetup.nextProfile\",\n \"Keep your profile up to date\",\n ),\n description: tr(\n \"auth.mfaSetup.nextProfileDesc\",\n \"Confirm your recovery email and contact details.\",\n ),\n onClick: () => navigate(\"/auth/profile\"),\n },\n ]}\n />\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MfaSetupPage.js","names":[],"sources":["../../../src/auth/pages/MfaSetupPage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useNavigate } from \"react-router\";\nimport { useTr } from \"../../shared/hooks/useTr\";\nimport { Button } from \"@burdenoff/fe-libs/button\";\nimport { PagePurpose, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { QRCodeSVG } from \"qrcode.react\";\nimport { useMfaOperations } from \"../hooks/useMfaOperations\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { ConfirmActionDialog } from \"../components/ConfirmActionDialog\";\nimport { SpinnerIcon, AlertIcon } from \"../components/AuthIcons\";\nimport type { MFAMethod, MFASetupResult } from \"../types\";\nimport {\n nativeCopyText,\n nativeImpact,\n nativeNotify,\n} from \"../../utils/nativeBridge\";\n\n/**\n * MFA setup and management page with professional UI\n */\nexport function MfaSetupPage() {\n const tr = useTr();\n\n const navigate = useNavigate();\n const { setupMFA, enableMFA, disableMFA, isLoading } = useMfaOperations();\n const user = useAuthStore((state) => state.user);\n const isAuthenticated = useAuthStore((state) => state.isAuthenticated);\n const [setupData, setSetupData] = useState<MFASetupResult | null>(null);\n const [verificationCode, setVerificationCode] = useState(\"\");\n const [error, setError] = useState<string | null>(null);\n const [successMessage, setSuccessMessage] = useState<string | null>(null);\n const [backupCodesCopied, setBackupCodesCopied] = useState(false);\n const [showDisableDialog, setShowDisableDialog] = useState(false);\n\n const handleSetupMfa = async (method: MFAMethod) => {\n try {\n setError(null);\n setSuccessMessage(null);\n const data = await setupMFA(method);\n setSetupData(data);\n } catch (err) {\n console.error(\"Failed to setup MFA:\", err);\n setError(\n err instanceof Error\n ? err.message\n : \"Failed to setup MFA. Please try again.\",\n );\n }\n };\n\n const handleVerifyAndEnable = async () => {\n if (verificationCode.length !== 6) {\n setError(tr(\"auth.mfaSetup.enter6Digit\", \"Please enter a 6-digit code\"));\n return;\n }\n\n try {\n setError(null);\n const success = await enableMFA(verificationCode);\n if (success) {\n setSetupData(null);\n setVerificationCode(\"\");\n setSuccessMessage(\n tr(\n \"auth.mfaSetup.enableSuccess\",\n \"Two-factor authentication has been enabled successfully!\",\n ),\n );\n }\n } catch (err) {\n console.error(\"Failed to verify MFA code:\", err);\n setError(\n err instanceof Error\n ? err.message\n : \"Invalid verification code. Please try again.\",\n );\n }\n };\n\n const handleDisableMfa = async () => {\n try {\n setError(null);\n setSuccessMessage(null);\n await disableMFA();\n setSuccessMessage(\n tr(\n \"auth.mfaSetup.disableSuccess\",\n \"Two-factor authentication has been disabled.\",\n ),\n );\n setShowDisableDialog(false);\n } catch (err) {\n console.error(\"Failed to disable MFA:\", err);\n setError(\n err instanceof Error\n ? err.message\n : \"Failed to disable MFA. Please try again.\",\n );\n }\n };\n\n const copyBackupCodes = async () => {\n if (setupData?.backupCodes) {\n void nativeImpact(\"light\");\n const ok = await nativeCopyText(setupData.backupCodes.join(\"\\n\"));\n if (ok) {\n setBackupCodesCopied(true);\n void nativeNotify(\"success\");\n setTimeout(() => setBackupCodesCopied(false), 2000);\n } else {\n void nativeNotify(\"error\");\n }\n }\n };\n\n const cancelSetup = () => {\n setSetupData(null);\n setVerificationCode(\"\");\n setError(null);\n };\n\n // Authentication check\n if (!isAuthenticated) {\n return (\n <div className=\"max-w-2xl mx-auto p-6\">\n <div className=\"text-center py-16 border-2 border-dashed border-border-default rounded-xl\">\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-status-warning-bg-subtle flex items-center justify-center\">\n <AlertIcon className=\"size-8 text-status-warning-text\" />\n </div>\n <h2 className=\"text-xl font-semibold text-text-primary mb-2\">\n {tr(\"auth.mfaSetup.authRequired\", \"Authentication Required\")}\n </h2>\n <p className=\"text-text-secondary\">\n {tr(\n \"auth.mfaSetup.signInToManage\",\n \"Please sign in to manage MFA settings\",\n )}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"max-w-2xl mx-auto p-6\">\n <ConfirmActionDialog\n open={showDisableDialog}\n onOpenChange={setShowDisableDialog}\n title={tr(\n \"auth.mfaSetup.disableTitle\",\n \"Disable two-factor authentication?\",\n )}\n description={tr(\n \"auth.mfaSetup.disableDesc\",\n \"Your account will become less secure and future sign-ins will only require your password until MFA is re-enabled.\",\n )}\n confirmText={tr(\"auth.mfaSetup.disableConfirm\", \"Disable MFA\")}\n variant=\"warning\"\n isPending={isLoading}\n onConfirm={handleDisableMfa}\n />\n {/* Header */}\n <div className=\"mb-8\">\n <h1 className=\"text-3xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\"auth.mfaSetup.title\", \"Two-Factor Authentication\")}\n </h1>\n <p className=\"text-[var(--color-text-secondary)] mt-2\">\n {tr(\n \"auth.mfaSetup.subtitle\",\n \"Add an extra layer of security to your account\",\n )}\n </p>\n <PagePurpose className=\"mt-3\">\n {tr(\n \"auth.mfaSetup.purpose\",\n \"Two-factor authentication (2FA) asks for a one-time code from an authenticator app at sign-in, so your account stays safe even if your password leaks. Set it up here and keep your backup codes somewhere safe.\",\n )}\n </PagePurpose>\n </div>\n\n {/* Success Message */}\n {successMessage && (\n <div className=\"mb-6 p-4 rounded-xl bg-[var(--color-status-success-bg-subtle)] border border-[var(--color-status-success-border)]\">\n <div className=\"flex items-center gap-3\">\n <svg\n className=\"size-5 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <p className=\"text-[var(--color-status-success-text)]\">\n {successMessage}\n </p>\n </div>\n </div>\n )}\n\n {/* Error Message */}\n {error && (\n <div className=\"mb-6 flex items-start gap-3 p-4 rounded-xl bg-[var(--color-status-error-bg-subtle)] border border-[var(--color-status-error-border)]\">\n <AlertIcon className=\"size-5 text-[var(--color-status-error-text)] flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1\">\n <p className=\"text-sm text-[var(--color-status-error-text)]\">\n {error}\n </p>\n <button\n type=\"button\"\n onClick={() => setError(null)}\n className=\"mt-2 text-sm text-[var(--color-status-error-text)] hover:underline transition-colors duration-200\"\n >\n {tr(\"auth.mfaSetup.dismiss\", \"Dismiss\")}\n </button>\n </div>\n </div>\n )}\n\n {setupData ? (\n /* Setup Flow */\n <div className=\"p-6 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-sm\">\n <div className=\"flex items-center gap-3 mb-6\">\n <div className=\"size-10 rounded-full bg-[var(--color-bg-accent)] flex items-center justify-center\">\n <svg\n className=\"size-5 text-[var(--color-text-link)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <div>\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\"auth.mfaSetup.setupAuthApp\", \"Setup Authenticator App\")}\n </h2>\n <p className=\"text-sm text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.mfaSetup.scanQr\",\n \"Scan the QR code with your authenticator app\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"space-y-6\">\n {/* QR Code */}\n {setupData.qrCode && (\n <div className=\"flex justify-center\">\n <div className=\"p-4 bg-[var(--color-bg-surface)] rounded-xl border border-[var(--color-border-default)]\">\n <QRCodeSVG\n value={setupData.qrCode}\n size={192}\n level=\"M\"\n includeMargin={false}\n className=\"size-48\"\n />\n </div>\n </div>\n )}\n\n {/* Manual Secret */}\n {setupData.secret && (\n <div>\n <p className=\"text-sm text-[var(--color-text-secondary)] mb-2\">\n {tr(\n \"auth.mfaSetup.cantScan\",\n \"Can't scan the QR code? Enter this key manually:\",\n )}\n </p>\n <code className=\"block p-3 rounded-lg bg-[var(--color-bg-muted)] text-[var(--color-text-primary)] font-mono text-sm break-all select-all\">\n {setupData.secret}\n </code>\n </div>\n )}\n\n {/* Backup Codes */}\n {setupData.backupCodes && setupData.backupCodes.length > 0 && (\n <div className=\"p-4 rounded-xl bg-[var(--color-status-warning-bg-subtle)] border border-[var(--color-status-warning-border)]\">\n <div className=\"flex items-start gap-3 mb-3\">\n <svg\n className=\"size-5 text-[var(--color-status-warning-text)] flex-shrink-0 mt-0.5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n <div>\n <h3 className=\"font-medium text-[var(--color-status-warning-text)]\">\n {tr(\n \"auth.mfaSetup.saveBackupCodes\",\n \"Save your backup codes\",\n )}\n </h3>\n <p className=\"text-sm text-[var(--color-status-warning-text)]\">\n {tr(\n \"auth.mfaSetup.storeCodesSafely\",\n \"Store these codes safely. You can use them to access your account if you lose your authenticator device.\",\n )}\n </p>\n </div>\n </div>\n <div className=\"p-3 rounded-lg bg-[var(--color-bg-surface)] grid grid-cols-2 gap-2 mb-3\">\n {setupData.backupCodes.map((code, i) => (\n <code\n key={code}\n className=\"text-sm text-[var(--color-text-primary)] font-mono\"\n >\n {i + 1}. {code}\n </code>\n ))}\n </div>\n <button\n type=\"button\"\n onClick={copyBackupCodes}\n className=\"text-sm font-medium text-[var(--color-status-warning-text)] hover:underline transition-colors duration-200\"\n >\n {backupCodesCopied\n ? tr(\"auth.mfaSetup.copied\", \"Copied!\")\n : tr(\"auth.mfaSetup.copyBackupCodes\", \"Copy backup codes\")}\n </button>\n </div>\n )}\n\n {/* Verification Code Input */}\n <div>\n <label\n htmlFor=\"mfa-verification-code\"\n className=\"block text-sm font-medium text-[var(--color-text-primary)] mb-2\"\n >\n {tr(\n \"auth.mfaSetup.enterCode\",\n \"Enter the 6-digit code from your app\",\n )}\n </label>\n <input\n id=\"mfa-verification-code\"\n type=\"text\"\n inputMode=\"numeric\"\n maxLength={6}\n value={verificationCode}\n onChange={(e) =>\n setVerificationCode(e.target.value.replace(/\\D/g, \"\"))\n }\n placeholder={tr(\n \"auth.mfa.verificationCodePlaceholder\",\n \"000000\",\n )}\n aria-label={tr(\n \"auth.mfaSetup.enterCode\",\n \"Enter the 6-digit code from your app\",\n )}\n aria-required=\"true\"\n autoComplete=\"one-time-code\"\n className=\"block w-full px-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] text-center text-2xl tracking-widest font-mono focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all duration-300\"\n />\n </div>\n\n {/* Action Buttons */}\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={cancelSetup}\n className=\"flex-1 py-3 px-4 rounded-xl border border-[var(--color-border-default)] text-[var(--color-text-secondary)] font-medium hover:bg-[var(--color-bg-muted)] transition-colors duration-200\"\n >\n {tr(\"auth.mfaSetup.cancel\", \"Cancel\")}\n </button>\n <Button\n type=\"button\"\n onClick={handleVerifyAndEnable}\n disabled={isLoading || verificationCode.length !== 6}\n variant=\"default\"\n size=\"lg\"\n className=\"flex-1 font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.mfa.verifying\", \"Verifying...\")}</span>\n </>\n ) : (\n tr(\"auth.mfaSetup.enable2fa\", \"Enable 2FA\")\n )}\n </Button>\n </div>\n </div>\n </div>\n ) : (\n /* Status Display */\n <div className=\"p-6 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] shadow-sm\">\n {!user?.mfaEnabled ? (\n /* MFA Not Enabled */\n <>\n <div className=\"flex items-center gap-4 mb-6\">\n <div className=\"size-12 rounded-full bg-[var(--color-bg-muted)] flex items-center justify-center\">\n <svg\n className=\"size-6 text-[var(--color-text-tertiary)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\"\n />\n </svg>\n </div>\n <div>\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\n \"auth.mfaSetup.twoFactorOff\",\n \"Two-Factor Authentication is Off\",\n )}\n </h2>\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.mfaSetup.notProtected\",\n \"Your account is not protected with 2FA\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"mb-6 p-4 rounded-lg bg-[var(--color-bg-accent)] border border-[var(--color-border-default)]\">\n <h3 className=\"font-medium text-[var(--color-text-link)] mb-2\">\n {tr(\"auth.mfaSetup.whyEnable\", \"Why enable 2FA?\")}\n </h3>\n <ul className=\"text-sm text-[var(--color-text-link)] space-y-1\">\n <li>\n • Protects your account even if your password is compromised\n </li>\n <li>• Adds a second verification step during sign-in</li>\n <li>\n • Works with popular authenticator apps (Google, Authy,\n etc.)\n </li>\n </ul>\n </div>\n\n <Button\n type=\"button\"\n onClick={() => handleSetupMfa(\"TOTP\")}\n disabled={isLoading}\n variant=\"default\"\n size=\"lg\"\n className=\"w-full font-semibold\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.mfa.settingUp\", \"Setting up...\")}</span>\n </>\n ) : (\n <>\n <svg\n className=\"size-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n <span>\n {tr(\n \"auth.mfaSetup.enableTwoFactor\",\n \"Enable Two-Factor Authentication\",\n )}\n </span>\n </>\n )}\n </Button>\n </>\n ) : (\n /* MFA Enabled */\n <>\n <div className=\"flex items-center gap-4 mb-6\">\n <div className=\"size-12 rounded-full bg-[var(--color-status-success-bg-subtle)] flex items-center justify-center\">\n <svg\n className=\"size-6 text-[var(--color-status-success-text)]\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z\"\n />\n </svg>\n </div>\n <div>\n <h2 className=\"text-xl font-semibold text-[var(--color-text-primary)]\">\n {tr(\n \"auth.mfaSetup.twoFactorOn\",\n \"Two-Factor Authentication is On\",\n )}\n </h2>\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr(\n \"auth.mfaSetup.protected\",\n \"Your account is protected with an authenticator app\",\n )}\n </p>\n </div>\n </div>\n\n <div className=\"mb-6 p-4 rounded-lg bg-[var(--color-status-success-bg-subtle)] border border-[var(--color-status-success-border)]\">\n <p className=\"text-sm text-[var(--color-status-success-text)]\">\n {tr(\n \"auth.mfaSetup.verificationOnSignIn\",\n \"You'll be asked for a verification code from your authenticator app when signing in.\",\n )}\n </p>\n </div>\n\n <button\n type=\"button\"\n onClick={() => setShowDisableDialog(true)}\n disabled={isLoading}\n className=\"w-full py-3 px-4 rounded-xl border border-[var(--color-status-error-border)] text-[var(--color-status-error-text)] font-medium bg-[var(--color-bg-surface)] hover:bg-[var(--color-status-error-bg-subtle)] disabled:opacity-50 disabled:cursor-not-allowed transition-colors duration-200 flex items-center justify-center gap-2\"\n >\n {isLoading ? (\n <>\n <SpinnerIcon className=\"size-5 animate-spin\" />\n <span>{tr(\"auth.mfa.disabling\", \"Disabling...\")}</span>\n </>\n ) : (\n tr(\n \"auth.mfaSetup.disableTwoFactor\",\n \"Disable Two-Factor Authentication\",\n )\n )}\n </button>\n\n <NextSteps\n className=\"mt-6\"\n storageKey=\"auth-mfa-enabled\"\n steps={[\n {\n id: \"review-sessions\",\n label: tr(\n \"auth.mfaSetup.nextReviewSessions\",\n \"Review your active sessions\",\n ),\n description: tr(\n \"auth.mfaSetup.nextReviewSessionsDesc\",\n \"Sign out any device you no longer recognise.\",\n ),\n onClick: () => navigate(\"/auth/sessions\"),\n },\n {\n id: \"security-center\",\n label: tr(\n \"auth.mfaSetup.nextSecurityCenter\",\n \"Visit the Security Center\",\n ),\n description: tr(\n \"auth.mfaSetup.nextSecurityCenterDesc\",\n \"Check your password and account protection at a glance.\",\n ),\n onClick: () => navigate(\"/auth/security\"),\n },\n {\n id: \"update-profile\",\n label: tr(\n \"auth.mfaSetup.nextProfile\",\n \"Keep your profile up to date\",\n ),\n description: tr(\n \"auth.mfaSetup.nextProfileDesc\",\n \"Confirm your recovery email and contact details.\",\n ),\n onClick: () => navigate(\"/auth/profile\"),\n },\n ]}\n />\n </>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -3,4 +3,4 @@
3
3
  * Shown when user needs to verify MFA code during login
4
4
  * Handles both regular login MFA and SSO MFA flows
5
5
  */
6
- export declare function MfaVerifyPage(): import("react").JSX.Element;
6
+ export declare function MfaVerifyPage(): import('react').JSX.Element;