@burdenoff/microfe-auth 2026.518.4 → 2026.519.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/auth/pages/LoginPage.d.ts.map +1 -1
  2. package/dist/auth/pages/LoginPage.js +2 -0
  3. package/dist/auth/pages/LoginPage.js.map +1 -1
  4. package/dist/auth/pages/MfaSetupPage.d.ts.map +1 -1
  5. package/dist/auth/pages/MfaSetupPage.js +9 -4
  6. package/dist/auth/pages/MfaSetupPage.js.map +1 -1
  7. package/dist/auth/pages/PasswordResetPage.d.ts.map +1 -1
  8. package/dist/auth/pages/PasswordResetPage.js +7 -0
  9. package/dist/auth/pages/PasswordResetPage.js.map +1 -1
  10. package/dist/auth/pages/RegisterPage.d.ts.map +1 -1
  11. package/dist/auth/pages/RegisterPage.js +8 -0
  12. package/dist/auth/pages/RegisterPage.js.map +1 -1
  13. package/dist/auth/pages/SSODepositPage.d.ts.map +1 -1
  14. package/dist/auth/pages/SSODepositPage.js.map +1 -1
  15. package/dist/auth/pages/SecurityPage.d.ts.map +1 -1
  16. package/dist/auth/pages/SecurityPage.js +9 -0
  17. package/dist/auth/pages/SecurityPage.js.map +1 -1
  18. package/dist/auth/pages/SsoConfigPage.d.ts.map +1 -1
  19. package/dist/auth/pages/SsoConfigPage.js +39 -1
  20. package/dist/auth/pages/SsoConfigPage.js.map +1 -1
  21. package/dist/auth/pages/SsoLoginPage.d.ts.map +1 -1
  22. package/dist/auth/pages/SsoLoginPage.js +8 -5
  23. package/dist/auth/pages/SsoLoginPage.js.map +1 -1
  24. package/dist/auth/pages/UserDetailsPage.d.ts +1 -1
  25. package/dist/auth/pages/UserDetailsPage.d.ts.map +1 -1
  26. package/dist/auth/pages/UserDetailsPage.js +251 -174
  27. package/dist/auth/pages/UserDetailsPage.js.map +1 -1
  28. package/dist/translations/en.d.ts +55 -0
  29. package/dist/translations/en.d.ts.map +1 -1
  30. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"SecurityPage.js","names":[],"sources":["../../../src/auth/pages/SecurityPage.tsx"],"sourcesContent":["import { useId, useRef, useEffect, useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { ConfirmActionDialog } from \"../components/ConfirmActionDialog\";\nimport { useAuthOperations, useAccountOperations } from \"../hooks\";\nimport { formatDate } from \"../utils\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n// Icons\nconst ShieldIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\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);\n\nconst LockIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n);\n\n// Hidden — moved to Developer Portal\n// const KeyIcon = ({ className }: { className?: string }) => (\n// <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n// <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5}\n// d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z\" />\n// </svg>\n// );\n\n// const DelegationIcon = ({ className }: { className?: string }) => (\n// <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n// <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5}\n// d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z\" />\n// </svg>\n// );\n\nconst UsersIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z\"\n />\n </svg>\n);\n\nconst UserProfileIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"\n />\n </svg>\n);\n\nconst LinkIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"\n />\n </svg>\n);\n\nconst ChevronRightIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n);\n\nconst CheckCircleIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clipRule=\"evenodd\"\n />\n </svg>\n);\n\nconst ExclamationIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n);\n\nconst SpinnerIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\ninterface NavItem {\n name: string;\n description: string;\n path: string;\n icon: React.FC<{ className?: string }>;\n color: string;\n bgColor: string;\n adminOnly?: boolean;\n}\n\nconst DELETE_ACCOUNT_CONFIRMATION = \"DELETE MY ACCOUNT\";\n\n/**\n * Security Dashboard - Main hub for all authentication features\n */\nexport function SecurityPage() {\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 user = useAuthStore((state) => state.user);\n const { signOut } = useAuthOperations({\n disableCurrentUserQuery: true,\n });\n const { deactivateAccount, deleteAccount, isDeactivating, isDeleting } =\n useAccountOperations();\n const [isLoggingOut, setIsLoggingOut] = useState(false);\n const [showLogoutDialog, setShowLogoutDialog] = useState(false);\n\n const navigationItems: NavItem[] = [\n {\n name: tr(\"auth.security.navProfile\", \"User Profile\"),\n description: tr(\n \"auth.security.navProfileDesc\",\n \"View and edit your profile information\",\n ),\n path: \"/auth/profile\",\n icon: UserProfileIcon,\n color: \"text-accent-teal\",\n bgColor: \"bg-accent-teal-subtle\",\n },\n {\n name: tr(\"auth.security.navMfa\", \"Two-Factor Authentication\"),\n description: tr(\n \"auth.security.navMfaDesc\",\n \"Secure your account with TOTP\",\n ),\n path: \"/auth/mfa\",\n icon: LockIcon,\n color: \"text-accent-purple\",\n bgColor: \"bg-accent-purple-subtle\",\n },\n // Hidden — moved to Developer Portal\n // {\n // name: tr(\"auth.security.navApiKeys\", \"API Keys\"),\n // description: tr(\"auth.security.navApiKeysDesc\", \"Manage programmatic access tokens\"),\n // path: \"/auth/api-keys\",\n // icon: KeyIcon,\n // color: \"text-status-warning-text\",\n // bgColor: \"bg-status-warning-bg-subtle\",\n // },\n // {\n // name: tr(\"auth.security.navDelegations\", \"Delegations\"),\n // description: tr(\"auth.security.navDelegationsDesc\", \"Manage apps acting on your behalf\"),\n // path: \"/auth/delegations\",\n // icon: DelegationIcon,\n // color: \"text-status-warning-text\",\n // bgColor: \"bg-status-warning-bg-subtle\",\n // },\n {\n name: tr(\"auth.security.navUsers\", \"Users\"),\n description: tr(\"auth.security.navUsersDesc\", \"Manage system users\"),\n path: \"/auth/users\",\n icon: UsersIcon,\n color: \"text-accent-indigo\",\n bgColor: \"bg-accent-indigo-subtle\",\n adminOnly: true,\n },\n ];\n\n const quickActions = [\n {\n name: tr(\"auth.security.navSso\", \"SSO Configuration\"),\n description: tr(\"auth.security.navSsoDesc\", \"Enterprise single sign-on\"),\n path: \"/auth/sso\",\n icon: LinkIcon,\n color: \"text-accent-cyan\",\n bgColor: \"bg-accent-cyan-subtle\",\n adminOnly: true,\n },\n ];\n\n // Account management modal states\n const [showDeactivateModal, setShowDeactivateModal] = useState(false);\n const [showDeleteModal, setShowDeleteModal] = useState(false);\n const [accountPassword, setAccountPassword] = useState(\"\");\n const [deleteConfirmPhrase, setDeleteConfirmPhrase] = useState(\"\");\n const [accountError, setAccountError] = useState<string | null>(null);\n const [accountSuccess, setAccountSuccess] = useState<string | null>(null);\n\n // Accessible IDs for modal labels and form fields\n const deactivateTitleId = useId();\n const deactivatePasswordId = useId();\n const deactivateErrorId = useId();\n const deleteTitleId = useId();\n const deletePasswordId = useId();\n const deleteConfirmId = useId();\n const deleteErrorId = useId();\n\n // Focus management: refs to restore focus and manage modal focus\n const deactivateTriggerRef = useRef<HTMLButtonElement>(null);\n const deleteTriggerRef = useRef<HTMLButtonElement>(null);\n const deactivateDialogRef = useRef<HTMLDivElement>(null);\n const deleteDialogRef = useRef<HTMLDivElement>(null);\n\n // Move focus into modal when it opens; restore to trigger on close\n useEffect(() => {\n if (showDeactivateModal) {\n deactivateDialogRef.current?.focus();\n } else {\n deactivateTriggerRef.current?.focus();\n }\n }, [showDeactivateModal]);\n\n useEffect(() => {\n if (showDeleteModal) {\n deleteDialogRef.current?.focus();\n } else {\n deleteTriggerRef.current?.focus();\n }\n }, [showDeleteModal]);\n\n const handleLogout = async () => {\n setIsLoggingOut(true);\n try {\n await signOut();\n navigate(\"/auth/login\");\n setShowLogoutDialog(false);\n } catch (error) {\n console.error(\"Logout failed:\", error);\n setIsLoggingOut(false);\n }\n };\n\n const handleDeactivateAccount = async () => {\n setAccountError(null);\n try {\n const result = await deactivateAccount(accountPassword);\n if (result.success) {\n // Immediately redirect to login page\n navigate(\"/auth/login\", { replace: true });\n } else {\n setAccountError(\n result.message ||\n tr(\n \"auth.security.deactivateFailed\",\n \"Failed to deactivate account\",\n ),\n );\n }\n } catch (error) {\n setAccountError(\n error instanceof Error\n ? error.message\n : tr(\n \"auth.security.deactivateFailed\",\n \"Failed to deactivate account\",\n ),\n );\n }\n };\n\n const handleDeleteAccount = async () => {\n setAccountError(null);\n if (deleteConfirmPhrase !== DELETE_ACCOUNT_CONFIRMATION) {\n setAccountError(\n tr(\n \"auth.security.deleteConfirmMismatch\",\n 'Please type \"DELETE MY ACCOUNT\" to confirm',\n ),\n );\n return;\n }\n void nativeImpact(\"medium\");\n try {\n const result = await deleteAccount(accountPassword, deleteConfirmPhrase);\n if (result.success) {\n void nativeNotify(\"success\");\n // Immediately redirect to login page\n navigate(\"/auth/login\", { replace: true });\n } else {\n void nativeNotify(\"error\");\n setAccountError(\n result.message ||\n tr(\"auth.security.deleteFailed\", \"Failed to delete account\"),\n );\n }\n } catch (error) {\n void nativeNotify(\"error\");\n setAccountError(\n error instanceof Error\n ? error.message\n : tr(\"auth.security.deleteFailed\", \"Failed to delete account\"),\n );\n }\n };\n\n const closeModals = () => {\n setShowDeactivateModal(false);\n setShowDeleteModal(false);\n setAccountPassword(\"\");\n setDeleteConfirmPhrase(\"\");\n setAccountError(null);\n setAccountSuccess(null);\n };\n\n const isAdmin =\n user?.role === \"SUPER_ADMIN\" ||\n user?.role === \"TENANT_ADMIN\" ||\n user?.role === \"ORG_ADMIN\";\n const filteredNavItems = navigationItems.filter(\n (item) => !item.adminOnly || isAdmin,\n );\n const filteredQuickActions = quickActions.filter(\n (item) => !item.adminOnly || isAdmin,\n );\n\n return (\n <div className=\"bg-bg-canvas p-6\">\n <ConfirmActionDialog\n open={showLogoutDialog}\n onOpenChange={setShowLogoutDialog}\n title={tr(\"auth.security.signOutDialogTitle\", \"Sign out now?\")}\n description={tr(\n \"auth.security.signOutDialogDescription\",\n \"You will be signed out of this device and returned to the login screen.\",\n )}\n confirmText={tr(\"auth.security.signOutDialogConfirm\", \"Sign out\")}\n variant=\"warning\"\n isPending={isLoggingOut}\n onConfirm={handleLogout}\n />\n <main className=\"max-w-7xl mx-auto space-y-8\">\n <div className=\"flex items-center gap-3\">\n <div className=\"auth-brand-badge flex h-10 w-10 items-center justify-center rounded-xl\">\n <ShieldIcon className=\"w-6 h-6 text-white\" />\n </div>\n <div>\n <h1 className=\"text-lg font-bold text-text-primary\">\n {tr(\"auth.security.title\", \"Security Center\")}\n </h1>\n <p className=\"text-xs text-text-secondary \">\n {tr(\"auth.security.subtitle\", \"Account & Authentication\")}\n </p>\n </div>\n </div>\n\n {/* Security Status Banner */}\n <div className=\"auth-hero-card rounded-2xl p-6\">\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between gap-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"w-14 h-14 rounded-2xl bg-bg-surface/20 backdrop-blur flex items-center justify-center\">\n <ShieldIcon className=\"w-8 h-8 text-white\" />\n </div>\n <div>\n <h2 className=\"text-xl font-bold\">\n {tr(\"auth.security.securityStatus\", \"Security Status\")}\n </h2>\n <p className=\"opacity-80\">\n {user?.mfaEnabled\n ? tr(\n \"auth.security.wellProtected\",\n \"Your account is well protected\",\n )\n : tr(\n \"auth.security.enableMfaSuggestion\",\n \"Enable MFA for better security\",\n )}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n {user?.mfaEnabled ? (\n <span className=\"inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-bg-surface/20 backdrop-blur text-white font-medium\">\n <CheckCircleIcon className=\"w-5 h-5 text-status-success-text\" />\n {tr(\"auth.security.mfaEnabled\", \"MFA Enabled\")}\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/mfa\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-bg-surface text-text-link font-semibold hover:bg-status-info-bg-subtle transition-colors shadow-lg\"\n >\n <ExclamationIcon className=\"w-5 h-5 text-status-warning-text\" />\n {tr(\"auth.security.enableMfaNow\", \"Enable MFA Now\")}\n </button>\n )}\n </div>\n </div>\n </div>\n\n {/* Account Information Card */}\n <div className=\"mb-8 p-6 rounded-2xl bg-bg-surface border border-border-subtle shadow-sm\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr(\"auth.security.accountInfo\", \"Account Information\")}\n </h3>\n <dl className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6\">\n <div className=\"sm:col-span-2 lg:col-span-1\">\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.email\", \"Email\")}\n </dt>\n <dd className=\"mt-1 text-text-primary\">\n <span className=\"block truncate\" title={user?.email}>\n {user?.email}\n </span>\n {user?.emailVerified && (\n <span className=\"mt-1 inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-status-success-bg-subtle text-status-success-text text-xs font-medium\">\n <CheckCircleIcon className=\"w-3 h-3\" />\n {tr(\"auth.security.verified\", \"Verified\")}\n </span>\n )}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.username\", \"Username\")}\n </dt>\n <dd\n className=\"mt-1 text-text-primary truncate\"\n title={user?.username ?? undefined}\n >\n {user?.username || \"-\"}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.role\", \"Role\")}\n </dt>\n <dd className=\"mt-1\">\n <span className=\"inline-flex px-2.5 py-0.5 rounded-full bg-accent-indigo-subtle text-accent-indigo text-xs font-medium\">\n {user?.role || \"USER\"}\n </span>\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.memberSince\", \"Member Since\")}\n </dt>\n <dd className=\"mt-1 text-text-primary\">\n {user?.createdAt ? formatDate(user.createdAt) : \"-\"}\n </dd>\n </div>\n </dl>\n </div>\n\n {/* Main Navigation Grid */}\n <div className=\"mb-8\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr(\"auth.security.securityAuth\", \"Security & Authentication\")}\n </h3>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {filteredNavItems.map((item) => (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => navigate(item.path)}\n aria-label={item.name}\n className=\"group relative p-5 rounded-2xl bg-bg-surface border border-border-subtle hover:border-border-default hover:shadow-lg transition-all duration-200 text-left\"\n >\n <div className=\"flex items-start gap-4\">\n <div\n className={`w-12 h-12 rounded-xl ${item.bgColor} flex items-center justify-center flex-shrink-0 transition-transform group-hover:scale-110`}\n >\n <item.icon className={`w-6 h-6 ${item.color}`} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"text-base font-semibold text-text-primary group-hover:text-accent-indigo transition-colors\">\n {item.name}\n </h4>\n <p className=\"mt-1 text-sm text-text-secondary \">\n {item.description}\n </p>\n </div>\n <ChevronRightIcon className=\"w-5 h-5 text-text-tertiary group-hover:text-indigo-500 transition-colors flex-shrink-0\" />\n </div>\n </button>\n ))}\n </div>\n </div>\n\n {/* Quick Actions */}\n <div className=\"mb-8\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr(\"auth.security.quickActions\", \"Quick Actions\")}\n </h3>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {filteredQuickActions.map((item) => (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => navigate(item.path)}\n aria-label={item.name}\n className=\"group relative p-5 rounded-2xl bg-bg-surface border border-border-subtle hover:border-border-default hover:shadow-lg transition-all duration-200 text-left\"\n >\n <div className=\"flex items-start gap-4\">\n <div\n className={`w-12 h-12 rounded-xl ${item.bgColor} flex items-center justify-center flex-shrink-0 transition-transform group-hover:scale-110`}\n >\n <item.icon className={`w-6 h-6 ${item.color}`} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"text-base font-semibold text-text-primary group-hover:text-accent-indigo transition-colors\">\n {item.name}\n </h4>\n <p className=\"mt-1 text-sm text-text-secondary \">\n {item.description}\n </p>\n </div>\n <ChevronRightIcon className=\"w-5 h-5 text-text-tertiary group-hover:text-indigo-500 transition-colors flex-shrink-0\" />\n </div>\n </button>\n ))}\n </div>\n </div>\n\n {/* Password & Danger Zone */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n {/* Password Section */}\n <div className=\"p-6 rounded-2xl bg-bg-surface border border-border-subtle \">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {tr(\"auth.security.password\", \"Password\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary \">\n {tr(\n \"auth.security.updatePassword\",\n \"Update your password to keep your account secure\",\n )}\n </p>\n <p className=\"mt-2 text-xs text-text-tertiary \">\n {tr(\"auth.security.lastChanged\", \"Last changed: Never\")}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/reset-password\")}\n className=\"auth-primary-button mt-4 w-full px-5 py-2.5 font-semibold sm:w-auto\"\n >\n {tr(\"auth.security.changePassword\", \"Change Password\")}\n </button>\n </div>\n\n {/* Danger Zone */}\n <div className=\"p-6 rounded-2xl bg-status-error-bg-subtle border border-status-error-border\">\n <h3 className=\"text-lg font-semibold text-status-error-text\">\n {tr(\"auth.security.dangerZone\", \"Danger Zone\")}\n </h3>\n <p className=\"mt-1 text-sm text-status-error-text/80\">\n {tr(\n \"auth.security.dangerWarning\",\n \"These actions affect your account. Proceed with caution.\",\n )}\n </p>\n <div className=\"mt-4 flex flex-wrap gap-3\">\n <button\n ref={deactivateTriggerRef}\n type=\"button\"\n onClick={() => setShowDeactivateModal(true)}\n className=\"px-5 py-2.5 rounded-xl border-2 border-status-warning-border text-status-warning-text font-semibold hover:bg-status-warning-bg-subtle transition-all duration-200\"\n >\n {tr(\"auth.security.deactivateAccount\", \"Deactivate Account\")}\n </button>\n <button\n ref={deleteTriggerRef}\n type=\"button\"\n onClick={() => setShowDeleteModal(true)}\n className=\"px-5 py-2.5 rounded-xl border-2 border-status-error-border text-status-error-text font-semibold hover:bg-status-error-bg-subtle transition-all duration-200\"\n >\n {tr(\"auth.security.deleteAccount\", \"Delete Account\")}\n </button>\n </div>\n </div>\n </div>\n\n {/* Deactivate Account Modal */}\n {showDeactivateModal && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4\"\n role=\"presentation\"\n onClick={(e) => {\n if (e.target === e.currentTarget) closeModals();\n }}\n >\n <div\n ref={deactivateDialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={deactivateTitleId}\n tabIndex={-1}\n className=\"w-full max-w-md bg-bg-surface rounded-2xl shadow-2xl p-6 outline-none\"\n >\n <h3\n id={deactivateTitleId}\n className=\"text-xl font-bold text-text-primary mb-2\"\n >\n {tr(\"auth.security.deactivateTitle\", \"Deactivate Account\")}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {tr(\n \"auth.security.deactivateDesc\",\n \"Your account will be temporarily disabled. You can reactivate it by signing in again with your credentials.\",\n )}\n </p>\n {accountError && (\n <div\n id={deactivateErrorId}\n role=\"alert\"\n className=\"mb-4 p-3 rounded-lg bg-status-error-bg-subtle text-status-error-text text-sm\"\n >\n {accountError}\n </div>\n )}\n {accountSuccess && (\n <div\n role=\"status\"\n className=\"mb-4 p-3 rounded-lg bg-status-success-bg-subtle text-status-success-text text-sm\"\n >\n {accountSuccess}\n </div>\n )}\n <div className=\"mb-4\">\n <label\n htmlFor={deactivatePasswordId}\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr(\n \"auth.security.enterPasswordConfirm\",\n \"Enter your password to confirm\",\n )}\n </label>\n <input\n id={deactivatePasswordId}\n type=\"password\"\n value={accountPassword}\n onChange={(e) => setAccountPassword(e.target.value)}\n aria-describedby={\n accountError ? deactivateErrorId : undefined\n }\n className=\"w-full px-4 py-2 rounded-lg border border-border-default bg-bg-surface text-text-primary focus:ring-2 focus:ring-status-warning-bg focus:border-transparent\"\n placeholder={tr(\n \"auth.security.yourPassword\",\n \"Your password\",\n )}\n />\n </div>\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={closeModals}\n className=\"flex-1 px-4 py-2 rounded-lg border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"auth.security.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleDeactivateAccount()}\n disabled={!accountPassword || isDeactivating}\n className=\"flex-1 px-4 py-2 rounded-lg bg-status-warning-bg text-white font-medium hover:bg-status-warning-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2\"\n >\n {isDeactivating && (\n <SpinnerIcon className=\"w-4 h-4 animate-spin\" />\n )}\n {tr(\"auth.security.deactivateBtn\", \"Deactivate\")}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Delete Account Modal */}\n {showDeleteModal && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4\"\n role=\"presentation\"\n onClick={(e) => {\n if (e.target === e.currentTarget) closeModals();\n }}\n >\n <div\n ref={deleteDialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={deleteTitleId}\n tabIndex={-1}\n className=\"w-full max-w-md bg-bg-surface rounded-2xl shadow-2xl p-6 outline-none\"\n >\n <h3\n id={deleteTitleId}\n className=\"text-xl font-bold text-status-error-text mb-2\"\n >\n {tr(\"auth.security.deleteTitle\", \"Delete Account Permanently\")}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {tr(\n \"auth.security.deleteDesc\",\n \"This action is irreversible. All your data will be permanently deleted and cannot be recovered.\",\n )}\n </p>\n {accountError && (\n <div\n id={deleteErrorId}\n role=\"alert\"\n className=\"mb-4 p-3 rounded-lg bg-status-error-bg-subtle text-status-error-text text-sm\"\n >\n {accountError}\n </div>\n )}\n {accountSuccess && (\n <div\n role=\"status\"\n className=\"mb-4 p-3 rounded-lg bg-status-success-bg-subtle text-status-success-text text-sm\"\n >\n {accountSuccess}\n </div>\n )}\n <div className=\"mb-4\">\n <label\n htmlFor={deletePasswordId}\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr(\n \"auth.security.enterPasswordDelete\",\n \"Enter your password\",\n )}\n </label>\n <input\n id={deletePasswordId}\n type=\"password\"\n value={accountPassword}\n onChange={(e) => setAccountPassword(e.target.value)}\n aria-describedby={accountError ? deleteErrorId : undefined}\n className=\"w-full px-4 py-2 rounded-lg border border-border-default bg-bg-surface text-text-primary focus:ring-2 focus:ring-status-error-bg focus:border-transparent\"\n placeholder={tr(\n \"auth.security.yourPassword\",\n \"Your password\",\n )}\n />\n </div>\n <div className=\"mb-4\">\n <label\n htmlFor={deleteConfirmId}\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr(\"auth.security.type\", \"Type\")}{\" \"}\n <code className=\"px-1 py-0.5 rounded bg-bg-sunken text-status-error-text font-mono text-sm\">\n {DELETE_ACCOUNT_CONFIRMATION}\n </code>{\" \"}\n {tr(\"auth.security.toConfirm\", \"to confirm\")}\n </label>\n <input\n id={deleteConfirmId}\n type=\"text\"\n value={deleteConfirmPhrase}\n onChange={(e) => setDeleteConfirmPhrase(e.target.value)}\n aria-describedby={accountError ? deleteErrorId : undefined}\n className=\"w-full px-4 py-2 rounded-lg border border-border-default bg-bg-surface text-text-primary focus:ring-2 focus:ring-status-error-bg focus:border-transparent font-mono\"\n placeholder={tr(\n \"auth.security.deleteConfirmPlaceholder\",\n \"DELETE MY ACCOUNT\",\n )}\n />\n </div>\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={closeModals}\n className=\"flex-1 px-4 py-2 rounded-lg border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"auth.security.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleDeleteAccount()}\n disabled={\n !accountPassword ||\n deleteConfirmPhrase !== DELETE_ACCOUNT_CONFIRMATION ||\n isDeleting\n }\n className=\"flex-1 px-4 py-2 rounded-lg bg-status-error-bg text-white font-medium hover:bg-status-error-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2\"\n >\n {isDeleting && (\n <SpinnerIcon className=\"w-4 h-4 animate-spin\" />\n )}\n {tr(\"auth.security.deleteForever\", \"Delete Forever\")}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Footer */}\n <footer className=\"mt-12 pt-6 border-t border-border-subtle \">\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 text-sm text-text-secondary \">\n <p>\n {tr(\"auth.security.signedInAs\", \"Signed in as\")}{\" \"}\n <span className=\"font-medium text-text-primary \">\n {user?.email}\n </span>\n </p>\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"hover:text-text-primary transition-colors\"\n >\n {tr(\"auth.security.switchAccount\", \"Switch Account\")}\n </button>\n <span className=\"text-text-muted\" aria-hidden=\"true\">\n |\n </span>\n <button\n type=\"button\"\n onClick={() => setShowLogoutDialog(true)}\n className=\"hover:text-status-error-text transition-colors\"\n >\n {tr(\"auth.security.signOut\", \"Sign Out\")}\n </button>\n </div>\n </div>\n </footer>\n </main>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SecurityPage.js","names":[],"sources":["../../../src/auth/pages/SecurityPage.tsx"],"sourcesContent":["import { useId, useRef, useEffect, useState } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useAuthStore } from \"../store/authStore\";\nimport { ConfirmActionDialog } from \"../components/ConfirmActionDialog\";\nimport { useAuthOperations, useAccountOperations } from \"../hooks\";\nimport { formatDate } from \"../utils\";\nimport { nativeImpact, nativeNotify } from \"../../utils/nativeBridge\";\n\n// Icons\nconst ShieldIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\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);\n\nconst LockIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n);\n\n// Hidden — moved to Developer Portal\n// const KeyIcon = ({ className }: { className?: string }) => (\n// <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n// <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5}\n// d=\"M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z\" />\n// </svg>\n// );\n\n// const DelegationIcon = ({ className }: { className?: string }) => (\n// <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n// <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={1.5}\n// d=\"M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z\" />\n// </svg>\n// );\n\nconst UsersIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z\"\n />\n </svg>\n);\n\nconst UserProfileIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z\"\n />\n </svg>\n);\n\nconst LinkIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1\"\n />\n </svg>\n);\n\nconst ChevronRightIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 5l7 7-7 7\"\n />\n </svg>\n);\n\nconst CheckCircleIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z\"\n clipRule=\"evenodd\"\n />\n </svg>\n);\n\nconst ExclamationIcon = ({ className }: { className?: string }) => (\n <svg\n className={className}\n fill=\"currentColor\"\n viewBox=\"0 0 20 20\"\n aria-hidden=\"true\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z\"\n clipRule=\"evenodd\"\n />\n </svg>\n);\n\nconst SpinnerIcon = ({ className }: { className?: string }) => (\n <svg className={className} fill=\"none\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <circle\n className=\"opacity-25\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"opacity-75\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n);\n\ninterface NavItem {\n name: string;\n description: string;\n path: string;\n icon: React.FC<{ className?: string }>;\n color: string;\n bgColor: string;\n adminOnly?: boolean;\n}\n\nconst DELETE_ACCOUNT_CONFIRMATION = \"DELETE MY ACCOUNT\";\n\n/**\n * Security Dashboard - Main hub for all authentication features\n */\nexport function SecurityPage() {\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 user = useAuthStore((state) => state.user);\n const { signOut } = useAuthOperations({\n disableCurrentUserQuery: true,\n });\n const { deactivateAccount, deleteAccount, isDeactivating, isDeleting } =\n useAccountOperations();\n const [isLoggingOut, setIsLoggingOut] = useState(false);\n const [showLogoutDialog, setShowLogoutDialog] = useState(false);\n\n const navigationItems: NavItem[] = [\n {\n name: tr(\"auth.security.navProfile\", \"User Profile\"),\n description: tr(\n \"auth.security.navProfileDesc\",\n \"View and edit your profile information\",\n ),\n path: \"/auth/profile\",\n icon: UserProfileIcon,\n color: \"text-accent-teal\",\n bgColor: \"bg-accent-teal-subtle\",\n },\n {\n name: tr(\"auth.security.navMfa\", \"Two-Factor Authentication\"),\n description: tr(\n \"auth.security.navMfaDesc\",\n \"Secure your account with TOTP\",\n ),\n path: \"/auth/mfa\",\n icon: LockIcon,\n color: \"text-accent-purple\",\n bgColor: \"bg-accent-purple-subtle\",\n },\n // Hidden — moved to Developer Portal\n // {\n // name: tr(\"auth.security.navApiKeys\", \"API Keys\"),\n // description: tr(\"auth.security.navApiKeysDesc\", \"Manage programmatic access tokens\"),\n // path: \"/auth/api-keys\",\n // icon: KeyIcon,\n // color: \"text-status-warning-text\",\n // bgColor: \"bg-status-warning-bg-subtle\",\n // },\n // {\n // name: tr(\"auth.security.navDelegations\", \"Delegations\"),\n // description: tr(\"auth.security.navDelegationsDesc\", \"Manage apps acting on your behalf\"),\n // path: \"/auth/delegations\",\n // icon: DelegationIcon,\n // color: \"text-status-warning-text\",\n // bgColor: \"bg-status-warning-bg-subtle\",\n // },\n {\n name: tr(\"auth.security.navUsers\", \"Users\"),\n description: tr(\"auth.security.navUsersDesc\", \"Manage system users\"),\n path: \"/auth/users\",\n icon: UsersIcon,\n color: \"text-accent-indigo\",\n bgColor: \"bg-accent-indigo-subtle\",\n adminOnly: true,\n },\n ];\n\n const quickActions = [\n {\n name: tr(\"auth.security.navSso\", \"SSO Configuration\"),\n description: tr(\"auth.security.navSsoDesc\", \"Enterprise single sign-on\"),\n path: \"/auth/sso\",\n icon: LinkIcon,\n color: \"text-accent-cyan\",\n bgColor: \"bg-accent-cyan-subtle\",\n adminOnly: true,\n },\n ];\n\n // Account management modal states\n const [showDeactivateModal, setShowDeactivateModal] = useState(false);\n const [showDeleteModal, setShowDeleteModal] = useState(false);\n const [accountPassword, setAccountPassword] = useState(\"\");\n const [deleteConfirmPhrase, setDeleteConfirmPhrase] = useState(\"\");\n const [accountError, setAccountError] = useState<string | null>(null);\n const [accountSuccess, setAccountSuccess] = useState<string | null>(null);\n\n // Accessible IDs for modal labels and form fields\n const deactivateTitleId = useId();\n const deactivatePasswordId = useId();\n const deactivateErrorId = useId();\n const deleteTitleId = useId();\n const deletePasswordId = useId();\n const deleteConfirmId = useId();\n const deleteErrorId = useId();\n\n // Focus management: refs to restore focus and manage modal focus\n const deactivateTriggerRef = useRef<HTMLButtonElement>(null);\n const deleteTriggerRef = useRef<HTMLButtonElement>(null);\n const deactivateDialogRef = useRef<HTMLDivElement>(null);\n const deleteDialogRef = useRef<HTMLDivElement>(null);\n\n // Move focus into modal when it opens; restore to trigger on close\n useEffect(() => {\n if (showDeactivateModal) {\n deactivateDialogRef.current?.focus();\n } else {\n deactivateTriggerRef.current?.focus();\n }\n }, [showDeactivateModal]);\n\n useEffect(() => {\n if (showDeleteModal) {\n deleteDialogRef.current?.focus();\n } else {\n deleteTriggerRef.current?.focus();\n }\n }, [showDeleteModal]);\n\n const handleLogout = async () => {\n setIsLoggingOut(true);\n try {\n await signOut();\n navigate(\"/auth/login\");\n setShowLogoutDialog(false);\n } catch (error) {\n console.error(\"Logout failed:\", error);\n setIsLoggingOut(false);\n }\n };\n\n const handleDeactivateAccount = async () => {\n setAccountError(null);\n try {\n const result = await deactivateAccount(accountPassword);\n if (result.success) {\n // Immediately redirect to login page\n navigate(\"/auth/login\", { replace: true });\n } else {\n setAccountError(\n result.message ||\n tr(\n \"auth.security.deactivateFailed\",\n \"Failed to deactivate account\",\n ),\n );\n }\n } catch (error) {\n setAccountError(\n error instanceof Error\n ? error.message\n : tr(\n \"auth.security.deactivateFailed\",\n \"Failed to deactivate account\",\n ),\n );\n }\n };\n\n const handleDeleteAccount = async () => {\n setAccountError(null);\n if (deleteConfirmPhrase !== DELETE_ACCOUNT_CONFIRMATION) {\n setAccountError(\n tr(\n \"auth.security.deleteConfirmMismatch\",\n 'Please type \"DELETE MY ACCOUNT\" to confirm',\n ),\n );\n return;\n }\n void nativeImpact(\"medium\");\n try {\n const result = await deleteAccount(accountPassword, deleteConfirmPhrase);\n if (result.success) {\n void nativeNotify(\"success\");\n // Immediately redirect to login page\n navigate(\"/auth/login\", { replace: true });\n } else {\n void nativeNotify(\"error\");\n setAccountError(\n result.message ||\n tr(\"auth.security.deleteFailed\", \"Failed to delete account\"),\n );\n }\n } catch (error) {\n void nativeNotify(\"error\");\n setAccountError(\n error instanceof Error\n ? error.message\n : tr(\"auth.security.deleteFailed\", \"Failed to delete account\"),\n );\n }\n };\n\n const closeModals = () => {\n setShowDeactivateModal(false);\n setShowDeleteModal(false);\n setAccountPassword(\"\");\n setDeleteConfirmPhrase(\"\");\n setAccountError(null);\n setAccountSuccess(null);\n };\n\n const isAdmin =\n user?.role === \"SUPER_ADMIN\" ||\n user?.role === \"TENANT_ADMIN\" ||\n user?.role === \"ORG_ADMIN\";\n const filteredNavItems = navigationItems.filter(\n (item) => !item.adminOnly || isAdmin,\n );\n const filteredQuickActions = quickActions.filter(\n (item) => !item.adminOnly || isAdmin,\n );\n\n return (\n <div className=\"bg-bg-canvas p-6\">\n <ConfirmActionDialog\n open={showLogoutDialog}\n onOpenChange={setShowLogoutDialog}\n title={tr(\"auth.security.signOutDialogTitle\", \"Sign out now?\")}\n description={tr(\n \"auth.security.signOutDialogDescription\",\n \"You will be signed out of this device and returned to the login screen.\",\n )}\n confirmText={tr(\"auth.security.signOutDialogConfirm\", \"Sign out\")}\n variant=\"warning\"\n isPending={isLoggingOut}\n onConfirm={handleLogout}\n />\n <main className=\"max-w-7xl mx-auto space-y-8\">\n <div className=\"flex items-center gap-3\">\n <div className=\"auth-brand-badge flex h-10 w-10 items-center justify-center rounded-xl\">\n <ShieldIcon className=\"w-6 h-6 text-white\" />\n </div>\n <div>\n <h1 className=\"text-lg font-bold text-text-primary\">\n {tr(\"auth.security.title\", \"Security Center\")}\n </h1>\n <p className=\"text-xs text-text-secondary \">\n {tr(\"auth.security.subtitle\", \"Account & Authentication\")}\n </p>\n </div>\n </div>\n\n {/* Security Status Banner */}\n <div className=\"auth-hero-card rounded-2xl p-6\">\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between gap-4\">\n <div className=\"flex items-center gap-4\">\n <div className=\"w-14 h-14 rounded-2xl bg-bg-surface/20 backdrop-blur flex items-center justify-center\">\n <ShieldIcon className=\"w-8 h-8 text-white\" />\n </div>\n <div>\n <h2 className=\"text-xl font-bold\">\n {tr(\"auth.security.securityStatus\", \"Security Status\")}\n </h2>\n <p className=\"opacity-80\">\n {user?.mfaEnabled\n ? tr(\n \"auth.security.wellProtected\",\n \"Your account is well protected\",\n )\n : tr(\n \"auth.security.enableMfaSuggestion\",\n \"Enable MFA for better security\",\n )}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n {user?.mfaEnabled ? (\n <span className=\"inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-bg-surface/20 backdrop-blur text-white font-medium\">\n <CheckCircleIcon className=\"w-5 h-5 text-status-success-text\" />\n {tr(\"auth.security.mfaEnabled\", \"MFA Enabled\")}\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/mfa\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 rounded-xl bg-bg-surface text-text-link font-semibold hover:bg-status-info-bg-subtle transition-colors shadow-lg\"\n >\n <ExclamationIcon className=\"w-5 h-5 text-status-warning-text\" />\n {tr(\"auth.security.enableMfaNow\", \"Enable MFA Now\")}\n </button>\n )}\n </div>\n </div>\n </div>\n\n {/* Account Information Card */}\n <div className=\"mb-8 p-6 rounded-2xl bg-bg-surface border border-border-subtle shadow-sm\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr(\"auth.security.accountInfo\", \"Account Information\")}\n </h3>\n <dl className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6\">\n <div className=\"sm:col-span-2 lg:col-span-1\">\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.email\", \"Email\")}\n </dt>\n <dd className=\"mt-1 text-text-primary\">\n <span className=\"block truncate\" title={user?.email}>\n {user?.email}\n </span>\n {user?.emailVerified && (\n <span className=\"mt-1 inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-status-success-bg-subtle text-status-success-text text-xs font-medium\">\n <CheckCircleIcon className=\"w-3 h-3\" />\n {tr(\"auth.security.verified\", \"Verified\")}\n </span>\n )}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.username\", \"Username\")}\n </dt>\n <dd\n className=\"mt-1 text-text-primary truncate\"\n title={user?.username ?? undefined}\n >\n {user?.username || \"-\"}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.role\", \"Role\")}\n </dt>\n <dd className=\"mt-1\">\n <span className=\"inline-flex px-2.5 py-0.5 rounded-full bg-accent-indigo-subtle text-accent-indigo text-xs font-medium\">\n {user?.role || \"USER\"}\n </span>\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-text-secondary\">\n {tr(\"auth.security.memberSince\", \"Member Since\")}\n </dt>\n <dd className=\"mt-1 text-text-primary\">\n {user?.createdAt ? formatDate(user.createdAt) : \"-\"}\n </dd>\n </div>\n </dl>\n </div>\n\n {/* Main Navigation Grid */}\n <div className=\"mb-8\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr(\"auth.security.securityAuth\", \"Security & Authentication\")}\n </h3>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {filteredNavItems.map((item) => (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => navigate(item.path)}\n aria-label={item.name}\n className=\"group relative p-5 rounded-2xl bg-bg-surface border border-border-subtle hover:border-border-default hover:shadow-lg transition-all duration-200 text-left\"\n >\n <div className=\"flex items-start gap-4\">\n <div\n className={`w-12 h-12 rounded-xl ${item.bgColor} flex items-center justify-center flex-shrink-0 transition-transform group-hover:scale-110`}\n >\n <item.icon className={`w-6 h-6 ${item.color}`} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"text-base font-semibold text-text-primary group-hover:text-accent-indigo transition-colors\">\n {item.name}\n </h4>\n <p className=\"mt-1 text-sm text-text-secondary \">\n {item.description}\n </p>\n </div>\n <ChevronRightIcon className=\"w-5 h-5 text-text-tertiary group-hover:text-indigo-500 transition-colors flex-shrink-0\" />\n </div>\n </button>\n ))}\n </div>\n </div>\n\n {/* Quick Actions */}\n <div className=\"mb-8\">\n <h3 className=\"text-lg font-semibold text-text-primary mb-4\">\n {tr(\"auth.security.quickActions\", \"Quick Actions\")}\n </h3>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {filteredQuickActions.map((item) => (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => navigate(item.path)}\n aria-label={item.name}\n className=\"group relative p-5 rounded-2xl bg-bg-surface border border-border-subtle hover:border-border-default hover:shadow-lg transition-all duration-200 text-left\"\n >\n <div className=\"flex items-start gap-4\">\n <div\n className={`w-12 h-12 rounded-xl ${item.bgColor} flex items-center justify-center flex-shrink-0 transition-transform group-hover:scale-110`}\n >\n <item.icon className={`w-6 h-6 ${item.color}`} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"text-base font-semibold text-text-primary group-hover:text-accent-indigo transition-colors\">\n {item.name}\n </h4>\n <p className=\"mt-1 text-sm text-text-secondary \">\n {item.description}\n </p>\n </div>\n <ChevronRightIcon className=\"w-5 h-5 text-text-tertiary group-hover:text-indigo-500 transition-colors flex-shrink-0\" />\n </div>\n </button>\n ))}\n </div>\n </div>\n\n {/* Password & Danger Zone */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n {/* Password Section */}\n <div className=\"p-6 rounded-2xl bg-bg-surface border border-border-subtle \">\n <div className=\"flex items-start justify-between\">\n <div>\n <h3 className=\"text-lg font-semibold text-text-primary\">\n {tr(\"auth.security.password\", \"Password\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary \">\n {tr(\n \"auth.security.updatePassword\",\n \"Update your password to keep your account secure\",\n )}\n </p>\n <p className=\"mt-2 text-xs text-text-tertiary \">\n {tr(\"auth.security.lastChanged\", \"Last changed: Never\")}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/reset-password\")}\n className=\"auth-primary-button mt-4 w-full px-5 py-2.5 font-semibold sm:w-auto\"\n >\n {tr(\"auth.security.changePassword\", \"Change Password\")}\n </button>\n </div>\n\n {/* Danger Zone */}\n <div className=\"p-6 rounded-2xl bg-status-error-bg-subtle border border-status-error-border\">\n <h3 className=\"text-lg font-semibold text-status-error-text\">\n {tr(\"auth.security.dangerZone\", \"Danger Zone\")}\n </h3>\n <p className=\"mt-1 text-sm text-status-error-text/80\">\n {tr(\n \"auth.security.dangerWarning\",\n \"These actions affect your account. Proceed with caution.\",\n )}\n </p>\n <div className=\"mt-4 flex flex-wrap gap-3\">\n <button\n ref={deactivateTriggerRef}\n type=\"button\"\n onClick={() => setShowDeactivateModal(true)}\n className=\"px-5 py-2.5 rounded-xl border-2 border-status-warning-border text-status-warning-text font-semibold hover:bg-status-warning-bg-subtle transition-all duration-200\"\n >\n {tr(\"auth.security.deactivateAccount\", \"Deactivate Account\")}\n </button>\n <button\n ref={deleteTriggerRef}\n type=\"button\"\n onClick={() => setShowDeleteModal(true)}\n className=\"px-5 py-2.5 rounded-xl border-2 border-status-error-border text-status-error-text font-semibold hover:bg-status-error-bg-subtle transition-all duration-200\"\n >\n {tr(\"auth.security.deleteAccount\", \"Delete Account\")}\n </button>\n </div>\n </div>\n </div>\n\n {/* Deactivate Account Modal */}\n {showDeactivateModal && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4\"\n role=\"presentation\"\n onClick={(e) => {\n if (e.target === e.currentTarget) closeModals();\n }}\n >\n <div\n ref={deactivateDialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={deactivateTitleId}\n tabIndex={-1}\n className=\"w-full max-w-md bg-bg-surface rounded-2xl shadow-2xl p-6 outline-none\"\n >\n <h3\n id={deactivateTitleId}\n className=\"text-xl font-bold text-text-primary mb-2\"\n >\n {tr(\"auth.security.deactivateTitle\", \"Deactivate Account\")}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {tr(\n \"auth.security.deactivateDesc\",\n \"Your account will be temporarily disabled. You can reactivate it by signing in again with your credentials.\",\n )}\n </p>\n {accountError && (\n <div\n id={deactivateErrorId}\n role=\"alert\"\n className=\"mb-4 p-3 rounded-lg bg-status-error-bg-subtle text-status-error-text text-sm\"\n >\n {accountError}\n </div>\n )}\n {accountSuccess && (\n <div\n role=\"status\"\n className=\"mb-4 p-3 rounded-lg bg-status-success-bg-subtle text-status-success-text text-sm\"\n >\n {accountSuccess}\n </div>\n )}\n <div className=\"mb-4\">\n <label\n htmlFor={deactivatePasswordId}\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr(\n \"auth.security.enterPasswordConfirm\",\n \"Enter your password to confirm\",\n )}\n </label>\n <input\n id={deactivatePasswordId}\n type=\"password\"\n value={accountPassword}\n onChange={(e) => setAccountPassword(e.target.value)}\n aria-required=\"true\"\n aria-describedby={\n accountError ? deactivateErrorId : undefined\n }\n aria-invalid={!!accountError}\n autoComplete=\"current-password\"\n className=\"w-full px-4 py-2 rounded-lg border border-border-default bg-bg-surface text-text-primary focus:ring-2 focus:ring-status-warning-bg focus:border-transparent\"\n placeholder={tr(\n \"auth.security.yourPassword\",\n \"Your password\",\n )}\n />\n </div>\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={closeModals}\n className=\"flex-1 px-4 py-2 rounded-lg border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"auth.security.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleDeactivateAccount()}\n disabled={!accountPassword || isDeactivating}\n className=\"flex-1 px-4 py-2 rounded-lg bg-status-warning-bg text-white font-medium hover:bg-status-warning-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2\"\n >\n {isDeactivating && (\n <SpinnerIcon className=\"w-4 h-4 animate-spin\" />\n )}\n {tr(\"auth.security.deactivateBtn\", \"Deactivate\")}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Delete Account Modal */}\n {showDeleteModal && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4\"\n role=\"presentation\"\n onClick={(e) => {\n if (e.target === e.currentTarget) closeModals();\n }}\n >\n <div\n ref={deleteDialogRef}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={deleteTitleId}\n tabIndex={-1}\n className=\"w-full max-w-md bg-bg-surface rounded-2xl shadow-2xl p-6 outline-none\"\n >\n <h3\n id={deleteTitleId}\n className=\"text-xl font-bold text-status-error-text mb-2\"\n >\n {tr(\"auth.security.deleteTitle\", \"Delete Account Permanently\")}\n </h3>\n <p className=\"text-sm text-text-secondary mb-4\">\n {tr(\n \"auth.security.deleteDesc\",\n \"This action is irreversible. All your data will be permanently deleted and cannot be recovered.\",\n )}\n </p>\n {accountError && (\n <div\n id={deleteErrorId}\n role=\"alert\"\n className=\"mb-4 p-3 rounded-lg bg-status-error-bg-subtle text-status-error-text text-sm\"\n >\n {accountError}\n </div>\n )}\n {accountSuccess && (\n <div\n role=\"status\"\n className=\"mb-4 p-3 rounded-lg bg-status-success-bg-subtle text-status-success-text text-sm\"\n >\n {accountSuccess}\n </div>\n )}\n <div className=\"mb-4\">\n <label\n htmlFor={deletePasswordId}\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr(\n \"auth.security.enterPasswordDelete\",\n \"Enter your password\",\n )}\n </label>\n <input\n id={deletePasswordId}\n type=\"password\"\n value={accountPassword}\n onChange={(e) => setAccountPassword(e.target.value)}\n aria-required=\"true\"\n aria-describedby={accountError ? deleteErrorId : undefined}\n aria-invalid={!!accountError}\n autoComplete=\"current-password\"\n className=\"w-full px-4 py-2 rounded-lg border border-border-default bg-bg-surface text-text-primary focus:ring-2 focus:ring-status-error-bg focus:border-transparent\"\n placeholder={tr(\n \"auth.security.yourPassword\",\n \"Your password\",\n )}\n />\n </div>\n <div className=\"mb-4\">\n <label\n htmlFor={deleteConfirmId}\n className=\"block text-sm font-medium text-text-primary mb-1\"\n >\n {tr(\"auth.security.type\", \"Type\")}{\" \"}\n <code className=\"px-1 py-0.5 rounded bg-bg-sunken text-status-error-text font-mono text-sm\">\n {DELETE_ACCOUNT_CONFIRMATION}\n </code>{\" \"}\n {tr(\"auth.security.toConfirm\", \"to confirm\")}\n </label>\n <input\n id={deleteConfirmId}\n type=\"text\"\n value={deleteConfirmPhrase}\n onChange={(e) => setDeleteConfirmPhrase(e.target.value)}\n aria-required=\"true\"\n aria-describedby={accountError ? deleteErrorId : undefined}\n aria-invalid={\n deleteConfirmPhrase.length > 0 &&\n deleteConfirmPhrase !== DELETE_ACCOUNT_CONFIRMATION\n }\n autoComplete=\"off\"\n className=\"w-full px-4 py-2 rounded-lg border border-border-default bg-bg-surface text-text-primary focus:ring-2 focus:ring-status-error-bg focus:border-transparent font-mono\"\n placeholder={tr(\n \"auth.security.deleteConfirmPlaceholder\",\n \"DELETE MY ACCOUNT\",\n )}\n />\n </div>\n <div className=\"flex gap-3\">\n <button\n type=\"button\"\n onClick={closeModals}\n className=\"flex-1 px-4 py-2 rounded-lg border border-border-default text-text-primary font-medium hover:bg-bg-sunken transition-colors\"\n >\n {tr(\"auth.security.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleDeleteAccount()}\n disabled={\n !accountPassword ||\n deleteConfirmPhrase !== DELETE_ACCOUNT_CONFIRMATION ||\n isDeleting\n }\n className=\"flex-1 px-4 py-2 rounded-lg bg-status-error-bg text-white font-medium hover:bg-status-error-bg-hover disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2\"\n >\n {isDeleting && (\n <SpinnerIcon className=\"w-4 h-4 animate-spin\" />\n )}\n {tr(\"auth.security.deleteForever\", \"Delete Forever\")}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Footer */}\n <footer className=\"mt-12 pt-6 border-t border-border-subtle \">\n <div className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 text-sm text-text-secondary \">\n <p>\n {tr(\"auth.security.signedInAs\", \"Signed in as\")}{\" \"}\n <span className=\"font-medium text-text-primary \">\n {user?.email}\n </span>\n </p>\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => navigate(\"/auth/login\")}\n className=\"hover:text-text-primary transition-colors\"\n >\n {tr(\"auth.security.switchAccount\", \"Switch Account\")}\n </button>\n <span className=\"text-text-muted\" aria-hidden=\"true\">\n |\n </span>\n <button\n type=\"button\"\n onClick={() => setShowLogoutDialog(true)}\n className=\"hover:text-status-error-text transition-colors\"\n >\n {tr(\"auth.security.signOut\", \"Sign Out\")}\n </button>\n </div>\n </div>\n </footer>\n </main>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAUA,IAAM,KAAc,EAAE,mBACpB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,QAAO;CACP,eAAY;WAEZ,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAGF,MAAY,EAAE,mBAClB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,QAAO;CACP,eAAY;WAEZ,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAkBF,MAAa,EAAE,mBACnB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,QAAO;CACP,eAAY;WAEZ,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAGF,MAAmB,EAAE,mBACzB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,QAAO;CACP,eAAY;WAEZ,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAGF,MAAY,EAAE,mBAClB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,QAAO;CACP,eAAY;WAEZ,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAGF,KAAoB,EAAE,mBAC1B,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,QAAO;CACP,eAAY;WAEZ,kBAAC,QAAD;EACE,eAAc;EACd,gBAAe;EACf,aAAa;EACb,GAAE;EACF,CAAA;CACE,CAAA,EAGF,KAAmB,EAAE,mBACzB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,eAAY;WAEZ,kBAAC,QAAD;EACE,UAAS;EACT,GAAE;EACF,UAAS;EACT,CAAA;CACE,CAAA,EAGF,KAAmB,EAAE,mBACzB,kBAAC,OAAD;CACa;CACX,MAAK;CACL,SAAQ;CACR,eAAY;WAEZ,kBAAC,QAAD;EACE,UAAS;EACT,GAAE;EACF,UAAS;EACT,CAAA;CACE,CAAA,EAGF,KAAe,EAAE,mBACrB,kBAAC,OAAD;CAAgB;CAAW,MAAK;CAAO,SAAQ;CAAY,eAAY;WAAvE,CACE,kBAAC,UAAD;EACE,WAAU;EACV,IAAG;EACH,IAAG;EACH,GAAE;EACF,QAAO;EACP,aAAY;EACZ,CAAA,EACF,kBAAC,QAAD;EACE,WAAU;EACV,MAAK;EACL,GAAE;EACF,CAAA,CACE;IAaF,IAA8B;AAKpC,SAAgB,IAAe;CAC7B,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAGnC,IAAW,GAAa,EACxB,IAAO,GAAc,MAAU,EAAM,KAAK,EAC1C,EAAE,gBAAY,EAAkB,EACpC,yBAAyB,IAC1B,CAAC,EACI,EAAE,uBAAmB,mBAAe,mBAAgB,kBACxD,GAAsB,EAClB,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,GAAkB,KAAuB,EAAS,GAAM,EAEzD,KAA6B;EACjC;GACE,MAAM,EAAG,4BAA4B,eAAe;GACpD,aAAa,EACX,gCACA,yCACD;GACD,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACV;EACD;GACE,MAAM,EAAG,wBAAwB,4BAA4B;GAC7D,aAAa,EACX,4BACA,gCACD;GACD,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACV;EAkBD;GACE,MAAM,EAAG,0BAA0B,QAAQ;GAC3C,aAAa,EAAG,8BAA8B,sBAAsB;GACpE,MAAM;GACN,MAAM;GACN,OAAO;GACP,SAAS;GACT,WAAW;GACZ;EACF,EAEK,KAAe,CACnB;EACE,MAAM,EAAG,wBAAwB,oBAAoB;EACrD,aAAa,EAAG,4BAA4B,4BAA4B;EACxE,MAAM;EACN,MAAM;EACN,OAAO;EACP,SAAS;EACT,WAAW;EACZ,CACF,EAGK,CAAC,GAAqB,KAA0B,EAAS,GAAM,EAC/D,CAAC,GAAiB,KAAsB,EAAS,GAAM,EACvD,CAAC,GAAiB,KAAsB,EAAS,GAAG,EACpD,CAAC,GAAqB,KAA0B,EAAS,GAAG,EAC5D,CAAC,GAAc,KAAmB,EAAwB,KAAK,EAC/D,CAAC,GAAgB,KAAqB,EAAwB,KAAK,EAGnE,IAAoB,GAAO,EAC3B,IAAuB,GAAO,EAC9B,IAAoB,GAAO,EAC3B,IAAgB,GAAO,EACvB,IAAmB,GAAO,EAC1B,IAAkB,GAAO,EACzB,IAAgB,GAAO,EAGvB,IAAuB,EAA0B,KAAK,EACtD,IAAmB,EAA0B,KAAK,EAClD,IAAsB,EAAuB,KAAK,EAClD,IAAkB,EAAuB,KAAK;AAWpD,CARA,QAAgB;AACd,EAAI,IACF,EAAoB,SAAS,OAAO,GAEpC,EAAqB,SAAS,OAAO;IAEtC,CAAC,EAAoB,CAAC,EAEzB,QAAgB;AACd,EAAI,IACF,EAAgB,SAAS,OAAO,GAEhC,EAAiB,SAAS,OAAO;IAElC,CAAC,EAAgB,CAAC;CAErB,IAAM,KAAe,YAAY;AAC/B,IAAgB,GAAK;AACrB,MAAI;AAGF,GAFA,MAAM,IAAS,EACf,EAAS,cAAc,EACvB,EAAoB,GAAM;WACnB,GAAO;AAEd,GADA,QAAQ,MAAM,kBAAkB,EAAM,EACtC,EAAgB,GAAM;;IAIpB,KAA0B,YAAY;AAC1C,IAAgB,KAAK;AACrB,MAAI;GACF,IAAM,IAAS,MAAM,GAAkB,EAAgB;AACvD,GAAI,EAAO,UAET,EAAS,eAAe,EAAE,SAAS,IAAM,CAAC,GAE1C,EACE,EAAO,WACL,EACE,kCACA,+BACD,CACJ;WAEI,GAAO;AACd,KACE,aAAiB,QACb,EAAM,UACN,EACE,kCACA,+BACD,CACN;;IAIC,KAAsB,YAAY;AAEtC,MADA,EAAgB,KAAK,EACjB,MAAwB,GAA6B;AACvD,KACE,EACE,uCACA,+CACD,CACF;AACD;;AAEG,IAAa,SAAS;AAC3B,MAAI;GACF,IAAM,IAAS,MAAM,GAAc,GAAiB,EAAoB;AACxE,GAAI,EAAO,WACJ,EAAa,UAAU,EAE5B,EAAS,eAAe,EAAE,SAAS,IAAM,CAAC,KAErC,EAAa,QAAQ,EAC1B,EACE,EAAO,WACL,EAAG,8BAA8B,2BAA2B,CAC/D;WAEI,GAAO;AAEd,GADK,EAAa,QAAQ,EAC1B,EACE,aAAiB,QACb,EAAM,UACN,EAAG,8BAA8B,2BAA2B,CACjE;;IAIC,UAAoB;AAMxB,EALA,EAAuB,GAAM,EAC7B,EAAmB,GAAM,EACzB,EAAmB,GAAG,EACtB,EAAuB,GAAG,EAC1B,EAAgB,KAAK,EACrB,EAAkB,KAAK;IAGnB,IACJ,GAAM,SAAS,iBACf,GAAM,SAAS,kBACf,GAAM,SAAS,aACX,KAAmB,GAAgB,QACtC,MAAS,CAAC,EAAK,aAAa,EAC9B,EACK,KAAuB,GAAa,QACvC,MAAS,CAAC,EAAK,aAAa,EAC9B;AAED,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,IAAD;GACE,MAAM;GACN,cAAc;GACd,OAAO,EAAG,oCAAoC,gBAAgB;GAC9D,aAAa,EACX,0CACA,0EACD;GACD,aAAa,EAAG,sCAAsC,WAAW;GACjE,SAAQ;GACR,WAAW;GACX,WAAW;GACX,CAAA,EACF,kBAAC,QAAD;GAAM,WAAU;aAAhB;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAY,WAAU,sBAAuB,CAAA;MACzC,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,uBAAuB,kBAAkB;MAC1C,CAAA,EACL,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAG,0BAA0B,2BAA2B;MACvD,CAAA,CACA,EAAA,CAAA,CACF;;IAGN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAY,WAAU,sBAAuB,CAAA;QACzC,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,gCAAgC,kBAAkB;QACnD,CAAA,EACL,kBAAC,KAAD;QAAG,WAAU;kBACV,GAAM,aACH,EACE,+BACA,iCACD,GACD,EACE,qCACA,iCACD;QACH,CAAA,CACA,EAAA,CAAA,CACF;UACN,kBAAC,OAAD;OAAK,WAAU;iBACZ,GAAM,aACL,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAiB,WAAU,oCAAqC,CAAA,EAC/D,EAAG,4BAA4B,cAAc,CACzC;YAEP,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAS,YAAY;QACpC,WAAU;kBAHZ,CAKE,kBAAC,GAAD,EAAiB,WAAU,oCAAqC,CAAA,EAC/D,EAAG,8BAA8B,iBAAiB,CAC5C;;OAEP,CAAA,CACF;;KACF,CAAA;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,6BAA6B,sBAAsB;MACpD,CAAA,EACL,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAG,uBAAuB,QAAQ;SAChC,CAAA,EACL,kBAAC,MAAD;SAAI,WAAU;mBAAd,CACE,kBAAC,QAAD;UAAM,WAAU;UAAiB,OAAO,GAAM;oBAC3C,GAAM;UACF,CAAA,EACN,GAAM,iBACL,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CACE,kBAAC,GAAD,EAAiB,WAAU,WAAY,CAAA,EACtC,EAAG,0BAA0B,WAAW,CACpC;YAEN;WACD;;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,0BAA0B,WAAW;QACtC,CAAA,EACL,kBAAC,MAAD;QACE,WAAU;QACV,OAAO,GAAM,YAAY,KAAA;kBAExB,GAAM,YAAY;QAChB,CAAA,CACD,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,sBAAsB,OAAO;QAC9B,CAAA,EACL,kBAAC,MAAD;QAAI,WAAU;kBACZ,kBAAC,QAAD;SAAM,WAAU;mBACb,GAAM,QAAQ;SACV,CAAA;QACJ,CAAA,CACD,EAAA,CAAA;OACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,6BAA6B,eAAe;QAC7C,CAAA,EACL,kBAAC,MAAD;QAAI,WAAU;kBACX,GAAM,YAAY,GAAW,EAAK,UAAU,GAAG;QAC7C,CAAA,CACD,EAAA,CAAA;OACH;QACD;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,8BAA8B,4BAA4B;MAC3D,CAAA,EACL,kBAAC,OAAD;MAAK,WAAU;gBACZ,GAAiB,KAAK,MACrB,kBAAC,UAAD;OAEE,MAAK;OACL,eAAe,EAAS,EAAK,KAAK;OAClC,cAAY,EAAK;OACjB,WAAU;iBAEV,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UACE,WAAW,wBAAwB,EAAK,QAAQ;oBAEhD,kBAAC,EAAK,MAAN,EAAW,WAAW,WAAW,EAAK,SAAW,CAAA;UAC7C,CAAA;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAK;WACH,CAAA,EACL,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAK;WACJ,CAAA,CACA;;SACN,kBAAC,GAAD,EAAkB,WAAU,0FAA2F,CAAA;SACnH;;OACC,EAtBF,EAAK,KAsBH,CACT;MACE,CAAA,CACF;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,8BAA8B,gBAAgB;MAC/C,CAAA,EACL,kBAAC,OAAD;MAAK,WAAU;gBACZ,GAAqB,KAAK,MACzB,kBAAC,UAAD;OAEE,MAAK;OACL,eAAe,EAAS,EAAK,KAAK;OAClC,cAAY,EAAK;OACjB,WAAU;iBAEV,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UACE,WAAW,wBAAwB,EAAK,QAAQ;oBAEhD,kBAAC,EAAK,MAAN,EAAW,WAAW,WAAW,EAAK,SAAW,CAAA;UAC7C,CAAA;SACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAK;WACH,CAAA,EACL,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAK;WACJ,CAAA,CACA;;SACN,kBAAC,GAAD,EAAkB,WAAU,0FAA2F,CAAA;SACnH;;OACC,EAtBF,EAAK,KAsBH,CACT;MACE,CAAA,CACF;;IAGN,kBAAC,OAAD;KAAK,WAAU;eAAf,CAEE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,OAAD,EAAA,UAAA;QACE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAG,0BAA0B,WAAW;SACtC,CAAA;QACL,kBAAC,KAAD;SAAG,WAAU;mBACV,EACC,gCACA,mDACD;SACC,CAAA;QACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,6BAA6B,sBAAsB;SACrD,CAAA;QACA,EAAA,CAAA;OACF,CAAA,EACN,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAS,uBAAuB;OAC/C,WAAU;iBAET,EAAG,gCAAgC,kBAAkB;OAC/C,CAAA,CACL;SAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,MAAD;QAAI,WAAU;kBACX,EAAG,4BAA4B,cAAc;QAC3C,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,+BACA,2DACD;QACC,CAAA;OACJ,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,KAAK;SACL,MAAK;SACL,eAAe,EAAuB,GAAK;SAC3C,WAAU;mBAET,EAAG,mCAAmC,qBAAqB;SACrD,CAAA,EACT,kBAAC,UAAD;SACE,KAAK;SACL,MAAK;SACL,eAAe,EAAmB,GAAK;SACvC,WAAU;mBAET,EAAG,+BAA+B,iBAAiB;SAC7C,CAAA,CACL;;OACF;QACF;;IAGL,KACC,kBAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,UAAU,MAAM;AACd,MAAI,EAAE,WAAW,EAAE,iBAAe,GAAa;;eAGjD,kBAAC,OAAD;MACE,KAAK;MACL,MAAK;MACL,cAAW;MACX,mBAAiB;MACjB,UAAU;MACV,WAAU;gBANZ;OAQE,kBAAC,MAAD;QACE,IAAI;QACJ,WAAU;kBAET,EAAG,iCAAiC,qBAAqB;QACvD,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,gCACA,8GACD;QACC,CAAA;OACH,KACC,kBAAC,OAAD;QACE,IAAI;QACJ,MAAK;QACL,WAAU;kBAET;QACG,CAAA;OAEP,KACC,kBAAC,OAAD;QACE,MAAK;QACL,WAAU;kBAET;QACG,CAAA;OAER,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SACE,SAAS;SACT,WAAU;mBAET,EACC,sCACA,iCACD;SACK,CAAA,EACR,kBAAC,SAAD;SACE,IAAI;SACJ,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAmB,EAAE,OAAO,MAAM;SACnD,iBAAc;SACd,oBACE,IAAe,IAAoB,KAAA;SAErC,gBAAc,CAAC,CAAC;SAChB,cAAa;SACb,WAAU;SACV,aAAa,EACX,8BACA,gBACD;SACD,CAAA,CACE;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,MAAK;SACL,SAAS;SACT,WAAU;mBAET,EAAG,wBAAwB,SAAS;SAC9B,CAAA,EACT,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,KAAK,IAAyB;SAC7C,UAAU,CAAC,KAAmB;SAC9B,WAAU;mBAJZ,CAMG,KACC,kBAAC,GAAD,EAAa,WAAU,wBAAyB,CAAA,EAEjD,EAAG,+BAA+B,aAAa,CACzC;WACL;;OACF;;KACF,CAAA;IAIP,KACC,kBAAC,OAAD;KACE,WAAU;KACV,MAAK;KACL,UAAU,MAAM;AACd,MAAI,EAAE,WAAW,EAAE,iBAAe,GAAa;;eAGjD,kBAAC,OAAD;MACE,KAAK;MACL,MAAK;MACL,cAAW;MACX,mBAAiB;MACjB,UAAU;MACV,WAAU;gBANZ;OAQE,kBAAC,MAAD;QACE,IAAI;QACJ,WAAU;kBAET,EAAG,6BAA6B,6BAA6B;QAC3D,CAAA;OACL,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,4BACA,kGACD;QACC,CAAA;OACH,KACC,kBAAC,OAAD;QACE,IAAI;QACJ,MAAK;QACL,WAAU;kBAET;QACG,CAAA;OAEP,KACC,kBAAC,OAAD;QACE,MAAK;QACL,WAAU;kBAET;QACG,CAAA;OAER,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SACE,SAAS;SACT,WAAU;mBAET,EACC,qCACA,sBACD;SACK,CAAA,EACR,kBAAC,SAAD;SACE,IAAI;SACJ,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAmB,EAAE,OAAO,MAAM;SACnD,iBAAc;SACd,oBAAkB,IAAe,IAAgB,KAAA;SACjD,gBAAc,CAAC,CAAC;SAChB,cAAa;SACb,WAAU;SACV,aAAa,EACX,8BACA,gBACD;SACD,CAAA,CACE;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SACE,SAAS;SACT,WAAU;mBAFZ;UAIG,EAAG,sBAAsB,OAAO;UAAE;UACnC,kBAAC,QAAD;WAAM,WAAU;qBACb;WACI,CAAA;UAAC;UACP,EAAG,2BAA2B,aAAa;UACtC;YACR,kBAAC,SAAD;SACE,IAAI;SACJ,MAAK;SACL,OAAO;SACP,WAAW,MAAM,EAAuB,EAAE,OAAO,MAAM;SACvD,iBAAc;SACd,oBAAkB,IAAe,IAAgB,KAAA;SACjD,gBACE,EAAoB,SAAS,KAC7B,MAAwB;SAE1B,cAAa;SACb,WAAU;SACV,aAAa,EACX,0CACA,oBACD;SACD,CAAA,CACE;;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,MAAK;SACL,SAAS;SACT,WAAU;mBAET,EAAG,wBAAwB,SAAS;SAC9B,CAAA,EACT,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,KAAK,IAAqB;SACzC,UACE,CAAC,KACD,MAAwB,KACxB;SAEF,WAAU;mBARZ,CAUG,KACC,kBAAC,GAAD,EAAa,WAAU,wBAAyB,CAAA,EAEjD,EAAG,+BAA+B,iBAAiB,CAC7C;WACL;;OACF;;KACF,CAAA;IAIR,kBAAC,UAAD;KAAQ,WAAU;eAChB,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD,EAAA,UAAA;OACG,EAAG,4BAA4B,eAAe;OAAE;OACjD,kBAAC,QAAD;QAAM,WAAU;kBACb,GAAM;QACF,CAAA;OACL,EAAA,CAAA,EACJ,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAS,cAAc;SACtC,WAAU;mBAET,EAAG,+BAA+B,iBAAiB;SAC7C,CAAA;QACT,kBAAC,QAAD;SAAM,WAAU;SAAkB,eAAY;mBAAO;SAE9C,CAAA;QACP,kBAAC,UAAD;SACE,MAAK;SACL,eAAe,EAAoB,GAAK;SACxC,WAAU;mBAET,EAAG,yBAAyB,WAAW;SACjC,CAAA;QACL;SACF;;KACC,CAAA;IACJ;KACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"SsoConfigPage.d.ts","sourceRoot":"","sources":["../../../src/auth/pages/SsoConfigPage.tsx"],"names":[],"mappings":"AAgHA;;;GAGG;AACH,wBAAgB,aAAa,4CA+7C5B"}
