@burdenoff/microfe-auth 2026.526.1 → 2026.527.2

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 (61) hide show
  1. package/dist/auth/AuthRoutes.js +1 -1
  2. package/dist/auth/AuthRoutes.js.map +1 -1
  3. package/dist/auth/components/AuthLayout.js +14 -14
  4. package/dist/auth/components/AuthLayout.js.map +1 -1
  5. package/dist/auth/components/CaptchaV2.js +1 -4
  6. package/dist/auth/components/CaptchaV2.js.map +1 -1
  7. package/dist/auth/components/ConfirmActionDialog.js +3 -3
  8. package/dist/auth/components/ConfirmActionDialog.js.map +1 -1
  9. package/dist/auth/components/profile/UserProfileMenu.js +10 -6
  10. package/dist/auth/components/profile/UserProfileMenu.js.map +1 -1
  11. package/dist/auth/components/workspace/WorkspaceSelector.js +5 -5
  12. package/dist/auth/components/workspace/WorkspaceSelector.js.map +1 -1
  13. package/dist/auth/hooks/index.js +2 -2
  14. package/dist/auth/index.js +4 -4
  15. package/dist/auth/pages/AuditLogPage.js +7 -7
  16. package/dist/auth/pages/AuditLogPage.js.map +1 -1
  17. package/dist/auth/pages/EmailVerifyPage.js +10 -8
  18. package/dist/auth/pages/EmailVerifyPage.js.map +1 -1
  19. package/dist/auth/pages/LoginPage.js +113 -94
  20. package/dist/auth/pages/LoginPage.js.map +1 -1
  21. package/dist/auth/pages/MagicLinkPage.js +10 -8
  22. package/dist/auth/pages/MagicLinkPage.js.map +1 -1
  23. package/dist/auth/pages/MfaSetupPage.js +26 -21
  24. package/dist/auth/pages/MfaSetupPage.js.map +1 -1
  25. package/dist/auth/pages/MfaVerifyPage.js +21 -21
  26. package/dist/auth/pages/MfaVerifyPage.js.map +1 -1
  27. package/dist/auth/pages/OAuthCallbackPage.js +7 -6
  28. package/dist/auth/pages/OAuthCallbackPage.js.map +1 -1
  29. package/dist/auth/pages/PasswordResetPage.js +25 -22
  30. package/dist/auth/pages/PasswordResetPage.js.map +1 -1
  31. package/dist/auth/pages/ReactivatePage.js +17 -15
  32. package/dist/auth/pages/ReactivatePage.js.map +1 -1
  33. package/dist/auth/pages/RegisterPage.js +198 -194
  34. package/dist/auth/pages/RegisterPage.js.map +1 -1
  35. package/dist/auth/pages/SSOClearPage.js +1 -1
  36. package/dist/auth/pages/SSOClearPage.js.map +1 -1
  37. package/dist/auth/pages/SSODepositPage.js +1 -1
  38. package/dist/auth/pages/SSODepositPage.js.map +1 -1
  39. package/dist/auth/pages/SSORelayCallbackPage.js +1 -1
  40. package/dist/auth/pages/SSORelayCallbackPage.js.map +1 -1
  41. package/dist/auth/pages/SSORelayPage.js +1 -1
  42. package/dist/auth/pages/SSORelayPage.js.map +1 -1
  43. package/dist/auth/pages/SecurityPage.js +15 -16
  44. package/dist/auth/pages/SecurityPage.js.map +1 -1
  45. package/dist/auth/pages/SessionsPage.js +19 -20
  46. package/dist/auth/pages/SessionsPage.js.map +1 -1
  47. package/dist/auth/pages/SsoCallbackPage.js +19 -15
  48. package/dist/auth/pages/SsoCallbackPage.js.map +1 -1
  49. package/dist/auth/pages/SsoConfigPage.js +41 -27
  50. package/dist/auth/pages/SsoConfigPage.js.map +1 -1
  51. package/dist/auth/pages/SsoLoginPage.js +16 -14
  52. package/dist/auth/pages/SsoLoginPage.js.map +1 -1
  53. package/dist/auth/pages/UserDetailsPage.js +16 -17
  54. package/dist/auth/pages/UserDetailsPage.js.map +1 -1
  55. package/dist/auth/pages/UserProfilePage.js +31 -25
  56. package/dist/auth/pages/UserProfilePage.js.map +1 -1
  57. package/dist/auth/pages/UsersPage.js +46 -42
  58. package/dist/auth/pages/UsersPage.js.map +1 -1
  59. package/dist/index.js +11 -11
  60. package/dist/microfe-auth.css +1 -1
  61. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { useAuthStore as e } from "../store/authStore.js";
2
- import { useSsoOperations as t } from "../hooks/useSsoOperations.js";
3
- import { AlertIcon as n, SpinnerIcon as r } from "../components/AuthIcons.js";
2
+ import { AlertIcon as t, SpinnerIcon as n } from "../components/AuthIcons.js";
3
+ import { useSsoOperations as r } from "../hooks/useSsoOperations.js";
4
4
  import { useEffect as i, useRef as a, useState as o } from "react";
5
5
  import { useNavigate as s, useSearchParams as c } from "react-router-dom";
6
6
  import { useI18n as l } from "@burdenoff/fe-libs/shared/providers/shell";
