@cedros/login-react 0.0.37 → 0.0.39

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 (108) hide show
  1. package/dist/{AuthenticationSettings-CsPbxwP7.js → AuthenticationSettings-BF_7Ea6Z.js} +1 -1
  2. package/dist/{AuthenticationSettings-CsPbxwP7.js.map → AuthenticationSettings-BF_7Ea6Z.js.map} +1 -1
  3. package/dist/{AuthenticationSettings-C-aYDXNH.cjs → AuthenticationSettings-BMDrCVSf.cjs} +1 -1
  4. package/dist/{AuthenticationSettings-C-aYDXNH.cjs.map → AuthenticationSettings-BMDrCVSf.cjs.map} +1 -1
  5. package/dist/{AuthenticationSettings-DIVk0OP8.js → AuthenticationSettings-DUXpyiJ5.js} +39 -39
  6. package/dist/{AuthenticationSettings-DIVk0OP8.js.map → AuthenticationSettings-DUXpyiJ5.js.map} +1 -1
  7. package/dist/{AuthenticationSettings-CoTic-d_.cjs → AuthenticationSettings-Dk1LX0CK.cjs} +1 -1
  8. package/dist/{AuthenticationSettings-CoTic-d_.cjs.map → AuthenticationSettings-Dk1LX0CK.cjs.map} +1 -1
  9. package/dist/{AutosaveStatus-DGNI4lXn.cjs → AutosaveStatus-BKsCIvPj.cjs} +1 -1
  10. package/dist/AutosaveStatus-BKsCIvPj.cjs.map +1 -0
  11. package/dist/{AutosaveStatus-f-jw25Ay.js → AutosaveStatus-CSZsp6w7.js} +221 -186
  12. package/dist/AutosaveStatus-CSZsp6w7.js.map +1 -0
  13. package/dist/{CreditSystemSettings-C6ed3yp7.js → CreditSystemSettings-Buu7Y-7I.js} +1 -1
  14. package/dist/{CreditSystemSettings-C6ed3yp7.js.map → CreditSystemSettings-Buu7Y-7I.js.map} +1 -1
  15. package/dist/{CreditSystemSettings-DM9ep1TF.cjs → CreditSystemSettings-C2HkyMXy.cjs} +1 -1
  16. package/dist/{CreditSystemSettings-DM9ep1TF.cjs.map → CreditSystemSettings-C2HkyMXy.cjs.map} +1 -1
  17. package/dist/{CreditSystemSettings-BNkvsgsk.cjs → CreditSystemSettings-CLImarX-.cjs} +1 -1
  18. package/dist/{CreditSystemSettings-BNkvsgsk.cjs.map → CreditSystemSettings-CLImarX-.cjs.map} +1 -1
  19. package/dist/{CreditSystemSettings-uinhzoha.js → CreditSystemSettings-Cj21_Ug8.js} +1 -1
  20. package/dist/{CreditSystemSettings-uinhzoha.js.map → CreditSystemSettings-Cj21_Ug8.js.map} +1 -1
  21. package/dist/EmailRegisterForm-CNjYrqU6.cjs +1 -0
  22. package/dist/EmailRegisterForm-CNjYrqU6.cjs.map +1 -0
  23. package/dist/EmailRegisterForm-D2VaJouj.js +750 -0
  24. package/dist/EmailRegisterForm-D2VaJouj.js.map +1 -0
  25. package/dist/{EmailSettings-BC0f1PCI.cjs → EmailSettings-9sdEAONl.cjs} +1 -1
  26. package/dist/{EmailSettings-BC0f1PCI.cjs.map → EmailSettings-9sdEAONl.cjs.map} +1 -1
  27. package/dist/{EmailSettings-BKuXy8sc.js → EmailSettings-CmxxnrA9.js} +1 -1
  28. package/dist/{EmailSettings-BKuXy8sc.js.map → EmailSettings-CmxxnrA9.js.map} +1 -1
  29. package/dist/{EmailSettings-BAuQtEfM.js → EmailSettings-DRfOF0Sf.js} +1 -1
  30. package/dist/{EmailSettings-BAuQtEfM.js.map → EmailSettings-DRfOF0Sf.js.map} +1 -1
  31. package/dist/{EmailSettings-BF5EiPl9.cjs → EmailSettings-eLlzzI5D.cjs} +1 -1
  32. package/dist/{EmailSettings-BF5EiPl9.cjs.map → EmailSettings-eLlzzI5D.cjs.map} +1 -1
  33. package/dist/{EmbeddedWalletSettings-CJY39UZN.cjs → EmbeddedWalletSettings-BuLN_Uqc.cjs} +1 -1
  34. package/dist/{EmbeddedWalletSettings-CJY39UZN.cjs.map → EmbeddedWalletSettings-BuLN_Uqc.cjs.map} +1 -1
  35. package/dist/{EmbeddedWalletSettings-C27X9He2.js → EmbeddedWalletSettings-CHkkCjyR.js} +1 -1
  36. package/dist/{EmbeddedWalletSettings-C27X9He2.js.map → EmbeddedWalletSettings-CHkkCjyR.js.map} +1 -1
  37. package/dist/EmbeddedWalletSettings-DGq-kXbw.cjs +1 -0
  38. package/dist/EmbeddedWalletSettings-DGq-kXbw.cjs.map +1 -0
  39. package/dist/{EmbeddedWalletSettings-Dmi-EQ7W.js → EmbeddedWalletSettings-M-D5N0eY.js} +5 -5
  40. package/dist/EmbeddedWalletSettings-M-D5N0eY.js.map +1 -0
  41. package/dist/{GoogleLoginButton-BDCbxoCB.cjs → GoogleLoginButton-JtRViYWS.cjs} +1 -1
  42. package/dist/GoogleLoginButton-JtRViYWS.cjs.map +1 -0
  43. package/dist/{GoogleLoginButton-6ip-vudk.js → GoogleLoginButton-qf4A_A3G.js} +6 -6
  44. package/dist/GoogleLoginButton-qf4A_A3G.js.map +1 -0
  45. package/dist/{ServerSettings-CKfiLfXi.cjs → ServerSettings-CMmH5pZv.cjs} +1 -1
  46. package/dist/{ServerSettings-CKfiLfXi.cjs.map → ServerSettings-CMmH5pZv.cjs.map} +1 -1
  47. package/dist/{ServerSettings-CZfBdMxG.js → ServerSettings-DQemMrNv.js} +1 -1
  48. package/dist/{ServerSettings-CZfBdMxG.js.map → ServerSettings-DQemMrNv.js.map} +1 -1
  49. package/dist/{ServerSettings-rHrVN8O8.cjs → ServerSettings-DfimU7ay.cjs} +1 -1
  50. package/dist/{ServerSettings-rHrVN8O8.cjs.map → ServerSettings-DfimU7ay.cjs.map} +1 -1
  51. package/dist/{ServerSettings-BT9weFPz.js → ServerSettings-qxi8aZO7.js} +1 -1
  52. package/dist/{ServerSettings-BT9weFPz.js.map → ServerSettings-qxi8aZO7.js.map} +1 -1
  53. package/dist/{WebhookSettings-DXjnq-c7.cjs → WebhookSettings-0sgWRI3U.cjs} +1 -1
  54. package/dist/{WebhookSettings-DXjnq-c7.cjs.map → WebhookSettings-0sgWRI3U.cjs.map} +1 -1
  55. package/dist/{WebhookSettings-Bgld6D_T.js → WebhookSettings-8QAqvkkO.js} +1 -1
  56. package/dist/{WebhookSettings-Bgld6D_T.js.map → WebhookSettings-8QAqvkkO.js.map} +1 -1
  57. package/dist/{WebhookSettings-DnLk97Mr.cjs → WebhookSettings-B6Y3Tnjv.cjs} +1 -1
  58. package/dist/{WebhookSettings-DnLk97Mr.cjs.map → WebhookSettings-B6Y3Tnjv.cjs.map} +1 -1
  59. package/dist/{WebhookSettings-ufiGTmbG.js → WebhookSettings-B8hAwhZ2.js} +1 -1
  60. package/dist/{WebhookSettings-ufiGTmbG.js.map → WebhookSettings-B8hAwhZ2.js.map} +1 -1
  61. package/dist/admin-only.cjs +1 -1
  62. package/dist/admin-only.js +1 -1
  63. package/dist/email-only.cjs +1 -1
  64. package/dist/email-only.d.ts +3 -2
  65. package/dist/email-only.js +2 -2
  66. package/dist/google-only.cjs +1 -1
  67. package/dist/google-only.d.ts +5 -4
  68. package/dist/google-only.js +2 -2
  69. package/dist/index.cjs +13 -13
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/index.d.ts +98 -7
  72. package/dist/index.js +8052 -5962
  73. package/dist/index.js.map +1 -1
  74. package/dist/login-react.css +1 -1
  75. package/dist/{plugin-Xca67fp7.cjs → plugin-CUxpAjL-.cjs} +1 -1
  76. package/dist/{plugin-Xca67fp7.cjs.map → plugin-CUxpAjL-.cjs.map} +1 -1
  77. package/dist/{plugin-BbExid4E.js → plugin-C_NDZ2-D.js} +5 -5
  78. package/dist/{plugin-BbExid4E.js.map → plugin-C_NDZ2-D.js.map} +1 -1
  79. package/dist/solana-only.cjs +1 -1
  80. package/dist/solana-only.d.ts +3 -2
  81. package/dist/solana-only.js +1 -1
  82. package/dist/{useAuth-CVLv2oKA.js → useAuth-C-Vw-ggy.js} +743 -803
  83. package/dist/useAuth-C-Vw-ggy.js.map +1 -0
  84. package/dist/useAuth-U5CYsHEU.cjs +1 -0
  85. package/dist/useAuth-U5CYsHEU.cjs.map +1 -0
  86. package/package.json +4 -1
  87. package/dist/AutosaveStatus-DGNI4lXn.cjs.map +0 -1
  88. package/dist/AutosaveStatus-f-jw25Ay.js.map +0 -1
  89. package/dist/EmailRegisterForm-B_TiJkD6.cjs +0 -1
  90. package/dist/EmailRegisterForm-B_TiJkD6.cjs.map +0 -1
  91. package/dist/EmailRegisterForm-CCEuQA-w.js +0 -773
  92. package/dist/EmailRegisterForm-CCEuQA-w.js.map +0 -1
  93. package/dist/EmbeddedWalletSettings-BRjt2PAj.cjs +0 -1
  94. package/dist/EmbeddedWalletSettings-BRjt2PAj.cjs.map +0 -1
  95. package/dist/EmbeddedWalletSettings-Dmi-EQ7W.js.map +0 -1
  96. package/dist/GoogleLoginButton-6ip-vudk.js.map +0 -1
  97. package/dist/GoogleLoginButton-BDCbxoCB.cjs.map +0 -1
  98. package/dist/shamir-DBpHm7WN.cjs +0 -1
  99. package/dist/shamir-DBpHm7WN.cjs.map +0 -1
  100. package/dist/shamir-R8ddesFt.js +0 -1940
  101. package/dist/shamir-R8ddesFt.js.map +0 -1
  102. package/dist/silentWalletEnroll-Dp1GTeNr.js +0 -41
  103. package/dist/silentWalletEnroll-Dp1GTeNr.js.map +0 -1
  104. package/dist/silentWalletEnroll-HPvsbd2J.cjs +0 -1
  105. package/dist/silentWalletEnroll-HPvsbd2J.cjs.map +0 -1
  106. package/dist/useAuth-CVLv2oKA.js.map +0 -1
  107. package/dist/useAuth-XZaciuLg.cjs +0 -1
  108. package/dist/useAuth-XZaciuLg.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleLoginButton-qf4A_A3G.js","sources":["../src/hooks/useGoogleAuth.ts","../src/components/google/GoogleLoginButton.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport type { AuthResponse, AuthError } from '../types';\n\n/**\n * Module-level singleton for Google script loading (P-01)\n *\n * Prevents race conditions when multiple components mount simultaneously.\n * Uses a promise queue pattern to ensure the script is only loaded once.\n *\n * ## SSR Limitations (F-08)\n *\n * This singleton persists across the module lifecycle. In SSR environments:\n * - Module state persists between requests (potential cross-request leakage)\n * - Google Sign-In requires browser APIs (document, window)\n * - The hook guards against SSR with `googleClientId` checks\n *\n * For SSR frameworks (Next.js, Remix), ensure this hook is only used\n * in client-side components.\n *\n * ## Test Isolation\n *\n * For test isolation, call `scriptLoader._reset()` in test setup/teardown.\n *\n * @internal\n */\nconst scriptLoader = {\n loading: false,\n loaded: false,\n error: null as Error | null,\n callbacks: [] as Array<{ resolve: () => void; reject: (err: Error) => void }>,\n\n load(): Promise<void> {\n // SSR guard: avoid touching browser globals when running in Node/SSR.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('Google Sign-In script loader cannot run in SSR'));\n }\n\n // Already loaded\n if (this.loaded) {\n return Promise.resolve();\n }\n\n // Loading in progress - queue callback\n if (this.loading) {\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n });\n }\n\n // Start loading\n this.loading = true;\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n\n // Check if script already exists (from previous session or SSR)\n const existingScript = document.getElementById('google-gsi-script');\n if (existingScript) {\n if (window.google?.accounts?.id) {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n } else {\n existingScript.addEventListener('load', () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n });\n }\n return;\n }\n\n const script = document.createElement('script');\n script.src = 'https://accounts.google.com/gsi/client';\n script.async = true;\n script.defer = true;\n script.id = 'google-gsi-script';\n\n script.onload = () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n };\n\n script.onerror = () => {\n this.loading = false;\n // M-02: Remove failed script from DOM to allow retry on next load() call.\n // Without removal, retry finds existingScript and waits for a load event\n // that will never fire on an already-failed script.\n script.remove();\n const error = new Error('Failed to load Google Sign-In script');\n this.callbacks.forEach((cb) => cb.reject(error));\n this.callbacks = [];\n };\n\n document.head.appendChild(script);\n });\n },\n\n /**\n * Reset singleton state for test isolation (F-08)\n * @internal - Only use in test setup/teardown\n */\n _reset(): void {\n this.loading = false;\n this.loaded = false;\n this.error = null;\n this.callbacks = [];\n },\n};\n\n/** @internal */\nexport const _internalGoogleScriptLoader = scriptLoader;\n\nexport interface UseGoogleAuthReturn {\n signIn: () => Promise<AuthResponse>;\n isLoading: boolean;\n isInitialized: boolean;\n error: AuthError | null;\n clearError: () => void;\n /** Access token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */\n pendingLinkToken: string | null;\n /** Clear the pending link state */\n clearPendingLink: () => void;\n}\n\ninterface PromiseCallbacks {\n resolve: (value: AuthResponse) => void;\n reject: (error: AuthError) => void;\n}\n\n/**\n * Hook for Google OAuth authentication.\n *\n * @example\n * ```tsx\n * function GoogleButton() {\n * const { signIn, isLoading, isInitialized, error } = useGoogleAuth();\n *\n * return (\n * <button onClick={signIn} disabled={!isInitialized || isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign in with Google'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useGoogleAuth(): UseGoogleAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n const [pendingLinkToken, setPendingLinkToken] = useState<string | null>(null);\n\n const promiseCallbacksRef = useRef<PromiseCallbacks | null>(null);\n const configRef = useRef(config);\n const tokenClientRef = useRef<GoogleTokenClient | null>(null);\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n // Keep config ref in sync\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Handle access token from OAuth popup (initTokenClient flow)\n const handleTokenResponse = useCallback(\n async (response: GoogleTokenResponse) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n if (response.error) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: response.error === 'access_denied'\n ? 'Google sign-in was cancelled.'\n : 'Unable to sign in with Google. Please try again.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n callbacks.reject(err);\n return;\n }\n\n try {\n const data = await apiClient.post<AuthResponse>('/google', {\n accessToken: response.access_token,\n });\n configRef.current.callbacks?.onLoginSuccess?.(data.user, 'google');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n setIsLoading(false);\n callbacks.resolve(data);\n } catch (err) {\n const authError = handleApiError(err, 'Unable to sign in with Google. Please try again.');\n if (authError.code === 'ACCOUNT_LINK_REQUIRED') {\n setPendingLinkToken(response.access_token ?? null);\n }\n setError(authError);\n setIsLoading(false);\n callbacks.reject(authError);\n } finally {\n promiseCallbacksRef.current = null;\n }\n },\n [apiClient, _internal]\n );\n\n // Handle popup closed / blocked without completing auth.\n // Google calls error_callback (not callback) when the user closes the popup.\n const handleTokenError = useCallback(\n (err: GoogleTokenErrorResponse) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n const authError: AuthError = {\n code: 'SERVER_ERROR',\n message: err.type === 'popup_failed_to_open'\n ? 'Google sign-in popup was blocked. Please allow popups for this site.'\n : 'Google sign-in was cancelled.',\n };\n setError(authError);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n callbacks.reject(authError);\n },\n []\n );\n\n // P-01: Initialize Google OAuth token client using singleton loader.\n // Uses initTokenClient (OAuth popup) instead of One Tap prompt() which\n // has exponential cooldown after dismissal and is blocked by Brave.\n useEffect(() => {\n if (!config.googleClientId) {\n return;\n }\n\n let isMounted = true;\n\n scriptLoader\n .load()\n .then(() => {\n if (!isMounted) return;\n\n const client = window.google?.accounts?.oauth2?.initTokenClient({\n client_id: config.googleClientId!,\n scope: 'openid email profile',\n callback: handleTokenResponse,\n error_callback: handleTokenError,\n });\n\n if (client) {\n tokenClientRef.current = client;\n setIsInitialized(true);\n }\n })\n .catch(() => {\n if (isMounted) {\n setError({\n code: 'SERVER_ERROR',\n message: 'Unable to load Google sign-in. Please refresh and try again.',\n });\n }\n });\n\n return () => {\n isMounted = false;\n tokenClientRef.current = null;\n };\n }, [config.googleClientId, handleTokenResponse, handleTokenError]);\n\n const signIn = useCallback(async (): Promise<AuthResponse> => {\n if (!config.googleClientId) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Client ID not configured',\n };\n setError(err);\n throw err;\n }\n\n if (!isInitialized) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is not ready yet. Please wait a moment and try again.',\n };\n setError(err);\n throw err;\n }\n\n if (promiseCallbacksRef.current) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is already in progress.',\n };\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise<AuthResponse>((resolve, reject) => {\n promiseCallbacksRef.current = { resolve, reject };\n\n // Open the Google OAuth popup via initTokenClient.\n // This avoids One Tap's exponential cooldown after dismissal and works\n // in browsers that block One Tap (e.g., Brave).\n tokenClientRef.current?.requestAccessToken();\n });\n }, [config.googleClientId, isInitialized]);\n\n const clearError = useCallback(() => setError(null), []);\n const clearPendingLink = useCallback(() => setPendingLinkToken(null), []);\n\n return {\n signIn,\n isLoading,\n isInitialized,\n error,\n clearError,\n pendingLinkToken,\n clearPendingLink,\n };\n}\n\n/** Response from Google's initTokenClient callback */\ninterface GoogleTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n}\n\n/** Error from initTokenClient error_callback (popup closed/blocked) */\ninterface GoogleTokenErrorResponse {\n type: 'popup_failed_to_open' | 'popup_closed' | 'unknown';\n}\n\n/** Token client returned by google.accounts.oauth2.initTokenClient */\ninterface GoogleTokenClient {\n requestAccessToken: () => void;\n}\n\n// Type declaration for Google Identity Services\ndeclare global {\n interface Window {\n google?: {\n accounts?: {\n /** Used only to detect if the GIS script has loaded */\n id?: object;\n oauth2?: {\n initTokenClient: (config: {\n client_id: string;\n scope: string;\n callback: (response: GoogleTokenResponse) => void;\n error_callback?: (error: GoogleTokenErrorResponse) => void;\n }) => GoogleTokenClient;\n };\n };\n };\n }\n}\n","import { useGoogleAuth } from '../../hooks/useGoogleAuth';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface GoogleLoginButtonProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n className?: string;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\n/**\n * Google OAuth login button\n */\nexport function GoogleLoginButton({\n onSuccess,\n onError,\n className = '',\n variant = 'default',\n size = 'md',\n disabled = false,\n}: GoogleLoginButtonProps) {\n const { signIn, isLoading, isInitialized } = useGoogleAuth();\n\n const handleClick = async () => {\n try {\n await signIn();\n onSuccess?.();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error);\n }\n };\n\n const sizeClasses = {\n sm: 'cedros-button-sm',\n md: 'cedros-button-md',\n lg: 'cedros-button-lg',\n };\n\n const variantClasses = {\n default: 'cedros-button-social',\n outline: 'cedros-button-social-outline',\n };\n\n return (\n <button\n type=\"button\"\n className={`cedros-button ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}\n onClick={handleClick}\n disabled={disabled || !isInitialized || isLoading}\n aria-label=\"Sign in with Google\"\n >\n {isLoading ? (\n <LoadingSpinner size=\"sm\" />\n ) : (\n <svg\n className=\"cedros-button-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z\"\n fill=\"#EA4335\"\n />\n </svg>\n )}\n <span>Continue with Google</span>\n </button>\n );\n}\n"],"names":["scriptLoader","resolve","reject","existingScript","cb","script","error","useGoogleAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","useState","isInitialized","setIsInitialized","setError","pendingLinkToken","setPendingLinkToken","promiseCallbacksRef","useRef","configRef","tokenClientRef","apiClient","useMemo","ApiClient","useEffect","handleTokenResponse","useCallback","response","callbacks","err","data","authError","handleApiError","handleTokenError","isMounted","client","signIn","clearError","clearPendingLink","GoogleLoginButton","onSuccess","onError","className","variant","size","disabled","handleClick","sizeClasses","jsxs","jsx","LoadingSpinner"],"mappings":"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"}
@@ -1 +1 @@
1
- "use strict";const e=require("react/jsx-runtime"),a=require("react"),p=require("./LoadingSpinner-d6sSxgQN.cjs"),_=require("./ErrorMessage-CHbYbVi2.cjs"),g=require("./AutosaveStatus-DGNI4lXn.cjs"),k=[{id:"integrations",label:"Integrations",keys:["server_cedros_pay_api_key"],requiredSetting:"feature_cedros_pay"},{id:"logging",label:"Logging",keys:["server_log_level"]},{id:"metrics",label:"Metrics",keys:["server_metrics_api_key"]},{id:"security",label:"Security",categories:["security","features"],keys:["feature_mfa","security_cors_origins","security_session_timeout"]}];function N({className:c}){const{settings:o,edits:h,isLoading:S,autosaveStatus:x,autosaveError:b,error:u,fetchSettings:m,handleChange:j,getEffectiveValue:y}=g.useSettingsAutosave(),t=a.useMemo(()=>k.filter(s=>s.requiredSetting?y(s.requiredSetting)==="true":!0),[y]),[r,d]=a.useState(null);a.useEffect(()=>{r===null&&t.length>0?d(t[0].id):r&&!t.some(s=>s.id===r)&&d(t[0]?.id??null)},[t,r]),a.useEffect(()=>{m()},[m]);const i=t.find(s=>s.id===r),v=a.useMemo(()=>{if(!i)return[];const s=i.categories??["server"],f=[];for(const n of s){const l=o[n]??[];f.push(...l)}return f.filter(n=>i.keys.includes(n.key)).sort((n,l)=>i.keys.indexOf(n.key)-i.keys.indexOf(l.key))},[o,i]);return S&&Object.keys(o).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${c??""}`,children:[e.jsx(p.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):u?e.jsx("div",{className:`cedros-system-settings ${c??""}`,children:e.jsx(_.ErrorMessage,{error:u.message})}):e.jsxs("div",{className:`cedros-system-settings ${c??""}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:"Auth Server"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Server infrastructure settings. Some may be overridden by environment variables."})]}),e.jsx(g.AutosaveStatus,{status:x,error:b})]}),e.jsx("div",{className:"cedros-admin-tabs cedros-admin-tabs--line",children:t.map(s=>e.jsx("button",{type:"button",className:`cedros-admin-tab ${r===s.id?"cedros-admin-tab-active":""}`,onClick:()=>d(s.id),"aria-selected":r===s.id,role:"tab",children:s.label},s.id))}),e.jsx("div",{className:"cedros-admin-tab-content",role:"tabpanel",children:v.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsxs("p",{children:["No settings found for ",i?.label??"this section","."]})}):e.jsx(g.SettingsSection,{settings:v,edits:h,onChange:j})})]})}exports.ServerSettings=N;
1
+ "use strict";const e=require("react/jsx-runtime"),a=require("react"),p=require("./LoadingSpinner-d6sSxgQN.cjs"),_=require("./ErrorMessage-CHbYbVi2.cjs"),g=require("./AutosaveStatus-BKsCIvPj.cjs"),k=[{id:"integrations",label:"Integrations",keys:["server_cedros_pay_api_key"],requiredSetting:"feature_cedros_pay"},{id:"logging",label:"Logging",keys:["server_log_level"]},{id:"metrics",label:"Metrics",keys:["server_metrics_api_key"]},{id:"security",label:"Security",categories:["security","features"],keys:["feature_mfa","security_cors_origins","security_session_timeout"]}];function N({className:c}){const{settings:o,edits:h,isLoading:S,autosaveStatus:x,autosaveError:b,error:u,fetchSettings:m,handleChange:j,getEffectiveValue:y}=g.useSettingsAutosave(),t=a.useMemo(()=>k.filter(s=>s.requiredSetting?y(s.requiredSetting)==="true":!0),[y]),[r,d]=a.useState(null);a.useEffect(()=>{r===null&&t.length>0?d(t[0].id):r&&!t.some(s=>s.id===r)&&d(t[0]?.id??null)},[t,r]),a.useEffect(()=>{m()},[m]);const i=t.find(s=>s.id===r),v=a.useMemo(()=>{if(!i)return[];const s=i.categories??["server"],f=[];for(const n of s){const l=o[n]??[];f.push(...l)}return f.filter(n=>i.keys.includes(n.key)).sort((n,l)=>i.keys.indexOf(n.key)-i.keys.indexOf(l.key))},[o,i]);return S&&Object.keys(o).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${c??""}`,children:[e.jsx(p.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):u?e.jsx("div",{className:`cedros-system-settings ${c??""}`,children:e.jsx(_.ErrorMessage,{error:u.message})}):e.jsxs("div",{className:`cedros-system-settings ${c??""}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:"Auth Server"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Server infrastructure settings. Some may be overridden by environment variables."})]}),e.jsx(g.AutosaveStatus,{status:x,error:b})]}),e.jsx("div",{className:"cedros-admin-tabs cedros-admin-tabs--line",children:t.map(s=>e.jsx("button",{type:"button",className:`cedros-admin-tab ${r===s.id?"cedros-admin-tab-active":""}`,onClick:()=>d(s.id),"aria-selected":r===s.id,role:"tab",children:s.label},s.id))}),e.jsx("div",{className:"cedros-admin-tab-content",role:"tabpanel",children:v.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsxs("p",{children:["No settings found for ",i?.label??"this section","."]})}):e.jsx(g.SettingsSection,{settings:v,edits:h,onChange:j})})]})}exports.ServerSettings=N;
@@ -1 +1 @@
1
- {"version":3,"file":"ServerSettings-CKfiLfXi.cjs","sources":["../src/components/admin/settings/ServerSettings.tsx"],"sourcesContent":["/**\n * Server settings page - infrastructure configuration with tabs\n *\n * Tab visibility:\n * - Integrations: only shown when `feature_cedros_pay` is enabled.\n * This tab contains the Cedros Pay API Key, which is only needed when\n * cedros-pay runs as a separate microservice. In co-located deployments\n * (e.g., cedros-login and cedros-pay in the same Rust binary), inter-service\n * auth uses JWT/JWKS and no API key is needed.\n * - Logging, Metrics, Security: always visible.\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\ntype ServerTab = 'integrations' | 'logging' | 'metrics' | 'security';\n\ninterface TabConfig {\n id: ServerTab;\n label: string;\n /** Categories to pull settings from (defaults to ['server']) */\n categories?: string[];\n keys: string[];\n /** When set, tab is only visible if this setting is 'true' */\n requiredSetting?: string;\n}\n\nconst TABS: TabConfig[] = [\n {\n id: 'integrations',\n label: 'Integrations',\n keys: ['server_cedros_pay_api_key'],\n requiredSetting: 'feature_cedros_pay',\n },\n {\n id: 'logging',\n label: 'Logging',\n keys: ['server_log_level'],\n },\n {\n id: 'metrics',\n label: 'Metrics',\n keys: ['server_metrics_api_key'],\n },\n {\n id: 'security',\n label: 'Security',\n categories: ['security', 'features'],\n keys: ['feature_mfa', 'security_cors_origins', 'security_session_timeout'],\n },\n];\n\nexport interface ServerSettingsProps {\n className?: string;\n}\n\nexport function ServerSettings({ className }: ServerSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n } = useSettingsAutosave();\n\n // Filter tabs based on feature flags\n const visibleTabs = useMemo(\n () =>\n TABS.filter((tab) => {\n if (!tab.requiredSetting) return true;\n return getEffectiveValue(tab.requiredSetting) === 'true';\n }),\n [getEffectiveValue]\n );\n\n // Default to first visible tab\n const [activeTab, setActiveTab] = useState<ServerTab | null>(null);\n\n // Set initial tab when tabs become available\n useEffect(() => {\n if (activeTab === null && visibleTabs.length > 0) {\n setActiveTab(visibleTabs[0].id);\n } else if (activeTab && !visibleTabs.some((t) => t.id === activeTab)) {\n // Active tab was hidden (feature toggled off) — fall back\n setActiveTab(visibleTabs[0]?.id ?? null);\n }\n }, [visibleTabs, activeTab]);\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get current tab config\n const currentTab = visibleTabs.find((t) => t.id === activeTab);\n\n // Collect settings from all categories for the current tab\n const currentSettings = useMemo(() => {\n if (!currentTab) return [];\n const categories = currentTab.categories ?? ['server'];\n const allSettings: (typeof settings)[string] = [];\n for (const category of categories) {\n const categorySettings = settings[category] ?? [];\n allSettings.push(...categorySettings);\n }\n // Filter by keys and sort by keys order\n return allSettings\n .filter((s) => currentTab.keys.includes(s.key))\n .sort((a, b) => currentTab.keys.indexOf(a.key) - currentTab.keys.indexOf(b.key));\n }, [settings, currentTab]);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Auth Server</h2>\n <p className=\"cedros-settings-page-description\">\n Server infrastructure settings. Some may be overridden by environment variables.\n </p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {/* Tabs */}\n <div className=\"cedros-admin-tabs cedros-admin-tabs--line\">\n {visibleTabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === tab.id ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab(tab.id)}\n aria-selected={activeTab === tab.id}\n role=\"tab\"\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Tab content */}\n <div className=\"cedros-admin-tab-content\" role=\"tabpanel\">\n {currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for {currentTab?.label ?? 'this section'}.</p>\n </div>\n ) : (\n <SettingsSection settings={currentSettings} edits={edits} onChange={handleChange} />\n )}\n </div>\n </div>\n );\n}\n"],"names":["TABS","ServerSettings","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","getEffectiveValue","useSettingsAutosave","visibleTabs","useMemo","tab","activeTab","setActiveTab","useState","useEffect","t","currentTab","currentSettings","categories","allSettings","category","categorySettings","s","a","b","jsx","LoadingSpinner","ErrorMessage","jsxs","AutosaveStatus","SettingsSection"],"mappings":"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"}
1
+ {"version":3,"file":"ServerSettings-CMmH5pZv.cjs","sources":["../src/components/admin/settings/ServerSettings.tsx"],"sourcesContent":["/**\n * Server settings page - infrastructure configuration with tabs\n *\n * Tab visibility:\n * - Integrations: only shown when `feature_cedros_pay` is enabled.\n * This tab contains the Cedros Pay API Key, which is only needed when\n * cedros-pay runs as a separate microservice. In co-located deployments\n * (e.g., cedros-login and cedros-pay in the same Rust binary), inter-service\n * auth uses JWT/JWKS and no API key is needed.\n * - Logging, Metrics, Security: always visible.\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\ntype ServerTab = 'integrations' | 'logging' | 'metrics' | 'security';\n\ninterface TabConfig {\n id: ServerTab;\n label: string;\n /** Categories to pull settings from (defaults to ['server']) */\n categories?: string[];\n keys: string[];\n /** When set, tab is only visible if this setting is 'true' */\n requiredSetting?: string;\n}\n\nconst TABS: TabConfig[] = [\n {\n id: 'integrations',\n label: 'Integrations',\n keys: ['server_cedros_pay_api_key'],\n requiredSetting: 'feature_cedros_pay',\n },\n {\n id: 'logging',\n label: 'Logging',\n keys: ['server_log_level'],\n },\n {\n id: 'metrics',\n label: 'Metrics',\n keys: ['server_metrics_api_key'],\n },\n {\n id: 'security',\n label: 'Security',\n categories: ['security', 'features'],\n keys: ['feature_mfa', 'security_cors_origins', 'security_session_timeout'],\n },\n];\n\nexport interface ServerSettingsProps {\n className?: string;\n}\n\nexport function ServerSettings({ className }: ServerSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n } = useSettingsAutosave();\n\n // Filter tabs based on feature flags\n const visibleTabs = useMemo(\n () =>\n TABS.filter((tab) => {\n if (!tab.requiredSetting) return true;\n return getEffectiveValue(tab.requiredSetting) === 'true';\n }),\n [getEffectiveValue]\n );\n\n // Default to first visible tab\n const [activeTab, setActiveTab] = useState<ServerTab | null>(null);\n\n // Set initial tab when tabs become available\n useEffect(() => {\n if (activeTab === null && visibleTabs.length > 0) {\n setActiveTab(visibleTabs[0].id);\n } else if (activeTab && !visibleTabs.some((t) => t.id === activeTab)) {\n // Active tab was hidden (feature toggled off) — fall back\n setActiveTab(visibleTabs[0]?.id ?? null);\n }\n }, [visibleTabs, activeTab]);\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get current tab config\n const currentTab = visibleTabs.find((t) => t.id === activeTab);\n\n // Collect settings from all categories for the current tab\n const currentSettings = useMemo(() => {\n if (!currentTab) return [];\n const categories = currentTab.categories ?? ['server'];\n const allSettings: (typeof settings)[string] = [];\n for (const category of categories) {\n const categorySettings = settings[category] ?? [];\n allSettings.push(...categorySettings);\n }\n // Filter by keys and sort by keys order\n return allSettings\n .filter((s) => currentTab.keys.includes(s.key))\n .sort((a, b) => currentTab.keys.indexOf(a.key) - currentTab.keys.indexOf(b.key));\n }, [settings, currentTab]);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Auth Server</h2>\n <p className=\"cedros-settings-page-description\">\n Server infrastructure settings. Some may be overridden by environment variables.\n </p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {/* Tabs */}\n <div className=\"cedros-admin-tabs cedros-admin-tabs--line\">\n {visibleTabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === tab.id ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab(tab.id)}\n aria-selected={activeTab === tab.id}\n role=\"tab\"\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Tab content */}\n <div className=\"cedros-admin-tab-content\" role=\"tabpanel\">\n {currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for {currentTab?.label ?? 'this section'}.</p>\n </div>\n ) : (\n <SettingsSection settings={currentSettings} edits={edits} onChange={handleChange} />\n )}\n </div>\n </div>\n );\n}\n"],"names":["TABS","ServerSettings","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","getEffectiveValue","useSettingsAutosave","visibleTabs","useMemo","tab","activeTab","setActiveTab","useState","useEffect","t","currentTab","currentSettings","categories","allSettings","category","categorySettings","s","a","b","jsx","LoadingSpinner","ErrorMessage","jsxs","AutosaveStatus","SettingsSection"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as r } from "react/jsx-runtime";
2
2
  import "react";
3
- import { S as e } from "./ServerSettings-BT9weFPz.js";
3
+ import { S as e } from "./ServerSettings-qxi8aZO7.js";
4
4
  function i() {
5
5
  return /* @__PURE__ */ r("div", { className: "cedros-dashboard__section", children: /* @__PURE__ */ r(e, {}) });
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ServerSettings-CZfBdMxG.js","sources":["../src/admin/sections/ServerSettings.tsx"],"sourcesContent":["/**\n * Server Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { ServerSettings as Settings } from '../../components/admin/settings';\n\nexport default function ServerSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["ServerSettings","jsx","Settings"],"mappings":";;;AAOA,SAAwBA,IAAoC;AAC1D,2BACG,OAAA,EAAI,WAAU,6BACb,UAAA,gBAAAC,EAACC,KAAS,GACZ;AAEJ;"}
1
+ {"version":3,"file":"ServerSettings-DQemMrNv.js","sources":["../src/admin/sections/ServerSettings.tsx"],"sourcesContent":["/**\n * Server Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { ServerSettings as Settings } from '../../components/admin/settings';\n\nexport default function ServerSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["ServerSettings","jsx","Settings"],"mappings":";;;AAOA,SAAwBA,IAAoC;AAC1D,2BACG,OAAA,EAAI,WAAU,6BACb,UAAA,gBAAAC,EAACC,KAAS,GACZ;AAEJ;"}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime");require("react");const r=require("./ServerSettings-CKfiLfXi.cjs");function t(){return e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx(r.ServerSettings,{})})}exports.default=t;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime");require("react");const r=require("./ServerSettings-CMmH5pZv.cjs");function t(){return e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx(r.ServerSettings,{})})}exports.default=t;
@@ -1 +1 @@
1
- {"version":3,"file":"ServerSettings-rHrVN8O8.cjs","sources":["../src/admin/sections/ServerSettings.tsx"],"sourcesContent":["/**\n * Server Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { ServerSettings as Settings } from '../../components/admin/settings';\n\nexport default function ServerSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["ServerSettings","jsx","Settings"],"mappings":"uLAOA,SAAwBA,GAAoC,CAC1D,aACG,MAAA,CAAI,UAAU,4BACb,SAAAC,MAACC,EAAAA,iBAAS,EACZ,CAEJ"}
1
+ {"version":3,"file":"ServerSettings-DfimU7ay.cjs","sources":["../src/admin/sections/ServerSettings.tsx"],"sourcesContent":["/**\n * Server Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { ServerSettings as Settings } from '../../components/admin/settings';\n\nexport default function ServerSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["ServerSettings","jsx","Settings"],"mappings":"uLAOA,SAAwBA,GAAoC,CAC1D,aACG,MAAA,CAAI,UAAU,4BACb,SAAAC,MAACC,EAAAA,iBAAS,EACZ,CAEJ"}
@@ -2,7 +2,7 @@ import { jsxs as a, jsx as s } from "react/jsx-runtime";
2
2
  import { useMemo as v, useState as N, useEffect as h } from "react";
3
3
  import { L as A } from "./LoadingSpinner-6vml-zwr.js";
4
4
  import { E as x } from "./ErrorMessage-CcEK0pYO.js";
5
- import { u as E, A as L, S as T } from "./AutosaveStatus-f-jw25Ay.js";
5
+ import { u as E, A as L, S as T } from "./AutosaveStatus-CSZsp6w7.js";
6
6
  const $ = [
7
7
  {
8
8
  id: "integrations",
@@ -1 +1 @@
1
- {"version":3,"file":"ServerSettings-BT9weFPz.js","sources":["../src/components/admin/settings/ServerSettings.tsx"],"sourcesContent":["/**\n * Server settings page - infrastructure configuration with tabs\n *\n * Tab visibility:\n * - Integrations: only shown when `feature_cedros_pay` is enabled.\n * This tab contains the Cedros Pay API Key, which is only needed when\n * cedros-pay runs as a separate microservice. In co-located deployments\n * (e.g., cedros-login and cedros-pay in the same Rust binary), inter-service\n * auth uses JWT/JWKS and no API key is needed.\n * - Logging, Metrics, Security: always visible.\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\ntype ServerTab = 'integrations' | 'logging' | 'metrics' | 'security';\n\ninterface TabConfig {\n id: ServerTab;\n label: string;\n /** Categories to pull settings from (defaults to ['server']) */\n categories?: string[];\n keys: string[];\n /** When set, tab is only visible if this setting is 'true' */\n requiredSetting?: string;\n}\n\nconst TABS: TabConfig[] = [\n {\n id: 'integrations',\n label: 'Integrations',\n keys: ['server_cedros_pay_api_key'],\n requiredSetting: 'feature_cedros_pay',\n },\n {\n id: 'logging',\n label: 'Logging',\n keys: ['server_log_level'],\n },\n {\n id: 'metrics',\n label: 'Metrics',\n keys: ['server_metrics_api_key'],\n },\n {\n id: 'security',\n label: 'Security',\n categories: ['security', 'features'],\n keys: ['feature_mfa', 'security_cors_origins', 'security_session_timeout'],\n },\n];\n\nexport interface ServerSettingsProps {\n className?: string;\n}\n\nexport function ServerSettings({ className }: ServerSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n } = useSettingsAutosave();\n\n // Filter tabs based on feature flags\n const visibleTabs = useMemo(\n () =>\n TABS.filter((tab) => {\n if (!tab.requiredSetting) return true;\n return getEffectiveValue(tab.requiredSetting) === 'true';\n }),\n [getEffectiveValue]\n );\n\n // Default to first visible tab\n const [activeTab, setActiveTab] = useState<ServerTab | null>(null);\n\n // Set initial tab when tabs become available\n useEffect(() => {\n if (activeTab === null && visibleTabs.length > 0) {\n setActiveTab(visibleTabs[0].id);\n } else if (activeTab && !visibleTabs.some((t) => t.id === activeTab)) {\n // Active tab was hidden (feature toggled off) — fall back\n setActiveTab(visibleTabs[0]?.id ?? null);\n }\n }, [visibleTabs, activeTab]);\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get current tab config\n const currentTab = visibleTabs.find((t) => t.id === activeTab);\n\n // Collect settings from all categories for the current tab\n const currentSettings = useMemo(() => {\n if (!currentTab) return [];\n const categories = currentTab.categories ?? ['server'];\n const allSettings: (typeof settings)[string] = [];\n for (const category of categories) {\n const categorySettings = settings[category] ?? [];\n allSettings.push(...categorySettings);\n }\n // Filter by keys and sort by keys order\n return allSettings\n .filter((s) => currentTab.keys.includes(s.key))\n .sort((a, b) => currentTab.keys.indexOf(a.key) - currentTab.keys.indexOf(b.key));\n }, [settings, currentTab]);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Auth Server</h2>\n <p className=\"cedros-settings-page-description\">\n Server infrastructure settings. Some may be overridden by environment variables.\n </p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {/* Tabs */}\n <div className=\"cedros-admin-tabs cedros-admin-tabs--line\">\n {visibleTabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === tab.id ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab(tab.id)}\n aria-selected={activeTab === tab.id}\n role=\"tab\"\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Tab content */}\n <div className=\"cedros-admin-tab-content\" role=\"tabpanel\">\n {currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for {currentTab?.label ?? 'this section'}.</p>\n </div>\n ) : (\n <SettingsSection settings={currentSettings} edits={edits} onChange={handleChange} />\n )}\n </div>\n </div>\n );\n}\n"],"names":["TABS","ServerSettings","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","getEffectiveValue","useSettingsAutosave","visibleTabs","useMemo","tab","activeTab","setActiveTab","useState","useEffect","t","currentTab","currentSettings","categories","allSettings","category","categorySettings","s","a","b","jsx","LoadingSpinner","ErrorMessage","jsxs","AutosaveStatus","SettingsSection"],"mappings":"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"}
1
+ {"version":3,"file":"ServerSettings-qxi8aZO7.js","sources":["../src/components/admin/settings/ServerSettings.tsx"],"sourcesContent":["/**\n * Server settings page - infrastructure configuration with tabs\n *\n * Tab visibility:\n * - Integrations: only shown when `feature_cedros_pay` is enabled.\n * This tab contains the Cedros Pay API Key, which is only needed when\n * cedros-pay runs as a separate microservice. In co-located deployments\n * (e.g., cedros-login and cedros-pay in the same Rust binary), inter-service\n * auth uses JWT/JWKS and no API key is needed.\n * - Logging, Metrics, Security: always visible.\n */\nimport { useState, useEffect, useMemo } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\ntype ServerTab = 'integrations' | 'logging' | 'metrics' | 'security';\n\ninterface TabConfig {\n id: ServerTab;\n label: string;\n /** Categories to pull settings from (defaults to ['server']) */\n categories?: string[];\n keys: string[];\n /** When set, tab is only visible if this setting is 'true' */\n requiredSetting?: string;\n}\n\nconst TABS: TabConfig[] = [\n {\n id: 'integrations',\n label: 'Integrations',\n keys: ['server_cedros_pay_api_key'],\n requiredSetting: 'feature_cedros_pay',\n },\n {\n id: 'logging',\n label: 'Logging',\n keys: ['server_log_level'],\n },\n {\n id: 'metrics',\n label: 'Metrics',\n keys: ['server_metrics_api_key'],\n },\n {\n id: 'security',\n label: 'Security',\n categories: ['security', 'features'],\n keys: ['feature_mfa', 'security_cors_origins', 'security_session_timeout'],\n },\n];\n\nexport interface ServerSettingsProps {\n className?: string;\n}\n\nexport function ServerSettings({ className }: ServerSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n } = useSettingsAutosave();\n\n // Filter tabs based on feature flags\n const visibleTabs = useMemo(\n () =>\n TABS.filter((tab) => {\n if (!tab.requiredSetting) return true;\n return getEffectiveValue(tab.requiredSetting) === 'true';\n }),\n [getEffectiveValue]\n );\n\n // Default to first visible tab\n const [activeTab, setActiveTab] = useState<ServerTab | null>(null);\n\n // Set initial tab when tabs become available\n useEffect(() => {\n if (activeTab === null && visibleTabs.length > 0) {\n setActiveTab(visibleTabs[0].id);\n } else if (activeTab && !visibleTabs.some((t) => t.id === activeTab)) {\n // Active tab was hidden (feature toggled off) — fall back\n setActiveTab(visibleTabs[0]?.id ?? null);\n }\n }, [visibleTabs, activeTab]);\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get current tab config\n const currentTab = visibleTabs.find((t) => t.id === activeTab);\n\n // Collect settings from all categories for the current tab\n const currentSettings = useMemo(() => {\n if (!currentTab) return [];\n const categories = currentTab.categories ?? ['server'];\n const allSettings: (typeof settings)[string] = [];\n for (const category of categories) {\n const categorySettings = settings[category] ?? [];\n allSettings.push(...categorySettings);\n }\n // Filter by keys and sort by keys order\n return allSettings\n .filter((s) => currentTab.keys.includes(s.key))\n .sort((a, b) => currentTab.keys.indexOf(a.key) - currentTab.keys.indexOf(b.key));\n }, [settings, currentTab]);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Auth Server</h2>\n <p className=\"cedros-settings-page-description\">\n Server infrastructure settings. Some may be overridden by environment variables.\n </p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {/* Tabs */}\n <div className=\"cedros-admin-tabs cedros-admin-tabs--line\">\n {visibleTabs.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === tab.id ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab(tab.id)}\n aria-selected={activeTab === tab.id}\n role=\"tab\"\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Tab content */}\n <div className=\"cedros-admin-tab-content\" role=\"tabpanel\">\n {currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for {currentTab?.label ?? 'this section'}.</p>\n </div>\n ) : (\n <SettingsSection settings={currentSettings} edits={edits} onChange={handleChange} />\n )}\n </div>\n </div>\n );\n}\n"],"names":["TABS","ServerSettings","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","getEffectiveValue","useSettingsAutosave","visibleTabs","useMemo","tab","activeTab","setActiveTab","useState","useEffect","t","currentTab","currentSettings","categories","allSettings","category","categorySettings","s","a","b","jsx","LoadingSpinner","ErrorMessage","jsxs","AutosaveStatus","SettingsSection"],"mappings":";;;;;AA8BA,MAAMA,IAAoB;AAAA,EACxB;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM,CAAC,2BAA2B;AAAA,IAClC,iBAAiB;AAAA,EAAA;AAAA,EAEnB;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM,CAAC,kBAAkB;AAAA,EAAA;AAAA,EAE3B;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,MAAM,CAAC,wBAAwB;AAAA,EAAA;AAAA,EAEjC;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,YAAY,CAAC,YAAY,UAAU;AAAA,IACnC,MAAM,CAAC,eAAe,yBAAyB,0BAA0B;AAAA,EAAA;AAE7E;AAMO,SAASC,EAAe,EAAE,WAAAC,KAAkC;AACjE,QAAM;AAAA,IACJ,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,eAAAC;AAAA,IACA,OAAAC;AAAA,IACA,eAAAC;AAAA,IACA,cAAAC;AAAA,IACA,mBAAAC;AAAA,EAAA,IACEC,EAAA,GAGEC,IAAcC;AAAA,IAClB,MACEd,EAAK,OAAO,CAACe,MACNA,EAAI,kBACFJ,EAAkBI,EAAI,eAAe,MAAM,SADjB,EAElC;AAAA,IACH,CAACJ,CAAiB;AAAA,EAAA,GAId,CAACK,GAAWC,CAAY,IAAIC,EAA2B,IAAI;AAGjE,EAAAC,EAAU,MAAM;AACd,IAAIH,MAAc,QAAQH,EAAY,SAAS,IAC7CI,EAAaJ,EAAY,CAAC,EAAE,EAAE,IACrBG,KAAa,CAACH,EAAY,KAAK,CAACO,MAAMA,EAAE,OAAOJ,CAAS,KAEjEC,EAAaJ,EAAY,CAAC,GAAG,MAAM,IAAI;AAAA,EAE3C,GAAG,CAACA,GAAaG,CAAS,CAAC,GAE3BG,EAAU,MAAM;AACd,IAAAV,EAAA;AAAA,EACF,GAAG,CAACA,CAAa,CAAC;AAGlB,QAAMY,IAAaR,EAAY,KAAK,CAACO,MAAMA,EAAE,OAAOJ,CAAS,GAGvDM,IAAkBR,EAAQ,MAAM;AACpC,QAAI,CAACO,EAAY,QAAO,CAAA;AACxB,UAAME,IAAaF,EAAW,cAAc,CAAC,QAAQ,GAC/CG,IAAyC,CAAA;AAC/C,eAAWC,KAAYF,GAAY;AACjC,YAAMG,IAAmBvB,EAASsB,CAAQ,KAAK,CAAA;AAC/C,MAAAD,EAAY,KAAK,GAAGE,CAAgB;AAAA,IACtC;AAEA,WAAOF,EACJ,OAAO,CAACG,MAAMN,EAAW,KAAK,SAASM,EAAE,GAAG,CAAC,EAC7C,KAAK,CAACC,GAAGC,MAAMR,EAAW,KAAK,QAAQO,EAAE,GAAG,IAAIP,EAAW,KAAK,QAAQQ,EAAE,GAAG,CAAC;AAAA,EACnF,GAAG,CAAC1B,GAAUkB,CAAU,CAAC;AAEzB,SAAIhB,KAAa,OAAO,KAAKF,CAAQ,EAAE,WAAW,sBAE7C,OAAA,EAAI,WAAW,yDAAyDD,KAAa,EAAE,IACtF,UAAA;AAAA,IAAA,gBAAA4B,EAACC,GAAA,EAAe;AAAA,IAChB,gBAAAD,EAAC,UAAK,UAAA,sBAAA,CAAmB;AAAA,EAAA,GAC3B,IAIAtB,IAEA,gBAAAsB,EAAC,OAAA,EAAI,WAAW,0BAA0B5B,KAAa,EAAE,IACvD,UAAA,gBAAA4B,EAACE,GAAA,EAAa,OAAOxB,EAAM,QAAA,CAAS,GACtC,sBAKD,OAAA,EAAI,WAAW,0BAA0BN,KAAa,EAAE,IACvD,UAAA;AAAA,IAAA,gBAAA+B,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,QAAA,gBAAAH,EAAC,MAAA,EAAG,WAAU,8BAA6B,UAAA,eAAW;AAAA,QACtD,gBAAAA,EAAC,KAAA,EAAE,WAAU,oCAAmC,UAAA,mFAAA,CAEhD;AAAA,MAAA,GACF;AAAA,MACA,gBAAAA,EAACI,GAAA,EAAe,QAAQ5B,GAAgB,OAAOC,EAAA,CAAe;AAAA,IAAA,GAChE;AAAA,sBAGC,OAAA,EAAI,WAAU,6CACZ,UAAAM,EAAY,IAAI,CAACE,MAChB,gBAAAe;AAAA,MAAC;AAAA,MAAA;AAAA,QAEC,MAAK;AAAA,QACL,WAAW,oBAAoBd,MAAcD,EAAI,KAAK,4BAA4B,EAAE;AAAA,QACpF,SAAS,MAAME,EAAaF,EAAI,EAAE;AAAA,QAClC,iBAAeC,MAAcD,EAAI;AAAA,QACjC,MAAK;AAAA,QAEJ,UAAAA,EAAI;AAAA,MAAA;AAAA,MAPAA,EAAI;AAAA,IAAA,CASZ,GACH;AAAA,IAGA,gBAAAe,EAAC,OAAA,EAAI,WAAU,4BAA2B,MAAK,YAC5C,UAAAR,EAAgB,WAAW,IAC1B,gBAAAQ,EAAC,OAAA,EAAI,WAAU,gCACb,4BAAC,KAAA,EAAE,UAAA;AAAA,MAAA;AAAA,MAAuBT,GAAY,SAAS;AAAA,MAAe;AAAA,IAAA,EAAA,CAAC,EAAA,CACjE,IAEA,gBAAAS,EAACK,GAAA,EAAgB,UAAUb,GAAiB,OAAAlB,GAAc,UAAUM,EAAA,CAAc,EAAA,CAEtF;AAAA,EAAA,GACF;AAEJ;"}
@@ -1 +1 @@
1
- "use strict";const e=require("react/jsx-runtime"),S=require("react"),f=require("./LoadingSpinner-d6sSxgQN.cjs"),p=require("./ErrorMessage-CHbYbVi2.cjs"),r=require("./AutosaveStatus-DGNI4lXn.cjs");function g({title:t,description:d,categories:u,className:n=""}){const{settings:i,edits:h,isLoading:l,autosaveStatus:j,autosaveError:x,error:o,fetchSettings:a,handleChange:m}=r.useSettingsAutosave();S.useEffect(()=>{a()},[a]);const c=u.filter(s=>i[s]?.length>0);return l&&Object.keys(i).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${n}`,children:[e.jsx(f.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):o?e.jsx("div",{className:`cedros-system-settings ${n}`,children:e.jsx(p.ErrorMessage,{error:o.message})}):e.jsxs("div",{className:`cedros-system-settings ${n}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:t}),e.jsx("p",{className:"cedros-settings-page-description",children:d})]}),e.jsx(r.AutosaveStatus,{status:j,error:x})]}),c.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsx("p",{children:"No settings found for this section."})}):c.map(s=>e.jsx(r.SettingsSection,{settings:i[s],edits:h,onChange:m},s))]})}const v=["webhook"];function y({className:t}){return e.jsx(g,{title:"Webhooks",description:"Configure HTTP webhook notifications for authentication events.",categories:v,className:t})}exports.SettingsPageLayout=g;exports.WebhookSettings=y;
1
+ "use strict";const e=require("react/jsx-runtime"),S=require("react"),f=require("./LoadingSpinner-d6sSxgQN.cjs"),p=require("./ErrorMessage-CHbYbVi2.cjs"),r=require("./AutosaveStatus-BKsCIvPj.cjs");function g({title:t,description:d,categories:u,className:n=""}){const{settings:i,edits:h,isLoading:l,autosaveStatus:j,autosaveError:x,error:o,fetchSettings:a,handleChange:m}=r.useSettingsAutosave();S.useEffect(()=>{a()},[a]);const c=u.filter(s=>i[s]?.length>0);return l&&Object.keys(i).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${n}`,children:[e.jsx(f.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):o?e.jsx("div",{className:`cedros-system-settings ${n}`,children:e.jsx(p.ErrorMessage,{error:o.message})}):e.jsxs("div",{className:`cedros-system-settings ${n}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:t}),e.jsx("p",{className:"cedros-settings-page-description",children:d})]}),e.jsx(r.AutosaveStatus,{status:j,error:x})]}),c.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsx("p",{children:"No settings found for this section."})}):c.map(s=>e.jsx(r.SettingsSection,{settings:i[s],edits:h,onChange:m},s))]})}const v=["webhook"];function y({className:t}){return e.jsx(g,{title:"Webhooks",description:"Configure HTTP webhook notifications for authentication events.",categories:v,className:t})}exports.SettingsPageLayout=g;exports.WebhookSettings=y;
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookSettings-DXjnq-c7.cjs","sources":["../src/components/admin/settings/SettingsPageLayout.tsx","../src/components/admin/settings/WebhookSettings.tsx"],"sourcesContent":["/**\n * Shared layout for settings pages with autosave\n */\nimport { useEffect } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\nexport interface SettingsPageLayoutProps {\n /** Page title */\n title: string;\n /** Page description */\n description: string;\n /** Categories to display on this page */\n categories: string[];\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * Shared layout component for settings pages.\n * Handles loading and displaying settings for specified categories.\n * Changes are automatically saved after a brief debounce.\n */\nexport function SettingsPageLayout({\n title,\n description,\n categories,\n className = '',\n}: SettingsPageLayoutProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n } = useSettingsAutosave();\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Filter settings to only show relevant categories\n const relevantCategories = categories.filter((cat) => settings[cat]?.length > 0);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">{title}</h2>\n <p className=\"cedros-settings-page-description\">{description}</p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {relevantCategories.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for this section.</p>\n </div>\n ) : (\n relevantCategories.map((category) => (\n <SettingsSection\n key={category}\n settings={settings[category]}\n edits={edits}\n onChange={handleChange}\n />\n ))\n )}\n </div>\n );\n}\n","/**\n * Webhook settings page - HTTP webhook configuration\n */\nimport { SettingsPageLayout } from './SettingsPageLayout';\n\nconst CATEGORIES = ['webhook'];\n\nexport interface WebhookSettingsProps {\n className?: string;\n}\n\nexport function WebhookSettings({ className }: WebhookSettingsProps) {\n return (\n <SettingsPageLayout\n title=\"Webhooks\"\n description=\"Configure HTTP webhook notifications for authentication events.\"\n categories={CATEGORIES}\n className={className}\n />\n );\n}\n"],"names":["SettingsPageLayout","title","description","categories","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","useSettingsAutosave","useEffect","relevantCategories","cat","jsxs","jsx","LoadingSpinner","ErrorMessage","AutosaveStatus","category","SettingsSection","CATEGORIES","WebhookSettings"],"mappings":"oMA0BO,SAASA,EAAmB,CACjC,MAAAC,EACA,YAAAC,EACA,WAAAC,EACA,UAAAC,EAAY,EACd,EAA4B,CAC1B,KAAM,CACJ,SAAAC,EACA,MAAAC,EACA,UAAAC,EACA,eAAAC,EACA,cAAAC,EACA,MAAAC,EACA,cAAAC,EACA,aAAAC,CAAA,EACEC,sBAAA,EAEJC,EAAAA,UAAU,IAAM,CACdH,EAAA,CACF,EAAG,CAACA,CAAa,CAAC,EAGlB,MAAMI,EAAqBZ,EAAW,OAAQa,GAAQX,EAASW,CAAG,GAAG,OAAS,CAAC,EAE/E,OAAIT,GAAa,OAAO,KAAKF,CAAQ,EAAE,SAAW,EAE9CY,EAAAA,KAAC,MAAA,CAAI,UAAW,yDAAyDb,CAAS,GAChF,SAAA,CAAAc,EAAAA,IAACC,EAAAA,eAAA,EAAe,EAChBD,EAAAA,IAAC,QAAK,SAAA,qBAAA,CAAmB,CAAA,EAC3B,EAIAR,EAEAQ,EAAAA,IAAC,MAAA,CAAI,UAAW,0BAA0Bd,CAAS,GACjD,SAAAc,EAAAA,IAACE,EAAAA,aAAA,CAAa,MAAOV,EAAM,OAAA,CAAS,EACtC,EAKFO,EAAAA,KAAC,MAAA,CAAI,UAAW,0BAA0Bb,CAAS,GACjD,SAAA,CAAAa,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,6BAA8B,SAAAjB,EAAM,EAClDiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mCAAoC,SAAAhB,CAAA,CAAY,CAAA,EAC/D,EACAgB,EAAAA,IAACG,EAAAA,eAAA,CAAe,OAAQb,EAAgB,MAAOC,CAAA,CAAe,CAAA,EAChE,EAECM,EAAmB,SAAW,EAC7BG,EAAAA,IAAC,OAAI,UAAU,+BACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,+CAAmC,CAAA,CACxC,EAEAH,EAAmB,IAAKO,GACtBJ,EAAAA,IAACK,EAAAA,gBAAA,CAEC,SAAUlB,EAASiB,CAAQ,EAC3B,MAAAhB,EACA,SAAUM,CAAA,EAHLU,CAAA,CAKR,CAAA,EAEL,CAEJ,CCxFA,MAAME,EAAa,CAAC,SAAS,EAMtB,SAASC,EAAgB,CAAE,UAAArB,GAAmC,CACnE,OACEc,EAAAA,IAAClB,EAAA,CACC,MAAM,WACN,YAAY,kEACZ,WAAYwB,EACZ,UAAApB,CAAA,CAAA,CAGN"}
1
+ {"version":3,"file":"WebhookSettings-0sgWRI3U.cjs","sources":["../src/components/admin/settings/SettingsPageLayout.tsx","../src/components/admin/settings/WebhookSettings.tsx"],"sourcesContent":["/**\n * Shared layout for settings pages with autosave\n */\nimport { useEffect } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\nexport interface SettingsPageLayoutProps {\n /** Page title */\n title: string;\n /** Page description */\n description: string;\n /** Categories to display on this page */\n categories: string[];\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * Shared layout component for settings pages.\n * Handles loading and displaying settings for specified categories.\n * Changes are automatically saved after a brief debounce.\n */\nexport function SettingsPageLayout({\n title,\n description,\n categories,\n className = '',\n}: SettingsPageLayoutProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n } = useSettingsAutosave();\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Filter settings to only show relevant categories\n const relevantCategories = categories.filter((cat) => settings[cat]?.length > 0);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">{title}</h2>\n <p className=\"cedros-settings-page-description\">{description}</p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {relevantCategories.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for this section.</p>\n </div>\n ) : (\n relevantCategories.map((category) => (\n <SettingsSection\n key={category}\n settings={settings[category]}\n edits={edits}\n onChange={handleChange}\n />\n ))\n )}\n </div>\n );\n}\n","/**\n * Webhook settings page - HTTP webhook configuration\n */\nimport { SettingsPageLayout } from './SettingsPageLayout';\n\nconst CATEGORIES = ['webhook'];\n\nexport interface WebhookSettingsProps {\n className?: string;\n}\n\nexport function WebhookSettings({ className }: WebhookSettingsProps) {\n return (\n <SettingsPageLayout\n title=\"Webhooks\"\n description=\"Configure HTTP webhook notifications for authentication events.\"\n categories={CATEGORIES}\n className={className}\n />\n );\n}\n"],"names":["SettingsPageLayout","title","description","categories","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","useSettingsAutosave","useEffect","relevantCategories","cat","jsxs","jsx","LoadingSpinner","ErrorMessage","AutosaveStatus","category","SettingsSection","CATEGORIES","WebhookSettings"],"mappings":"oMA0BO,SAASA,EAAmB,CACjC,MAAAC,EACA,YAAAC,EACA,WAAAC,EACA,UAAAC,EAAY,EACd,EAA4B,CAC1B,KAAM,CACJ,SAAAC,EACA,MAAAC,EACA,UAAAC,EACA,eAAAC,EACA,cAAAC,EACA,MAAAC,EACA,cAAAC,EACA,aAAAC,CAAA,EACEC,sBAAA,EAEJC,EAAAA,UAAU,IAAM,CACdH,EAAA,CACF,EAAG,CAACA,CAAa,CAAC,EAGlB,MAAMI,EAAqBZ,EAAW,OAAQa,GAAQX,EAASW,CAAG,GAAG,OAAS,CAAC,EAE/E,OAAIT,GAAa,OAAO,KAAKF,CAAQ,EAAE,SAAW,EAE9CY,EAAAA,KAAC,MAAA,CAAI,UAAW,yDAAyDb,CAAS,GAChF,SAAA,CAAAc,EAAAA,IAACC,EAAAA,eAAA,EAAe,EAChBD,EAAAA,IAAC,QAAK,SAAA,qBAAA,CAAmB,CAAA,EAC3B,EAIAR,EAEAQ,EAAAA,IAAC,MAAA,CAAI,UAAW,0BAA0Bd,CAAS,GACjD,SAAAc,EAAAA,IAACE,EAAAA,aAAA,CAAa,MAAOV,EAAM,OAAA,CAAS,EACtC,EAKFO,EAAAA,KAAC,MAAA,CAAI,UAAW,0BAA0Bb,CAAS,GACjD,SAAA,CAAAa,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,6BAA8B,SAAAjB,EAAM,EAClDiB,EAAAA,IAAC,IAAA,CAAE,UAAU,mCAAoC,SAAAhB,CAAA,CAAY,CAAA,EAC/D,EACAgB,EAAAA,IAACG,EAAAA,eAAA,CAAe,OAAQb,EAAgB,MAAOC,CAAA,CAAe,CAAA,EAChE,EAECM,EAAmB,SAAW,EAC7BG,EAAAA,IAAC,OAAI,UAAU,+BACb,SAAAA,EAAAA,IAAC,IAAA,CAAE,+CAAmC,CAAA,CACxC,EAEAH,EAAmB,IAAKO,GACtBJ,EAAAA,IAACK,EAAAA,gBAAA,CAEC,SAAUlB,EAASiB,CAAQ,EAC3B,MAAAhB,EACA,SAAUM,CAAA,EAHLU,CAAA,CAKR,CAAA,EAEL,CAEJ,CCxFA,MAAME,EAAa,CAAC,SAAS,EAMtB,SAASC,EAAgB,CAAE,UAAArB,GAAmC,CACnE,OACEc,EAAAA,IAAClB,EAAA,CACC,MAAM,WACN,YAAY,kEACZ,WAAYwB,EACZ,UAAApB,CAAA,CAAA,CAGN"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as o } from "react/jsx-runtime";
2
2
  import "react";