1
+ {"version":3,"file":"SsoConfigPage.d.ts","sourceRoot":"","sources":["../../../src/auth/pages/SsoConfigPage.tsx"],"names":[],"mappings":"AAgHA;;;GAGG;AACH,wBAAgB,aAAa,4CAqgD5B"}
@@ -110,12 +110,14 @@ function y() {
110
110
  className: "flex items-center gap-4",
111
111
  children: [/* @__PURE__ */ h("button", {
112
112
  onClick: () => a("/auth/security"),
113
+ "aria-label": k("auth.sso.backToSecurity", "Back to Security"),
113
114
  className: "p-2 rounded-lg hover:bg-bg-sunken transition-colors",
114
115
  children: /* @__PURE__ */ h("svg", {
115
116
  className: "w-5 h-5 text-text-secondary",
116
117
  fill: "none",
117
118
  viewBox: "0 0 24 24",
118
119
  stroke: "currentColor",
120
+ "aria-hidden": "true",
119
121
  children: /* @__PURE__ */ h("path", {
120
122
  strokeLinecap: "round",
121
123
  strokeLinejoin: "round",
@@ -331,10 +333,12 @@ function y() {
331
333
  }), /* @__PURE__ */ g("div", {
332
334
  className: "flex gap-2",
333
335
  children: [/* @__PURE__ */ h("input", {
336
+ id: "sso-metadata-url",
334
337
  type: "url",
335
338
  value: B,
336
339
  onChange: (e) => V(e.target.value),
337
340
  placeholder: "https://idp.example.com/metadata.xml",
341
+ "aria-label": k("auth.sso.fetchFromUrl", "Fetch from URL"),
338
342
  className: "flex-1 px-4 py-2.5 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all text-sm"
339
343
  }), /* @__PURE__ */ g("button", {
340
344
  type: "button",
@@ -354,7 +358,7 @@ function y() {
354
358
  ssoUrl: t.ssoUrl,
355
359
  sloUrl: t.sloUrl || "",
356
360
  certificate: t.certificate
357
- }), z("SAML metadata imported successfully! Review and save the configuration."), N(!0), V("")) : L(k("auth.sso.parseUrlError", "Failed to parse SAML metadata from URL."));
361
+ }), z(k("auth.sso.importSuccessFromUrl", "SAML metadata imported successfully! Review and save the configuration.")), N(!0), V("")) : L(k("auth.sso.parseUrlError", "Failed to parse SAML metadata from URL."));
358
362
  } catch (e) {
359
363
  L(e instanceof Error ? e.message : k("auth.sso.fetchError", "Failed to fetch metadata from URL"));
360
364
  } finally {
@@ -452,17 +456,20 @@ function y() {
452
456
  children: [
453
457
  /* @__PURE__ */ g("div", { children: [
454
458
  /* @__PURE__ */ g("label", {
459
+ htmlFor: "sso-entity-id",
455
460
  className: "block text-sm font-medium text-text-primary mb-2",
456
461
  children: [
457
462
  k("auth.sso.idpEntityId", "IdP Entity ID / Issuer URL"),
458
463
  " ",
459
464
  /* @__PURE__ */ h("span", {
460
465
  className: "text-status-error-text",
466
+ "aria-hidden": "true",
461
467
  children: "*"
462
468
  })
463
469
  ]
464
470
  }),
465
471
  /* @__PURE__ */ h("input", {
472
+ id: "sso-entity-id",
466
473
  type: "url",
467
474
  value: Q.entityId,
468
475
  onChange: (e) => $({
@@ -472,26 +479,32 @@ function y() {
472
479
  disabled: !M && !!x,
473
480
  placeholder: k("auth.sso.idpEntityIdPlaceholder", "https://your-idp.example.com/saml/metadata"),
474
481
  required: !0,
482
+ "aria-required": "true",
483
+ "aria-describedby": "sso-entity-id-hint",
475
484
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg disabled:opacity-60 disabled:cursor-not-allowed transition-all"
476
485
  }),
477
486
  /* @__PURE__ */ h("p", {
487
+ id: "sso-entity-id-hint",
478
488
  className: "mt-1 text-xs text-text-secondary",
479
489
  children: k("auth.sso.idpEntityIdHelper", "The unique identifier of your Identity Provider")
480
490
  })
481
491
  ] }),
482
492
  /* @__PURE__ */ g("div", { children: [
483
493
  /* @__PURE__ */ g("label", {
494
+ htmlFor: "sso-sso-url",
484
495
  className: "block text-sm font-medium text-text-primary mb-2",
485
496
  children: [
486
497
  k("auth.sso.ssoUrl", "SSO URL (Login URL)"),
487
498
  " ",
488
499
  /* @__PURE__ */ h("span", {
489
500
  className: "text-status-error-text",
501
+ "aria-hidden": "true",
490
502
  children: "*"
491
503
  })
492
504
  ]
493
505
  }),
494
506
  /* @__PURE__ */ h("input", {
507
+ id: "sso-sso-url",
495
508
  type: "url",
496
509
  value: Q.ssoUrl,
497
510
  onChange: (e) => $({
@@ -501,19 +514,24 @@ function y() {
501
514
  disabled: !M && !!x,
502
515
  placeholder: k("auth.sso.ssoUrlPlaceholder", "https://your-idp.example.com/saml/sso"),
503
516
  required: !0,
517
+ "aria-required": "true",
518
+ "aria-describedby": "sso-sso-url-hint",
504
519
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg disabled:opacity-60 disabled:cursor-not-allowed transition-all"
505
520
  }),
506
521
  /* @__PURE__ */ h("p", {
522
+ id: "sso-sso-url-hint",
507
523
  className: "mt-1 text-xs text-text-secondary",
508
524
  children: k("auth.sso.ssoUrlHelper", "The URL where users are redirected to authenticate")
509
525
  })
510
526
  ] }),
511
527
  /* @__PURE__ */ g("div", { children: [
512
528
  /* @__PURE__ */ h("label", {
529
+ htmlFor: "sso-slo-url",
513
530
  className: "block text-sm font-medium text-text-primary mb-2",
514
531
  children: k("auth.sso.sloUrl", "Single Logout (SLO) URL")
515
532
  }),
516
533
  /* @__PURE__ */ h("input", {
534
+ id: "sso-slo-url",
517
535
  type: "url",
518
536
  value: Q.sloUrl,
519
537
  onChange: (e) => $({
@@ -522,26 +540,31 @@ function y() {
522
540
  }),
523
541
  disabled: !M && !!x,
524
542
  placeholder: k("auth.sso.sloUrlPlaceholder", "https://your-idp.example.com/saml/slo"),
543
+ "aria-describedby": "sso-slo-url-hint",
525
544
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg disabled:opacity-60 disabled:cursor-not-allowed transition-all"
526
545
  }),
527
546
  /* @__PURE__ */ h("p", {
547
+ id: "sso-slo-url-hint",
528
548
  className: "mt-1 text-xs text-text-secondary",
529
549
  children: k("auth.sso.sloUrlHelper", "Optional: URL for single logout across all applications")
530
550
  })
531
551
  ] }),
532
552
  /* @__PURE__ */ g("div", { children: [
533
553
  /* @__PURE__ */ g("label", {
554
+ htmlFor: "sso-certificate",
534
555
  className: "block text-sm font-medium text-text-primary mb-2",
535
556
  children: [
536
557
  k("auth.sso.certificate", "X.509 Certificate"),
537
558
  " ",
538
559
  /* @__PURE__ */ h("span", {
539
560
  className: "text-status-error-text",
561
+ "aria-hidden": "true",
540
562
  children: "*"
541
563
  })
542
564
  ]
543
565
  }),
544
566
  /* @__PURE__ */ h("textarea", {
567
+ id: "sso-certificate",
545
568
  value: Q.certificate,
546
569
  onChange: (e) => $({
547
570
  ...Q,
@@ -550,10 +573,13 @@ function y() {
550
573
  disabled: !M && !!x,
551
574
  placeholder: k("auth.sso.certificatePlaceholder", "-----BEGIN CERTIFICATE-----\nMIIDpDCCAoygAwIBAgIGAX...\n-----END CERTIFICATE-----"),
552
575
  required: !0,
576
+ "aria-required": "true",
577
+ "aria-describedby": "sso-certificate-hint",
553
578
  rows: 6,
554
579
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg disabled:opacity-60 disabled:cursor-not-allowed transition-all font-mono text-sm"
555
580
  }),
556
581
  /* @__PURE__ */ h("p", {
582
+ id: "sso-certificate-hint",
557
583
  className: "mt-1 text-xs text-text-secondary",
558
584
  children: k("auth.sso.certificateHelper", "The public X.509 certificate from your IdP for signature verification")
559
585
  })
@@ -836,16 +862,19 @@ function y() {
836
862
  className: "space-y-5",
837
863
  children: [
838
864
  /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ g("label", {
865
+ htmlFor: "oidc-client-name",
839
866
  className: "block text-sm font-medium text-text-primary mb-2",
840
867
  children: [
841
868
  k("auth.sso.clientName", "Client Name"),
842
869
  " ",
843
870
  /* @__PURE__ */ h("span", {
844
871
  className: "text-status-error-text",
872
+ "aria-hidden": "true",
845
873
  children: "*"
846
874
  })
847
875
  ]
848
876
  }), /* @__PURE__ */ h("input", {
877
+ id: "oidc-client-name",
849
878
  type: "text",
850
879
  value: K.client_name,
851
880
  onChange: (e) => q({
@@ -853,21 +882,25 @@ function y() {
853
882
  client_name: e.target.value
854
883
  }),
855
884
  placeholder: k("auth.sso.clientNamePlaceholder", "My Application"),
885
+ "aria-required": "true",
856
886
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
857
887
  })] }),
858
888
  /* @__PURE__ */ g("div", { children: [
859
889
  /* @__PURE__ */ g("label", {
890
+ htmlFor: "oidc-redirect-uris",
860
891
  className: "block text-sm font-medium text-text-primary mb-2",
861
892
  children: [
862
893
  k("auth.sso.redirectUris", "Redirect URIs"),
863
894
  " ",
864
895
  /* @__PURE__ */ h("span", {
865
896
  className: "text-status-error-text",
897
+ "aria-hidden": "true",
866
898
  children: "*"
867
899
  })
868
900
  ]
869
901
  }),
870
902
  /* @__PURE__ */ h("input", {
903
+ id: "oidc-redirect-uris",
871
904
  type: "text",
872
905
  value: K.redirect_uris,
873
906
  onChange: (e) => q({
@@ -875,9 +908,12 @@ function y() {
875
908
  redirect_uris: e.target.value
876
909
  }),
877
910
  placeholder: k("auth.sso.redirectUrisPlaceholder", "http://localhost:3000/callback, https://app.example.com/callback"),
911
+ "aria-required": "true",
912
+ "aria-describedby": "oidc-redirect-uris-hint",
878
913
  className: "block w-full px-4 py-3 border border-border-default rounded-xl bg-bg-surface text-text-primary placeholder-text-tertiary focus:outline-none focus:ring-2 focus:ring-action-primary-bg/20 focus:border-action-primary-bg transition-all"
879
914
  }),
880
915
  /* @__PURE__ */ h("p", {
916
+ id: "oidc-redirect-uris-hint",
881
917
  className: "mt-1 text-xs text-text-secondary",
882
918
  children: k("auth.sso.redirectUrisHelper", "Separate multiple URIs with commas")
883
919
  })
@@ -913,9 +949,11 @@ function y() {
913
949
  }, e))
914
950
  })] }),
915
951
  /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("label", {
952
+ htmlFor: "oidc-token-auth-method",
916
953
  className: "block text-sm font-medium text-text-primary mb-2",
917
954
  children: k("auth.sso.tokenEndpointAuth", "Token Endpoint Auth Method")
918
955
  }), /* @__PURE__ */ g("select", {
956
+ id: "oidc-token-auth-method",
919
957
  value: K.token_endpoint_auth_method,
920
958
  onChange: (e) => q({
921
959
  ...K,