@burdenoff/microfe-auth 2026.528.1 → 2026.528.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"useMfaOperations.js","names":[],"sources":["../../../src/auth/hooks/useMfaOperations.ts"],"sourcesContent":["import { useMutation } from \"@apollo/client/react\";\nimport { useEventBus } from \"@burdenoff/fe-libs/shared/events\";\nimport {\n loginProfile,\n type ProfileUser,\n} from \"@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useAuth } from \"../providers/AuthProvider\";\nimport {\n SetupMfaDocument,\n EnableMfaDocument,\n VerifyMfaDocument,\n DisableMfaDocument,\n} from \"../../generated/global-operations\";\nimport type {\n MFAMethod,\n MFASetupResult,\n MFAVerifyInput,\n AuthResult,\n User,\n} from \"../types\";\n\nfunction toProfileUser(user: User): ProfileUser {\n return { ...user };\n}\n\nfunction setShellSsoCookie(userId: string): void {\n try {\n const hostname = window.location.hostname;\n const domain = hostname.endsWith(\".local.burdenoff.com\")\n ? \".local.burdenoff.com\"\n : undefined;\n const domainPart = domain ? `; domain=${domain}` : \"\";\n const securePart = window.location.protocol === \"https:\" ? \"; secure\" : \"\";\n const ssoValue = JSON.stringify({\n id: userId,\n origin: window.location.origin,\n });\n document.cookie = `bf-sso=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n document.cookie = `bf-sso-profile=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n } catch {\n // Best effort only.\n }\n}\n\n// =============================================================================\n// GRAPHQL RESPONSE INTERFACES\n// =============================================================================\n\ninterface SetupMFAResponse {\n setupMFA: MFASetupResult;\n}\n\ninterface SetupMFAVariables {\n method: MFAMethod;\n}\n\ninterface EnableMFAResponse {\n enableMFA: boolean;\n}\n\ninterface EnableMFAVariables {\n code: string;\n}\n\ninterface VerifyMFAResponse {\n verifyMFA: AuthResult;\n}\n\ninterface VerifyMFAVariables {\n input: MFAVerifyInput;\n}\n\ninterface DisableMFAResponse {\n disableMFA: boolean;\n}\n\n// GraphQL Operations\n\n/**\n * Hook for MFA operations\n */\nexport function useMfaOperations() {\n const store = useAuthStore();\n const context = useAuth();\n const eventBus = useEventBus();\n const [setupMfaMutation] = useMutation<SetupMFAResponse, SetupMFAVariables>(\n SetupMfaDocument,\n );\n const [enableMfaMutation] = useMutation<\n EnableMFAResponse,\n EnableMFAVariables\n >(EnableMfaDocument);\n const [verifyMfaMutation] = useMutation<\n VerifyMFAResponse,\n VerifyMFAVariables\n >(VerifyMfaDocument);\n const [disableMfaMutation] =\n useMutation<DisableMFAResponse>(DisableMfaDocument);\n\n /**\n * Setup MFA for the user\n */\n const setupMFA = async (method: MFAMethod): Promise<MFASetupResult> => {\n try {\n store.setLoading(true);\n\n const { data } = await setupMfaMutation({\n variables: { method },\n });\n\n return data!.setupMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA setup failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Enable MFA after setup with verification code\n */\n const enableMFA = async (code: string): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await enableMfaMutation({\n variables: { code },\n });\n\n if (data!.enableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: true });\n }\n\n return data!.enableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to enable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Verify MFA code during login\n */\n const verifyMFA = async (input: MFAVerifyInput): Promise<AuthResult> => {\n try {\n store.setLoading(true);\n\n const { data, error } = await verifyMfaMutation({\n variables: { input },\n });\n\n const result = data?.verifyMFA;\n\n // Server returned no data (GraphQL errors, network failure, or null payload).\n // Surface a friendly message instead of letting `result.success` throw a\n // \"Cannot read properties of null\" error to the UI.\n if (!result) {\n return {\n success: false,\n error:\n error?.message || \"Invalid verification code. Please try again.\",\n } as AuthResult;\n }\n\n if (result.success && result.user && result.token) {\n store.setUser(result.user);\n store.setAuthTokens(result.token, result.refreshToken || \"\");\n store.setAuthenticated(true);\n store.setMfaRequired(false);\n\n const expiresAt = result.expiresIn\n ? Date.now() + result.expiresIn * 1000\n : undefined;\n loginProfile(toProfileUser(result.user), {\n accessToken: result.token,\n refreshToken: result.refreshToken || \"\",\n expiresAt,\n });\n setShellSsoCookie(result.user.id);\n\n eventBus.emit(\n \"auth.signed_in\",\n {\n userId: result.user.id,\n tenantId: result.user.tenantId,\n workspaceId: result.user.defaultWorkspaceId,\n mfaEnabled: result.user.mfaEnabled,\n emailVerified: result.user.emailVerified,\n },\n { component: \"useMfaOperations\" },\n );\n\n context.onAuthSuccess?.(result.user, result.token, result.refreshToken);\n } else {\n console.warn(\n \"[useMfaOperations] NOT saving tokens - condition failed:\",\n {\n success: result.success,\n hasUser: !!result.user,\n hasToken: !!result.token,\n },\n );\n }\n\n return result;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA verification failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Disable MFA\n */\n const disableMFA = async (): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await disableMfaMutation();\n\n if (data!.disableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: false });\n }\n\n return data!.disableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to disable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n // Legacy aliases\n const enableMfa = enableMFA;\n const verifyMfa = verifyMFA;\n const disableMfa = disableMFA;\n\n return {\n setupMFA,\n enableMFA,\n verifyMFA,\n disableMFA,\n // Legacy aliases\n enableMfa,\n verifyMfa,\n disableMfa,\n // State\n mfaRequired: store.mfaRequired,\n mfaChallengeId: store.mfaChallengeId,\n isLoading: store.isLoading,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useMfaOperations.js","names":[],"sources":["../../../src/auth/hooks/useMfaOperations.ts"],"sourcesContent":["import { useMutation } from \"@apollo/client/react\";\nimport { useEventBus } from \"@burdenoff/fe-libs/shared/events\";\nimport {\n loginProfile,\n type ProfileUser,\n} from \"@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useAuth } from \"../providers/AuthProvider\";\nimport {\n SetupMfaDocument,\n EnableMfaDocument,\n VerifyMfaDocument,\n DisableMfaDocument,\n} from \"../../generated/global-operations\";\nimport type {\n MFAMethod,\n MFASetupResult,\n MFAVerifyInput,\n AuthResult,\n User,\n} from \"../types\";\n\nfunction toProfileUser(user: User): ProfileUser {\n return { ...user };\n}\n\nfunction setShellSsoCookie(userId: string): void {\n try {\n const hostname = window.location.hostname;\n const domain = hostname.endsWith(\".local.burdenoff.com\")\n ? \".local.burdenoff.com\"\n : undefined;\n const domainPart = domain ? `; domain=${domain}` : \"\";\n const securePart = window.location.protocol === \"https:\" ? \"; secure\" : \"\";\n const ssoValue = JSON.stringify({\n id: userId,\n origin: window.location.origin,\n });\n document.cookie = `bf-sso=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n document.cookie = `bf-sso-profile=${encodeURIComponent(ssoValue)}${domainPart}; path=/; samesite=lax${securePart}; max-age=86400`;\n } catch {\n // Best effort only.\n }\n}\n\n// =============================================================================\n// GRAPHQL RESPONSE INTERFACES\n// =============================================================================\n\ninterface SetupMFAResponse {\n setupMFA: MFASetupResult;\n}\n\ninterface SetupMFAVariables {\n method: MFAMethod;\n}\n\ninterface EnableMFAResponse {\n enableMFA: boolean;\n}\n\ninterface EnableMFAVariables {\n code: string;\n}\n\ninterface VerifyMFAResponse {\n verifyMFA: AuthResult;\n}\n\ninterface VerifyMFAVariables {\n input: MFAVerifyInput;\n}\n\ninterface DisableMFAResponse {\n disableMFA: boolean;\n}\n\n// GraphQL Operations\n\n/**\n * Hook for MFA operations\n */\nexport function useMfaOperations() {\n const store = useAuthStore();\n const context = useAuth();\n const eventBus = useEventBus();\n const [setupMfaMutation] = useMutation<SetupMFAResponse, SetupMFAVariables>(\n SetupMfaDocument,\n );\n const [enableMfaMutation] = useMutation<\n EnableMFAResponse,\n EnableMFAVariables\n >(EnableMfaDocument);\n const [verifyMfaMutation] = useMutation<\n VerifyMFAResponse,\n VerifyMFAVariables\n >(VerifyMfaDocument);\n const [disableMfaMutation] =\n useMutation<DisableMFAResponse>(DisableMfaDocument);\n\n /**\n * Setup MFA for the user\n */\n const setupMFA = async (method: MFAMethod): Promise<MFASetupResult> => {\n try {\n store.setLoading(true);\n\n const { data } = await setupMfaMutation({\n variables: { method },\n });\n\n return data!.setupMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA setup failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Enable MFA after setup with verification code\n */\n const enableMFA = async (code: string): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await enableMfaMutation({\n variables: { code },\n });\n\n if (data!.enableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: true });\n }\n\n return data!.enableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to enable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Verify MFA code during login\n */\n const verifyMFA = async (input: MFAVerifyInput): Promise<AuthResult> => {\n try {\n store.setLoading(true);\n\n const { data, error } = await verifyMfaMutation({\n variables: { input },\n });\n\n const result = data?.verifyMFA;\n\n // Server returned no data (GraphQL errors, network failure, or null payload).\n // Surface a friendly message instead of letting `result.success` throw a\n // \"Cannot read properties of null\" error to the UI. Apollo Client v4\n // exposes a single `error` (ApolloError) on MutateResult, not an array.\n if (!result) {\n const gqlMessage = error?.message;\n return {\n success: false,\n error: gqlMessage || \"Invalid verification code. Please try again.\",\n } as AuthResult;\n }\n\n if (result.success && result.user && result.token) {\n store.setUser(result.user);\n store.setAuthTokens(result.token, result.refreshToken || \"\");\n store.setAuthenticated(true);\n store.setMfaRequired(false);\n\n const expiresAt = result.expiresIn\n ? Date.now() + result.expiresIn * 1000\n : undefined;\n loginProfile(toProfileUser(result.user), {\n accessToken: result.token,\n refreshToken: result.refreshToken || \"\",\n expiresAt,\n });\n setShellSsoCookie(result.user.id);\n\n eventBus.emit(\n \"auth.signed_in\",\n {\n userId: result.user.id,\n tenantId: result.user.tenantId,\n workspaceId: result.user.defaultWorkspaceId,\n mfaEnabled: result.user.mfaEnabled,\n emailVerified: result.user.emailVerified,\n },\n { component: \"useMfaOperations\" },\n );\n\n context.onAuthSuccess?.(result.user, result.token, result.refreshToken);\n } else {\n console.warn(\n \"[useMfaOperations] NOT saving tokens - condition failed:\",\n {\n success: result.success,\n hasUser: !!result.user,\n hasToken: !!result.token,\n },\n );\n }\n\n return result;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"MFA verification failed:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n /**\n * Disable MFA\n */\n const disableMFA = async (): Promise<boolean> => {\n try {\n store.setLoading(true);\n\n const { data } = await disableMfaMutation();\n\n if (data!.disableMFA && store.user) {\n store.setUser({ ...store.user, mfaEnabled: false });\n }\n\n return data!.disableMFA;\n } catch (error) {\n if (import.meta.env.DEV) {\n console.error(\"Failed to disable MFA:\", error);\n }\n throw error;\n } finally {\n store.setLoading(false);\n }\n };\n\n // Legacy aliases\n const enableMfa = enableMFA;\n const verifyMfa = verifyMFA;\n const disableMfa = disableMFA;\n\n return {\n setupMFA,\n enableMFA,\n verifyMFA,\n disableMFA,\n // Legacy aliases\n enableMfa,\n verifyMfa,\n disableMfa,\n // State\n mfaRequired: store.mfaRequired,\n mfaChallengeId: store.mfaChallengeId,\n isLoading: store.isLoading,\n };\n}\n"],"mappings":"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"}
@@ -4,17 +4,18 @@ import { useAuthOperations as n } from "../hooks/useAuthOperations.js";
4
4
  import { useMyWorkspaces as r } from "../hooks/useMyWorkspaces.js";
5
5
  import { useOAuthOperations as i } from "../hooks/useOAuthOperations.js";
6
6
  import { AuthLayout as a } from "../components/AuthLayout.js";
7
- import { AlertIcon as o, EmailIcon as s, EyeIcon as c, EyeOffIcon as ee, GoogleIcon as l, LockIcon as u, MicrosoftIcon as te, SpinnerIcon as ne } from "../components/AuthIcons.js";
7
+ import { AlertIcon as o, EmailIcon as s, EyeIcon as ee, EyeOffIcon as te, GoogleIcon as c, LockIcon as l, MicrosoftIcon as ne, SpinnerIcon as u } from "../components/AuthIcons.js";
8
8
  import { useCaptchaV3 as re } from "../hooks/useCaptchaV3.js";
9
- import { useCallback as d, useEffect as f, useRef as ie, useState as p } from "react";
10
- import { SSORedirectSpinner as ae, getSSORedirectUrl as oe } from "@burdenoff/fe-libs/shared/components";
11
- import { useLocation as se, useNavigate as ce, useSearchParams as le } from "react-router-dom";
12
- import { useActiveContext as ue, useI18n as de } from "@burdenoff/fe-libs/shared/providers/shell";
9
+ import { MFA_REDIRECT as ie } from "../constants/sessionKeys.js";
10
+ import { useCallback as d, useEffect as f, useRef as ae, useState as p } from "react";
11
+ import { SSORedirectSpinner as oe, getSSORedirectUrl as se } from "@burdenoff/fe-libs/shared/components";
12
+ import { useLocation as ce, useNavigate as le, useSearchParams as ue } from "react-router-dom";
13
+ import { useActiveContext as de, useI18n as fe } from "@burdenoff/fe-libs/shared/providers/shell";
13
14
  import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
14
- import { resolveAuthBridgeConfig as fe } from "@burdenoff/fe-libs/shared/config";
15
- import { getProfileTokens as pe, getProfileUser as me, getProfileWorkspaceToken as he, getProfiles as _, resolveActiveProfileId as v } from "@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager";
15
+ import { resolveAuthBridgeConfig as pe } from "@burdenoff/fe-libs/shared/config";
16
+ import { getProfileTokens as me, getProfileUser as he, getProfileWorkspaceToken as ge, getProfiles as _, resolveActiveProfileId as _e } from "@burdenoff/fe-libs/shared/providers/shell/ProfileStorageManager";
16
17
  //#region src/auth/pages/LoginPage.tsx
17
- function ge() {
18
+ function v() {
18
19
  if (typeof window > "u") return !1;
19
20
  let e = window;
20
21
  if (typeof e.Capacitor?.isNativePlatform == "function") try {
@@ -22,7 +23,7 @@ function ge() {
22
23
  } catch {}
23
24
  return !!(typeof navigator < "u" && /Electron/i.test(navigator.userAgent || ""));
24
25
  }
25
- function _e(e) {
26
+ function ve(e) {
26
27
  if (typeof window > "u") return e;
27
28
  try {
28
29
  let t = new URL(e, window.location.origin);
@@ -31,7 +32,7 @@ function _e(e) {
31
32
  return e;
32
33
  }
33
34
  }
34
- function ve(e) {
35
+ function ye(e) {
35
36
  try {
36
37
  let t = e.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), n = t.padEnd(Math.ceil(t.length / 4) * 4, "="), r = JSON.parse(atob(n));
37
38
  return typeof r.exp == "number" && r.exp > Date.now() / 1e3;
@@ -39,7 +40,7 @@ function ve(e) {
39
40
  return !1;
40
41
  }
41
42
  }
42
- function ye(e) {
43
+ function be(e) {
43
44
  if (!e) return null;
44
45
  try {
45
46
  let t = new URL(decodeURIComponent(e), window.location.origin);
@@ -58,7 +59,7 @@ function y(e, t) {
58
59
  let n = e.searchParams.toString();
59
60
  return `${e.pathname}${n ? `?${n}` : ""}${e.hash}`;
60
61
  }
61
- function be(e) {
62
+ function xe(e) {
62
63
  try {
63
64
  let t = new URL(decodeURIComponent(e), window.location.origin);
64
65
  return y(t, { includeOrigin: t.origin !== window.location.origin });
@@ -67,73 +68,73 @@ function be(e) {
67
68
  }
68
69
  }
69
70
  function b() {
70
- let y = ce(), b = se(), [x] = le(), { t: xe } = de(), S = d((e, t) => {
71
- let n = xe(e);
71
+ let y = le(), b = ce(), [x] = ue(), { t: Se } = fe(), S = d((e, t) => {
72
+ let n = Se(e);
72
73
  return n === e ? t : n;
73
- }, [xe]), { signIn: Se, isLoading: C, error: w, errorCode: T, resendVerification: Ce } = n(), { completeAuthFlow: we } = r(), { setWorkspace: E, setOrganization: D } = ue(), { defaultPostLoginPath: Te } = e(), { initiateGoogleOAuth: Ee, initiateMicrosoftOAuth: De, isProviderConfigured: O } = i(), k = t((e) => e.mfaRequired), { executeRecaptcha: Oe } = re(), [A, j] = p(!1), [ke, Ae] = p(!1), M = d((e) => {
74
- if (typeof window > "u" || ge()) return e;
74
+ }, [Se]), { signIn: Ce, isLoading: C, error: w, errorCode: T, resendVerification: we } = n(), { completeAuthFlow: Te } = r(), { setWorkspace: E, setOrganization: D } = de(), { defaultPostLoginPath: O } = e(), { initiateGoogleOAuth: Ee, initiateMicrosoftOAuth: De, isProviderConfigured: k } = i(), A = t((e) => e.mfaRequired), { executeRecaptcha: Oe } = re(), [j, M] = p(!1), [ke, Ae] = p(!1), N = d((e) => {
75
+ if (typeof window > "u" || v()) return e;
75
76
  try {
76
- let t = fe(), n = new URL(t.url), r = window.location.origin;
77
+ let t = pe(), n = new URL(t.url), r = window.location.origin;
77
78
  if (n.origin === r) return e;
78
- let i = new URL(e, r).href, a = v();
79
+ let i = new URL(e, r).href, a = _e();
79
80
  if (!a) return e;
80
- let o = pe(a), s = me(a);
81
+ let o = me(a), s = he(a);
81
82
  if (!o || !s) return e;
82
- let c = he(a), ee = {
83
+ let ee = ge(a), te = {
83
84
  profileId: a,
84
85
  tokens: JSON.stringify({
85
86
  ...o,
86
- workspaceToken: c
87
+ workspaceToken: ee
87
88
  }),
88
89
  user: JSON.stringify(s),
89
90
  profiles: JSON.stringify(_())
90
- }, l = btoa(JSON.stringify(ee)), u = new URL("/auth/sso-deposit", n.origin);
91
- return u.searchParams.set("returnTo", i), `${u.href}#sso=${l}`;
91
+ }, c = btoa(JSON.stringify(te)), l = new URL("/auth/sso-deposit", n.origin);
92
+ return l.searchParams.set("returnTo", i), `${l.href}#sso=${c}`;
92
93
  } catch {
93
94
  return e;
94
95
  }
95
- }, []), N = d((e) => {
96
+ }, []), P = d((e) => {
96
97
  if (typeof window < "u") {
97
98
  try {
98
99
  sessionStorage.setItem("bf-post-login-return-to", e);
99
100
  } catch {}
100
- if (ge()) {
101
- y(_e(e));
101
+ if (v()) {
102
+ y(ve(e));
102
103
  return;
103
104
  }
104
- window.location.assign(M(e));
105
+ window.location.assign(N(e));
105
106
  return;
106
107
  }
107
108
  y(e);
108
- }, [y, M]), [P, je] = p(!1), [F, I] = p(!1), [Me, L] = p(!1), [Ne, R] = p(!1), [z, B] = p(!1), [V, H] = p(!1), [Pe, Fe] = p(!1), [Ie, U] = p(!1), [Le, W] = p(null), [Re, ze] = p(null), [G, K] = p({
109
+ }, [y, N]), [F, je] = p(!1), [I, L] = p(!1), [Me, R] = p(!1), [Ne, z] = p(!1), [B, V] = p(!1), [H, U] = p(!1), [Pe, Fe] = p(!1), [Ie, W] = p(!1), [Le, G] = p(null), [Re, ze] = p(null), [K, q] = p({
109
110
  email: "",
110
111
  password: "",
111
112
  rememberMe: !1
112
- }), [q, J] = p(null), [Be, Y] = p(!1), X = x.get("mode") === "add-account", Z = x.get("returnTo"), Q = ie(Z);
113
+ }), [J, Y] = p(null), [Be, X] = p(!1), Z = x.get("mode") === "add-account", Q = x.get("returnTo"), $ = ae(Q);
113
114
  f(() => {
114
- !Q.current && Z && (Q.current = Z);
115
- }, [Z]), f(() => {
116
- if (X || A) return;
117
- let e = v();
115
+ !$.current && Q && ($.current = Q);
116
+ }, [Q]), f(() => {
117
+ if (Z || j) return;
118
+ let e = _e();
118
119
  if (e) {
119
- let n = pe(e), r = me(e);
120
- if (n?.accessToken && r && ve(n.accessToken)) {
121
- t.getState().loadFromProfile(e), N(ye(Z) ?? "/");
120
+ let n = me(e), r = he(e);
121
+ if (n?.accessToken && r && ye(n.accessToken)) {
122
+ t.getState().loadFromProfile(e), P(be(Q) ?? "/");
122
123
  return;
123
124
  }
124
125
  }
125
- let n = oe();
126
+ let n = se();
126
127
  n && (Ae(!0), window.location.replace(n));
127
128
  }, [
128
- X,
129
- A,
130
- N,
131
- Z
129
+ Z,
130
+ j,
131
+ P,
132
+ Q
132
133
  ]), f(() => {
133
134
  try {
134
135
  localStorage.removeItem("remembered_password");
135
136
  let e = localStorage.getItem("remembered_email");
136
- e && K((t) => ({
137
+ e && q((t) => ({
137
138
  ...t,
138
139
  email: e,
139
140
  rememberMe: !0
@@ -143,7 +144,7 @@ function b() {
143
144
  }
144
145
  }, []), f(() => {
145
146
  let e = b.state;
146
- e?.message && ze(e.message), e?.email && K((t) => ({
147
+ e?.message && ze(e.message), e?.email && q((t) => ({
147
148
  ...t,
148
149
  email: e.email
149
150
  })), e && window.history.replaceState({}, document.title);
@@ -163,7 +164,7 @@ function b() {
163
164
  };
164
165
  f(() => {
165
166
  let e = x.get("email");
166
- if (e && K((t) => ({
167
+ if (e && q((t) => ({
167
168
  ...t,
168
169
  email: e
169
170
  })), x.get("expired") === "true") {
@@ -172,36 +173,42 @@ function b() {
172
173
  window.history.replaceState({}, document.title, e);
173
174
  }
174
175
  }, [x, S]), f(() => {
175
- k && y("/auth/mfa-verify");
176
- }, [k, y]);
176
+ A && y("/auth/mfa-verify");
177
+ }, [A, y]);
177
178
  let He = async (e) => {
178
- e.preventDefault(), I(!1), L(!1), R(!1), B(!1), H(!1), Y(!1), U(!1), J(null);
179
- let n = (G.email ?? "").trim();
179
+ e.preventDefault(), L(!1), R(!1), z(!1), V(!1), U(!1), X(!1), W(!1), Y(null);
180
+ let n = (K.email ?? "").trim();
180
181
  if (!n) {
181
- J(S("auth.login.enterEmailOrUsername", "Please enter your email or username"));
182
+ Y(S("auth.login.enterEmailOrUsername", "Please enter your email or username"));
182
183
  return;
183
184
  }
184
185
  if (n.includes("@") && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n)) {
185
- J(S("auth.login.invalidEmail", "Please enter a valid email address"));
186
+ Y(S("auth.login.invalidEmail", "Please enter a valid email address"));
186
187
  return;
187
188
  }
188
- if (!G.password || G.password.length < 1) {
189
- J(S("auth.login.enterPassword", "Please enter your password"));
189
+ if (!K.password || K.password.length < 1) {
190
+ Y(S("auth.login.enterPassword", "Please enter your password"));
190
191
  return;
191
192
  }
192
- if (X && _().some((e) => e.email.toLowerCase() === n.toLowerCase())) {
193
- Y(!0), J(null);
193
+ if (Z && _().some((e) => e.email.toLowerCase() === n.toLowerCase())) {
194
+ X(!0), Y(null);
194
195
  return;
195
196
  }
196
- Y(!1);
197
+ X(!1);
197
198
  try {
198
- let e = await Oe("login"), t = await Se({
199
+ let e = await Oe("login"), t = await Ce({
199
200
  email: n,
200
- password: G.password,
201
- rememberMe: G.rememberMe,
201
+ password: K.password,
202
+ rememberMe: K.rememberMe,
202
203
  ...e ? { recaptchaToken: e } : {}
203
204
  });
204
- if (t.requiresMFA) return;
205
+ if (t.requiresMFA) {
206
+ let e = xe($.current || Q || (O ?? "/dashboard"));
207
+ try {
208
+ sessionStorage.setItem(ie, e);
209
+ } catch {}
210
+ return;
211
+ }
205
212
  if (t.success) {
206
213
  try {
207
214
  let e = t.user?.id;
@@ -214,14 +221,14 @@ function b() {
214
221
  }
215
222
  } catch {}
216
223
  try {
217
- G.rememberMe ? localStorage.setItem("remembered_email", n) : localStorage.removeItem("remembered_email");
224
+ K.rememberMe ? localStorage.setItem("remembered_email", n) : localStorage.removeItem("remembered_email");
218
225
  } catch (e) {
219
226
  console.warn("[LoginPage] Failed to save/clear remembered email:", e);
220
227
  }
221
- j(!0);
222
- let e = be(Q.current || Z || (Te ?? "/dashboard"));
228
+ M(!0);
229
+ let e = xe($.current || Q || (O ?? "/dashboard"));
223
230
  try {
224
- let n = await Promise.race([we(t.token), new Promise((e) => {
231
+ let n = await Promise.race([Te(t.token), new Promise((e) => {
225
232
  window.setTimeout(() => {
226
233
  e({
227
234
  success: !1,
@@ -229,63 +236,63 @@ function b() {
229
236
  });
230
237
  }, 5e3);
231
238
  })]);
232
- n.success ? (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)), N(e)) : n.error?.includes("No workspaces found") ? y("/onboarding/create-workspace") : (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)), console.warn("Auth flow warning:", n.error), N(e));
239
+ n.success ? (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)), P(e)) : n.error?.includes("No workspaces found") ? y("/onboarding/create-workspace") : (n.workspace && (E(n.workspace.id), n.workspace.organizationId && D(n.workspace.organizationId)), console.warn("Auth flow warning:", n.error), P(e));
233
240
  } catch (t) {
234
- console.error("Auth flow error (login succeeded):", t), N(e);
241
+ console.error("Auth flow error (login succeeded):", t), P(e);
235
242
  } finally {
236
- j(!1);
243
+ M(!1);
237
244
  }
238
245
  }
239
246
  } catch (e) {
240
247
  let n = e instanceof Error ? e.message : String(e);
241
- n.includes("reCAPTCHA") && J(n);
248
+ n.includes("reCAPTCHA") && Y(n);
242
249
  let r = t.getState().errorCode, i = Ve(n, r);
243
- i === "DELETED" ? L(!0) : i === "SUSPENDED" ? R(!0) : i === "OAUTH_ONLY" ? B(!0) : i === "INACTIVE" ? I(!0) : i === "EMAIL_NOT_VERIFIED" && H(!0);
250
+ i === "DELETED" ? R(!0) : i === "SUSPENDED" ? z(!0) : i === "OAUTH_ONLY" ? V(!0) : i === "INACTIVE" ? L(!0) : i === "EMAIL_NOT_VERIFIED" && U(!0);
244
251
  }
245
252
  };
246
253
  f(() => {
247
254
  if (w) {
248
255
  let e = Ve(w, T);
249
- e === "DELETED" ? L(!0) : e === "SUSPENDED" ? R(!0) : e === "OAUTH_ONLY" ? B(!0) : e === "INACTIVE" ? I(!0) : e === "EMAIL_NOT_VERIFIED" && H(!0);
256
+ e === "DELETED" ? R(!0) : e === "SUSPENDED" ? z(!0) : e === "OAUTH_ONLY" ? V(!0) : e === "INACTIVE" ? L(!0) : e === "EMAIL_NOT_VERIFIED" && U(!0);
250
257
  }
251
258
  }, [w, T]);
252
259
  let Ue = () => {
253
- W(null);
260
+ G(null);
254
261
  try {
255
262
  Ee();
256
263
  } catch (e) {
257
- W(e instanceof Error ? e.message : S("auth.login.googleSignInFailed", "Failed to initiate Google sign in"));
264
+ G(e instanceof Error ? e.message : S("auth.login.googleSignInFailed", "Failed to initiate Google sign in"));
258
265
  }
259
266
  }, We = () => {
260
- W(null);
267
+ G(null);
261
268
  try {
262
269
  De();
263
270
  } catch (e) {
264
- W(e instanceof Error ? e.message : S("auth.login.microsoftSignInFailed", "Failed to initiate Microsoft sign in"));
271
+ G(e instanceof Error ? e.message : S("auth.login.microsoftSignInFailed", "Failed to initiate Microsoft sign in"));
265
272
  }
266
273
  }, Ge = async () => {
267
- Fe(!0), U(!1);
274
+ Fe(!0), W(!1);
268
275
  try {
269
- (await Ce((G.email ?? "").trim())).success ? U(!0) : J(S("auth.login.resendFailed", "Failed to resend verification email. Please try again."));
276
+ (await we((K.email ?? "").trim())).success ? W(!0) : Y(S("auth.login.resendFailed", "Failed to resend verification email. Please try again."));
270
277
  } catch (e) {
271
- console.error("Failed to resend verification email:", e), J(e instanceof Error ? e.message : S("auth.login.resendFailed", "Failed to resend verification email. Please try again."));
278
+ console.error("Failed to resend verification email:", e), Y(e instanceof Error ? e.message : S("auth.login.resendFailed", "Failed to resend verification email. Please try again."));
272
279
  } finally {
273
280
  Fe(!1);
274
281
  }
275
- }, Ke = O("google"), $ = O("microsoft"), qe = [{
282
+ }, Ke = k("google"), qe = k("microsoft"), Je = [{
276
283
  name: "Google",
277
- icon: l,
284
+ icon: c,
278
285
  onClick: Ue,
279
286
  disabled: !Ke,
280
287
  tooltip: Ke ? void 0 : S("auth.login.googleNotConfigured", "Google sign in is not configured")
281
288
  }, {
282
289
  name: "Microsoft",
283
- icon: te,
290
+ icon: ne,
284
291
  onClick: We,
285
- disabled: !$,
286
- tooltip: $ ? void 0 : S("auth.login.microsoftNotConfigured", "Microsoft sign in is not configured")
292
+ disabled: !qe,
293
+ tooltip: qe ? void 0 : S("auth.login.microsoftNotConfigured", "Microsoft sign in is not configured")
287
294
  }];
288
- return ke ? /* @__PURE__ */ h(ae, {}) : /* @__PURE__ */ g(a, {
295
+ return ke ? /* @__PURE__ */ h(oe, {}) : /* @__PURE__ */ g(a, {
289
296
  title: S("auth.login.welcomeBack", "Welcome back"),
290
297
  subtitle: S("auth.login.enterCredentials", "Enter your credentials to continue"),
291
298
  children: [
@@ -311,11 +318,11 @@ function b() {
311
318
  children: Re
312
319
  })]
313
320
  }),
314
- q && /* @__PURE__ */ g("div", {
321
+ J && /* @__PURE__ */ g("div", {
315
322
  className: "flex items-start gap-3 p-4 rounded-xl border bg-status-warning-bg-subtle border-status-warning-border",
316
323
  children: [/* @__PURE__ */ h(o, { className: "size-5 flex-shrink-0 mt-0.5 text-status-warning-text" }), /* @__PURE__ */ h("p", {
317
324
  className: "text-sm text-status-warning-text",
318
- children: q
325
+ children: J
319
326
  })]
320
327
  }),
321
328
  Be && /* @__PURE__ */ g("div", {
@@ -331,9 +338,9 @@ function b() {
331
338
  className: "mt-1 text-sm text-status-warning-text/80",
332
339
  children: S("auth.login.duplicateAccountHint", "Please use a different account, or go back and switch to this account from the profile menu.")
333
340
  }),
334
- (Q.current || Z) && /* @__PURE__ */ g("button", {
341
+ ($.current || Q) && /* @__PURE__ */ g("button", {
335
342
  type: "button",
336
- onClick: () => y(decodeURIComponent(Q.current || Z || "/dashboard")),
343
+ onClick: () => y(decodeURIComponent($.current || Q || "/dashboard")),
337
344
  className: "mt-3 inline-flex items-center gap-2 px-4 py-2.5 rounded-xl border border-status-warning-border bg-bg-surface text-status-warning-text text-sm font-medium hover:bg-status-warning-bg-subtle hover:border-status-warning-border transition-all shadow-sm",
338
345
  children: [/* @__PURE__ */ h("svg", {
339
346
  className: "size-4",
@@ -351,22 +358,22 @@ function b() {
351
358
  ]
352
359
  })]
353
360
  }),
354
- w && !q && !Be && /* @__PURE__ */ g("div", {
355
- className: `flex items-start gap-3 p-4 rounded-xl border ${F || z || V ? "bg-status-warning-bg-subtle border-status-warning-border" : "bg-status-error-bg-subtle border-status-error-border"}`,
356
- children: [/* @__PURE__ */ h(o, { className: `size-5 flex-shrink-0 mt-0.5 ${F || z || V ? "text-status-warning-text" : "text-status-error-text"}` }), /* @__PURE__ */ g("div", {
361
+ w && !J && !Be && /* @__PURE__ */ g("div", {
362
+ className: `flex items-start gap-3 p-4 rounded-xl border ${I || B || H ? "bg-status-warning-bg-subtle border-status-warning-border" : "bg-status-error-bg-subtle border-status-error-border"}`,
363
+ children: [/* @__PURE__ */ h(o, { className: `size-5 flex-shrink-0 mt-0.5 ${I || B || H ? "text-status-warning-text" : "text-status-error-text"}` }), /* @__PURE__ */ g("div", {
357
364
  className: "flex-1",
358
365
  children: [
359
366
  /* @__PURE__ */ h("p", {
360
- className: `text-sm ${F || z || V ? "text-status-warning-text" : "text-status-error-text"}`,
361
- children: Me ? S("auth.login.accountDeleted", "This account has been permanently deleted and cannot be recovered.") : Ne ? S("auth.login.accountSuspended", "Your account has been suspended. Please contact support for assistance.") : F ? S("auth.login.accountDeactivated", "Your account has been deactivated.") : z ? S("auth.login.oauthOnly", "This account uses OAuth sign-in. Please use Google or Microsoft to sign in.") : V ? S("auth.login.emailNotVerified", "Please verify your email before signing in. Check your inbox for the verification link.") : w
367
+ className: `text-sm ${I || B || H ? "text-status-warning-text" : "text-status-error-text"}`,
368
+ children: Me ? S("auth.login.accountDeleted", "This account has been permanently deleted and cannot be recovered.") : Ne ? S("auth.login.accountSuspended", "Your account has been suspended. Please contact support for assistance.") : I ? S("auth.login.accountDeactivated", "Your account has been deactivated.") : B ? S("auth.login.oauthOnly", "This account uses OAuth sign-in. Please use Google or Microsoft to sign in.") : H ? S("auth.login.emailNotVerified", "Please verify your email before signing in. Check your inbox for the verification link.") : w
362
369
  }),
363
- F && /* @__PURE__ */ h("button", {
370
+ I && /* @__PURE__ */ h("button", {
364
371
  type: "button",
365
- onClick: () => y("/auth/reactivate", { state: { email: G.email } }),
372
+ onClick: () => y("/auth/reactivate", { state: { email: K.email } }),
366
373
  className: "mt-2 text-sm font-semibold text-status-warning-text hover:text-status-warning-text underline underline-offset-2",
367
374
  children: S("auth.login.clickReactivate", "Click here to reactivate your account")
368
375
  }),
369
- V && /* @__PURE__ */ h("div", {
376
+ H && /* @__PURE__ */ h("div", {
370
377
  className: "mt-3",
371
378
  children: Ie ? /* @__PURE__ */ g("div", {
372
379
  className: "flex items-center gap-2 text-sm text-status-success-text",
@@ -387,7 +394,7 @@ function b() {
387
394
  onClick: Ge,
388
395
  disabled: Pe,
389
396
  className: "inline-flex items-center gap-2 px-4 py-2.5 rounded-xl border border-status-warning-border bg-bg-surface text-status-warning-text text-sm font-medium hover:bg-status-warning-bg-subtle hover:border-status-warning-border transition-all shadow-sm disabled:opacity-50 disabled:cursor-not-allowed",
390
- children: Pe ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(ne, { className: "size-4 animate-spin" }), S("auth.login.sending", "Sending...")] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("svg", {
397
+ children: Pe ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(u, { className: "size-4 animate-spin" }), S("auth.login.sending", "Sending...")] }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("svg", {
391
398
  className: "size-4",
392
399
  fill: "none",
393
400
  viewBox: "0 0 24 24",
@@ -401,18 +408,18 @@ function b() {
401
408
  }), S("auth.login.resendVerification", "Resend verification email")] })
402
409
  })
403
410
  }),
404
- z && /* @__PURE__ */ g("div", {
411
+ B && /* @__PURE__ */ g("div", {
405
412
  className: "mt-3 flex flex-col gap-2",
406
- children: [O("google") && /* @__PURE__ */ g("button", {
413
+ children: [k("google") && /* @__PURE__ */ g("button", {
407
414
  type: "button",
408
415
  onClick: Ue,
409
416
  className: "inline-flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl border border-border-default bg-bg-surface text-text-primary text-sm font-medium hover:bg-bg-canvas hover:border-border-default transition-all shadow-sm",
410
- children: [/* @__PURE__ */ h(l, { className: "size-5" }), S("auth.login.signInWithGoogle", "Sign in with Google")]
411
- }), O("microsoft") && /* @__PURE__ */ g("button", {
417
+ children: [/* @__PURE__ */ h(c, { className: "size-5" }), S("auth.login.signInWithGoogle", "Sign in with Google")]
418
+ }), k("microsoft") && /* @__PURE__ */ g("button", {
412
419
  type: "button",
413
420
  onClick: We,
414
421
  className: "inline-flex items-center justify-center gap-2 px-4 py-2.5 rounded-xl border border-border-default bg-bg-surface text-text-primary text-sm font-medium hover:bg-bg-canvas hover:border-border-default transition-all shadow-sm",
415
- children: [/* @__PURE__ */ h(te, { className: "size-5" }), S("auth.login.signInWithMicrosoft", "Sign in with Microsoft")]
422
+ children: [/* @__PURE__ */ h(ne, { className: "size-5" }), S("auth.login.signInWithMicrosoft", "Sign in with Microsoft")]
416
423
  })]
417
424
  })
418
425
  ]
@@ -436,9 +443,9 @@ function b() {
436
443
  required: !0,
437
444
  "aria-required": "true",
438
445
  "aria-label": S("auth.login.emailLabel", "Email"),
439
- value: G.email,
440
- onChange: (e) => K({
441
- ...G,
446
+ value: K.email,
447
+ onChange: (e) => q({
448
+ ...K,
442
449
  email: e.target.value
443
450
  }),
444
451
  className: "block w-full pl-[3.5rem] pr-4 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
@@ -457,18 +464,18 @@ function b() {
457
464
  children: [
458
465
  /* @__PURE__ */ h("div", {
459
466
  className: "absolute inset-y-0 left-0 pl-3.5 flex items-center pointer-events-none",
460
- children: /* @__PURE__ */ h(u, { className: "size-5 text-[var(--color-text-tertiary)]" })
467
+ children: /* @__PURE__ */ h(l, { className: "size-5 text-[var(--color-text-tertiary)]" })
461
468
  }),
462
469
  /* @__PURE__ */ h("input", {
463
470
  id: "password",
464
- type: P ? "text" : "password",
471
+ type: F ? "text" : "password",
465
472
  autoComplete: "current-password",
466
473
  required: !0,
467
474
  "aria-required": "true",
468
475
  "aria-label": S("auth.login.passwordLabel", "Password"),
469
- value: G.password,
470
- onChange: (e) => K({
471
- ...G,
476
+ value: K.password,
477
+ onChange: (e) => q({
478
+ ...K,
472
479
  password: e.target.value
473
480
  }),
474
481
  className: "block w-full pl-[3.5rem] pr-12 py-3 rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] text-[var(--color-text-primary)] placeholder:text-[var(--color-text-tertiary)] focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all",
@@ -476,10 +483,10 @@ function b() {
476
483
  }),
477
484
  /* @__PURE__ */ h("button", {
478
485
  type: "button",
479
- onClick: () => je(!P),
480
- "aria-label": P ? "Hide password" : "Show password",
486
+ onClick: () => je(!F),
487
+ "aria-label": F ? "Hide password" : "Show password",
481
488
  className: "absolute inset-y-0 right-0 pr-3.5 flex items-center text-[var(--color-text-tertiary)] hover:text-[var(--color-text-secondary)] transition-colors",
482
- children: h(P ? ee : c, { className: "size-5" })
489
+ children: h(F ? te : ee, { className: "size-5" })
483
490
  })
484
491
  ]
485
492
  })]
@@ -493,11 +500,11 @@ function b() {
493
500
  children: [/* @__PURE__ */ h("input", {
494
501
  type: "checkbox",
495
502
  "aria-label": S("auth.login.rememberMe", "Remember me"),
496
- checked: G.rememberMe,
503
+ checked: K.rememberMe,
497
504
  onChange: (e) => {
498
505
  let t = e.target.checked;
499
- if (K({
500
- ...G,
506
+ if (q({
507
+ ...K,
501
508
  rememberMe: t
502
509
  }), !t) try {
503
510
  localStorage.removeItem("remembered_email");
@@ -534,9 +541,9 @@ function b() {
534
541
  }),
535
542
  /* @__PURE__ */ h("button", {
536
543
  type: "submit",
537
- disabled: C || A,
544
+ disabled: C || j,
538
545
  className: "auth-primary-button flex w-full items-center justify-center gap-2 px-4 py-3 font-semibold",
539
- children: C || A ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(ne, { className: "size-5 animate-spin" }), /* @__PURE__ */ h("span", { children: A ? S("auth.login.settingUpWorkspace", "Setting up workspace...") : S("auth.login.signingIn", "Signing in...") })] }) : S("auth.login.signIn", "Sign in")
546
+ children: C || j ? /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h(u, { className: "size-5 animate-spin" }), /* @__PURE__ */ h("span", { children: j ? S("auth.login.settingUpWorkspace", "Setting up workspace...") : S("auth.login.signingIn", "Signing in...") })] }) : S("auth.login.signIn", "Sign in")
540
547
  })
541
548
  ]
542
549
  }),
@@ -562,7 +569,7 @@ function b() {
562
569
  }),
563
570
  /* @__PURE__ */ h("div", {
564
571
  className: "grid grid-cols-3 gap-3",
565
- children: qe.map((e) => /* @__PURE__ */ g("button", {
572
+ children: Je.map((e) => /* @__PURE__ */ g("button", {
566
573
  type: "button",
567
574
  onClick: e.onClick,
568
575
  disabled: e.disabled,