3
- import { W as t } from "./WebhookSettings-ufiGTmbG.js";
3
+ import { W as t } from "./WebhookSettings-B8hAwhZ2.js";
4
4
  function i() {
5
5
  return /* @__PURE__ */ o("div", { className: "cedros-dashboard__section", children: /* @__PURE__ */ o(t, {}) });
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookSettings-Bgld6D_T.js","sources":["../src/admin/sections/WebhookSettings.tsx"],"sourcesContent":["/**\n * Webhook Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { WebhookSettings as Settings } from '../../components/admin/settings';\n\nexport default function WebhookSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["WebhookSettings","jsx","Settings"],"mappings":";;;AAOA,SAAwBA,IAAqC;AAC3D,2BACG,OAAA,EAAI,WAAU,6BACb,UAAA,gBAAAC,EAACC,KAAS,GACZ;AAEJ;"}
1
+ {"version":3,"file":"WebhookSettings-8QAqvkkO.js","sources":["../src/admin/sections/WebhookSettings.tsx"],"sourcesContent":["/**\n * Webhook Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { WebhookSettings as Settings } from '../../components/admin/settings';\n\nexport default function WebhookSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["WebhookSettings","jsx","Settings"],"mappings":";;;AAOA,SAAwBA,IAAqC;AAC3D,2BACG,OAAA,EAAI,WAAU,6BACb,UAAA,gBAAAC,EAACC,KAAS,GACZ;AAEJ;"}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime");require("react");const t=require("./WebhookSettings-DXjnq-c7.cjs");function o(){return e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx(t.WebhookSettings,{})})}exports.default=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime");require("react");const t=require("./WebhookSettings-0sgWRI3U.cjs");function o(){return e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx(t.WebhookSettings,{})})}exports.default=o;
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookSettings-DnLk97Mr.cjs","sources":["../src/admin/sections/WebhookSettings.tsx"],"sourcesContent":["/**\n * Webhook Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { WebhookSettings as Settings } from '../../components/admin/settings';\n\nexport default function WebhookSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["WebhookSettings","jsx","Settings"],"mappings":"wLAOA,SAAwBA,GAAqC,CAC3D,aACG,MAAA,CAAI,UAAU,4BACb,SAAAC,MAACC,EAAAA,kBAAS,EACZ,CAEJ"}
1
+ {"version":3,"file":"WebhookSettings-B6Y3Tnjv.cjs","sources":["../src/admin/sections/WebhookSettings.tsx"],"sourcesContent":["/**\n * Webhook Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { WebhookSettings as Settings } from '../../components/admin/settings';\n\nexport default function WebhookSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["WebhookSettings","jsx","Settings"],"mappings":"wLAOA,SAAwBA,GAAqC,CAC3D,aACG,MAAA,CAAI,UAAU,4BACb,SAAAC,MAACC,EAAAA,kBAAS,EACZ,CAEJ"}
@@ -2,7 +2,7 @@ import { jsxs as t, jsx as e } from "react/jsx-runtime";
2
2
  import { useEffect as p } from "react";
3
3
  import { L as v } from "./LoadingSpinner-6vml-zwr.js";
4
4
  import { E as S } from "./ErrorMessage-CcEK0pYO.js";
5
- import { u as y, A as N, S as E } from "./AutosaveStatus-f-jw25Ay.js";
5
+ import { u as y, A as N, S as E } from "./AutosaveStatus-CSZsp6w7.js";
6
6
  function b({
7
7
  title: i,
8
8
  description: d,
@@ -1 +1 @@
1
- {"version":3,"file":"WebhookSettings-ufiGTmbG.js","sources":["../src/components/admin/settings/SettingsPageLayout.tsx","../src/components/admin/settings/WebhookSettings.tsx"],"sourcesContent":["/**\n * Shared layout for settings pages with autosave\n */\nimport { useEffect } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\nexport interface SettingsPageLayoutProps {\n /** Page title */\n title: string;\n /** Page description */\n description: string;\n /** Categories to display on this page */\n categories: string[];\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * Shared layout component for settings pages.\n * Handles loading and displaying settings for specified categories.\n * Changes are automatically saved after a brief debounce.\n */\nexport function SettingsPageLayout({\n title,\n description,\n categories,\n className = '',\n}: SettingsPageLayoutProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n } = useSettingsAutosave();\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Filter settings to only show relevant categories\n const relevantCategories = categories.filter((cat) => settings[cat]?.length > 0);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">{title}</h2>\n <p className=\"cedros-settings-page-description\">{description}</p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {relevantCategories.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for this section.</p>\n </div>\n ) : (\n relevantCategories.map((category) => (\n <SettingsSection\n key={category}\n settings={settings[category]}\n edits={edits}\n onChange={handleChange}\n />\n ))\n )}\n </div>\n );\n}\n","/**\n * Webhook settings page - HTTP webhook configuration\n */\nimport { SettingsPageLayout } from './SettingsPageLayout';\n\nconst CATEGORIES = ['webhook'];\n\nexport interface WebhookSettingsProps {\n className?: string;\n}\n\nexport function WebhookSettings({ className }: WebhookSettingsProps) {\n return (\n <SettingsPageLayout\n title=\"Webhooks\"\n description=\"Configure HTTP webhook notifications for authentication events.\"\n categories={CATEGORIES}\n className={className}\n />\n );\n}\n"],"names":["SettingsPageLayout","title","description","categories","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","useSettingsAutosave","useEffect","relevantCategories","cat","jsxs","jsx","LoadingSpinner","ErrorMessage","AutosaveStatus","category","SettingsSection","CATEGORIES","WebhookSettings"],"mappings":";;;;;AA0BO,SAASA,EAAmB;AAAA,EACjC,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAA4B;AAC1B,QAAM;AAAA,IACJ,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,eAAAC;AAAA,IACA,OAAAC;AAAA,IACA,eAAAC;AAAA,IACA,cAAAC;AAAA,EAAA,IACEC,EAAA;AAEJ,EAAAC,EAAU,MAAM;AACd,IAAAH,EAAA;AAAA,EACF,GAAG,CAACA,CAAa,CAAC;AAGlB,QAAMI,IAAqBZ,EAAW,OAAO,CAACa,MAAQX,EAASW,CAAG,GAAG,SAAS,CAAC;AAE/E,SAAIT,KAAa,OAAO,KAAKF,CAAQ,EAAE,WAAW,IAE9C,gBAAAY,EAAC,OAAA,EAAI,WAAW,yDAAyDb,CAAS,IAChF,UAAA;AAAA,IAAA,gBAAAc,EAACC,GAAA,EAAe;AAAA,IAChB,gBAAAD,EAAC,UAAK,UAAA,sBAAA,CAAmB;AAAA,EAAA,GAC3B,IAIAR,IAEA,gBAAAQ,EAAC,OAAA,EAAI,WAAW,0BAA0Bd,CAAS,IACjD,UAAA,gBAAAc,EAACE,GAAA,EAAa,OAAOV,EAAM,QAAA,CAAS,GACtC,IAKF,gBAAAO,EAAC,OAAA,EAAI,WAAW,0BAA0Bb,CAAS,IACjD,UAAA;AAAA,IAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,8BAA8B,UAAAjB,GAAM;AAAA,QAClD,gBAAAiB,EAAC,KAAA,EAAE,WAAU,oCAAoC,UAAAhB,EAAA,CAAY;AAAA,MAAA,GAC/D;AAAA,MACA,gBAAAgB,EAACG,GAAA,EAAe,QAAQb,GAAgB,OAAOC,EAAA,CAAe;AAAA,IAAA,GAChE;AAAA,IAECM,EAAmB,WAAW,IAC7B,gBAAAG,EAAC,SAAI,WAAU,gCACb,UAAA,gBAAAA,EAAC,KAAA,EAAE,iDAAmC,EAAA,CACxC,IAEAH,EAAmB,IAAI,CAACO,MACtB,gBAAAJ;AAAA,MAACK;AAAA,MAAA;AAAA,QAEC,UAAUlB,EAASiB,CAAQ;AAAA,QAC3B,OAAAhB;AAAA,QACA,UAAUM;AAAA,MAAA;AAAA,MAHLU;AAAA,IAAA,CAKR;AAAA,EAAA,GAEL;AAEJ;ACxFA,MAAME,IAAa,CAAC,SAAS;AAMtB,SAASC,EAAgB,EAAE,WAAArB,KAAmC;AACnE,SACE,gBAAAc;AAAA,IAAClB;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,aAAY;AAAA,MACZ,YAAYwB;AAAA,MACZ,WAAApB;AAAA,IAAA;AAAA,EAAA;AAGN;"}
1
+ {"version":3,"file":"WebhookSettings-B8hAwhZ2.js","sources":["../src/components/admin/settings/SettingsPageLayout.tsx","../src/components/admin/settings/WebhookSettings.tsx"],"sourcesContent":["/**\n * Shared layout for settings pages with autosave\n */\nimport { useEffect } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\nexport interface SettingsPageLayoutProps {\n /** Page title */\n title: string;\n /** Page description */\n description: string;\n /** Categories to display on this page */\n categories: string[];\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * Shared layout component for settings pages.\n * Handles loading and displaying settings for specified categories.\n * Changes are automatically saved after a brief debounce.\n */\nexport function SettingsPageLayout({\n title,\n description,\n categories,\n className = '',\n}: SettingsPageLayoutProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n } = useSettingsAutosave();\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Filter settings to only show relevant categories\n const relevantCategories = categories.filter((cat) => settings[cat]?.length > 0);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">{title}</h2>\n <p className=\"cedros-settings-page-description\">{description}</p>\n </div>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n\n {relevantCategories.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for this section.</p>\n </div>\n ) : (\n relevantCategories.map((category) => (\n <SettingsSection\n key={category}\n settings={settings[category]}\n edits={edits}\n onChange={handleChange}\n />\n ))\n )}\n </div>\n );\n}\n","/**\n * Webhook settings page - HTTP webhook configuration\n */\nimport { SettingsPageLayout } from './SettingsPageLayout';\n\nconst CATEGORIES = ['webhook'];\n\nexport interface WebhookSettingsProps {\n className?: string;\n}\n\nexport function WebhookSettings({ className }: WebhookSettingsProps) {\n return (\n <SettingsPageLayout\n title=\"Webhooks\"\n description=\"Configure HTTP webhook notifications for authentication events.\"\n categories={CATEGORIES}\n className={className}\n />\n );\n}\n"],"names":["SettingsPageLayout","title","description","categories","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","useSettingsAutosave","useEffect","relevantCategories","cat","jsxs","jsx","LoadingSpinner","ErrorMessage","AutosaveStatus","category","SettingsSection","CATEGORIES","WebhookSettings"],"mappings":";;;;;AA0BO,SAASA,EAAmB;AAAA,EACjC,OAAAC;AAAA,EACA,aAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC,IAAY;AACd,GAA4B;AAC1B,QAAM;AAAA,IACJ,UAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,eAAAC;AAAA,IACA,OAAAC;AAAA,IACA,eAAAC;AAAA,IACA,cAAAC;AAAA,EAAA,IACEC,EAAA;AAEJ,EAAAC,EAAU,MAAM;AACd,IAAAH,EAAA;AAAA,EACF,GAAG,CAACA,CAAa,CAAC;AAGlB,QAAMI,IAAqBZ,EAAW,OAAO,CAACa,MAAQX,EAASW,CAAG,GAAG,SAAS,CAAC;AAE/E,SAAIT,KAAa,OAAO,KAAKF,CAAQ,EAAE,WAAW,IAE9C,gBAAAY,EAAC,OAAA,EAAI,WAAW,yDAAyDb,CAAS,IAChF,UAAA;AAAA,IAAA,gBAAAc,EAACC,GAAA,EAAe;AAAA,IAChB,gBAAAD,EAAC,UAAK,UAAA,sBAAA,CAAmB;AAAA,EAAA,GAC3B,IAIAR,IAEA,gBAAAQ,EAAC,OAAA,EAAI,WAAW,0BAA0Bd,CAAS,IACjD,UAAA,gBAAAc,EAACE,GAAA,EAAa,OAAOV,EAAM,QAAA,CAAS,GACtC,IAKF,gBAAAO,EAAC,OAAA,EAAI,WAAW,0BAA0Bb,CAAS,IACjD,UAAA;AAAA,IAAA,gBAAAa,EAAC,OAAA,EAAI,WAAU,+BACb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,uCACb,UAAA;AAAA,QAAA,gBAAAC,EAAC,MAAA,EAAG,WAAU,8BAA8B,UAAAjB,GAAM;AAAA,QAClD,gBAAAiB,EAAC,KAAA,EAAE,WAAU,oCAAoC,UAAAhB,EAAA,CAAY;AAAA,MAAA,GAC/D;AAAA,MACA,gBAAAgB,EAACG,GAAA,EAAe,QAAQb,GAAgB,OAAOC,EAAA,CAAe;AAAA,IAAA,GAChE;AAAA,IAECM,EAAmB,WAAW,IAC7B,gBAAAG,EAAC,SAAI,WAAU,gCACb,UAAA,gBAAAA,EAAC,KAAA,EAAE,iDAAmC,EAAA,CACxC,IAEAH,EAAmB,IAAI,CAACO,MACtB,gBAAAJ;AAAA,MAACK;AAAA,MAAA;AAAA,QAEC,UAAUlB,EAASiB,CAAQ;AAAA,QAC3B,OAAAhB;AAAA,QACA,UAAUM;AAAA,MAAA;AAAA,MAHLU;AAAA,IAAA,CAKR;AAAA,EAAA,GAEL;AAEJ;ACxFA,MAAME,IAAa,CAAC,SAAS;AAMtB,SAASC,EAAgB,EAAE,WAAArB,KAAmC;AACnE,SACE,gBAAAc;AAAA,IAAClB;AAAA,IAAA;AAAA,MACC,OAAM;AAAA,MACN,aAAY;AAAA,MACZ,YAAYwB;AAAA,MACZ,WAAApB;AAAA,IAAA;AAAA,EAAA;AAGN;"}
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./plugin-Xca67fp7.cjs");exports.AdminShell=e.AdminShell;exports.CEDROS_LOGIN_SECTION_IDS=e.CEDROS_LOGIN_SECTION_IDS;exports.Icons=e.Icons;exports.cedrosLoginPlugin=e.cedrosLoginPlugin;exports.loginPlugin=e.cedrosLoginPlugin;exports.useAdminShell=e.useAdminShell;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./plugin-CUxpAjL-.cjs");exports.AdminShell=e.AdminShell;exports.CEDROS_LOGIN_SECTION_IDS=e.CEDROS_LOGIN_SECTION_IDS;exports.Icons=e.Icons;exports.cedrosLoginPlugin=e.cedrosLoginPlugin;exports.loginPlugin=e.cedrosLoginPlugin;exports.useAdminShell=e.useAdminShell;
@@ -1,4 +1,4 @@
1
- import { A as n, C as a, I as i, c as o, c as e, u as I } from "./plugin-BbExid4E.js";
1
+ import { A as n, C as a, I as i, c as o, c as e, u as I } from "./plugin-C_NDZ2-D.js";
2
2
  export {
3
3
  n as AdminShell,
4
4
  a as CEDROS_LOGIN_SECTION_IDS,
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./useAuth-XZaciuLg.cjs"),o=require("./useCedrosLogin-DtJorrE7.cjs"),e=require("./EmailRegisterForm-B_TiJkD6.cjs"),i=require("./LoadingSpinner-d6sSxgQN.cjs"),s=require("./ErrorMessage-CHbYbVi2.cjs"),n=require("./validation-BuGQrA-K.cjs");exports.CedrosLoginProvider=r.CedrosLoginProvider;exports.useAuth=r.useAuth;exports.useCedrosLogin=o.useCedrosLogin;exports.EmailLoginForm=e.EmailLoginForm;exports.EmailRegisterForm=e.EmailRegisterForm;exports.PasswordInput=e.PasswordInput;exports.useEmailAuth=e.useEmailAuth;exports.LoadingSpinner=i.LoadingSpinner;exports.ErrorMessage=s.ErrorMessage;exports.validatePassword=n.validatePassword;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("./useAuth-U5CYsHEU.cjs"),o=require("./useCedrosLogin-DtJorrE7.cjs"),e=require("./EmailRegisterForm-CNjYrqU6.cjs"),i=require("./LoadingSpinner-d6sSxgQN.cjs"),s=require("./ErrorMessage-CHbYbVi2.cjs"),n=require("./validation-BuGQrA-K.cjs");exports.CedrosLoginProvider=r.CedrosLoginProvider;exports.useAuth=r.useAuth;exports.useCedrosLogin=o.useCedrosLogin;exports.EmailLoginForm=e.EmailLoginForm;exports.EmailRegisterForm=e.EmailRegisterForm;exports.PasswordInput=e.PasswordInput;exports.useEmailAuth=e.useEmailAuth;exports.LoadingSpinner=i.LoadingSpinner;exports.ErrorMessage=s.ErrorMessage;exports.validatePassword=n.validatePassword;
@@ -92,6 +92,7 @@ export declare interface AuthUser {
92
92
  id: string;
93
93
  email?: string;
94
94
  name?: string;
95
+ username?: string;
95
96
  picture?: string;
96
97
  walletAddress?: string;
97
98
  authMethods: AuthMethod[];
@@ -414,8 +415,8 @@ export declare interface PasswordValidation {
414
415
  * Post-login action returned by the server after authentication
415
416
  */
416
417
  declare interface PostLoginAction {
417
- /** Action type: "welcome", "complete_profile", "redirect", or "setup_mfa" */
418
- action: 'welcome' | 'complete_profile' | 'redirect' | 'setup_mfa';
418
+ /** Action type: "setup_mfa", "enroll_wallet", "acknowledge_recovery", "choose_username", "welcome", "complete_profile", or "redirect" */
419
+ action: 'setup_mfa' | 'enroll_wallet' | 'acknowledge_recovery' | 'choose_username' | 'welcome' | 'complete_profile' | 'redirect';
419
420
  /** URL/route for redirect or welcome page */
420
421
  redirectUrl?: string;
421
422
  }
@@ -1,6 +1,6 @@
1
- import { C as s, u as a } from "./useAuth-CVLv2oKA.js";
1
+ import { C as s, u as a } from "./useAuth-C-Vw-ggy.js";
2
2
  import { u as i } from "./useCedrosLogin-CFfID-0i.js";
3
- import { E as t, a as u, P as p, u as d } from "./EmailRegisterForm-CCEuQA-w.js";
3
+ import { E as t, a as u, P as p, u as d } from "./EmailRegisterForm-D2VaJouj.js";
4
4
  import { L as f } from "./LoadingSpinner-6vml-zwr.js";
5
5
  import { E as x } from "./ErrorMessage-CcEK0pYO.js";
6
6
  import { v as L } from "./validation-B8kMV3BL.js";
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAuth-XZaciuLg.cjs"),r=require("./useCedrosLogin-DtJorrE7.cjs"),o=require("./GoogleLoginButton-BDCbxoCB.cjs"),n=require("./LoadingSpinner-d6sSxgQN.cjs"),s=require("./ErrorMessage-CHbYbVi2.cjs");exports.CedrosLoginProvider=e.CedrosLoginProvider;exports.useAuth=e.useAuth;exports.useCedrosLogin=r.useCedrosLogin;exports.GoogleLoginButton=o.GoogleLoginButton;exports.useGoogleAuth=o.useGoogleAuth;exports.LoadingSpinner=n.LoadingSpinner;exports.ErrorMessage=s.ErrorMessage;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useAuth-U5CYsHEU.cjs"),r=require("./useCedrosLogin-DtJorrE7.cjs"),o=require("./GoogleLoginButton-JtRViYWS.cjs"),n=require("./LoadingSpinner-d6sSxgQN.cjs"),s=require("./ErrorMessage-CHbYbVi2.cjs");exports.CedrosLoginProvider=e.CedrosLoginProvider;exports.useAuth=e.useAuth;exports.useCedrosLogin=r.useCedrosLogin;exports.GoogleLoginButton=o.GoogleLoginButton;exports.useGoogleAuth=o.useGoogleAuth;exports.LoadingSpinner=n.LoadingSpinner;exports.ErrorMessage=s.ErrorMessage;
@@ -91,6 +91,7 @@ export declare interface AuthUser {
91
91
  id: string;
92
92
  email?: string;
93
93
  name?: string;
94
+ username?: string;
94
95
  picture?: string;
95
96
  walletAddress?: string;
96
97
  authMethods: AuthMethod[];
@@ -357,8 +358,8 @@ declare interface LoadingSpinnerProps {
357
358
  * Post-login action returned by the server after authentication
358
359
  */
359
360
  declare interface PostLoginAction {
360
- /** Action type: "welcome", "complete_profile", "redirect", or "setup_mfa" */
361
- action: 'welcome' | 'complete_profile' | 'redirect' | 'setup_mfa';
361
+ /** Action type: "setup_mfa", "enroll_wallet", "acknowledge_recovery", "choose_username", "welcome", "complete_profile", or "redirect" */
362
+ action: 'setup_mfa' | 'enroll_wallet' | 'acknowledge_recovery' | 'choose_username' | 'welcome' | 'complete_profile' | 'redirect';
362
363
  /** URL/route for redirect or welcome page */
363
364
  redirectUrl?: string;
364
365
  }
@@ -562,8 +563,8 @@ declare interface UseGoogleAuthReturn {
562
563
  isInitialized: boolean;
563
564
  error: AuthError | null;
564
565
  clearError: () => void;
565
- /** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */
566
- pendingLinkIdToken: string | null;
566
+ /** Access token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */
567
+ pendingLinkToken: string | null;
567
568
  /** Clear the pending link state */
568
569
  clearPendingLink: () => void;
569
570
  }
@@ -1,6 +1,6 @@
1
- import { C as e, u as s } from "./useAuth-CVLv2oKA.js";
1
+ import { C as e, u as s } from "./useAuth-C-Vw-ggy.js";
2
2
  import { u as t } from "./useCedrosLogin-CFfID-0i.js";
3
- import { G as g, u as n } from "./GoogleLoginButton-6ip-vudk.js";
3
+ import { G as g, u as n } from "./GoogleLoginButton-qf4A_A3G.js";
4
4
  import { L as p } from "./LoadingSpinner-6vml-zwr.js";
5
5
  import { E as m } from "./ErrorMessage-CcEK0pYO.js";
6
6
  export {