@@ -10,7 +10,7 @@ function p() {
10
10
  let { t: p } = l(), m = (e, t) => {
11
11
  let n = p(e);
12
12
  return n === e ? t : n;
13
- }, h = s(), [g] = c(), _ = e((e) => e.setAuthTokens), v = e((e) => e.setAuthenticated), { exchangeOidcCode: y, validateOidcState: b, isExternalOidcCallback: x, handleExternalOidcCallback: S } = t(), [C, w] = o(null), [T, E] = o("processing"), [D, O] = o("unknown"), k = a(!1);
13
+ }, h = s(), [g] = c(), _ = e((e) => e.setAuthTokens), v = e((e) => e.setAuthenticated), { exchangeOidcCode: y, validateOidcState: b, isExternalOidcCallback: x, handleExternalOidcCallback: S } = r(), [C, w] = o(null), [T, E] = o("processing"), [D, O] = o("unknown"), k = a(!1), A = a(null);
14
14
  return i(() => {
15
15
  if (k.current) return;
16
16
  k.current = !0;
@@ -31,7 +31,7 @@ function p() {
31
31
  sessionStorage.setItem("mfa_challenge_id", i), sessionStorage.setItem("mfa_pending_token", e), sessionStorage.setItem("mfa_pending_refresh", t || ""), sessionStorage.setItem("mfa_redirect", n || "/dashboard"), h("/auth/mfa-verify", { replace: !0 });
32
32
  return;
33
33
  }
34
- _(e, t || ""), v(!0), E("success"), setTimeout(() => {
34
+ _(e, t || ""), v(!0), E("success"), A.current = setTimeout(() => {
35
35
  h(n || "/dashboard", { replace: !0 });
36
36
  }, 1500);
37
37
  }, n = async (e, t) => {
@@ -41,7 +41,7 @@ function p() {
41
41
  if (!n.success) throw Error(n.error || "Failed to authenticate with external OIDC provider");
42
42
  E("success");
43
43
  let r = n.redirectPath || "/dashboard";
44
- setTimeout(() => {
44
+ A.current = setTimeout(() => {
45
45
  h(r, { replace: !0 });
46
46
  }, 1500);
47
47
  return;
@@ -55,11 +55,13 @@ function p() {
55
55
  }
56
56
  E("success");
57
57
  let r = sessionStorage.getItem("oidc_redirect") || "/dashboard";
58
- sessionStorage.removeItem("oidc_redirect"), sessionStorage.removeItem("oidc_client_id"), setTimeout(() => {
58
+ sessionStorage.removeItem("oidc_redirect"), sessionStorage.removeItem("oidc_client_id"), A.current = setTimeout(() => {
59
59
  h(r, { replace: !0 });
60
60
  }, 1500);
61
61
  };
62
- e();
62
+ return e(), () => {
63
+ A.current &&= (clearTimeout(A.current), null);
64
+ };
63
65
  }, [
64
66
  g,
65
67
  h,
@@ -79,9 +81,9 @@ function p() {
79
81
  /* @__PURE__ */ d("div", {
80
82
  className: "mb-6",
81
83
  children: /* @__PURE__ */ d("div", {
82
- className: "auth-brand-badge mx-auto flex h-16 w-16 items-center justify-center rounded-xl",
84
+ className: "auth-brand-badge mx-auto flex size-16 items-center justify-center rounded-xl",
83
85
  children: /* @__PURE__ */ d("svg", {
84
- className: "w-8 h-8 text-white",
86
+ className: "size-8 text-white",
85
87
  fill: "none",
86
88
  viewBox: "0 0 24 24",
87
89
  stroke: "currentColor",
@@ -105,14 +107,14 @@ function p() {
105
107
  }),
106
108
  /* @__PURE__ */ d("div", {
107
109
  className: "flex justify-center",
108
- children: /* @__PURE__ */ d(r, { className: "w-10 h-10 text-text-link animate-spin" })
110
+ children: /* @__PURE__ */ d(n, { className: "size-10 text-text-link animate-spin" })
109
111
  })
110
112
  ] }),
111
113
  T === "success" && /* @__PURE__ */ f(u, { children: [
112
114
  /* @__PURE__ */ d("div", {
113
- className: "w-16 h-16 mx-auto mb-4 rounded-full bg-status-success-bg-subtle flex items-center justify-center",
115
+ className: "size-16 mx-auto mb-4 rounded-full bg-status-success-bg-subtle flex items-center justify-center",
114
116
  children: /* @__PURE__ */ d("svg", {
115
- className: "w-8 h-8 text-status-success-text",
117
+ className: "size-8 text-status-success-text",
116
118
  fill: "none",
117
119
  viewBox: "0 0 24 24",
118
120
  stroke: "currentColor",
@@ -134,13 +136,13 @@ function p() {
134
136
  }),
135
137
  /* @__PURE__ */ d("div", {
136
138
  className: "flex justify-center",
137
- children: /* @__PURE__ */ d(r, { className: "w-6 h-6 text-status-success-text animate-spin" })
139
+ children: /* @__PURE__ */ d(n, { className: "size-6 text-status-success-text animate-spin" })
138
140
  })
139
141
  ] }),
140
142
  T === "error" && /* @__PURE__ */ f(u, { children: [
141
143
  /* @__PURE__ */ d("div", {
142
- className: "w-16 h-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center",
143
- children: /* @__PURE__ */ d(n, { className: "w-8 h-8 text-status-error-text" })
144
+ className: "size-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center",
145
+ children: /* @__PURE__ */ d(t, { className: "size-8 text-status-error-text" })
144
146
  }),
145
147
  /* @__PURE__ */ d("h1", {
146
148
  className: "text-2xl font-semibold text-text-primary mb-4",
@@ -153,10 +155,12 @@ function p() {
153
155
  /* @__PURE__ */ f("div", {
154
156
  className: "space-y-3",
155
157
  children: [/* @__PURE__ */ d("button", {
158
+ type: "button",
156
159
  onClick: () => h("/auth/sso/login", { replace: !0 }),
157
160
  className: "auth-primary-button w-full px-6 py-3 font-medium",
158
161
  children: m("auth.ssoCallback.tryAgain", "Try Again")
159
162
  }), /* @__PURE__ */ d("button", {
163
+ type: "button",
160
164
  onClick: () => h("/auth/login", { replace: !0 }),
161
165
  className: "w-full px-6 py-3 rounded-xl border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors",
162
166
  children: m("auth.ssoCallback.backToLogin", "Back to Login")
@@ -1 +1 @@
1
- {"version":3,"file":"SsoCallbackPage.js","names":[],"sources":["../../../src/auth/pages/SsoCallbackPage.tsx"],"sourcesContent":["import { useEffect, useState, useRef } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useNavigate, useSearchParams } from \"react-router-dom\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useSsoOperations } from \"../hooks/useSsoOperations\";\nimport { SpinnerIcon, AlertIcon } from \"../components/AuthIcons\";\n\n/**\n * SSO Callback Page\n * Handles redirects from:\n * - SAML ACS server (with token/refreshToken in query params)\n * - OIDC Authorization Server (with code/state in query params)\n */\nexport function SsoCallbackPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const setAuthTokens = useAuthStore((state) => state.setAuthTokens);\n const setAuthenticated = useAuthStore((state) => state.setAuthenticated);\n const {\n exchangeOidcCode,\n validateOidcState,\n isExternalOidcCallback,\n handleExternalOidcCallback,\n } = useSsoOperations();\n\n const [error, setError] = useState<string | null>(null);\n const [status, setStatus] = useState<\"processing\" | \"success\" | \"error\">(\n \"processing\",\n );\n const [callbackType, setCallbackType] = useState<\"saml\" | \"oidc\" | \"unknown\">(\n \"unknown\",\n );\n const processedRef = useRef(false);\n\n useEffect(() => {\n // Prevent double execution in React StrictMode\n if (processedRef.current) {\n return;\n }\n processedRef.current = true;\n\n const processCallback = async () => {\n try {\n // Check for error from either SSO provider\n const errorParam = searchParams.get(\"error\");\n const errorMessage =\n searchParams.get(\"message\") || searchParams.get(\"error_description\");\n\n if (errorParam) {\n throw new Error(\n errorMessage || `SSO authentication failed: ${errorParam}`,\n );\n }\n\n // Detect callback type based on query parameters\n const token = searchParams.get(\"token\");\n const code = searchParams.get(\"code\");\n const state = searchParams.get(\"state\");\n\n if (token) {\n // SAML callback - token already exchanged by ACS server\n setCallbackType(\"saml\");\n await handleSamlCallback(token);\n } else if (code) {\n // OIDC callback - need to exchange code for tokens\n setCallbackType(\"oidc\");\n await handleOidcCallback(code, state);\n } else {\n throw new Error(\n \"Invalid SSO callback. No token or authorization code received.\",\n );\n }\n } catch (err) {\n console.error(\"[SSO Callback] Error:\", err);\n setError(\n err instanceof Error ? err.message : \"Failed to process SSO response\",\n );\n setStatus(\"error\");\n }\n };\n\n /**\n * Handle SAML callback from ACS server\n * Token is already exchanged, just store and redirect\n * Also handles MFA if required\n */\n const handleSamlCallback = async (token: string) => {\n const refreshToken = searchParams.get(\"refreshToken\");\n const redirect = searchParams.get(\"redirect\");\n const requiresMFA = searchParams.get(\"requiresMFA\") === \"true\";\n const mfaChallengeId = searchParams.get(\"mfaChallengeId\");\n\n // Check if MFA is required\n if (requiresMFA && mfaChallengeId) {\n // Store partial auth state and MFA info\n sessionStorage.setItem(\"mfa_challenge_id\", mfaChallengeId);\n sessionStorage.setItem(\"mfa_pending_token\", token);\n sessionStorage.setItem(\"mfa_pending_refresh\", refreshToken || \"\");\n sessionStorage.setItem(\"mfa_redirect\", redirect || \"/dashboard\");\n\n // Redirect to MFA verification\n navigate(\"/auth/mfa-verify\", { replace: true });\n return;\n }\n\n // Store tokens\n setAuthTokens(token, refreshToken || \"\");\n setAuthenticated(true);\n\n setStatus(\"success\");\n\n // Redirect to the specified URL or default to dashboard\n setTimeout(() => {\n const redirectUrl = redirect || \"/dashboard\";\n navigate(redirectUrl, { replace: true });\n }, 1500);\n };\n\n /**\n * Handle OIDC callback - exchange code for tokens\n */\n const handleOidcCallback = async (code: string, state: string | null) => {\n const isExternal = isExternalOidcCallback();\n\n // Check if this is an external OIDC flow (Azure AD, Google, etc.)\n if (isExternal) {\n if (!state) {\n throw new Error(\"State parameter is required for external OIDC flow\");\n }\n\n // Use the external OIDC handler\n const result = await handleExternalOidcCallback(code, state);\n\n if (!result.success) {\n throw new Error(\n result.error ||\n \"Failed to authenticate with external OIDC provider\",\n );\n }\n\n setStatus(\"success\");\n\n // Redirect after brief success message using the redirect path from result\n const redirectUrl = result.redirectPath || \"/dashboard\";\n setTimeout(() => {\n navigate(redirectUrl, { replace: true });\n }, 1500);\n return;\n }\n\n // Internal OIDC flow (our auth service as provider)\n // Validate state to prevent CSRF\n if (state && !validateOidcState(state)) {\n throw new Error(\n \"Invalid state parameter. This may be a CSRF attack. Please try logging in again.\",\n );\n }\n\n // Get client configuration from session storage\n const clientId =\n sessionStorage.getItem(\"oidc_client_id\") || \"default-client\";\n const redirectUri = window.location.origin + \"/auth/sso/callback\";\n\n // Exchange code for tokens\n const result = await exchangeOidcCode(code, clientId, redirectUri);\n\n if (!result.success) {\n throw new Error(\n result.error || \"Failed to exchange authorization code\",\n );\n }\n\n // Check if MFA is required after OIDC authentication\n if (result.requiresMFA && result.mfaChallengeId) {\n // Store MFA challenge info for the verification page\n sessionStorage.setItem(\"mfa_challenge_id\", result.mfaChallengeId);\n sessionStorage.setItem(\n \"mfa_redirect\",\n sessionStorage.getItem(\"oidc_redirect\") || \"/dashboard\",\n );\n\n // Clean up OIDC session data\n sessionStorage.removeItem(\"oidc_redirect\");\n sessionStorage.removeItem(\"oidc_client_id\");\n\n // Redirect to MFA verification\n navigate(\"/auth/mfa-verify\", { replace: true });\n return;\n }\n\n setStatus(\"success\");\n\n // Get redirect URL from state or session storage\n const redirect = sessionStorage.getItem(\"oidc_redirect\") || \"/dashboard\";\n sessionStorage.removeItem(\"oidc_redirect\");\n sessionStorage.removeItem(\"oidc_client_id\");\n\n // Redirect after brief success message\n setTimeout(() => {\n navigate(redirect, { replace: true });\n }, 1500);\n };\n\n processCallback();\n }, [\n searchParams,\n navigate,\n setAuthTokens,\n setAuthenticated,\n exchangeOidcCode,\n validateOidcState,\n isExternalOidcCallback,\n handleExternalOidcCallback,\n ]);\n\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-bg-canvas p-4\">\n <div className=\"w-full max-w-md\">\n <div className=\"bg-bg-surface rounded-2xl shadow-xl p-8 text-center\">\n {/* Logo */}\n <div className=\"mb-6\">\n <div className=\"auth-brand-badge mx-auto flex h-16 w-16 items-center justify-center rounded-xl\">\n <svg\n className=\"w-8 h-8 text-white\"\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\n {/* Processing State */}\n {status === \"processing\" && (\n <>\n <h1 className=\"text-2xl font-semibold text-text-primary mb-4\">\n {tr(\"auth.ssoCallback.completing\", \"Completing Sign In\")}\n </h1>\n <p className=\"text-text-secondary mb-6\">\n {callbackType === \"oidc\"\n ? tr(\n \"auth.ssoCallback.exchangingCode\",\n \"Exchanging authorization code for access tokens...\",\n )\n : callbackType === \"saml\"\n ? tr(\n \"auth.ssoCallback.validatingSaml\",\n \"Validating your SAML credentials...\",\n )\n : tr(\n \"auth.ssoCallback.validatingCreds\",\n \"Validating your credentials from your identity provider...\",\n )}\n </p>\n <div className=\"flex justify-center\">\n <SpinnerIcon className=\"w-10 h-10 text-text-link animate-spin\" />\n </div>\n </>\n )}\n\n {/* Success State */}\n {status === \"success\" && (\n <>\n <div className=\"w-16 h-16 mx-auto mb-4 rounded-full bg-status-success-bg-subtle flex items-center justify-center\">\n <svg\n className=\"w-8 h-8 text-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=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n <h1 className=\"text-2xl font-semibold text-text-primary mb-4\">\n {tr(\"auth.ssoCallback.success\", \"Sign In Successful\")}\n </h1>\n <p className=\"text-text-secondary mb-6\">\n {callbackType === \"oidc\"\n ? tr(\n \"auth.ssoCallback.oidcComplete\",\n \"OIDC authentication complete. Redirecting...\",\n )\n : callbackType === \"saml\"\n ? tr(\n \"auth.ssoCallback.samlComplete\",\n \"SAML authentication complete. Redirecting...\",\n )\n : tr(\n \"auth.ssoCallback.authSuccess\",\n \"You have been authenticated successfully. Redirecting...\",\n )}\n </p>\n <div className=\"flex justify-center\">\n <SpinnerIcon className=\"w-6 h-6 text-status-success-text animate-spin\" />\n </div>\n </>\n )}\n\n {/* Error State */}\n {status === \"error\" && (\n <>\n <div className=\"w-16 h-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <AlertIcon className=\"w-8 h-8 text-status-error-text\" />\n </div>\n <h1 className=\"text-2xl font-semibold text-text-primary mb-4\">\n {tr(\"auth.ssoCallback.failed\", \"Sign In Failed\")}\n </h1>\n <p className=\"text-status-error-text mb-6 text-sm\">{error}</p>\n <div className=\"space-y-3\">\n <button\n onClick={() => navigate(\"/auth/sso/login\", { replace: true })}\n className=\"auth-primary-button w-full px-6 py-3 font-medium\"\n >\n {tr(\"auth.ssoCallback.tryAgain\", \"Try Again\")}\n </button>\n <button\n onClick={() => navigate(\"/auth/login\", { replace: true })}\n className=\"w-full px-6 py-3 rounded-xl border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"auth.ssoCallback.backToLogin\", \"Back to Login\")}\n </button>\n </div>\n </>\n )}\n\n {/* SSO Type Badge */}\n {callbackType !== \"unknown\" && (\n <div className=\"mt-6\">\n <span\n className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${\n callbackType === \"oidc\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : \"bg-status-info-bg-subtle text-text-linkHover\"\n }`}\n >\n {callbackType === \"oidc\" ? \"OpenID Connect\" : \"SAML 2.0\"}\n </span>\n </div>\n )}\n\n {/* Help Text */}\n <div className=\"mt-8 pt-6 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary\">\n {tr(\n \"auth.ssoCallback.helpText\",\n \"Having trouble? Contact your organization's IT administrator for assistance with SSO login.\",\n )}\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;AAaA,SAAgB,IAAkB;CAChC,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAGnC,IAAW,GAAa,EACxB,CAAC,KAAgB,GAAiB,EAClC,IAAgB,GAAc,MAAU,EAAM,cAAc,EAC5D,IAAmB,GAAc,MAAU,EAAM,iBAAiB,EAClE,EACJ,qBACA,sBACA,2BACA,kCACE,GAAkB,EAEhB,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAQ,KAAa,EAC1B,aACD,EACK,CAAC,GAAc,KAAmB,EACtC,UACD,EACK,IAAe,EAAO,GAAM;AAuLlC,QArLA,QAAgB;AAEd,MAAI,EAAa,QACf;AAEF,IAAa,UAAU;EAEvB,IAAM,IAAkB,YAAY;AAClC,OAAI;IAEF,IAAM,IAAa,EAAa,IAAI,QAAQ,EACtC,IACJ,EAAa,IAAI,UAAU,IAAI,EAAa,IAAI,oBAAoB;AAEtE,QAAI,EACF,OAAU,MACR,KAAgB,8BAA8B,IAC/C;IAIH,IAAM,IAAQ,EAAa,IAAI,QAAQ,EACjC,IAAO,EAAa,IAAI,OAAO,EAC/B,IAAQ,EAAa,IAAI,QAAQ;AAEvC,QAAI,EAGF,CADA,EAAgB,OAAO,EACvB,MAAM,EAAmB,EAAM;aACtB,EAGT,CADA,EAAgB,OAAO,EACvB,MAAM,EAAmB,GAAM,EAAM;QAErC,OAAU,MACR,iEACD;YAEI,GAAK;AAKZ,IAJA,QAAQ,MAAM,yBAAyB,EAAI,EAC3C,EACE,aAAe,QAAQ,EAAI,UAAU,iCACtC,EACD,EAAU,QAAQ;;KAShB,IAAqB,OAAO,MAAkB;GAClD,IAAM,IAAe,EAAa,IAAI,eAAe,EAC/C,IAAW,EAAa,IAAI,WAAW,EACvC,IAAc,EAAa,IAAI,cAAc,KAAK,QAClD,IAAiB,EAAa,IAAI,iBAAiB;AAGzD,OAAI,KAAe,GAAgB;AAQjC,IANA,eAAe,QAAQ,oBAAoB,EAAe,EAC1D,eAAe,QAAQ,qBAAqB,EAAM,EAClD,eAAe,QAAQ,uBAAuB,KAAgB,GAAG,EACjE,eAAe,QAAQ,gBAAgB,KAAY,aAAa,EAGhE,EAAS,oBAAoB,EAAE,SAAS,IAAM,CAAC;AAC/C;;AAUF,GANA,EAAc,GAAO,KAAgB,GAAG,EACxC,EAAiB,GAAK,EAEtB,EAAU,UAAU,EAGpB,iBAAiB;AAEf,MADoB,KAAY,cACV,EAAE,SAAS,IAAM,CAAC;MACvC,KAAK;KAMJ,IAAqB,OAAO,GAAc,MAAyB;AAIvE,OAHmB,GAAwB,EAG3B;AACd,QAAI,CAAC,EACH,OAAU,MAAM,qDAAqD;IAIvE,IAAM,IAAS,MAAM,EAA2B,GAAM,EAAM;AAE5D,QAAI,CAAC,EAAO,QACV,OAAU,MACR,EAAO,SACL,qDACH;AAGH,MAAU,UAAU;IAGpB,IAAM,IAAc,EAAO,gBAAgB;AAC3C,qBAAiB;AACf,OAAS,GAAa,EAAE,SAAS,IAAM,CAAC;OACvC,KAAK;AACR;;AAKF,OAAI,KAAS,CAAC,EAAkB,EAAM,CACpC,OAAU,MACR,mFACD;GASH,IAAM,IAAS,MAAM,EAAiB,GAJpC,eAAe,QAAQ,iBAAiB,IAAI,kBAC1B,OAAO,SAAS,SAAS,qBAGqB;AAElE,OAAI,CAAC,EAAO,QACV,OAAU,MACR,EAAO,SAAS,wCACjB;AAIH,OAAI,EAAO,eAAe,EAAO,gBAAgB;AAa/C,IAXA,eAAe,QAAQ,oBAAoB,EAAO,eAAe,EACjE,eAAe,QACb,gBACA,eAAe,QAAQ,gBAAgB,IAAI,aAC5C,EAGD,eAAe,WAAW,gBAAgB,EAC1C,eAAe,WAAW,iBAAiB,EAG3C,EAAS,oBAAoB,EAAE,SAAS,IAAM,CAAC;AAC/C;;AAGF,KAAU,UAAU;GAGpB,IAAM,IAAW,eAAe,QAAQ,gBAAgB,IAAI;AAK5D,GAJA,eAAe,WAAW,gBAAgB,EAC1C,eAAe,WAAW,iBAAiB,EAG3C,iBAAiB;AACf,MAAS,GAAU,EAAE,SAAS,IAAM,CAAC;MACpC,KAAK;;AAGV,KAAiB;IAChB;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,EAGA,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf;KAEE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,OAAD;QACE,WAAU;QACV,MAAK;QACL,SAAQ;QACR,QAAO;kBAEP,kBAAC,QAAD;SACE,eAAc;SACd,gBAAe;SACf,aAAa;SACb,GAAE;SACF,CAAA;QACE,CAAA;OACF,CAAA;MACF,CAAA;KAGL,MAAW,gBACV,kBAAA,GAAA,EAAA,UAAA;MACE,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,+BAA+B,qBAAqB;OACrD,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,MAAiB,SACd,EACE,mCACA,qDACD,GACD,MAAiB,SACf,EACE,mCACA,sCACD,GACD,EACE,oCACA,6DACD;OACL,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAa,WAAU,yCAA0C,CAAA;OAC7D,CAAA;MACL,EAAA,CAAA;KAIJ,MAAW,aACV,kBAAA,GAAA,EAAA,UAAA;MACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,OAAD;QACE,WAAU;QACV,MAAK;QACL,SAAQ;QACR,QAAO;kBAEP,kBAAC,QAAD;SACE,eAAc;SACd,gBAAe;SACf,aAAa;SACb,GAAE;SACF,CAAA;QACE,CAAA;OACF,CAAA;MACN,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,4BAA4B,qBAAqB;OAClD,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBACV,MAAiB,SACd,EACE,iCACA,+CACD,GACD,MAAiB,SACf,EACE,iCACA,+CACD,GACD,EACE,gCACA,2DACD;OACL,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAa,WAAU,iDAAkD,CAAA;OACrE,CAAA;MACL,EAAA,CAAA;KAIJ,MAAW,WACV,kBAAA,GAAA,EAAA,UAAA;MACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAW,WAAU,kCAAmC,CAAA;OACpD,CAAA;MACN,kBAAC,MAAD;OAAI,WAAU;iBACX,EAAG,2BAA2B,iBAAiB;OAC7C,CAAA;MACL,kBAAC,KAAD;OAAG,WAAU;iBAAuC;OAAU,CAAA;MAC9D,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,UAAD;QACE,eAAe,EAAS,mBAAmB,EAAE,SAAS,IAAM,CAAC;QAC7D,WAAU;kBAET,EAAG,6BAA6B,YAAY;QACtC,CAAA,EACT,kBAAC,UAAD;QACE,eAAe,EAAS,eAAe,EAAE,SAAS,IAAM,CAAC;QACzD,WAAU;kBAET,EAAG,gCAAgC,gBAAgB;QAC7C,CAAA,CACL;;MACL,EAAA,CAAA;KAIJ,MAAiB,aAChB,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,QAAD;OACE,WAAW,uEACT,MAAiB,SACb,+CACA;iBAGL,MAAiB,SAAS,mBAAmB;OACzC,CAAA;MACH,CAAA;KAIR,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,6BACA,8FACD;OACC,CAAA;MACA,CAAA;KACF;;GACF,CAAA;EACF,CAAA"}
1
+ {"version":3,"file":"SsoCallbackPage.js","names":[],"sources":["../../../src/auth/pages/SsoCallbackPage.tsx"],"sourcesContent":["import { useEffect, useState, useRef } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useNavigate, useSearchParams } from \"react-router-dom\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { useSsoOperations } from \"../hooks/useSsoOperations\";\nimport { SpinnerIcon, AlertIcon } from \"../components/AuthIcons\";\n\n/**\n * SSO Callback Page\n * Handles redirects from:\n * - SAML ACS server (with token/refreshToken in query params)\n * - OIDC Authorization Server (with code/state in query params)\n */\nexport function SsoCallbackPage() {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const setAuthTokens = useAuthStore((state) => state.setAuthTokens);\n const setAuthenticated = useAuthStore((state) => state.setAuthenticated);\n const {\n exchangeOidcCode,\n validateOidcState,\n isExternalOidcCallback,\n handleExternalOidcCallback,\n } = useSsoOperations();\n\n const [error, setError] = useState<string | null>(null);\n const [status, setStatus] = useState<\"processing\" | \"success\" | \"error\">(\n \"processing\",\n );\n const [callbackType, setCallbackType] = useState<\"saml\" | \"oidc\" | \"unknown\">(\n \"unknown\",\n );\n const processedRef = useRef(false);\n const redirectTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n // Prevent double execution in React StrictMode\n if (processedRef.current) {\n return;\n }\n processedRef.current = true;\n\n const processCallback = async () => {\n try {\n // Check for error from either SSO provider\n const errorParam = searchParams.get(\"error\");\n const errorMessage =\n searchParams.get(\"message\") || searchParams.get(\"error_description\");\n\n if (errorParam) {\n throw new Error(\n errorMessage || `SSO authentication failed: ${errorParam}`,\n );\n }\n\n // Detect callback type based on query parameters\n const token = searchParams.get(\"token\");\n const code = searchParams.get(\"code\");\n const state = searchParams.get(\"state\");\n\n if (token) {\n // SAML callback - token already exchanged by ACS server\n setCallbackType(\"saml\");\n await handleSamlCallback(token);\n } else if (code) {\n // OIDC callback - need to exchange code for tokens\n setCallbackType(\"oidc\");\n await handleOidcCallback(code, state);\n } else {\n throw new Error(\n \"Invalid SSO callback. No token or authorization code received.\",\n );\n }\n } catch (err) {\n console.error(\"[SSO Callback] Error:\", err);\n setError(\n err instanceof Error ? err.message : \"Failed to process SSO response\",\n );\n setStatus(\"error\");\n }\n };\n\n /**\n * Handle SAML callback from ACS server\n * Token is already exchanged, just store and redirect\n * Also handles MFA if required\n */\n const handleSamlCallback = async (token: string) => {\n const refreshToken = searchParams.get(\"refreshToken\");\n const redirect = searchParams.get(\"redirect\");\n const requiresMFA = searchParams.get(\"requiresMFA\") === \"true\";\n const mfaChallengeId = searchParams.get(\"mfaChallengeId\");\n\n // Check if MFA is required\n if (requiresMFA && mfaChallengeId) {\n // Store partial auth state and MFA info\n sessionStorage.setItem(\"mfa_challenge_id\", mfaChallengeId);\n sessionStorage.setItem(\"mfa_pending_token\", token);\n sessionStorage.setItem(\"mfa_pending_refresh\", refreshToken || \"\");\n sessionStorage.setItem(\"mfa_redirect\", redirect || \"/dashboard\");\n\n // Redirect to MFA verification\n navigate(\"/auth/mfa-verify\", { replace: true });\n return;\n }\n\n // Store tokens\n setAuthTokens(token, refreshToken || \"\");\n setAuthenticated(true);\n\n setStatus(\"success\");\n\n // Redirect to the specified URL or default to dashboard\n redirectTimerRef.current = setTimeout(() => {\n const redirectUrl = redirect || \"/dashboard\";\n navigate(redirectUrl, { replace: true });\n }, 1500);\n };\n\n /**\n * Handle OIDC callback - exchange code for tokens\n */\n const handleOidcCallback = async (code: string, state: string | null) => {\n const isExternal = isExternalOidcCallback();\n\n // Check if this is an external OIDC flow (Azure AD, Google, etc.)\n if (isExternal) {\n if (!state) {\n throw new Error(\"State parameter is required for external OIDC flow\");\n }\n\n // Use the external OIDC handler\n const result = await handleExternalOidcCallback(code, state);\n\n if (!result.success) {\n throw new Error(\n result.error ||\n \"Failed to authenticate with external OIDC provider\",\n );\n }\n\n setStatus(\"success\");\n\n // Redirect after brief success message using the redirect path from result\n const redirectUrl = result.redirectPath || \"/dashboard\";\n redirectTimerRef.current = setTimeout(() => {\n navigate(redirectUrl, { replace: true });\n }, 1500);\n return;\n }\n\n // Internal OIDC flow (our auth service as provider)\n // Validate state to prevent CSRF\n if (state && !validateOidcState(state)) {\n throw new Error(\n \"Invalid state parameter. This may be a CSRF attack. Please try logging in again.\",\n );\n }\n\n // Get client configuration from session storage\n const clientId =\n sessionStorage.getItem(\"oidc_client_id\") || \"default-client\";\n const redirectUri = window.location.origin + \"/auth/sso/callback\";\n\n // Exchange code for tokens\n const result = await exchangeOidcCode(code, clientId, redirectUri);\n\n if (!result.success) {\n throw new Error(\n result.error || \"Failed to exchange authorization code\",\n );\n }\n\n // Check if MFA is required after OIDC authentication\n if (result.requiresMFA && result.mfaChallengeId) {\n // Store MFA challenge info for the verification page\n sessionStorage.setItem(\"mfa_challenge_id\", result.mfaChallengeId);\n sessionStorage.setItem(\n \"mfa_redirect\",\n sessionStorage.getItem(\"oidc_redirect\") || \"/dashboard\",\n );\n\n // Clean up OIDC session data\n sessionStorage.removeItem(\"oidc_redirect\");\n sessionStorage.removeItem(\"oidc_client_id\");\n\n // Redirect to MFA verification\n navigate(\"/auth/mfa-verify\", { replace: true });\n return;\n }\n\n setStatus(\"success\");\n\n // Get redirect URL from state or session storage\n const redirect = sessionStorage.getItem(\"oidc_redirect\") || \"/dashboard\";\n sessionStorage.removeItem(\"oidc_redirect\");\n sessionStorage.removeItem(\"oidc_client_id\");\n\n // Redirect after brief success message\n redirectTimerRef.current = setTimeout(() => {\n navigate(redirect, { replace: true });\n }, 1500);\n };\n\n processCallback();\n return () => {\n if (redirectTimerRef.current) {\n clearTimeout(redirectTimerRef.current);\n redirectTimerRef.current = null;\n }\n };\n }, [\n searchParams,\n navigate,\n setAuthTokens,\n setAuthenticated,\n exchangeOidcCode,\n validateOidcState,\n isExternalOidcCallback,\n handleExternalOidcCallback,\n ]);\n\n return (\n <div className=\"min-h-screen flex items-center justify-center bg-bg-canvas p-4\">\n <div className=\"w-full max-w-md\">\n <div className=\"bg-bg-surface rounded-2xl shadow-xl p-8 text-center\">\n {/* Logo */}\n <div className=\"mb-6\">\n <div className=\"auth-brand-badge mx-auto flex size-16 items-center justify-center rounded-xl\">\n <svg\n className=\"size-8 text-white\"\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\n {/* Processing State */}\n {status === \"processing\" && (\n <>\n <h1 className=\"text-2xl font-semibold text-text-primary mb-4\">\n {tr(\"auth.ssoCallback.completing\", \"Completing Sign In\")}\n </h1>\n <p className=\"text-text-secondary mb-6\">\n {callbackType === \"oidc\"\n ? tr(\n \"auth.ssoCallback.exchangingCode\",\n \"Exchanging authorization code for access tokens...\",\n )\n : callbackType === \"saml\"\n ? tr(\n \"auth.ssoCallback.validatingSaml\",\n \"Validating your SAML credentials...\",\n )\n : tr(\n \"auth.ssoCallback.validatingCreds\",\n \"Validating your credentials from your identity provider...\",\n )}\n </p>\n <div className=\"flex justify-center\">\n <SpinnerIcon className=\"size-10 text-text-link animate-spin\" />\n </div>\n </>\n )}\n\n {/* Success State */}\n {status === \"success\" && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-status-success-bg-subtle flex items-center justify-center\">\n <svg\n className=\"size-8 text-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=\"M5 13l4 4L19 7\"\n />\n </svg>\n </div>\n <h1 className=\"text-2xl font-semibold text-text-primary mb-4\">\n {tr(\"auth.ssoCallback.success\", \"Sign In Successful\")}\n </h1>\n <p className=\"text-text-secondary mb-6\">\n {callbackType === \"oidc\"\n ? tr(\n \"auth.ssoCallback.oidcComplete\",\n \"OIDC authentication complete. Redirecting...\",\n )\n : callbackType === \"saml\"\n ? tr(\n \"auth.ssoCallback.samlComplete\",\n \"SAML authentication complete. Redirecting...\",\n )\n : tr(\n \"auth.ssoCallback.authSuccess\",\n \"You have been authenticated successfully. Redirecting...\",\n )}\n </p>\n <div className=\"flex justify-center\">\n <SpinnerIcon className=\"size-6 text-status-success-text animate-spin\" />\n </div>\n </>\n )}\n\n {/* Error State */}\n {status === \"error\" && (\n <>\n <div className=\"size-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <AlertIcon className=\"size-8 text-status-error-text\" />\n </div>\n <h1 className=\"text-2xl font-semibold text-text-primary mb-4\">\n {tr(\"auth.ssoCallback.failed\", \"Sign In Failed\")}\n </h1>\n <p className=\"text-status-error-text mb-6 text-sm\">{error}</p>\n <div className=\"space-y-3\">\n <button type=\"button\"\n onClick={() => navigate(\"/auth/sso/login\", { replace: true })}\n className=\"auth-primary-button w-full px-6 py-3 font-medium\"\n >\n {tr(\"auth.ssoCallback.tryAgain\", \"Try Again\")}\n </button>\n <button type=\"button\"\n onClick={() => navigate(\"/auth/login\", { replace: true })}\n className=\"w-full px-6 py-3 rounded-xl border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"auth.ssoCallback.backToLogin\", \"Back to Login\")}\n </button>\n </div>\n </>\n )}\n\n {/* SSO Type Badge */}\n {callbackType !== \"unknown\" && (\n <div className=\"mt-6\">\n <span\n className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-medium ${\n callbackType === \"oidc\"\n ? \"bg-accent-purple-subtle text-accent-purple\"\n : \"bg-status-info-bg-subtle text-text-linkHover\"\n }`}\n >\n {callbackType === \"oidc\" ? \"OpenID Connect\" : \"SAML 2.0\"}\n </span>\n </div>\n )}\n\n {/* Help Text */}\n <div className=\"mt-8 pt-6 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary\">\n {tr(\n \"auth.ssoCallback.helpText\",\n \"Having trouble? Contact your organization's IT administrator for assistance with SSO login.\",\n )}\n </p>\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,6 @@
1
- import { useSsoOperations as e } from "../hooks/useSsoOperations.js";
2
- import { useAuthPermissions as t } from "../hooks/useAuthPermissions.js";
3
- import "../hooks/index.js";
4
- import { AlertIcon as n, SpinnerIcon as r } from "../components/AuthIcons.js";
1
+ import { AlertIcon as e, SpinnerIcon as t } from "../components/AuthIcons.js";
2
+ import { useSsoOperations as n } from "../hooks/useSsoOperations.js";
3
+ import { useAuthPermissions as r } from "../hooks/useAuthPermissions.js";
5
4
  import { ConfirmActionDialog as i } from "../components/ConfirmActionDialog.js";
6
5
  import { nativeCopyText as a, nativeImpact as o, nativeNotify as s } from "../../utils/nativeBridge.js";
7
6
  import { useCallback as c, useEffect as l, useRef as ee, useState as u } from "react";
@@ -47,7 +46,7 @@ function g(e) {
47
46
  }
48
47
  }
49
48
  function _({ bypassEnterprisePlanGate: a = !1 }) {
50
- let _ = te(), [v] = d(), { canManageSsoConfig: y, isLoading: ie } = t(), ae = re("workspace.auth.enterprise-sso"), oe = a || ae?.value === !0, b = ee(null), x = v.get("tenant"), S = v.get("org"), C = v.get("workspace"), { ssoConfig: w, oidcConfig: T, isLoading: E, isSaving: D, isDeleting: O, saveSsoConfig: k, deleteSsoConfig: se } = e(x ?? "burdenoff.com"), { t: A } = ne(), j = c((e, t) => {
49
+ let _ = te(), [v] = d(), { canManageSsoConfig: y, isLoading: ie } = r(), ae = re("workspace.auth.enterprise-sso"), oe = a || ae?.value === !0, b = ee(null), x = v.get("tenant"), S = v.get("org"), C = v.get("workspace"), { ssoConfig: w, oidcConfig: T, isLoading: E, isSaving: D, isDeleting: O, saveSsoConfig: k, deleteSsoConfig: se } = n(x ?? "burdenoff.com"), { t: A } = ne(), j = c((e, t) => {
51
50
  let n = A(e);
52
51
  return n === e ? t : n;
53
52
  }, [A]), [M, ce] = u("saml"), [N, P] = u(!1), [le, F] = u(!1), [I, L] = u(null), [R, z] = u(null), [B, V] = u(""), [H, U] = u(!1), [W, G] = u(!1), [K, q] = u({
@@ -74,7 +73,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
74
73
  className: "max-w-5xl mx-auto p-6",
75
74
  children: /* @__PURE__ */ m("div", {
76
75
  className: "text-center py-16",
77
- children: [/* @__PURE__ */ p(r, { className: "w-8 h-8 mx-auto text-text-secondary animate-spin" }), /* @__PURE__ */ p("p", {
76
+ children: [/* @__PURE__ */ p(t, { className: "size-8 mx-auto text-text-secondary animate-spin" }), /* @__PURE__ */ p("p", {
78
77
  className: "mt-4 text-text-secondary",
79
78
  children: j("auth.sso.loadingPermissions", "Loading permissions...")
80
79
  })]
@@ -110,11 +109,12 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
110
109
  children: [/* @__PURE__ */ m("div", {
111
110
  className: "flex items-center gap-4",
112
111
  children: [/* @__PURE__ */ p("button", {
112
+ type: "button",
113
113
  onClick: () => _("/auth/security"),
114
114
  "aria-label": j("auth.sso.backToSecurity", "Back to Security"),
115
115
  className: "p-2 rounded-lg hover:bg-bg-sunken transition-colors",
116
116
  children: /* @__PURE__ */ p("svg", {
117
- className: "w-5 h-5 text-text-secondary",
117
+ className: "size-5 text-text-secondary",
118
118
  fill: "none",
119
119
  viewBox: "0 0 24 24",
120
120
  stroke: "currentColor",
@@ -139,6 +139,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
139
139
  className: `px-3 py-1 rounded-full text-sm font-medium ${Q.enabled ? "bg-status-success-bg-subtle text-status-success-text" : "bg-bg-sunken text-text-secondary"}`,
140
140
  children: Q.enabled ? j("auth.sso.enabled", "Enabled") : j("auth.sso.disabled", "Disabled")
141
141
  }), /* @__PURE__ */ p("button", {
142
+ type: "button",
142
143
  onClick: async () => {
143
144
  L(null);
144
145
  try {
@@ -202,12 +203,13 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
202
203
  }),
203
204
  I && /* @__PURE__ */ m("div", {
204
205
  className: "mb-6 flex items-start gap-3 p-4 rounded-xl bg-status-error-bg-subtle border border-status-error-border",
205
- children: [/* @__PURE__ */ p(n, { className: "w-5 h-5 text-status-error-text flex-shrink-0 mt-0.5" }), /* @__PURE__ */ m("div", {
206
+ children: [/* @__PURE__ */ p(e, { className: "size-5 text-status-error-text flex-shrink-0 mt-0.5" }), /* @__PURE__ */ m("div", {
206
207
  className: "flex-1",
207
208
  children: [/* @__PURE__ */ p("p", {
208
209
  className: "text-sm text-status-error-text",
209
210
  children: I
210
211
  }), /* @__PURE__ */ p("button", {
212
+ type: "button",
211
213
  onClick: () => L(null),
212
214
  className: "mt-2 text-sm text-status-error-text hover:underline",
213
215
  children: j("auth.sso.dismiss", "Dismiss")
@@ -217,7 +219,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
217
219
  R && /* @__PURE__ */ m("div", {
218
220
  className: "mb-6 flex items-start gap-3 p-4 rounded-xl bg-status-success-bg-subtle border border-status-success-border",
219
221
  children: [/* @__PURE__ */ p("svg", {
220
- className: "w-5 h-5 text-status-success-text flex-shrink-0 mt-0.5",
222
+ className: "size-5 text-status-success-text flex-shrink-0 mt-0.5",
221
223
  fill: "currentColor",
222
224
  viewBox: "0 0 20 20",
223
225
  children: /* @__PURE__ */ p("path", {
@@ -231,6 +233,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
231
233
  className: "text-sm text-status-success-text",
232
234
  children: R
233
235
  }), /* @__PURE__ */ p("button", {
236
+ type: "button",
234
237
  onClick: () => z(null),
235
238
  className: "mt-2 text-sm text-status-success-text hover:underline",
236
239
  children: j("auth.sso.dismiss", "Dismiss")
@@ -263,6 +266,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
263
266
  icon: "🧪"
264
267
  }
265
268
  ].map((e) => /* @__PURE__ */ m("button", {
269
+ type: "button",
266
270
  onClick: () => ce(e.id),
267
271
  className: `pb-3 text-sm font-medium transition-colors relative ${M === e.id ? "text-text-link" : "text-text-secondary hover:text-text-primary"}`,
268
272
  children: [/* @__PURE__ */ m("span", {
@@ -274,7 +278,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
274
278
  }),
275
279
  E && /* @__PURE__ */ m("div", {
276
280
  className: "flex items-center justify-center py-12",
277
- children: [/* @__PURE__ */ p(r, { className: "w-8 h-8 text-text-link animate-spin" }), /* @__PURE__ */ p("span", {
281
+ children: [/* @__PURE__ */ p(t, { className: "size-8 text-text-link animate-spin" }), /* @__PURE__ */ p("span", {
278
282
  className: "ml-3 text-text-secondary",
279
283
  children: j("auth.sso.loadingConfig", "Loading configuration...")
280
284
  })]
@@ -353,8 +357,8 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
353
357
  /* @__PURE__ */ m("label", {
354
358
  htmlFor: "metadata-file",
355
359
  className: "flex items-center justify-center gap-2 w-full px-4 py-3 border-2 border-dashed border-border-default rounded-xl cursor-pointer hover:border-action-primary-bg transition-colors",
356
- children: [H ? /* @__PURE__ */ p(r, { className: "w-5 h-5 animate-spin text-text-link" }) : /* @__PURE__ */ p("svg", {
357
- className: "w-5 h-5 text-text-tertiary",
360
+ children: [H ? /* @__PURE__ */ p(t, { className: "size-5 animate-spin text-text-link" }) : /* @__PURE__ */ p("svg", {
361
+ className: "size-5 text-text-tertiary",
358
362
  fill: "none",
359
363
  viewBox: "0 0 24 24",
360
364
  stroke: "currentColor",
@@ -412,8 +416,8 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
412
416
  },
413
417
  disabled: H || !B,
414
418
  className: "px-4 py-2.5 rounded-xl bg-action-primary-bg text-white font-medium hover:bg-action-primary-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center gap-2",
415
- children: [H ? /* @__PURE__ */ p(r, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ p("svg", {
416
- className: "w-4 h-4",
419
+ children: [H ? /* @__PURE__ */ p(t, { className: "size-4 animate-spin" }) : /* @__PURE__ */ p("svg", {
420
+ className: "size-4",
417
421
  fill: "none",
418
422
  viewBox: "0 0 24 24",
419
423
  stroke: "currentColor",
@@ -452,6 +456,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
452
456
  className: "flex-1 px-3 py-2 rounded-lg bg-bg-sunken text-sm text-text-primary font-mono",
453
457
  children: [window.location.origin, "/auth/saml/metadata"]
454
458
  }), /* @__PURE__ */ p("button", {
459
+ type: "button",
455
460
  onClick: () => void h(`${window.location.origin}/auth/saml/metadata`),
456
461
  className: "px-3 py-2 rounded-lg border border-border-default text-text-secondary hover:bg-bg-sunken",
457
462
  children: j("auth.sso.copy", "Copy")
@@ -465,6 +470,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
465
470
  className: "flex-1 px-3 py-2 rounded-lg bg-bg-sunken text-sm text-text-primary font-mono",
466
471
  children: [window.location.origin, "/auth/sso/callback"]
467
472
  }), /* @__PURE__ */ p("button", {
473
+ type: "button",
468
474
  onClick: () => void h(`${window.location.origin}/auth/sso/callback`),
469
475
  className: "px-3 py-2 rounded-lg border border-border-default text-text-secondary hover:bg-bg-sunken",
470
476
  children: j("auth.sso.copy", "Copy")
@@ -637,7 +643,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
637
643
  type: "submit",
638
644
  disabled: D,
639
645
  className: "auth-primary-button flex items-center gap-2 px-6 py-3 font-medium",
640
- children: D ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(r, { className: "w-4 h-4 animate-spin" }), j("auth.sso.saving", "Saving...")] }) : j("auth.sso.saveConfig", "Save Configuration")
646
+ children: D ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(t, { className: "size-4 animate-spin" }), j("auth.sso.saving", "Saving...")] }) : j("auth.sso.saveConfig", "Save Configuration")
641
647
  }), N && /* @__PURE__ */ p("button", {
642
648
  type: "button",
643
649
  onClick: () => {
@@ -667,10 +673,11 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
667
673
  children: j("auth.sso.dangerZoneDesc", "Deleting the SSO configuration will prevent users from signing in with their enterprise credentials. This action cannot be undone.")
668
674
  }),
669
675
  /* @__PURE__ */ p("button", {
676
+ type: "button",
670
677
  onClick: () => F(!0),
671
678
  disabled: O,
672
679
  className: "px-4 py-2 rounded-lg bg-status-error-bg text-white font-medium hover:bg-status-error-bg-hover disabled:opacity-50 transition-colors flex items-center gap-2",
673
- children: O ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(r, { className: "w-4 h-4 animate-spin" }), j("auth.sso.deleting", "Deleting...")] }) : j("auth.sso.deleteConfig", "Delete SSO Configuration")
680
+ children: O ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(t, { className: "size-4 animate-spin" }), j("auth.sso.deleting", "Deleting...")] }) : j("auth.sso.deleteConfig", "Delete SSO Configuration")
674
681
  })
675
682
  ]
676
683
  })
@@ -706,6 +713,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
706
713
  className: "flex-1 px-3 py-2 rounded-lg bg-bg-sunken text-sm text-text-primary font-mono break-all",
707
714
  children: T?.issuer ? `${T.issuer}/.well-known/openid-configuration` : "Discovery endpoint unavailable until OIDC is configured"
708
715
  }), /* @__PURE__ */ p("button", {
716
+ type: "button",
709
717
  onClick: () => {
710
718
  let e = T?.issuer ? `${T.issuer}/.well-known/openid-configuration` : "";
711
719
  e && h(e);
@@ -791,7 +799,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
791
799
  }
792
800
  ].map((e) => /* @__PURE__ */ m("div", {
793
801
  className: "flex items-center gap-2",
794
- children: [/* @__PURE__ */ p("span", { className: `w-2 h-2 rounded-full ${e.status ? "bg-status-success-text" : "bg-bg-sunken"}` }), /* @__PURE__ */ p("span", {
802
+ children: [/* @__PURE__ */ p("span", { className: `size-2 rounded-full ${e.status ? "bg-status-success-text" : "bg-bg-sunken"}` }), /* @__PURE__ */ p("span", {
795
803
  className: "text-sm text-text-primary",
796
804
  children: e.name
797
805
  })]
@@ -824,10 +832,11 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
824
832
  className: "text-sm text-status-success-text mt-1",
825
833
  children: j("auth.sso.clientCreatedDesc", "Save these credentials securely. The client secret will not be shown again.")
826
834
  })] }), /* @__PURE__ */ p("button", {
835
+ type: "button",
827
836
  onClick: () => Z(null),
828
837
  className: "text-status-success-text hover:text-status-success-text",
829
838
  children: /* @__PURE__ */ p("svg", {
830
- className: "w-5 h-5",
839
+ className: "size-5",
831
840
  fill: "none",
832
841
  viewBox: "0 0 24 24",
833
842
  stroke: "currentColor",
@@ -851,6 +860,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
851
860
  className: "flex-1 px-3 py-2 rounded-lg bg-bg-surface text-sm font-mono border border-status-success-border",
852
861
  children: X.client_id
853
862
  }), /* @__PURE__ */ p("button", {
863
+ type: "button",
854
864
  onClick: () => void h(X.client_id),
855
865
  className: "px-3 py-2 rounded-lg bg-status-success-bg text-white text-sm hover:bg-status-success-bg",
856
866
  children: j("auth.sso.copy", "Copy")
@@ -865,6 +875,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
865
875
  className: "flex-1 px-3 py-2 rounded-lg bg-bg-surface text-sm font-mono border border-status-success-border",
866
876
  children: X.client_secret
867
877
  }), /* @__PURE__ */ p("button", {
878
+ type: "button",
868
879
  onClick: () => void h(X.client_secret || ""),
869
880
  className: "px-3 py-2 rounded-lg bg-status-success-bg text-white text-sm hover:bg-status-success-bg",
870
881
  children: j("auth.sso.copy", "Copy")
@@ -888,10 +899,11 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
888
899
  className: "text-lg font-medium text-text-primary",
889
900
  children: j("auth.sso.registerClient", "Register New Client")
890
901
  }), !W && /* @__PURE__ */ m("button", {
902
+ type: "button",
891
903
  onClick: () => G(!0),
892
904
  className: "px-4 py-2 rounded-lg bg-action-primary-bg text-white font-medium hover:bg-action-primary-bg-hover transition-colors flex items-center gap-2",
893
905
  children: [/* @__PURE__ */ p("svg", {
894
- className: "w-4 h-4",
906
+ className: "size-4",
895
907
  fill: "none",
896
908
  viewBox: "0 0 24 24",
897
909
  stroke: "currentColor",
@@ -986,7 +998,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
986
998
  grant_types: K.grant_types.filter((t) => t !== e)
987
999
  });
988
1000
  },
989
- className: "w-4 h-4 rounded border-border-default text-text-link focus:ring-action-primary-bg"
1001
+ className: "size-4 rounded border-border-default text-text-link focus:ring-action-primary-bg"
990
1002
  }), /* @__PURE__ */ p("span", {
991
1003
  className: "text-sm text-text-primary",
992
1004
  children: e.replace(/_/g, " ")
@@ -1023,6 +1035,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
1023
1035
  /* @__PURE__ */ m("div", {
1024
1036
  className: "flex items-center gap-3 pt-2",
1025
1037
  children: [/* @__PURE__ */ p("button", {
1038
+ type: "button",
1026
1039
  onClick: async () => {
1027
1040
  if (!K.client_name || !K.redirect_uris) {
1028
1041
  L(j("auth.sso.clientRequired", "Client name and redirect URI are required"));
@@ -1061,8 +1074,9 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
1061
1074
  },
1062
1075
  disabled: J,
1063
1076
  className: "auth-primary-button flex items-center gap-2 px-6 py-3 font-medium",
1064
- children: J ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(r, { className: "w-4 h-4 animate-spin" }), j("auth.sso.registering", "Registering...")] }) : j("auth.sso.registerClientButton", "Register Client")
1077
+ children: J ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(t, { className: "size-4 animate-spin" }), j("auth.sso.registering", "Registering...")] }) : j("auth.sso.registerClientButton", "Register Client")
1065
1078
  }), /* @__PURE__ */ p("button", {
1079
+ type: "button",
1066
1080
  onClick: () => {
1067
1081
  G(!1), q({
1068
1082
  client_name: "",
@@ -1079,7 +1093,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
1079
1093
  }) : /* @__PURE__ */ m("div", {
1080
1094
  className: "text-center py-8 text-text-secondary",
1081
1095
  children: [/* @__PURE__ */ p("svg", {
1082
- className: "w-12 h-12 mx-auto mb-3 text-text-muted",
1096
+ className: "size-12 mx-auto mb-3 text-text-muted",
1083
1097
  fill: "none",
1084
1098
  viewBox: "0 0 24 24",
1085
1099
  stroke: "currentColor",
@@ -1170,7 +1184,7 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
1170
1184
  href: `${window.location.origin}/auth/sso/login`,
1171
1185
  className: "inline-flex items-center gap-2 px-6 py-3 rounded-xl bg-status-success-bg text-white font-medium shadow-sm hover:opacity-90 transition-all duration-200",
1172
1186
  children: [/* @__PURE__ */ p("svg", {
1173
- className: "w-5 h-5",
1187
+ className: "size-5",
1174
1188
  fill: "none",
1175
1189
  viewBox: "0 0 24 24",
1176
1190
  stroke: "currentColor",
@@ -1206,8 +1220,8 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
1206
1220
  className: "text-center py-16 border-2 border-dashed border-border-subtle rounded-xl",
1207
1221
  children: [
1208
1222
  /* @__PURE__ */ p("div", {
1209
- className: "w-16 h-16 mx-auto mb-4 rounded-full bg-status-warning-bg-subtle flex items-center justify-center",
1210
- children: /* @__PURE__ */ p(n, { className: "w-8 h-8 text-status-warning-text" })
1223
+ className: "size-16 mx-auto mb-4 rounded-full bg-status-warning-bg-subtle flex items-center justify-center",
1224
+ children: /* @__PURE__ */ p(e, { className: "size-8 text-status-warning-text" })
1211
1225
  }),
1212
1226
  /* @__PURE__ */ p("h2", {
1213
1227
  className: "text-xl font-semibold text-text-primary mb-2",
@@ -1229,8 +1243,8 @@ function _({ bypassEnterprisePlanGate: a = !1 }) {
1229
1243
  className: "text-center py-16 border-2 border-dashed border-border-subtle rounded-xl",
1230
1244
  children: [
1231
1245
  /* @__PURE__ */ p("div", {
1232
- className: "w-16 h-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center",
1233
- children: /* @__PURE__ */ p(n, { className: "w-8 h-8 text-status-error-text" })
1246
+ className: "size-16 mx-auto mb-4 rounded-full bg-status-error-bg-subtle flex items-center justify-center",
1247
+ children: /* @__PURE__ */ p(e, { className: "size-8 text-status-error-text" })
1234
1248
  }),
1235
1249
  /* @__PURE__ */ p("h2", {
1236
1250
  className: "text-xl font-semibold text-text-primary mb-2",