@cedros/login-react 0.0.45 → 0.0.47
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.
- package/README.md +32 -2
- package/dist/{AuthenticationSettings-bNQiNQ9g.cjs → AuthenticationSettings-BBOjHR6j.cjs} +1 -1
- package/dist/{AuthenticationSettings-bNQiNQ9g.cjs.map → AuthenticationSettings-BBOjHR6j.cjs.map} +1 -1
- package/dist/{AuthenticationSettings-BlYOmaEG.cjs → AuthenticationSettings-BXZRBZqc.cjs} +1 -1
- package/dist/{AuthenticationSettings-BlYOmaEG.cjs.map → AuthenticationSettings-BXZRBZqc.cjs.map} +1 -1
- package/dist/{AuthenticationSettings-BsuwWKbT.js → AuthenticationSettings-Bc_qT4nV.js} +1 -1
- package/dist/{AuthenticationSettings-BsuwWKbT.js.map → AuthenticationSettings-Bc_qT4nV.js.map} +1 -1
- package/dist/{AuthenticationSettings-DrHqtD7p.js → AuthenticationSettings-DXWCVZxS.js} +1 -1
- package/dist/{AuthenticationSettings-DrHqtD7p.js.map → AuthenticationSettings-DXWCVZxS.js.map} +1 -1
- package/dist/{AutosaveStatus-CZSwtgrL.cjs → AutosaveStatus-DfMPudTQ.cjs} +1 -1
- package/dist/AutosaveStatus-DfMPudTQ.cjs.map +1 -0
- package/dist/{AutosaveStatus-D-roPsRx.js → AutosaveStatus-DhGM3UUx.js} +103 -36
- package/dist/AutosaveStatus-DhGM3UUx.js.map +1 -0
- package/dist/{CreditSystemSettings-BTqZFn4K.js → CreditSystemSettings-B59-gOQT.js} +1 -1
- package/dist/{CreditSystemSettings-BTqZFn4K.js.map → CreditSystemSettings-B59-gOQT.js.map} +1 -1
- package/dist/{CreditSystemSettings-3R6crxvW.cjs → CreditSystemSettings-Badz4iAc.cjs} +1 -1
- package/dist/{CreditSystemSettings-3R6crxvW.cjs.map → CreditSystemSettings-Badz4iAc.cjs.map} +1 -1
- package/dist/{CreditSystemSettings-BskW_NKx.cjs → CreditSystemSettings-BxSoDwEi.cjs} +1 -1
- package/dist/{CreditSystemSettings-BskW_NKx.cjs.map → CreditSystemSettings-BxSoDwEi.cjs.map} +1 -1
- package/dist/{CreditSystemSettings-SL45GRH3.js → CreditSystemSettings-DxFpOeBW.js} +1 -1
- package/dist/{CreditSystemSettings-SL45GRH3.js.map → CreditSystemSettings-DxFpOeBW.js.map} +1 -1
- package/dist/EmailRegisterForm-ByYQ43yL.cjs +1 -0
- package/dist/EmailRegisterForm-ByYQ43yL.cjs.map +1 -0
- package/dist/EmailRegisterForm-DMUcNQT-.js +781 -0
- package/dist/EmailRegisterForm-DMUcNQT-.js.map +1 -0
- package/dist/{EmailSettings-XETM8FdS.js → EmailSettings-0y8D1QzF.js} +1 -1
- package/dist/{EmailSettings-XETM8FdS.js.map → EmailSettings-0y8D1QzF.js.map} +1 -1
- package/dist/{EmailSettings-BUAQji4I.js → EmailSettings-BA722mhf.js} +1 -1
- package/dist/{EmailSettings-BUAQji4I.js.map → EmailSettings-BA722mhf.js.map} +1 -1
- package/dist/{EmailSettings-CihElRkc.cjs → EmailSettings-BwZvdOYB.cjs} +1 -1
- package/dist/{EmailSettings-CihElRkc.cjs.map → EmailSettings-BwZvdOYB.cjs.map} +1 -1
- package/dist/{EmailSettings-CEC1rhrm.cjs → EmailSettings-DIjo3aJo.cjs} +1 -1
- package/dist/{EmailSettings-CEC1rhrm.cjs.map → EmailSettings-DIjo3aJo.cjs.map} +1 -1
- package/dist/{EmbeddedWalletSettings-CCT9DwmL.js → EmbeddedWalletSettings-BDbPpqWD.js} +1 -1
- package/dist/{EmbeddedWalletSettings-CCT9DwmL.js.map → EmbeddedWalletSettings-BDbPpqWD.js.map} +1 -1
- package/dist/{EmbeddedWalletSettings-MtwR81WH.cjs → EmbeddedWalletSettings-Db9a0D5l.cjs} +1 -1
- package/dist/{EmbeddedWalletSettings-MtwR81WH.cjs.map → EmbeddedWalletSettings-Db9a0D5l.cjs.map} +1 -1
- package/dist/{EmbeddedWalletSettings-B-083zu6.js → EmbeddedWalletSettings-MH4A6e6S.js} +1 -1
- package/dist/{EmbeddedWalletSettings-B-083zu6.js.map → EmbeddedWalletSettings-MH4A6e6S.js.map} +1 -1
- package/dist/{EmbeddedWalletSettings-DXIjansC.cjs → EmbeddedWalletSettings-T7LwbGok.cjs} +1 -1
- package/dist/{EmbeddedWalletSettings-DXIjansC.cjs.map → EmbeddedWalletSettings-T7LwbGok.cjs.map} +1 -1
- package/dist/GoogleLoginButton-DEwtBp56.cjs +1 -0
- package/dist/GoogleLoginButton-DEwtBp56.cjs.map +1 -0
- package/dist/{GoogleLoginButton-C1WNu7W3.js → GoogleLoginButton-DwyxvhnL.js} +82 -80
- package/dist/GoogleLoginButton-DwyxvhnL.js.map +1 -0
- package/dist/{PermissionsSection-mm9hfp-u.js → PermissionsSection-0oNHPZzL.js} +383 -415
- package/dist/PermissionsSection-0oNHPZzL.js.map +1 -0
- package/dist/PermissionsSection-CZsJuxo4.cjs +1 -0
- package/dist/PermissionsSection-CZsJuxo4.cjs.map +1 -0
- package/dist/{ServerSettings-DBpbRihl.js → ServerSettings-CwCkkU50.js} +1 -1
- package/dist/{ServerSettings-DBpbRihl.js.map → ServerSettings-CwCkkU50.js.map} +1 -1
- package/dist/{ServerSettings-24DA_BOI.js → ServerSettings-DKzWaqjC.js} +1 -1
- package/dist/{ServerSettings-24DA_BOI.js.map → ServerSettings-DKzWaqjC.js.map} +1 -1
- package/dist/{ServerSettings-BTEuzdrf.cjs → ServerSettings-DptlzQAu.cjs} +1 -1
- package/dist/{ServerSettings-BTEuzdrf.cjs.map → ServerSettings-DptlzQAu.cjs.map} +1 -1
- package/dist/{ServerSettings-BNc4LEs4.cjs → ServerSettings-j5Lu5D-R.cjs} +1 -1
- package/dist/{ServerSettings-BNc4LEs4.cjs.map → ServerSettings-j5Lu5D-R.cjs.map} +1 -1
- package/dist/SolanaLoginButton-2504p6cr.cjs +1 -0
- package/dist/SolanaLoginButton-2504p6cr.cjs.map +1 -0
- package/dist/SolanaLoginButton-C7Kc_m6n.js +234 -0
- package/dist/SolanaLoginButton-C7Kc_m6n.js.map +1 -0
- package/dist/{TeamSection-Km7EwLWD.cjs → TeamSection-DN8PEHH3.cjs} +1 -1
- package/dist/{TeamSection-Km7EwLWD.cjs.map → TeamSection-DN8PEHH3.cjs.map} +1 -1
- package/dist/{TeamSection-C_eODdLU.js → TeamSection-gUyP4YDM.js} +1 -1
- package/dist/{TeamSection-C_eODdLU.js.map → TeamSection-gUyP4YDM.js.map} +1 -1
- package/dist/{UsersSection-C1Tt0ePx.cjs → UsersSection-8wLuD0fr.cjs} +1 -1
- package/dist/{UsersSection-C1Tt0ePx.cjs.map → UsersSection-8wLuD0fr.cjs.map} +1 -1
- package/dist/{UsersSection-Ct_E-MBF.js → UsersSection-CnsFrG-6.js} +1 -1
- package/dist/{UsersSection-Ct_E-MBF.js.map → UsersSection-CnsFrG-6.js.map} +1 -1
- package/dist/{WebhookSettings-D9IsXZJN.js → WebhookSettings-2hlLLyGd.js} +1 -1
- package/dist/{WebhookSettings-D9IsXZJN.js.map → WebhookSettings-2hlLLyGd.js.map} +1 -1
- package/dist/{WebhookSettings-C6X_JJcD.cjs → WebhookSettings-CoEoVRRO.cjs} +1 -1
- package/dist/{WebhookSettings-C6X_JJcD.cjs.map → WebhookSettings-CoEoVRRO.cjs.map} +1 -1
- package/dist/{WebhookSettings-H1x6IKOj.cjs → WebhookSettings-DOaydSWQ.cjs} +1 -1
- package/dist/{WebhookSettings-H1x6IKOj.cjs.map → WebhookSettings-DOaydSWQ.cjs.map} +1 -1
- package/dist/{WebhookSettings-BhIwucKb.js → WebhookSettings-LS_wUimF.js} +1 -1
- package/dist/{WebhookSettings-BhIwucKb.js.map → WebhookSettings-LS_wUimF.js.map} +1 -1
- package/dist/admin-only.cjs +1 -1
- package/dist/admin-only.js +1 -1
- package/dist/email-only.cjs +1 -1
- package/dist/email-only.d.ts +10 -2
- package/dist/email-only.js +2 -2
- package/dist/google-only.cjs +1 -1
- package/dist/google-only.d.ts +7 -2
- package/dist/google-only.js +2 -2
- package/dist/index.cjs +12 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +182 -11
- package/dist/index.js +5221 -4657
- package/dist/index.js.map +1 -1
- package/dist/login-react.css +1 -1
- package/dist/{plugin-BwwJh2cY.cjs → plugin-DNFjEfYp.cjs} +1 -1
- package/dist/{plugin-BwwJh2cY.cjs.map → plugin-DNFjEfYp.cjs.map} +1 -1
- package/dist/{plugin-CetHtdLq.js → plugin-WYMrRNbz.js} +1 -1
- package/dist/{plugin-CetHtdLq.js.map → plugin-WYMrRNbz.js.map} +1 -1
- package/dist/solana-only.cjs +1 -1
- package/dist/solana-only.d.ts +6 -1
- package/dist/solana-only.js +2 -2
- package/dist/useAuth-2vgrAH-M.cjs +1 -0
- package/dist/useAuth-2vgrAH-M.cjs.map +1 -0
- package/dist/{useAuth-l-itM5am.js → useAuth-CNflw856.js} +465 -469
- package/dist/useAuth-CNflw856.js.map +1 -0
- package/dist/useServerFeatures-9_aNPaa6.cjs +1 -0
- package/dist/useServerFeatures-9_aNPaa6.cjs.map +1 -0
- package/dist/useServerFeatures-DSkYdan-.js +82 -0
- package/dist/useServerFeatures-DSkYdan-.js.map +1 -0
- package/dist/{useUsersStatsSummary-BGeh3RnI.js → useUsersStatsSummary-B4_RBEYy.js} +504 -442
- package/dist/useUsersStatsSummary-B4_RBEYy.js.map +1 -0
- package/dist/useUsersStatsSummary-CHRMrlk4.cjs +1 -0
- package/dist/useUsersStatsSummary-CHRMrlk4.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/AutosaveStatus-CZSwtgrL.cjs.map +0 -1
- package/dist/AutosaveStatus-D-roPsRx.js.map +0 -1
- package/dist/EmailRegisterForm-p2X5QP58.js +0 -750
- package/dist/EmailRegisterForm-p2X5QP58.js.map +0 -1
- package/dist/EmailRegisterForm-xFb6MaVA.cjs +0 -1
- package/dist/EmailRegisterForm-xFb6MaVA.cjs.map +0 -1
- package/dist/GoogleLoginButton-2zNTIKMm.cjs +0 -1
- package/dist/GoogleLoginButton-2zNTIKMm.cjs.map +0 -1
- package/dist/GoogleLoginButton-C1WNu7W3.js.map +0 -1
- package/dist/PermissionsSection-4zcE9Zs9.cjs +0 -1
- package/dist/PermissionsSection-4zcE9Zs9.cjs.map +0 -1
- package/dist/PermissionsSection-mm9hfp-u.js.map +0 -1
- package/dist/SolanaLoginButton-CqdzSSeJ.cjs +0 -1
- package/dist/SolanaLoginButton-CqdzSSeJ.cjs.map +0 -1
- package/dist/SolanaLoginButton-CyeX35eU.js +0 -232
- package/dist/SolanaLoginButton-CyeX35eU.js.map +0 -1
- package/dist/sanitization-Bo_tn-L2.cjs +0 -1
- package/dist/sanitization-Bo_tn-L2.cjs.map +0 -1
- package/dist/sanitization-CQ-H1MSg.js +0 -39
- package/dist/sanitization-CQ-H1MSg.js.map +0 -1
- package/dist/useAuth-B1yS_YiD.cjs +0 -1
- package/dist/useAuth-B1yS_YiD.cjs.map +0 -1
- package/dist/useAuth-l-itM5am.js.map +0 -1
- package/dist/useUsersStatsSummary-BGeh3RnI.js.map +0 -1
- package/dist/useUsersStatsSummary-DnsYtFGX.cjs +0 -1
- package/dist/useUsersStatsSummary-DnsYtFGX.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -204,7 +204,8 @@ function AuthStatus() {
|
|
|
204
204
|
|
|
205
205
|
| Component | Description |
|
|
206
206
|
|-----------|-------------|
|
|
207
|
-
| `CedrosAdminDashboard` | Complete standalone admin panel with sidebar navigation and all sections |
|
|
207
|
+
| `CedrosAdminDashboard` | Complete standalone admin panel with sidebar navigation and all sections. **Auto-detects first run and shows SetupWizard.** |
|
|
208
|
+
| `SetupWizard` | First-run setup wizard — creates the first admin account (email, password, name, org). Shown automatically by `CedrosAdminDashboard` when no admin exists. |
|
|
208
209
|
| `AdminShell` | Plugin host for combining multiple admin dashboards (cedros-login + cedros-pay) |
|
|
209
210
|
| `AdminPanel` | Legacy admin dashboard with tabs for members, invites, sessions, system settings |
|
|
210
211
|
| `SystemSettings` | System settings editor (privacy, withdrawal, rate limits) - system admin only |
|
|
@@ -1367,7 +1368,9 @@ function AdminStatsWidget() {
|
|
|
1367
1368
|
|
|
1368
1369
|
### Admin Dashboard
|
|
1369
1370
|
|
|
1370
|
-
The `CedrosAdminDashboard` is a complete, ready-to-use admin panel with sidebar navigation
|
|
1371
|
+
The `CedrosAdminDashboard` is a complete, ready-to-use admin panel with sidebar navigation.
|
|
1372
|
+
|
|
1373
|
+
**First-run setup is automatic** — when no admin user exists, the dashboard shows a WordPress-style setup wizard instead of the normal admin interface. The wizard prompts for email, password, name, and organization name to create the first admin account. Once created, it reloads into the full dashboard. No env vars or SQL needed.
|
|
1371
1374
|
|
|
1372
1375
|
```tsx
|
|
1373
1376
|
import { CedrosAdminDashboard } from '@cedros/login-react';
|
|
@@ -1385,16 +1388,43 @@ function AdminPage() {
|
|
|
1385
1388
|
}
|
|
1386
1389
|
```
|
|
1387
1390
|
|
|
1391
|
+
If you need custom setup flow control, use the `SetupWizard` component directly:
|
|
1392
|
+
|
|
1393
|
+
```tsx
|
|
1394
|
+
import { SetupWizard, useSetup, CedrosAdminDashboard } from '@cedros/login-react';
|
|
1395
|
+
|
|
1396
|
+
function AdminApp() {
|
|
1397
|
+
const { status, isLoading, checkStatus } = useSetup();
|
|
1398
|
+
|
|
1399
|
+
useEffect(() => { checkStatus(); }, [checkStatus]);
|
|
1400
|
+
|
|
1401
|
+
if (isLoading) return <div>Loading...</div>;
|
|
1402
|
+
if (status?.needsSetup) {
|
|
1403
|
+
return <SetupWizard onComplete={() => window.location.reload()} />;
|
|
1404
|
+
}
|
|
1405
|
+
return <CedrosAdminDashboard />;
|
|
1406
|
+
}
|
|
1407
|
+
```
|
|
1408
|
+
|
|
1388
1409
|
**Available sections:**
|
|
1389
1410
|
- `users` - User management with stats (system admin only)
|
|
1390
1411
|
- `team` - Organization members and pending invites
|
|
1412
|
+
- `referrals` - Referral analytics and payout management
|
|
1391
1413
|
- `deposits` - Browse all deposits with status filtering
|
|
1392
1414
|
- `withdrawals` - Process company withdrawal queue
|
|
1415
|
+
- `compliance` - Token gate rule management
|
|
1416
|
+
- `accreditation-queue` - Review accredited investor submissions
|
|
1417
|
+
- `sanctions` - Sanctions screening stats and refresh
|
|
1418
|
+
- `signup-gating` - Access code management and signup stats
|
|
1393
1419
|
- `settings-auth` - Authentication settings (OAuth, passkeys, etc.)
|
|
1394
1420
|
- `settings-messaging` - Email/SMTP and webhook configuration
|
|
1395
1421
|
- `settings-wallet` - User wallet settings
|
|
1396
1422
|
- `settings-credits` - Credit system and treasury configuration
|
|
1423
|
+
- `settings-compliance` - KYC, accreditation, sanctions, token gating settings
|
|
1424
|
+
- `settings-referrals` - Referral reward configuration
|
|
1425
|
+
- `settings-signup` - Signup volume limits and access code settings
|
|
1397
1426
|
- `settings-server` - Auth server settings
|
|
1427
|
+
- `settings-images` - Image storage (S3) settings
|
|
1398
1428
|
|
|
1399
1429
|
### Unified Admin Dashboard (Plugin System)
|
|
1400
1430
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("react/jsx-runtime"),a=require("react"),A=require("./LoadingSpinner-d6sSxgQN.cjs"),C=require("./ErrorMessage-CHbYbVi2.cjs"),_=require("./AutosaveStatus-CZSwtgrL.cjs"),M=require("./useCedrosLogin-DtJorrE7.cjs"),I=require("./useOrgs-CNqfn-fk.cjs");function L(){const{config:r,_internal:g}=M.useCedrosLogin(),l=r.serverUrl,p=a.useRef(g?.getAccessToken??(()=>null));p.current=g?.getAccessToken??(()=>null);const[f,y]=a.useState([]),[x,v]=a.useState(0),[N,m]=a.useState(!1),[S,n]=a.useState(null),t=a.useCallback(()=>{const b=p.current();return{"Content-Type":"application/json",...b?{Authorization:`Bearer ${b}`}:{}}},[]),o=a.useCallback(async(b,c=50,d=0)=>{m(!0),n(null);try{const u=new URLSearchParams;b&&u.set("org_id",b),u.set("limit",String(c)),u.set("offset",String(d));const s=await fetch(`${l}/admin/sso-providers?${u}`,{headers:t()});if(!s.ok){const P=await s.json().catch(()=>({}));throw new Error(P.error||`Failed to fetch SSO providers: ${s.status}`)}const j=await s.json();return y(j.providers),v(j.total),j}catch(u){const s=u instanceof Error?u:new Error(String(u));throw n(s),s}finally{m(!1)}},[l,t]),i=a.useCallback(async b=>{m(!0),n(null);try{const c=await fetch(`${l}/admin/sso-providers`,{method:"POST",headers:t(),body:JSON.stringify(b)});if(!c.ok){const u=await c.json().catch(()=>({}));throw new Error(u.error||`Failed to create SSO provider: ${c.status}`)}const d=await c.json();return y(u=>[...u,d]),v(u=>u+1),d}catch(c){const d=c instanceof Error?c:new Error(String(c));throw n(d),d}finally{m(!1)}},[l,t]),h=a.useCallback(async(b,c)=>{m(!0),n(null);try{const d=await fetch(`${l}/admin/sso-providers/${b}`,{method:"PUT",headers:t(),body:JSON.stringify(c)});if(!d.ok){const s=await d.json().catch(()=>({}));throw new Error(s.error||`Failed to update SSO provider: ${d.status}`)}const u=await d.json();return y(s=>s.map(j=>j.id===b?u:j)),u}catch(d){const u=d instanceof Error?d:new Error(String(d));throw n(u),u}finally{m(!1)}},[l,t]),w=a.useCallback(async b=>{m(!0),n(null);try{const c=await fetch(`${l}/admin/sso-providers/${b}`,{method:"DELETE",headers:t()});if(!c.ok){const d=await c.json().catch(()=>({}));throw new Error(d.error||`Failed to delete SSO provider: ${c.status}`)}y(d=>d.filter(u=>u.id!==b)),v(d=>d-1)}catch(c){const d=c instanceof Error?c:new Error(String(c));throw n(d),d}finally{m(!1)}},[l,t]),k=a.useCallback(async(b,c)=>h(b,{enabled:c}),[h]);return{providers:f,total:x,isLoading:N,error:S,fetchProviders:o,createProvider:i,updateProvider:h,deleteProvider:w,toggleProvider:k}}function $({className:r}){const{providers:g,isLoading:l,error:p,fetchProviders:f,createProvider:y,updateProvider:x,deleteProvider:v,toggleProvider:N}=L(),{activeOrg:m}=I.useOrgs(),[S,n]=a.useState("list"),[t,o]=a.useState(null),[i,h]=a.useState(null);a.useEffect(()=>{f(m?.id)},[f,m?.id]);const w=()=>{o(null),h(null),n("add")},k=s=>{o(s),h(null),n("edit")},b=()=>{n("list"),o(null),h(null)},c=async s=>{if(confirm(`Delete SSO provider "${s.name}"? This cannot be undone.`))try{await v(s.id)}catch{}},d=async s=>{try{await N(s.id,!s.enabled)}catch{}},u=async s=>{h(null);try{S==="add"?await y(s):t&&await x(t.id,s),n("list"),o(null)}catch(j){h(j instanceof Error?j.message:"Failed to save provider")}};return l&&g.length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${r??""}`,children:[e.jsx(A.LoadingSpinner,{}),e.jsx("span",{children:"Loading SSO providers..."})]}):S==="add"||S==="edit"?e.jsx("div",{className:`cedros-system-settings ${r??""}`,children:e.jsx(T,{provider:t,orgId:m?.id,error:i,isLoading:l,onSave:u,onCancel:b})}):e.jsxs("div",{className:`cedros-system-settings ${r??""}`,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:"SSO Providers"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure OIDC identity providers for enterprise single sign-on."})]}),e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-primary",onClick:w,children:"Add Provider"})]}),p&&e.jsx(C.ErrorMessage,{error:p.message}),g.length===0?e.jsxs("div",{className:"cedros-system-settings-empty",children:[e.jsx("p",{children:"No SSO providers configured."}),e.jsx("p",{className:"cedros-text-muted",children:"Add an OIDC provider like Okta, Azure AD, or Auth0 to enable enterprise SSO."})]}):e.jsx("div",{className:"cedros-sso-provider-list",children:g.map(s=>e.jsx(R,{provider:s,onEdit:()=>k(s),onDelete:()=>c(s),onToggle:()=>d(s)},s.id))})]})}function R({provider:r,onEdit:g,onDelete:l,onToggle:p}){return e.jsxs("div",{className:`cedros-sso-provider-card ${r.enabled?"":"cedros-sso-provider-card--disabled"}`,children:[e.jsxs("div",{className:"cedros-sso-provider-card-header",children:[e.jsxs("div",{className:"cedros-sso-provider-card-info",children:[e.jsx("h3",{className:"cedros-sso-provider-card-name",children:r.name}),e.jsx("p",{className:"cedros-sso-provider-card-issuer",children:r.issuerUrl})]}),e.jsxs("button",{type:"button",role:"switch","aria-checked":r.enabled,className:`cedros-toggle ${r.enabled?"cedros-toggle-on":"cedros-toggle-off"}`,onClick:p,children:[e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})}),e.jsx("span",{className:"cedros-toggle-label",children:r.enabled?"Enabled":"Disabled"})]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-details",children:[e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Client ID"}),e.jsx("code",{className:"cedros-sso-provider-card-detail-value",children:r.clientId})]}),r.emailDomain&&e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Email Domain"}),e.jsxs("span",{className:"cedros-sso-provider-card-detail-value",children:["@",r.emailDomain]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Registration"}),e.jsx("span",{className:"cedros-sso-provider-card-detail-value",children:r.allowRegistration?"Allowed":"Existing users only"})]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-actions",children:[e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost",onClick:g,children:"Edit"}),e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost cedros-btn-danger",onClick:l,children:"Delete"})]})]})}function T({provider:r,orgId:g,error:l,isLoading:p,onSave:f,onCancel:y}){const x=!!r,[v,N]=a.useState(r?.name??""),[m,S]=a.useState(r?.issuerUrl??""),[n,t]=a.useState(r?.clientId??""),[o,i]=a.useState(""),[h,w]=a.useState(r?.emailDomain??""),[k,b]=a.useState(r?.allowRegistration??!0),[c,d]=a.useState(r?.enabled??!0),u=a.useCallback(s=>{if(s.preventDefault(),x){const j={name:v,issuerUrl:m,clientId:n,emailDomain:h||null,allowRegistration:k,enabled:c};o&&(j.clientSecret=o),f(j)}else{if(!g)return;f({orgId:g,name:v,issuerUrl:m,clientId:n,clientSecret:o,emailDomain:h||null,allowRegistration:k,enabled:c})}},[x,g,v,m,n,o,h,k,c,f]);return e.jsxs("form",{className:"cedros-sso-provider-form",onSubmit:u,children:[e.jsx("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:x?"Edit SSO Provider":"Add SSO Provider"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure an OIDC identity provider for enterprise single sign-on."})]})}),l&&e.jsx(C.ErrorMessage,{error:l}),e.jsxs("div",{className:"cedros-form-section",children:[e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-name",children:"Provider Name"}),e.jsx("input",{id:"sso-name",type:"text",className:"cedros-form-input",value:v,onChange:s=>N(s.target.value),placeholder:"e.g., Okta, Azure AD",required:!0})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-issuer",children:"Issuer URL"}),e.jsx("input",{id:"sso-issuer",type:"url",className:"cedros-form-input",value:m,onChange:s=>S(s.target.value),placeholder:"https://your-org.okta.com",required:!0}),e.jsx("p",{className:"cedros-form-hint",children:"The OIDC issuer URL. Must support discovery at /.well-known/openid-configuration"})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-client-id",children:"Client ID"}),e.jsx("input",{id:"sso-client-id",type:"text",className:"cedros-form-input",value:n,onChange:s=>t(s.target.value),placeholder:"OAuth client ID",required:!0})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsxs("label",{className:"cedros-form-label",htmlFor:"sso-client-secret",children:["Client Secret"," ",x&&e.jsx("span",{className:"cedros-form-hint-inline",children:"(leave blank to keep current)"})]}),e.jsx("input",{id:"sso-client-secret",type:"password",className:"cedros-form-input",value:o,onChange:s=>i(s.target.value),placeholder:x?"••••••••":"OAuth client secret",required:!x})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-email-domain",children:"Email Domain (optional)"}),e.jsx("input",{id:"sso-email-domain",type:"text",className:"cedros-form-input",value:h,onChange:s=>w(s.target.value),placeholder:"company.com"}),e.jsx("p",{className:"cedros-form-hint",children:"Restrict to users with emails from this domain"})]}),e.jsx("div",{className:"cedros-form-group",children:e.jsxs("label",{className:"cedros-form-checkbox",children:[e.jsx("input",{type:"checkbox",checked:k,onChange:s=>b(s.target.checked)}),e.jsx("span",{children:"Allow new user registration via SSO"})]})}),e.jsx("div",{className:"cedros-form-group",children:e.jsxs("label",{className:"cedros-form-checkbox",children:[e.jsx("input",{type:"checkbox",checked:c,onChange:s=>d(s.target.checked)}),e.jsx("span",{children:"Enable this provider"})]})})]}),e.jsxs("div",{className:"cedros-form-actions",children:[e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost",onClick:y,disabled:p,children:"Cancel"}),e.jsx("button",{type:"submit",className:"cedros-btn cedros-btn-primary",disabled:p,children:p?"Saving...":x?"Save Changes":"Add Provider"})]})]})}function F(){return e.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none","aria-hidden":"true",children:[e.jsx("path",{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",fill:"#4285F4"}),e.jsx("path",{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",fill:"#34A853"}),e.jsx("path",{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",fill:"#FBBC05"}),e.jsx("path",{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",fill:"#EA4335"})]})}function z(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:"M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"})})}function B(){return e.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 128 128",fill:"currentColor","aria-hidden":"true",children:[e.jsx("path",{d:"M25.38 96.04a4.35 4.35 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7l-17.71 17.72a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7l17.71-17.72z"}),e.jsx("path",{d:"M25.38 11.81a4.47 4.47 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7L103.96 31.96a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7L25.38 11.81z"}),e.jsx("path",{d:"M102.62 53.76a4.35 4.35 0 0 0-3.07-1.27H7.87c-1.93 0-2.9 2.34-1.54 3.7l17.71 17.72a4.35 4.35 0 0 0 3.07 1.27h91.68c1.93 0 2.9-2.34 1.54-3.7L102.62 53.76z"})]})}function q(){return e.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[e.jsx("path",{d:"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"}),e.jsx("path",{d:"M14 13.12c0 2.38 0 6.38-1 8.88"}),e.jsx("path",{d:"M17.29 21.02c.12-.6.43-2.3.5-3.02"}),e.jsx("path",{d:"M2 12a10 10 0 0 1 18-6"}),e.jsx("path",{d:"M2 16h.01"}),e.jsx("path",{d:"M21.8 16c.2-2 .131-5.354 0-6"}),e.jsx("path",{d:"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2"}),e.jsx("path",{d:"M8.65 22c.21-.66.45-1.32.57-2"}),e.jsx("path",{d:"M9 6.8a6 6 0 0 1 9 5.2v2"})]})}const E={webauthn:{label:"Passkey",icon:e.jsx(q,{}),enabledKey:"auth_webauthn_enabled"},google:{label:"Google",icon:e.jsx(F,{}),enabledKey:"auth_google_enabled"},apple:{label:"Apple",icon:e.jsx(z,{}),enabledKey:"auth_apple_enabled"},solana:{label:"Solana",icon:e.jsx(B,{}),enabledKey:"auth_solana_enabled"}},U=["webauthn","google","apple","solana"],H={webauthn:"Continue with Passkey",google:"Continue with Google",apple:"Continue with Apple",solana:"Continue with Solana"};function O(r,g){for(const l of Object.values(r)){const p=l.find(f=>f.key===g);if(p)return p.value==="true"}return!0}function K(r){for(const g of Object.values(r)){const l=g.find(p=>p.key==="ui_social_button_order");if(l&&l.value)return l.value.split(",").map(p=>p.trim())}return U}function W(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",style:{opacity:.4},children:[e.jsx("circle",{cx:"5",cy:"3",r:"1.5"}),e.jsx("circle",{cx:"11",cy:"3",r:"1.5"}),e.jsx("circle",{cx:"5",cy:"8",r:"1.5"}),e.jsx("circle",{cx:"11",cy:"8",r:"1.5"}),e.jsx("circle",{cx:"5",cy:"13",r:"1.5"}),e.jsx("circle",{cx:"11",cy:"13",r:"1.5"})]})}function G({settings:r,handleChange:g}){const[l,p]=a.useState(()=>K(r)),f=a.useRef(null),[y,x]=a.useState(null),v=a.useCallback(t=>{p(t),g("ui_social_button_order",t.join(","))},[g]),N=a.useCallback(t=>{f.current=t},[]),m=a.useCallback((t,o)=>{t.preventDefault(),x(o)},[]),S=a.useCallback(t=>{const o=f.current;if(o===null||o===t){x(null);return}const i=[...l],[h]=i.splice(o,1);i.splice(t,0,h),v(i),f.current=null,x(null)},[l,v]),n=a.useCallback(()=>{f.current=null,x(null)},[]);return e.jsxs("div",{className:"cedros-system-settings",children:[e.jsx("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:"Button Order"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Drag to reorder the social login buttons on your sign-in form."})]})}),e.jsxs("div",{style:{display:"flex",gap:"2rem",flexWrap:"wrap"},children:[e.jsx("div",{style:{flex:"1 1 260px",minWidth:260},children:e.jsx("ul",{style:{listStyle:"none",padding:0,margin:0,display:"flex",flexDirection:"column",gap:"0.5rem"},children:l.map((t,o)=>{const i=E[t];if(!i)return null;const h=O(r,i.enabledKey),w=y===o;return e.jsxs("li",{draggable:!0,onDragStart:()=>N(o),onDragOver:k=>m(k,o),onDrop:()=>S(o),onDragEnd:n,className:"cedros-btn-order-item",style:{display:"flex",alignItems:"center",gap:"0.75rem",padding:"0.625rem 0.75rem",borderRadius:"var(--cedros-radius, 0.5rem)",border:w?"2px solid var(--cedros-primary, #6366f1)":"1px solid var(--cedros-border, #e5e7eb)",background:"var(--cedros-background, #fff)",cursor:"grab",opacity:h?1:.5,transition:"border-color 0.15s"},children:[e.jsx(W,{}),e.jsx("span",{className:"cedros-button-icon",style:{display:"flex",alignItems:"center"},children:i.icon}),e.jsx("span",{style:{flex:1,fontWeight:500,fontSize:"0.875rem"},children:i.label}),e.jsx("span",{style:{fontSize:"0.7rem",padding:"0.125rem 0.5rem",borderRadius:"9999px",background:h?"var(--cedros-primary, #6366f1)":"var(--cedros-muted, #f3f4f6)",color:h?"var(--cedros-primary-foreground, #fff)":"var(--cedros-muted-foreground, #6b7280)"},children:h?"Enabled":"Disabled"})]},t)})})}),e.jsxs("div",{style:{flex:"1 1 280px",minWidth:280},children:[e.jsx("p",{style:{fontSize:"0.75rem",color:"var(--cedros-muted-foreground, #6b7280)",margin:"0 0 0.75rem"},children:"This is how your login form buttons will appear:"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",padding:"1.25rem",borderRadius:"var(--cedros-radius, 0.5rem)",border:"1px solid var(--cedros-border, #e5e7eb)",background:"var(--cedros-background, #fff)"},children:l.map(t=>{const o=E[t];return!o||!O(r,o.enabledKey)?null:e.jsxs("button",{type:"button",className:"cedros-button cedros-button-social",style:{pointerEvents:"none",width:"100%"},tabIndex:-1,children:[e.jsx("span",{className:"cedros-button-icon",children:o.icon}),H[t]]},t)})})]})]})]})}const D=[{id:"email",label:"Email",categories:["auth.email"],keys:["auth_email_enabled","auth_email_require_verification","auth_email_block_disposable"]},{id:"google",label:"Google",categories:["auth.google"],keys:["auth_google_enabled","auth_google_client_id"]},{id:"apple",label:"Apple",categories:["auth.apple"],keys:["auth_apple_enabled","auth_apple_client_id","auth_apple_team_id"]},{id:"solana",label:"Solana",categories:["auth.solana"],keys:["auth_solana_enabled","auth_solana_challenge_expiry"]},{id:"passkeys",label:"Passkeys",categories:["auth.webauthn"],keys:["auth_webauthn_enabled","auth_webauthn_rp_id","auth_webauthn_rp_name","auth_webauthn_rp_origin"]},{id:"instantlink",label:"Instant Link",categories:["auth.instantlink"],keys:["auth_instantlink_enabled","auth_instantlink_expiry","auth_instantlink_rate_limit"]},{id:"sso",label:"SSO Providers",categories:[],isCustom:!0},{id:"buttonorder",label:"Button Order",categories:[],isCustom:!0},{id:"postlogin",label:"Post-Login",categories:["postlogin","postlogin.welcome","postlogin.username","postlogin.complete","postlogin.wallet"],keys:["postlogin_redirect_url","postlogin_welcome_enabled","postlogin_welcome_route","postlogin_username_enabled","postlogin_complete_enabled","postlogin_wallet_enroll_enabled","postlogin_show_recovery_enabled"]}];function V({className:r}){const{settings:g,edits:l,isLoading:p,autosaveStatus:f,autosaveError:y,error:x,fetchSettings:v,handleChange:N}=_.useSettingsAutosave(),[m,S]=a.useState("email");a.useEffect(()=>{v()},[v]);const n=D.find(i=>i.id===m),t=a.useMemo(()=>{if(!n)return[];const i=[];for(const h of n.categories){const w=g[h]??[];i.push(...w)}return i},[g,n]),o=a.useMemo(()=>n?.keys?t.filter(i=>n.keys.includes(i.key)).sort((i,h)=>n.keys.indexOf(i.key)-n.keys.indexOf(h.key)):t,[t,n]);return p&&Object.keys(g).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${r??""}`,children:[e.jsx(A.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):x?e.jsx("div",{className:`cedros-system-settings ${r??""}`,children:e.jsx(C.ErrorMessage,{error:x.message})}):e.jsxs("div",{className:`cedros-system-settings ${r??""}`,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:"Authentication"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure authentication providers and methods for user sign-in."})]}),e.jsx(_.AutosaveStatus,{status:f,error:y})]}),e.jsx("div",{className:"cedros-admin-tabs cedros-admin-tabs--line",children:D.map(i=>e.jsx("button",{type:"button",className:`cedros-admin-tab ${m===i.id?"cedros-admin-tab-active":""}`,onClick:()=>S(i.id),"aria-selected":m===i.id,role:"tab",children:i.label},i.id))}),e.jsx("div",{className:"cedros-admin-tab-content",role:"tabpanel",children:n?.id==="buttonorder"?e.jsx(G,{settings:g,handleChange:N}):n?.isCustom?e.jsx($,{}):o.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsxs("p",{children:["No settings found for ",n?.label??"this provider","."]})}):e.jsx(_.SettingsSection,{settings:o,edits:l,onChange:N})})]})}exports.AuthenticationSettings=V;
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),a=require("react"),A=require("./LoadingSpinner-d6sSxgQN.cjs"),C=require("./ErrorMessage-CHbYbVi2.cjs"),_=require("./AutosaveStatus-DfMPudTQ.cjs"),M=require("./useCedrosLogin-DtJorrE7.cjs"),I=require("./useOrgs-CNqfn-fk.cjs");function L(){const{config:r,_internal:g}=M.useCedrosLogin(),l=r.serverUrl,p=a.useRef(g?.getAccessToken??(()=>null));p.current=g?.getAccessToken??(()=>null);const[f,y]=a.useState([]),[x,v]=a.useState(0),[N,m]=a.useState(!1),[S,n]=a.useState(null),t=a.useCallback(()=>{const b=p.current();return{"Content-Type":"application/json",...b?{Authorization:`Bearer ${b}`}:{}}},[]),o=a.useCallback(async(b,c=50,d=0)=>{m(!0),n(null);try{const u=new URLSearchParams;b&&u.set("org_id",b),u.set("limit",String(c)),u.set("offset",String(d));const s=await fetch(`${l}/admin/sso-providers?${u}`,{headers:t()});if(!s.ok){const P=await s.json().catch(()=>({}));throw new Error(P.error||`Failed to fetch SSO providers: ${s.status}`)}const j=await s.json();return y(j.providers),v(j.total),j}catch(u){const s=u instanceof Error?u:new Error(String(u));throw n(s),s}finally{m(!1)}},[l,t]),i=a.useCallback(async b=>{m(!0),n(null);try{const c=await fetch(`${l}/admin/sso-providers`,{method:"POST",headers:t(),body:JSON.stringify(b)});if(!c.ok){const u=await c.json().catch(()=>({}));throw new Error(u.error||`Failed to create SSO provider: ${c.status}`)}const d=await c.json();return y(u=>[...u,d]),v(u=>u+1),d}catch(c){const d=c instanceof Error?c:new Error(String(c));throw n(d),d}finally{m(!1)}},[l,t]),h=a.useCallback(async(b,c)=>{m(!0),n(null);try{const d=await fetch(`${l}/admin/sso-providers/${b}`,{method:"PUT",headers:t(),body:JSON.stringify(c)});if(!d.ok){const s=await d.json().catch(()=>({}));throw new Error(s.error||`Failed to update SSO provider: ${d.status}`)}const u=await d.json();return y(s=>s.map(j=>j.id===b?u:j)),u}catch(d){const u=d instanceof Error?d:new Error(String(d));throw n(u),u}finally{m(!1)}},[l,t]),w=a.useCallback(async b=>{m(!0),n(null);try{const c=await fetch(`${l}/admin/sso-providers/${b}`,{method:"DELETE",headers:t()});if(!c.ok){const d=await c.json().catch(()=>({}));throw new Error(d.error||`Failed to delete SSO provider: ${c.status}`)}y(d=>d.filter(u=>u.id!==b)),v(d=>d-1)}catch(c){const d=c instanceof Error?c:new Error(String(c));throw n(d),d}finally{m(!1)}},[l,t]),k=a.useCallback(async(b,c)=>h(b,{enabled:c}),[h]);return{providers:f,total:x,isLoading:N,error:S,fetchProviders:o,createProvider:i,updateProvider:h,deleteProvider:w,toggleProvider:k}}function $({className:r}){const{providers:g,isLoading:l,error:p,fetchProviders:f,createProvider:y,updateProvider:x,deleteProvider:v,toggleProvider:N}=L(),{activeOrg:m}=I.useOrgs(),[S,n]=a.useState("list"),[t,o]=a.useState(null),[i,h]=a.useState(null);a.useEffect(()=>{f(m?.id)},[f,m?.id]);const w=()=>{o(null),h(null),n("add")},k=s=>{o(s),h(null),n("edit")},b=()=>{n("list"),o(null),h(null)},c=async s=>{if(confirm(`Delete SSO provider "${s.name}"? This cannot be undone.`))try{await v(s.id)}catch{}},d=async s=>{try{await N(s.id,!s.enabled)}catch{}},u=async s=>{h(null);try{S==="add"?await y(s):t&&await x(t.id,s),n("list"),o(null)}catch(j){h(j instanceof Error?j.message:"Failed to save provider")}};return l&&g.length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${r??""}`,children:[e.jsx(A.LoadingSpinner,{}),e.jsx("span",{children:"Loading SSO providers..."})]}):S==="add"||S==="edit"?e.jsx("div",{className:`cedros-system-settings ${r??""}`,children:e.jsx(T,{provider:t,orgId:m?.id,error:i,isLoading:l,onSave:u,onCancel:b})}):e.jsxs("div",{className:`cedros-system-settings ${r??""}`,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:"SSO Providers"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure OIDC identity providers for enterprise single sign-on."})]}),e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-primary",onClick:w,children:"Add Provider"})]}),p&&e.jsx(C.ErrorMessage,{error:p.message}),g.length===0?e.jsxs("div",{className:"cedros-system-settings-empty",children:[e.jsx("p",{children:"No SSO providers configured."}),e.jsx("p",{className:"cedros-text-muted",children:"Add an OIDC provider like Okta, Azure AD, or Auth0 to enable enterprise SSO."})]}):e.jsx("div",{className:"cedros-sso-provider-list",children:g.map(s=>e.jsx(R,{provider:s,onEdit:()=>k(s),onDelete:()=>c(s),onToggle:()=>d(s)},s.id))})]})}function R({provider:r,onEdit:g,onDelete:l,onToggle:p}){return e.jsxs("div",{className:`cedros-sso-provider-card ${r.enabled?"":"cedros-sso-provider-card--disabled"}`,children:[e.jsxs("div",{className:"cedros-sso-provider-card-header",children:[e.jsxs("div",{className:"cedros-sso-provider-card-info",children:[e.jsx("h3",{className:"cedros-sso-provider-card-name",children:r.name}),e.jsx("p",{className:"cedros-sso-provider-card-issuer",children:r.issuerUrl})]}),e.jsxs("button",{type:"button",role:"switch","aria-checked":r.enabled,className:`cedros-toggle ${r.enabled?"cedros-toggle-on":"cedros-toggle-off"}`,onClick:p,children:[e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})}),e.jsx("span",{className:"cedros-toggle-label",children:r.enabled?"Enabled":"Disabled"})]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-details",children:[e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Client ID"}),e.jsx("code",{className:"cedros-sso-provider-card-detail-value",children:r.clientId})]}),r.emailDomain&&e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Email Domain"}),e.jsxs("span",{className:"cedros-sso-provider-card-detail-value",children:["@",r.emailDomain]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Registration"}),e.jsx("span",{className:"cedros-sso-provider-card-detail-value",children:r.allowRegistration?"Allowed":"Existing users only"})]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-actions",children:[e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost",onClick:g,children:"Edit"}),e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost cedros-btn-danger",onClick:l,children:"Delete"})]})]})}function T({provider:r,orgId:g,error:l,isLoading:p,onSave:f,onCancel:y}){const x=!!r,[v,N]=a.useState(r?.name??""),[m,S]=a.useState(r?.issuerUrl??""),[n,t]=a.useState(r?.clientId??""),[o,i]=a.useState(""),[h,w]=a.useState(r?.emailDomain??""),[k,b]=a.useState(r?.allowRegistration??!0),[c,d]=a.useState(r?.enabled??!0),u=a.useCallback(s=>{if(s.preventDefault(),x){const j={name:v,issuerUrl:m,clientId:n,emailDomain:h||null,allowRegistration:k,enabled:c};o&&(j.clientSecret=o),f(j)}else{if(!g)return;f({orgId:g,name:v,issuerUrl:m,clientId:n,clientSecret:o,emailDomain:h||null,allowRegistration:k,enabled:c})}},[x,g,v,m,n,o,h,k,c,f]);return e.jsxs("form",{className:"cedros-sso-provider-form",onSubmit:u,children:[e.jsx("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:x?"Edit SSO Provider":"Add SSO Provider"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure an OIDC identity provider for enterprise single sign-on."})]})}),l&&e.jsx(C.ErrorMessage,{error:l}),e.jsxs("div",{className:"cedros-form-section",children:[e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-name",children:"Provider Name"}),e.jsx("input",{id:"sso-name",type:"text",className:"cedros-form-input",value:v,onChange:s=>N(s.target.value),placeholder:"e.g., Okta, Azure AD",required:!0})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-issuer",children:"Issuer URL"}),e.jsx("input",{id:"sso-issuer",type:"url",className:"cedros-form-input",value:m,onChange:s=>S(s.target.value),placeholder:"https://your-org.okta.com",required:!0}),e.jsx("p",{className:"cedros-form-hint",children:"The OIDC issuer URL. Must support discovery at /.well-known/openid-configuration"})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-client-id",children:"Client ID"}),e.jsx("input",{id:"sso-client-id",type:"text",className:"cedros-form-input",value:n,onChange:s=>t(s.target.value),placeholder:"OAuth client ID",required:!0})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsxs("label",{className:"cedros-form-label",htmlFor:"sso-client-secret",children:["Client Secret"," ",x&&e.jsx("span",{className:"cedros-form-hint-inline",children:"(leave blank to keep current)"})]}),e.jsx("input",{id:"sso-client-secret",type:"password",className:"cedros-form-input",value:o,onChange:s=>i(s.target.value),placeholder:x?"••••••••":"OAuth client secret",required:!x})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-email-domain",children:"Email Domain (optional)"}),e.jsx("input",{id:"sso-email-domain",type:"text",className:"cedros-form-input",value:h,onChange:s=>w(s.target.value),placeholder:"company.com"}),e.jsx("p",{className:"cedros-form-hint",children:"Restrict to users with emails from this domain"})]}),e.jsx("div",{className:"cedros-form-group",children:e.jsxs("label",{className:"cedros-form-checkbox",children:[e.jsx("input",{type:"checkbox",checked:k,onChange:s=>b(s.target.checked)}),e.jsx("span",{children:"Allow new user registration via SSO"})]})}),e.jsx("div",{className:"cedros-form-group",children:e.jsxs("label",{className:"cedros-form-checkbox",children:[e.jsx("input",{type:"checkbox",checked:c,onChange:s=>d(s.target.checked)}),e.jsx("span",{children:"Enable this provider"})]})})]}),e.jsxs("div",{className:"cedros-form-actions",children:[e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost",onClick:y,disabled:p,children:"Cancel"}),e.jsx("button",{type:"submit",className:"cedros-btn cedros-btn-primary",disabled:p,children:p?"Saving...":x?"Save Changes":"Add Provider"})]})]})}function F(){return e.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 18 18",fill:"none","aria-hidden":"true",children:[e.jsx("path",{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",fill:"#4285F4"}),e.jsx("path",{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",fill:"#34A853"}),e.jsx("path",{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",fill:"#FBBC05"}),e.jsx("path",{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",fill:"#EA4335"})]})}function z(){return e.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"currentColor","aria-hidden":"true",children:e.jsx("path",{d:"M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z"})})}function B(){return e.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 128 128",fill:"currentColor","aria-hidden":"true",children:[e.jsx("path",{d:"M25.38 96.04a4.35 4.35 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7l-17.71 17.72a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7l17.71-17.72z"}),e.jsx("path",{d:"M25.38 11.81a4.47 4.47 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7L103.96 31.96a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7L25.38 11.81z"}),e.jsx("path",{d:"M102.62 53.76a4.35 4.35 0 0 0-3.07-1.27H7.87c-1.93 0-2.9 2.34-1.54 3.7l17.71 17.72a4.35 4.35 0 0 0 3.07 1.27h91.68c1.93 0 2.9-2.34 1.54-3.7L102.62 53.76z"})]})}function q(){return e.jsxs("svg",{width:"20",height:"20",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[e.jsx("path",{d:"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4"}),e.jsx("path",{d:"M14 13.12c0 2.38 0 6.38-1 8.88"}),e.jsx("path",{d:"M17.29 21.02c.12-.6.43-2.3.5-3.02"}),e.jsx("path",{d:"M2 12a10 10 0 0 1 18-6"}),e.jsx("path",{d:"M2 16h.01"}),e.jsx("path",{d:"M21.8 16c.2-2 .131-5.354 0-6"}),e.jsx("path",{d:"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2"}),e.jsx("path",{d:"M8.65 22c.21-.66.45-1.32.57-2"}),e.jsx("path",{d:"M9 6.8a6 6 0 0 1 9 5.2v2"})]})}const E={webauthn:{label:"Passkey",icon:e.jsx(q,{}),enabledKey:"auth_webauthn_enabled"},google:{label:"Google",icon:e.jsx(F,{}),enabledKey:"auth_google_enabled"},apple:{label:"Apple",icon:e.jsx(z,{}),enabledKey:"auth_apple_enabled"},solana:{label:"Solana",icon:e.jsx(B,{}),enabledKey:"auth_solana_enabled"}},U=["webauthn","google","apple","solana"],H={webauthn:"Continue with Passkey",google:"Continue with Google",apple:"Continue with Apple",solana:"Continue with Solana"};function O(r,g){for(const l of Object.values(r)){const p=l.find(f=>f.key===g);if(p)return p.value==="true"}return!0}function K(r){for(const g of Object.values(r)){const l=g.find(p=>p.key==="ui_social_button_order");if(l&&l.value)return l.value.split(",").map(p=>p.trim())}return U}function W(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"currentColor","aria-hidden":"true",style:{opacity:.4},children:[e.jsx("circle",{cx:"5",cy:"3",r:"1.5"}),e.jsx("circle",{cx:"11",cy:"3",r:"1.5"}),e.jsx("circle",{cx:"5",cy:"8",r:"1.5"}),e.jsx("circle",{cx:"11",cy:"8",r:"1.5"}),e.jsx("circle",{cx:"5",cy:"13",r:"1.5"}),e.jsx("circle",{cx:"11",cy:"13",r:"1.5"})]})}function G({settings:r,handleChange:g}){const[l,p]=a.useState(()=>K(r)),f=a.useRef(null),[y,x]=a.useState(null),v=a.useCallback(t=>{p(t),g("ui_social_button_order",t.join(","))},[g]),N=a.useCallback(t=>{f.current=t},[]),m=a.useCallback((t,o)=>{t.preventDefault(),x(o)},[]),S=a.useCallback(t=>{const o=f.current;if(o===null||o===t){x(null);return}const i=[...l],[h]=i.splice(o,1);i.splice(t,0,h),v(i),f.current=null,x(null)},[l,v]),n=a.useCallback(()=>{f.current=null,x(null)},[]);return e.jsxs("div",{className:"cedros-system-settings",children:[e.jsx("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:"Button Order"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Drag to reorder the social login buttons on your sign-in form."})]})}),e.jsxs("div",{style:{display:"flex",gap:"2rem",flexWrap:"wrap"},children:[e.jsx("div",{style:{flex:"1 1 260px",minWidth:260},children:e.jsx("ul",{style:{listStyle:"none",padding:0,margin:0,display:"flex",flexDirection:"column",gap:"0.5rem"},children:l.map((t,o)=>{const i=E[t];if(!i)return null;const h=O(r,i.enabledKey),w=y===o;return e.jsxs("li",{draggable:!0,onDragStart:()=>N(o),onDragOver:k=>m(k,o),onDrop:()=>S(o),onDragEnd:n,className:"cedros-btn-order-item",style:{display:"flex",alignItems:"center",gap:"0.75rem",padding:"0.625rem 0.75rem",borderRadius:"var(--cedros-radius, 0.5rem)",border:w?"2px solid var(--cedros-primary, #6366f1)":"1px solid var(--cedros-border, #e5e7eb)",background:"var(--cedros-background, #fff)",cursor:"grab",opacity:h?1:.5,transition:"border-color 0.15s"},children:[e.jsx(W,{}),e.jsx("span",{className:"cedros-button-icon",style:{display:"flex",alignItems:"center"},children:i.icon}),e.jsx("span",{style:{flex:1,fontWeight:500,fontSize:"0.875rem"},children:i.label}),e.jsx("span",{style:{fontSize:"0.7rem",padding:"0.125rem 0.5rem",borderRadius:"9999px",background:h?"var(--cedros-primary, #6366f1)":"var(--cedros-muted, #f3f4f6)",color:h?"var(--cedros-primary-foreground, #fff)":"var(--cedros-muted-foreground, #6b7280)"},children:h?"Enabled":"Disabled"})]},t)})})}),e.jsxs("div",{style:{flex:"1 1 280px",minWidth:280},children:[e.jsx("p",{style:{fontSize:"0.75rem",color:"var(--cedros-muted-foreground, #6b7280)",margin:"0 0 0.75rem"},children:"This is how your login form buttons will appear:"}),e.jsx("div",{style:{display:"flex",flexDirection:"column",gap:"0.5rem",padding:"1.25rem",borderRadius:"var(--cedros-radius, 0.5rem)",border:"1px solid var(--cedros-border, #e5e7eb)",background:"var(--cedros-background, #fff)"},children:l.map(t=>{const o=E[t];return!o||!O(r,o.enabledKey)?null:e.jsxs("button",{type:"button",className:"cedros-button cedros-button-social",style:{pointerEvents:"none",width:"100%"},tabIndex:-1,children:[e.jsx("span",{className:"cedros-button-icon",children:o.icon}),H[t]]},t)})})]})]})]})}const D=[{id:"email",label:"Email",categories:["auth.email"],keys:["auth_email_enabled","auth_email_require_verification","auth_email_block_disposable"]},{id:"google",label:"Google",categories:["auth.google"],keys:["auth_google_enabled","auth_google_client_id"]},{id:"apple",label:"Apple",categories:["auth.apple"],keys:["auth_apple_enabled","auth_apple_client_id","auth_apple_team_id"]},{id:"solana",label:"Solana",categories:["auth.solana"],keys:["auth_solana_enabled","auth_solana_challenge_expiry"]},{id:"passkeys",label:"Passkeys",categories:["auth.webauthn"],keys:["auth_webauthn_enabled","auth_webauthn_rp_id","auth_webauthn_rp_name","auth_webauthn_rp_origin"]},{id:"instantlink",label:"Instant Link",categories:["auth.instantlink"],keys:["auth_instantlink_enabled","auth_instantlink_expiry","auth_instantlink_rate_limit"]},{id:"sso",label:"SSO Providers",categories:[],isCustom:!0},{id:"buttonorder",label:"Button Order",categories:[],isCustom:!0},{id:"postlogin",label:"Post-Login",categories:["postlogin","postlogin.welcome","postlogin.username","postlogin.complete","postlogin.wallet"],keys:["postlogin_redirect_url","postlogin_welcome_enabled","postlogin_welcome_route","postlogin_username_enabled","postlogin_complete_enabled","postlogin_wallet_enroll_enabled","postlogin_show_recovery_enabled"]}];function V({className:r}){const{settings:g,edits:l,isLoading:p,autosaveStatus:f,autosaveError:y,error:x,fetchSettings:v,handleChange:N}=_.useSettingsAutosave(),[m,S]=a.useState("email");a.useEffect(()=>{v()},[v]);const n=D.find(i=>i.id===m),t=a.useMemo(()=>{if(!n)return[];const i=[];for(const h of n.categories){const w=g[h]??[];i.push(...w)}return i},[g,n]),o=a.useMemo(()=>n?.keys?t.filter(i=>n.keys.includes(i.key)).sort((i,h)=>n.keys.indexOf(i.key)-n.keys.indexOf(h.key)):t,[t,n]);return p&&Object.keys(g).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${r??""}`,children:[e.jsx(A.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):x?e.jsx("div",{className:`cedros-system-settings ${r??""}`,children:e.jsx(C.ErrorMessage,{error:x.message})}):e.jsxs("div",{className:`cedros-system-settings ${r??""}`,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:"Authentication"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure authentication providers and methods for user sign-in."})]}),e.jsx(_.AutosaveStatus,{status:f,error:y})]}),e.jsx("div",{className:"cedros-admin-tabs cedros-admin-tabs--line",children:D.map(i=>e.jsx("button",{type:"button",className:`cedros-admin-tab ${m===i.id?"cedros-admin-tab-active":""}`,onClick:()=>S(i.id),"aria-selected":m===i.id,role:"tab",children:i.label},i.id))}),e.jsx("div",{className:"cedros-admin-tab-content",role:"tabpanel",children:n?.id==="buttonorder"?e.jsx(G,{settings:g,handleChange:N}):n?.isCustom?e.jsx($,{}):o.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsxs("p",{children:["No settings found for ",n?.label??"this provider","."]})}):e.jsx(_.SettingsSection,{settings:o,edits:l,onChange:N})})]})}exports.AuthenticationSettings=V;
|
package/dist/{AuthenticationSettings-bNQiNQ9g.cjs.map → AuthenticationSettings-BBOjHR6j.cjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationSettings-bNQiNQ9g.cjs","sources":["../src/hooks/useSsoProviders.ts","../src/components/admin/settings/SsoProvidersSettings.tsx","../src/components/admin/settings/SocialButtonOrderSettings.tsx","../src/components/admin/settings/AuthenticationSettings.tsx"],"sourcesContent":["/**\n * Hook for managing SSO providers (admin)\n */\nimport { useState, useCallback, useRef } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\n\nexport interface SsoProvider {\n id: string;\n orgId: string;\n name: string;\n issuerUrl: string;\n clientId: string;\n scopes: string[];\n enabled: boolean;\n allowRegistration: boolean;\n emailDomain: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateSsoProviderInput {\n orgId: string;\n name: string;\n issuerUrl: string;\n clientId: string;\n clientSecret: string;\n scopes?: string[];\n enabled?: boolean;\n allowRegistration?: boolean;\n emailDomain?: string | null;\n}\n\nexport interface UpdateSsoProviderInput {\n name?: string;\n issuerUrl?: string;\n clientId?: string;\n clientSecret?: string;\n scopes?: string[];\n enabled?: boolean;\n allowRegistration?: boolean;\n emailDomain?: string | null;\n}\n\ninterface ListResponse {\n providers: SsoProvider[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport function useSsoProviders() {\n const { config, _internal } = useCedrosLogin();\n const serverUrl = config.serverUrl;\n\n // PERF-03: Stabilize getAccessToken reference using ref pattern\n // to prevent unnecessary re-creation of callbacks\n const getAccessTokenRef = useRef(_internal?.getAccessToken ?? (() => null));\n getAccessTokenRef.current = _internal?.getAccessToken ?? (() => null);\n\n const [providers, setProviders] = useState<SsoProvider[]>([]);\n const [total, setTotal] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Memoize getHeaders with empty deps since it uses ref\n const getHeaders = useCallback(() => {\n const token = getAccessTokenRef.current();\n return {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n };\n }, []);\n\n const fetchProviders = useCallback(\n async (orgId?: string, limit = 50, offset = 0) => {\n setIsLoading(true);\n setError(null);\n try {\n const params = new URLSearchParams();\n if (orgId) params.set('org_id', orgId);\n params.set('limit', String(limit));\n params.set('offset', String(offset));\n\n const res = await fetch(`${serverUrl}/admin/sso-providers?${params}`, {\n headers: getHeaders(),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to fetch SSO providers: ${res.status}`);\n }\n\n const data: ListResponse = await res.json();\n setProviders(data.providers);\n setTotal(data.total);\n return data;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const createProvider = useCallback(\n async (input: CreateSsoProviderInput): Promise<SsoProvider> => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetch(`${serverUrl}/admin/sso-providers`, {\n method: 'POST',\n headers: getHeaders(),\n body: JSON.stringify(input),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to create SSO provider: ${res.status}`);\n }\n\n const provider: SsoProvider = await res.json();\n setProviders((prev) => [...prev, provider]);\n setTotal((prev) => prev + 1);\n return provider;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const updateProvider = useCallback(\n async (id: string, input: UpdateSsoProviderInput): Promise<SsoProvider> => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetch(`${serverUrl}/admin/sso-providers/${id}`, {\n method: 'PUT',\n headers: getHeaders(),\n body: JSON.stringify(input),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to update SSO provider: ${res.status}`);\n }\n\n const provider: SsoProvider = await res.json();\n setProviders((prev) => prev.map((p) => (p.id === id ? provider : p)));\n return provider;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const deleteProvider = useCallback(\n async (id: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetch(`${serverUrl}/admin/sso-providers/${id}`, {\n method: 'DELETE',\n headers: getHeaders(),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to delete SSO provider: ${res.status}`);\n }\n\n setProviders((prev) => prev.filter((p) => p.id !== id));\n setTotal((prev) => prev - 1);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const toggleProvider = useCallback(\n async (id: string, enabled: boolean): Promise<SsoProvider> => {\n return updateProvider(id, { enabled });\n },\n [updateProvider]\n );\n\n return {\n providers,\n total,\n isLoading,\n error,\n fetchProviders,\n createProvider,\n updateProvider,\n deleteProvider,\n toggleProvider,\n };\n}\n","/**\n * SSO Providers settings - manage OIDC identity providers\n */\nimport { useState, useEffect, useCallback } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport {\n useSsoProviders,\n type SsoProvider,\n type CreateSsoProviderInput,\n type UpdateSsoProviderInput,\n} from '../../../hooks/useSsoProviders';\nimport { useOrgs } from '../../../hooks/useOrgs';\n\nexport interface SsoProvidersSettingsProps {\n className?: string;\n}\n\ntype ViewMode = 'list' | 'add' | 'edit';\n\nexport function SsoProvidersSettings({ className }: SsoProvidersSettingsProps) {\n const {\n providers,\n isLoading,\n error,\n fetchProviders,\n createProvider,\n updateProvider,\n deleteProvider,\n toggleProvider,\n } = useSsoProviders();\n\n const { activeOrg } = useOrgs();\n const [viewMode, setViewMode] = useState<ViewMode>('list');\n const [editingProvider, setEditingProvider] = useState<SsoProvider | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n\n useEffect(() => {\n fetchProviders(activeOrg?.id);\n }, [fetchProviders, activeOrg?.id]);\n\n const handleAdd = () => {\n setEditingProvider(null);\n setFormError(null);\n setViewMode('add');\n };\n\n const handleEdit = (provider: SsoProvider) => {\n setEditingProvider(provider);\n setFormError(null);\n setViewMode('edit');\n };\n\n const handleCancel = () => {\n setViewMode('list');\n setEditingProvider(null);\n setFormError(null);\n };\n\n const handleDelete = async (provider: SsoProvider) => {\n if (!confirm(`Delete SSO provider \"${provider.name}\"? This cannot be undone.`)) {\n return;\n }\n try {\n await deleteProvider(provider.id);\n } catch {\n // Error is already set in hook\n }\n };\n\n const handleToggle = async (provider: SsoProvider) => {\n try {\n await toggleProvider(provider.id, !provider.enabled);\n } catch {\n // Error is already set in hook\n }\n };\n\n const handleSave = async (data: CreateSsoProviderInput | UpdateSsoProviderInput) => {\n setFormError(null);\n try {\n if (viewMode === 'add') {\n await createProvider(data as CreateSsoProviderInput);\n } else if (editingProvider) {\n await updateProvider(editingProvider.id, data as UpdateSsoProviderInput);\n }\n setViewMode('list');\n setEditingProvider(null);\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to save provider');\n }\n };\n\n if (isLoading && providers.length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading SSO providers...</span>\n </div>\n );\n }\n\n if (viewMode === 'add' || viewMode === 'edit') {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <SsoProviderForm\n provider={editingProvider}\n orgId={activeOrg?.id}\n error={formError}\n isLoading={isLoading}\n onSave={handleSave}\n onCancel={handleCancel}\n />\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\">SSO Providers</h2>\n <p className=\"cedros-settings-page-description\">\n Configure OIDC identity providers for enterprise single sign-on.\n </p>\n </div>\n <button type=\"button\" className=\"cedros-btn cedros-btn-primary\" onClick={handleAdd}>\n Add Provider\n </button>\n </div>\n\n {error && <ErrorMessage error={error.message} />}\n\n {providers.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No SSO providers configured.</p>\n <p className=\"cedros-text-muted\">\n Add an OIDC provider like Okta, Azure AD, or Auth0 to enable enterprise SSO.\n </p>\n </div>\n ) : (\n <div className=\"cedros-sso-provider-list\">\n {providers.map((provider) => (\n <SsoProviderCard\n key={provider.id}\n provider={provider}\n onEdit={() => handleEdit(provider)}\n onDelete={() => handleDelete(provider)}\n onToggle={() => handleToggle(provider)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// =============================================================================\n// Provider Card\n// =============================================================================\n\ninterface SsoProviderCardProps {\n provider: SsoProvider;\n onEdit: () => void;\n onDelete: () => void;\n onToggle: () => void;\n}\n\nfunction SsoProviderCard({ provider, onEdit, onDelete, onToggle }: SsoProviderCardProps) {\n return (\n <div\n className={`cedros-sso-provider-card ${provider.enabled ? '' : 'cedros-sso-provider-card--disabled'}`}\n >\n <div className=\"cedros-sso-provider-card-header\">\n <div className=\"cedros-sso-provider-card-info\">\n <h3 className=\"cedros-sso-provider-card-name\">{provider.name}</h3>\n <p className=\"cedros-sso-provider-card-issuer\">{provider.issuerUrl}</p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={provider.enabled}\n className={`cedros-toggle ${provider.enabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={onToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">{provider.enabled ? 'Enabled' : 'Disabled'}</span>\n </button>\n </div>\n\n <div className=\"cedros-sso-provider-card-details\">\n <div className=\"cedros-sso-provider-card-detail\">\n <span className=\"cedros-sso-provider-card-detail-label\">Client ID</span>\n <code className=\"cedros-sso-provider-card-detail-value\">{provider.clientId}</code>\n </div>\n {provider.emailDomain && (\n <div className=\"cedros-sso-provider-card-detail\">\n <span className=\"cedros-sso-provider-card-detail-label\">Email Domain</span>\n <span className=\"cedros-sso-provider-card-detail-value\">@{provider.emailDomain}</span>\n </div>\n )}\n <div className=\"cedros-sso-provider-card-detail\">\n <span className=\"cedros-sso-provider-card-detail-label\">Registration</span>\n <span className=\"cedros-sso-provider-card-detail-value\">\n {provider.allowRegistration ? 'Allowed' : 'Existing users only'}\n </span>\n </div>\n </div>\n\n <div className=\"cedros-sso-provider-card-actions\">\n <button type=\"button\" className=\"cedros-btn cedros-btn-ghost\" onClick={onEdit}>\n Edit\n </button>\n <button\n type=\"button\"\n className=\"cedros-btn cedros-btn-ghost cedros-btn-danger\"\n onClick={onDelete}\n >\n Delete\n </button>\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// Provider Form\n// =============================================================================\n\ninterface SsoProviderFormProps {\n provider: SsoProvider | null;\n orgId?: string;\n error: string | null;\n isLoading: boolean;\n onSave: (data: CreateSsoProviderInput | UpdateSsoProviderInput) => void;\n onCancel: () => void;\n}\n\nfunction SsoProviderForm({\n provider,\n orgId,\n error,\n isLoading,\n onSave,\n onCancel,\n}: SsoProviderFormProps) {\n const isEditing = Boolean(provider);\n\n const [name, setName] = useState(provider?.name ?? '');\n const [issuerUrl, setIssuerUrl] = useState(provider?.issuerUrl ?? '');\n const [clientId, setClientId] = useState(provider?.clientId ?? '');\n const [clientSecret, setClientSecret] = useState('');\n const [emailDomain, setEmailDomain] = useState(provider?.emailDomain ?? '');\n const [allowRegistration, setAllowRegistration] = useState(provider?.allowRegistration ?? true);\n const [enabled, setEnabled] = useState(provider?.enabled ?? true);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent) => {\n e.preventDefault();\n\n if (isEditing) {\n const updates: UpdateSsoProviderInput = {\n name,\n issuerUrl,\n clientId,\n emailDomain: emailDomain || null,\n allowRegistration,\n enabled,\n };\n // Only include secret if changed\n if (clientSecret) {\n updates.clientSecret = clientSecret;\n }\n onSave(updates);\n } else {\n if (!orgId) {\n return;\n }\n const data: CreateSsoProviderInput = {\n orgId,\n name,\n issuerUrl,\n clientId,\n clientSecret,\n emailDomain: emailDomain || null,\n allowRegistration,\n enabled,\n };\n onSave(data);\n }\n },\n [\n isEditing,\n orgId,\n name,\n issuerUrl,\n clientId,\n clientSecret,\n emailDomain,\n allowRegistration,\n enabled,\n onSave,\n ]\n );\n\n return (\n <form className=\"cedros-sso-provider-form\" onSubmit={handleSubmit}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">\n {isEditing ? 'Edit SSO Provider' : 'Add SSO Provider'}\n </h2>\n <p className=\"cedros-settings-page-description\">\n Configure an OIDC identity provider for enterprise single sign-on.\n </p>\n </div>\n </div>\n\n {error && <ErrorMessage error={error} />}\n\n <div className=\"cedros-form-section\">\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-name\">\n Provider Name\n </label>\n <input\n id=\"sso-name\"\n type=\"text\"\n className=\"cedros-form-input\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g., Okta, Azure AD\"\n required\n />\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-issuer\">\n Issuer URL\n </label>\n <input\n id=\"sso-issuer\"\n type=\"url\"\n className=\"cedros-form-input\"\n value={issuerUrl}\n onChange={(e) => setIssuerUrl(e.target.value)}\n placeholder=\"https://your-org.okta.com\"\n required\n />\n <p className=\"cedros-form-hint\">\n The OIDC issuer URL. Must support discovery at /.well-known/openid-configuration\n </p>\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-client-id\">\n Client ID\n </label>\n <input\n id=\"sso-client-id\"\n type=\"text\"\n className=\"cedros-form-input\"\n value={clientId}\n onChange={(e) => setClientId(e.target.value)}\n placeholder=\"OAuth client ID\"\n required\n />\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-client-secret\">\n Client Secret{' '}\n {isEditing && (\n <span className=\"cedros-form-hint-inline\">(leave blank to keep current)</span>\n )}\n </label>\n <input\n id=\"sso-client-secret\"\n type=\"password\"\n className=\"cedros-form-input\"\n value={clientSecret}\n onChange={(e) => setClientSecret(e.target.value)}\n placeholder={isEditing ? '••••••••' : 'OAuth client secret'}\n required={!isEditing}\n />\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-email-domain\">\n Email Domain (optional)\n </label>\n <input\n id=\"sso-email-domain\"\n type=\"text\"\n className=\"cedros-form-input\"\n value={emailDomain}\n onChange={(e) => setEmailDomain(e.target.value)}\n placeholder=\"company.com\"\n />\n <p className=\"cedros-form-hint\">Restrict to users with emails from this domain</p>\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-checkbox\">\n <input\n type=\"checkbox\"\n checked={allowRegistration}\n onChange={(e) => setAllowRegistration(e.target.checked)}\n />\n <span>Allow new user registration via SSO</span>\n </label>\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-checkbox\">\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(e) => setEnabled(e.target.checked)}\n />\n <span>Enable this provider</span>\n </label>\n </div>\n </div>\n\n <div className=\"cedros-form-actions\">\n <button\n type=\"button\"\n className=\"cedros-btn cedros-btn-ghost\"\n onClick={onCancel}\n disabled={isLoading}\n >\n Cancel\n </button>\n <button type=\"submit\" className=\"cedros-btn cedros-btn-primary\" disabled={isLoading}>\n {isLoading ? 'Saving...' : isEditing ? 'Save Changes' : 'Add Provider'}\n </button>\n </div>\n </form>\n );\n}\n","/**\n * Drag-and-drop social button order settings with live preview.\n *\n * Uses HTML5 Drag and Drop API (no library needed for 4 items).\n * Reads enabled state from shared settings map (`auth_*_enabled` keys).\n */\nimport { useState, useCallback, useRef, type ReactNode } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SocialButtonOrderSettingsProps {\n /** Settings map (key -> SystemSetting[]) from useSettingsAutosave */\n settings: Record<string, { key: string; value: string }[]>;\n /** Autosave handler from parent */\n handleChange: (key: string, value: string) => void;\n}\n\ninterface ProviderMeta {\n label: string;\n icon: ReactNode;\n enabledKey: string;\n}\n\n// ---------------------------------------------------------------------------\n// Provider metadata + icons (matching existing button components)\n// ---------------------------------------------------------------------------\n\nfunction GoogleIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path 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\" fill=\"#4285F4\" />\n <path 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\" fill=\"#34A853\" />\n <path 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\" fill=\"#FBBC05\" />\n <path 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\" fill=\"#EA4335\" />\n </svg>\n );\n}\n\nfunction AppleIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z\" />\n </svg>\n );\n}\n\nfunction SolanaIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 128 128\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M25.38 96.04a4.35 4.35 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7l-17.71 17.72a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7l17.71-17.72z\" />\n <path d=\"M25.38 11.81a4.47 4.47 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7L103.96 31.96a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7L25.38 11.81z\" />\n <path d=\"M102.62 53.76a4.35 4.35 0 0 0-3.07-1.27H7.87c-1.93 0-2.9 2.34-1.54 3.7l17.71 17.72a4.35 4.35 0 0 0 3.07 1.27h91.68c1.93 0 2.9-2.34 1.54-3.7L102.62 53.76z\" />\n </svg>\n );\n}\n\nfunction PasskeyIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4\" />\n <path d=\"M14 13.12c0 2.38 0 6.38-1 8.88\" />\n <path d=\"M17.29 21.02c.12-.6.43-2.3.5-3.02\" />\n <path d=\"M2 12a10 10 0 0 1 18-6\" />\n <path d=\"M2 16h.01\" />\n <path d=\"M21.8 16c.2-2 .131-5.354 0-6\" />\n <path d=\"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2\" />\n <path d=\"M8.65 22c.21-.66.45-1.32.57-2\" />\n <path d=\"M9 6.8a6 6 0 0 1 9 5.2v2\" />\n </svg>\n );\n}\n\nconst PROVIDERS: Record<string, ProviderMeta> = {\n webauthn: { label: 'Passkey', icon: <PasskeyIcon />, enabledKey: 'auth_webauthn_enabled' },\n google: { label: 'Google', icon: <GoogleIcon />, enabledKey: 'auth_google_enabled' },\n apple: { label: 'Apple', icon: <AppleIcon />, enabledKey: 'auth_apple_enabled' },\n solana: { label: 'Solana', icon: <SolanaIcon />, enabledKey: 'auth_solana_enabled' },\n};\n\nconst DEFAULT_ORDER = ['webauthn', 'google', 'apple', 'solana'];\n\nconst PREVIEW_LABELS: Record<string, string> = {\n webauthn: 'Continue with Passkey',\n google: 'Continue with Google',\n apple: 'Continue with Apple',\n solana: 'Continue with Solana',\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Read whether a provider is enabled from the flattened settings. */\nfunction isProviderEnabled(\n settings: Record<string, { key: string; value: string }[]>,\n enabledKey: string,\n): boolean {\n for (const group of Object.values(settings)) {\n const found = group.find((s) => s.key === enabledKey);\n if (found) return found.value === 'true';\n }\n return true; // default enabled when setting is absent\n}\n\n/** Read current order from settings map, falling back to default. */\nfunction readOrder(settings: Record<string, { key: string; value: string }[]>): string[] {\n for (const group of Object.values(settings)) {\n const found = group.find((s) => s.key === 'ui_social_button_order');\n if (found && found.value) return found.value.split(',').map((s) => s.trim());\n }\n return DEFAULT_ORDER;\n}\n\n// ---------------------------------------------------------------------------\n// Grab-handle icon\n// ---------------------------------------------------------------------------\n\nfunction GrabHandle() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\" style={{ opacity: 0.4 }}>\n <circle cx=\"5\" cy=\"3\" r=\"1.5\" />\n <circle cx=\"11\" cy=\"3\" r=\"1.5\" />\n <circle cx=\"5\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"11\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"5\" cy=\"13\" r=\"1.5\" />\n <circle cx=\"11\" cy=\"13\" r=\"1.5\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function SocialButtonOrderSettings({ settings, handleChange }: SocialButtonOrderSettingsProps) {\n const [order, setOrder] = useState<string[]>(() => readOrder(settings));\n const dragIdx = useRef<number | null>(null);\n const [dragOverIdx, setDragOverIdx] = useState<number | null>(null);\n\n const persist = useCallback(\n (newOrder: string[]) => {\n setOrder(newOrder);\n handleChange('ui_social_button_order', newOrder.join(','));\n },\n [handleChange],\n );\n\n const onDragStart = useCallback((idx: number) => {\n dragIdx.current = idx;\n }, []);\n\n const onDragOver = useCallback((e: React.DragEvent, idx: number) => {\n e.preventDefault();\n setDragOverIdx(idx);\n }, []);\n\n const onDrop = useCallback(\n (targetIdx: number) => {\n const fromIdx = dragIdx.current;\n if (fromIdx === null || fromIdx === targetIdx) {\n setDragOverIdx(null);\n return;\n }\n const next = [...order];\n const [moved] = next.splice(fromIdx, 1);\n next.splice(targetIdx, 0, moved);\n persist(next);\n dragIdx.current = null;\n setDragOverIdx(null);\n },\n [order, persist],\n );\n\n const onDragEnd = useCallback(() => {\n dragIdx.current = null;\n setDragOverIdx(null);\n }, []);\n\n return (\n <div className=\"cedros-system-settings\">\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Button Order</h2>\n <p className=\"cedros-settings-page-description\">\n Drag to reorder the social login buttons on your sign-in form.\n </p>\n </div>\n </div>\n\n <div style={{ display: 'flex', gap: '2rem', flexWrap: 'wrap' }}>\n {/* Left: Reorder list */}\n <div style={{ flex: '1 1 260px', minWidth: 260 }}>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {order.map((id, idx) => {\n const meta = PROVIDERS[id];\n if (!meta) return null;\n const enabled = isProviderEnabled(settings, meta.enabledKey);\n const isDragOver = dragOverIdx === idx;\n return (\n <li\n key={id}\n draggable\n onDragStart={() => onDragStart(idx)}\n onDragOver={(e) => onDragOver(e, idx)}\n onDrop={() => onDrop(idx)}\n onDragEnd={onDragEnd}\n className=\"cedros-btn-order-item\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.75rem',\n padding: '0.625rem 0.75rem',\n borderRadius: 'var(--cedros-radius, 0.5rem)',\n border: isDragOver\n ? '2px solid var(--cedros-primary, #6366f1)'\n : '1px solid var(--cedros-border, #e5e7eb)',\n background: 'var(--cedros-background, #fff)',\n cursor: 'grab',\n opacity: enabled ? 1 : 0.5,\n transition: 'border-color 0.15s',\n }}\n >\n <GrabHandle />\n <span className=\"cedros-button-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n {meta.icon}\n </span>\n <span style={{ flex: 1, fontWeight: 500, fontSize: '0.875rem' }}>{meta.label}</span>\n <span\n style={{\n fontSize: '0.7rem',\n padding: '0.125rem 0.5rem',\n borderRadius: '9999px',\n background: enabled\n ? 'var(--cedros-primary, #6366f1)'\n : 'var(--cedros-muted, #f3f4f6)',\n color: enabled\n ? 'var(--cedros-primary-foreground, #fff)'\n : 'var(--cedros-muted-foreground, #6b7280)',\n }}\n >\n {enabled ? 'Enabled' : 'Disabled'}\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n\n {/* Right: Live preview */}\n <div style={{ flex: '1 1 280px', minWidth: 280 }}>\n <p style={{ fontSize: '0.75rem', color: 'var(--cedros-muted-foreground, #6b7280)', margin: '0 0 0.75rem' }}>\n This is how your login form buttons will appear:\n </p>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n padding: '1.25rem',\n borderRadius: 'var(--cedros-radius, 0.5rem)',\n border: '1px solid var(--cedros-border, #e5e7eb)',\n background: 'var(--cedros-background, #fff)',\n }}\n >\n {order.map((id) => {\n const meta = PROVIDERS[id];\n if (!meta) return null;\n const enabled = isProviderEnabled(settings, meta.enabledKey);\n if (!enabled) return null;\n return (\n <button\n key={id}\n type=\"button\"\n className=\"cedros-button cedros-button-social\"\n style={{ pointerEvents: 'none', width: '100%' }}\n tabIndex={-1}\n >\n <span className=\"cedros-button-icon\">{meta.icon}</span>\n {PREVIEW_LABELS[id]}\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Authentication settings page - configure auth providers with tabs\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';\nimport { SsoProvidersSettings } from './SsoProvidersSettings';\nimport { SocialButtonOrderSettings } from './SocialButtonOrderSettings';\n\ntype AuthTab = 'email' | 'google' | 'apple' | 'solana' | 'passkeys' | 'instantlink' | 'sso' | 'buttonorder' | 'postlogin';\n\ninterface TabConfig {\n id: AuthTab;\n label: string;\n /** Categories to pull settings from (not used for 'sso' tab) */\n categories: string[];\n /** Optional list of specific keys to show (if omitted, show all in categories) */\n keys?: string[];\n /** If true, renders a custom component instead of settings section */\n isCustom?: boolean;\n}\n\nconst TABS: TabConfig[] = [\n { id: 'email', label: 'Email', categories: ['auth.email'],\n keys: ['auth_email_enabled', 'auth_email_require_verification', 'auth_email_block_disposable'] },\n { id: 'google', label: 'Google', categories: ['auth.google'],\n keys: ['auth_google_enabled', 'auth_google_client_id'] },\n { id: 'apple', label: 'Apple', categories: ['auth.apple'],\n keys: ['auth_apple_enabled', 'auth_apple_client_id', 'auth_apple_team_id'] },\n { id: 'solana', label: 'Solana', categories: ['auth.solana'],\n keys: ['auth_solana_enabled', 'auth_solana_challenge_expiry'] },\n { id: 'passkeys', label: 'Passkeys', categories: ['auth.webauthn'],\n keys: ['auth_webauthn_enabled', 'auth_webauthn_rp_id', 'auth_webauthn_rp_name', 'auth_webauthn_rp_origin'] },\n { id: 'instantlink', label: 'Instant Link', categories: ['auth.instantlink'],\n keys: ['auth_instantlink_enabled', 'auth_instantlink_expiry', 'auth_instantlink_rate_limit'] },\n { id: 'sso', label: 'SSO Providers', categories: [], isCustom: true },\n { id: 'buttonorder', label: 'Button Order', categories: [], isCustom: true },\n { id: 'postlogin', label: 'Post-Login', categories: ['postlogin', 'postlogin.welcome', 'postlogin.username', 'postlogin.complete', 'postlogin.wallet'],\n keys: ['postlogin_redirect_url', 'postlogin_welcome_enabled', 'postlogin_welcome_route', 'postlogin_username_enabled', 'postlogin_complete_enabled', 'postlogin_wallet_enroll_enabled', 'postlogin_show_recovery_enabled'] },\n];\n\nexport interface AuthenticationSettingsProps {\n className?: string;\n}\n\nexport function AuthenticationSettings({ className }: AuthenticationSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n } = useSettingsAutosave();\n\n const [activeTab, setActiveTab] = useState<AuthTab>('email');\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get current tab config\n const currentTab = TABS.find((t) => t.id === activeTab);\n\n // Collect settings from all categories for the current tab\n const allTabSettings = useMemo(() => {\n if (!currentTab) return [];\n const allSettings: (typeof settings)[string] = [];\n for (const category of currentTab.categories) {\n const categorySettings = settings[category] ?? [];\n allSettings.push(...categorySettings);\n }\n return allSettings;\n }, [settings, currentTab]);\n\n const currentSettings = useMemo(() => {\n if (!currentTab?.keys) return allTabSettings;\n // Filter and sort by keys order\n return allTabSettings\n .filter((s) => currentTab.keys!.includes(s.key))\n .sort((a, b) => currentTab.keys!.indexOf(a.key) - currentTab.keys!.indexOf(b.key));\n }, [allTabSettings, 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\">Authentication</h2>\n <p className=\"cedros-settings-page-description\">\n Configure authentication providers and methods for user sign-in.\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 {TABS.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 {currentTab?.id === 'buttonorder' ? (\n <SocialButtonOrderSettings settings={settings} handleChange={handleChange} />\n ) : currentTab?.isCustom ? (\n <SsoProvidersSettings />\n ) : currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for {currentTab?.label ?? 'this provider'}.</p>\n </div>\n ) : (\n <SettingsSection settings={currentSettings} edits={edits} onChange={handleChange} />\n )}\n </div>\n </div>\n );\n}\n"],"names":["useSsoProviders","config","_internal","useCedrosLogin","serverUrl","getAccessTokenRef","useRef","providers","setProviders","useState","total","setTotal","isLoading","setIsLoading","error","setError","getHeaders","useCallback","token","fetchProviders","orgId","limit","offset","params","res","err","data","createProvider","input","provider","prev","updateProvider","id","p","deleteProvider","toggleProvider","enabled","SsoProvidersSettings","className","activeOrg","useOrgs","viewMode","setViewMode","editingProvider","setEditingProvider","formError","setFormError","useEffect","handleAdd","handleEdit","handleCancel","handleDelete","handleToggle","handleSave","jsx","LoadingSpinner","SsoProviderForm","jsxs","ErrorMessage","SsoProviderCard","onEdit","onDelete","onToggle","onSave","onCancel","isEditing","name","setName","issuerUrl","setIssuerUrl","clientId","setClientId","clientSecret","setClientSecret","emailDomain","setEmailDomain","allowRegistration","setAllowRegistration","setEnabled","handleSubmit","e","updates","GoogleIcon","AppleIcon","SolanaIcon","PasskeyIcon","PROVIDERS","DEFAULT_ORDER","PREVIEW_LABELS","isProviderEnabled","settings","enabledKey","group","found","s","readOrder","GrabHandle","SocialButtonOrderSettings","handleChange","order","setOrder","dragIdx","dragOverIdx","setDragOverIdx","persist","newOrder","onDragStart","idx","onDragOver","onDrop","targetIdx","fromIdx","next","moved","onDragEnd","meta","isDragOver","TABS","AuthenticationSettings","edits","autosaveStatus","autosaveError","fetchSettings","useSettingsAutosave","activeTab","setActiveTab","currentTab","t","allTabSettings","useMemo","allSettings","category","categorySettings","currentSettings","a","b","AutosaveStatus","tab","SettingsSection"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AuthenticationSettings-BBOjHR6j.cjs","sources":["../src/hooks/useSsoProviders.ts","../src/components/admin/settings/SsoProvidersSettings.tsx","../src/components/admin/settings/SocialButtonOrderSettings.tsx","../src/components/admin/settings/AuthenticationSettings.tsx"],"sourcesContent":["/**\n * Hook for managing SSO providers (admin)\n */\nimport { useState, useCallback, useRef } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\n\nexport interface SsoProvider {\n id: string;\n orgId: string;\n name: string;\n issuerUrl: string;\n clientId: string;\n scopes: string[];\n enabled: boolean;\n allowRegistration: boolean;\n emailDomain: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface CreateSsoProviderInput {\n orgId: string;\n name: string;\n issuerUrl: string;\n clientId: string;\n clientSecret: string;\n scopes?: string[];\n enabled?: boolean;\n allowRegistration?: boolean;\n emailDomain?: string | null;\n}\n\nexport interface UpdateSsoProviderInput {\n name?: string;\n issuerUrl?: string;\n clientId?: string;\n clientSecret?: string;\n scopes?: string[];\n enabled?: boolean;\n allowRegistration?: boolean;\n emailDomain?: string | null;\n}\n\ninterface ListResponse {\n providers: SsoProvider[];\n total: number;\n limit: number;\n offset: number;\n}\n\nexport function useSsoProviders() {\n const { config, _internal } = useCedrosLogin();\n const serverUrl = config.serverUrl;\n\n // PERF-03: Stabilize getAccessToken reference using ref pattern\n // to prevent unnecessary re-creation of callbacks\n const getAccessTokenRef = useRef(_internal?.getAccessToken ?? (() => null));\n getAccessTokenRef.current = _internal?.getAccessToken ?? (() => null);\n\n const [providers, setProviders] = useState<SsoProvider[]>([]);\n const [total, setTotal] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Memoize getHeaders with empty deps since it uses ref\n const getHeaders = useCallback(() => {\n const token = getAccessTokenRef.current();\n return {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n };\n }, []);\n\n const fetchProviders = useCallback(\n async (orgId?: string, limit = 50, offset = 0) => {\n setIsLoading(true);\n setError(null);\n try {\n const params = new URLSearchParams();\n if (orgId) params.set('org_id', orgId);\n params.set('limit', String(limit));\n params.set('offset', String(offset));\n\n const res = await fetch(`${serverUrl}/admin/sso-providers?${params}`, {\n headers: getHeaders(),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to fetch SSO providers: ${res.status}`);\n }\n\n const data: ListResponse = await res.json();\n setProviders(data.providers);\n setTotal(data.total);\n return data;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const createProvider = useCallback(\n async (input: CreateSsoProviderInput): Promise<SsoProvider> => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetch(`${serverUrl}/admin/sso-providers`, {\n method: 'POST',\n headers: getHeaders(),\n body: JSON.stringify(input),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to create SSO provider: ${res.status}`);\n }\n\n const provider: SsoProvider = await res.json();\n setProviders((prev) => [...prev, provider]);\n setTotal((prev) => prev + 1);\n return provider;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const updateProvider = useCallback(\n async (id: string, input: UpdateSsoProviderInput): Promise<SsoProvider> => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetch(`${serverUrl}/admin/sso-providers/${id}`, {\n method: 'PUT',\n headers: getHeaders(),\n body: JSON.stringify(input),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to update SSO provider: ${res.status}`);\n }\n\n const provider: SsoProvider = await res.json();\n setProviders((prev) => prev.map((p) => (p.id === id ? provider : p)));\n return provider;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const deleteProvider = useCallback(\n async (id: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n try {\n const res = await fetch(`${serverUrl}/admin/sso-providers/${id}`, {\n method: 'DELETE',\n headers: getHeaders(),\n });\n\n if (!res.ok) {\n const err = await res.json().catch(() => ({}));\n throw new Error(err.error || `Failed to delete SSO provider: ${res.status}`);\n }\n\n setProviders((prev) => prev.filter((p) => p.id !== id));\n setTotal((prev) => prev - 1);\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [serverUrl, getHeaders]\n );\n\n const toggleProvider = useCallback(\n async (id: string, enabled: boolean): Promise<SsoProvider> => {\n return updateProvider(id, { enabled });\n },\n [updateProvider]\n );\n\n return {\n providers,\n total,\n isLoading,\n error,\n fetchProviders,\n createProvider,\n updateProvider,\n deleteProvider,\n toggleProvider,\n };\n}\n","/**\n * SSO Providers settings - manage OIDC identity providers\n */\nimport { useState, useEffect, useCallback } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport {\n useSsoProviders,\n type SsoProvider,\n type CreateSsoProviderInput,\n type UpdateSsoProviderInput,\n} from '../../../hooks/useSsoProviders';\nimport { useOrgs } from '../../../hooks/useOrgs';\n\nexport interface SsoProvidersSettingsProps {\n className?: string;\n}\n\ntype ViewMode = 'list' | 'add' | 'edit';\n\nexport function SsoProvidersSettings({ className }: SsoProvidersSettingsProps) {\n const {\n providers,\n isLoading,\n error,\n fetchProviders,\n createProvider,\n updateProvider,\n deleteProvider,\n toggleProvider,\n } = useSsoProviders();\n\n const { activeOrg } = useOrgs();\n const [viewMode, setViewMode] = useState<ViewMode>('list');\n const [editingProvider, setEditingProvider] = useState<SsoProvider | null>(null);\n const [formError, setFormError] = useState<string | null>(null);\n\n useEffect(() => {\n fetchProviders(activeOrg?.id);\n }, [fetchProviders, activeOrg?.id]);\n\n const handleAdd = () => {\n setEditingProvider(null);\n setFormError(null);\n setViewMode('add');\n };\n\n const handleEdit = (provider: SsoProvider) => {\n setEditingProvider(provider);\n setFormError(null);\n setViewMode('edit');\n };\n\n const handleCancel = () => {\n setViewMode('list');\n setEditingProvider(null);\n setFormError(null);\n };\n\n const handleDelete = async (provider: SsoProvider) => {\n if (!confirm(`Delete SSO provider \"${provider.name}\"? This cannot be undone.`)) {\n return;\n }\n try {\n await deleteProvider(provider.id);\n } catch {\n // Error is already set in hook\n }\n };\n\n const handleToggle = async (provider: SsoProvider) => {\n try {\n await toggleProvider(provider.id, !provider.enabled);\n } catch {\n // Error is already set in hook\n }\n };\n\n const handleSave = async (data: CreateSsoProviderInput | UpdateSsoProviderInput) => {\n setFormError(null);\n try {\n if (viewMode === 'add') {\n await createProvider(data as CreateSsoProviderInput);\n } else if (editingProvider) {\n await updateProvider(editingProvider.id, data as UpdateSsoProviderInput);\n }\n setViewMode('list');\n setEditingProvider(null);\n } catch (err) {\n setFormError(err instanceof Error ? err.message : 'Failed to save provider');\n }\n };\n\n if (isLoading && providers.length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading SSO providers...</span>\n </div>\n );\n }\n\n if (viewMode === 'add' || viewMode === 'edit') {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <SsoProviderForm\n provider={editingProvider}\n orgId={activeOrg?.id}\n error={formError}\n isLoading={isLoading}\n onSave={handleSave}\n onCancel={handleCancel}\n />\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\">SSO Providers</h2>\n <p className=\"cedros-settings-page-description\">\n Configure OIDC identity providers for enterprise single sign-on.\n </p>\n </div>\n <button type=\"button\" className=\"cedros-btn cedros-btn-primary\" onClick={handleAdd}>\n Add Provider\n </button>\n </div>\n\n {error && <ErrorMessage error={error.message} />}\n\n {providers.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No SSO providers configured.</p>\n <p className=\"cedros-text-muted\">\n Add an OIDC provider like Okta, Azure AD, or Auth0 to enable enterprise SSO.\n </p>\n </div>\n ) : (\n <div className=\"cedros-sso-provider-list\">\n {providers.map((provider) => (\n <SsoProviderCard\n key={provider.id}\n provider={provider}\n onEdit={() => handleEdit(provider)}\n onDelete={() => handleDelete(provider)}\n onToggle={() => handleToggle(provider)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// =============================================================================\n// Provider Card\n// =============================================================================\n\ninterface SsoProviderCardProps {\n provider: SsoProvider;\n onEdit: () => void;\n onDelete: () => void;\n onToggle: () => void;\n}\n\nfunction SsoProviderCard({ provider, onEdit, onDelete, onToggle }: SsoProviderCardProps) {\n return (\n <div\n className={`cedros-sso-provider-card ${provider.enabled ? '' : 'cedros-sso-provider-card--disabled'}`}\n >\n <div className=\"cedros-sso-provider-card-header\">\n <div className=\"cedros-sso-provider-card-info\">\n <h3 className=\"cedros-sso-provider-card-name\">{provider.name}</h3>\n <p className=\"cedros-sso-provider-card-issuer\">{provider.issuerUrl}</p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={provider.enabled}\n className={`cedros-toggle ${provider.enabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={onToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">{provider.enabled ? 'Enabled' : 'Disabled'}</span>\n </button>\n </div>\n\n <div className=\"cedros-sso-provider-card-details\">\n <div className=\"cedros-sso-provider-card-detail\">\n <span className=\"cedros-sso-provider-card-detail-label\">Client ID</span>\n <code className=\"cedros-sso-provider-card-detail-value\">{provider.clientId}</code>\n </div>\n {provider.emailDomain && (\n <div className=\"cedros-sso-provider-card-detail\">\n <span className=\"cedros-sso-provider-card-detail-label\">Email Domain</span>\n <span className=\"cedros-sso-provider-card-detail-value\">@{provider.emailDomain}</span>\n </div>\n )}\n <div className=\"cedros-sso-provider-card-detail\">\n <span className=\"cedros-sso-provider-card-detail-label\">Registration</span>\n <span className=\"cedros-sso-provider-card-detail-value\">\n {provider.allowRegistration ? 'Allowed' : 'Existing users only'}\n </span>\n </div>\n </div>\n\n <div className=\"cedros-sso-provider-card-actions\">\n <button type=\"button\" className=\"cedros-btn cedros-btn-ghost\" onClick={onEdit}>\n Edit\n </button>\n <button\n type=\"button\"\n className=\"cedros-btn cedros-btn-ghost cedros-btn-danger\"\n onClick={onDelete}\n >\n Delete\n </button>\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// Provider Form\n// =============================================================================\n\ninterface SsoProviderFormProps {\n provider: SsoProvider | null;\n orgId?: string;\n error: string | null;\n isLoading: boolean;\n onSave: (data: CreateSsoProviderInput | UpdateSsoProviderInput) => void;\n onCancel: () => void;\n}\n\nfunction SsoProviderForm({\n provider,\n orgId,\n error,\n isLoading,\n onSave,\n onCancel,\n}: SsoProviderFormProps) {\n const isEditing = Boolean(provider);\n\n const [name, setName] = useState(provider?.name ?? '');\n const [issuerUrl, setIssuerUrl] = useState(provider?.issuerUrl ?? '');\n const [clientId, setClientId] = useState(provider?.clientId ?? '');\n const [clientSecret, setClientSecret] = useState('');\n const [emailDomain, setEmailDomain] = useState(provider?.emailDomain ?? '');\n const [allowRegistration, setAllowRegistration] = useState(provider?.allowRegistration ?? true);\n const [enabled, setEnabled] = useState(provider?.enabled ?? true);\n\n const handleSubmit = useCallback(\n (e: React.FormEvent) => {\n e.preventDefault();\n\n if (isEditing) {\n const updates: UpdateSsoProviderInput = {\n name,\n issuerUrl,\n clientId,\n emailDomain: emailDomain || null,\n allowRegistration,\n enabled,\n };\n // Only include secret if changed\n if (clientSecret) {\n updates.clientSecret = clientSecret;\n }\n onSave(updates);\n } else {\n if (!orgId) {\n return;\n }\n const data: CreateSsoProviderInput = {\n orgId,\n name,\n issuerUrl,\n clientId,\n clientSecret,\n emailDomain: emailDomain || null,\n allowRegistration,\n enabled,\n };\n onSave(data);\n }\n },\n [\n isEditing,\n orgId,\n name,\n issuerUrl,\n clientId,\n clientSecret,\n emailDomain,\n allowRegistration,\n enabled,\n onSave,\n ]\n );\n\n return (\n <form className=\"cedros-sso-provider-form\" onSubmit={handleSubmit}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">\n {isEditing ? 'Edit SSO Provider' : 'Add SSO Provider'}\n </h2>\n <p className=\"cedros-settings-page-description\">\n Configure an OIDC identity provider for enterprise single sign-on.\n </p>\n </div>\n </div>\n\n {error && <ErrorMessage error={error} />}\n\n <div className=\"cedros-form-section\">\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-name\">\n Provider Name\n </label>\n <input\n id=\"sso-name\"\n type=\"text\"\n className=\"cedros-form-input\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"e.g., Okta, Azure AD\"\n required\n />\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-issuer\">\n Issuer URL\n </label>\n <input\n id=\"sso-issuer\"\n type=\"url\"\n className=\"cedros-form-input\"\n value={issuerUrl}\n onChange={(e) => setIssuerUrl(e.target.value)}\n placeholder=\"https://your-org.okta.com\"\n required\n />\n <p className=\"cedros-form-hint\">\n The OIDC issuer URL. Must support discovery at /.well-known/openid-configuration\n </p>\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-client-id\">\n Client ID\n </label>\n <input\n id=\"sso-client-id\"\n type=\"text\"\n className=\"cedros-form-input\"\n value={clientId}\n onChange={(e) => setClientId(e.target.value)}\n placeholder=\"OAuth client ID\"\n required\n />\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-client-secret\">\n Client Secret{' '}\n {isEditing && (\n <span className=\"cedros-form-hint-inline\">(leave blank to keep current)</span>\n )}\n </label>\n <input\n id=\"sso-client-secret\"\n type=\"password\"\n className=\"cedros-form-input\"\n value={clientSecret}\n onChange={(e) => setClientSecret(e.target.value)}\n placeholder={isEditing ? '••••••••' : 'OAuth client secret'}\n required={!isEditing}\n />\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-label\" htmlFor=\"sso-email-domain\">\n Email Domain (optional)\n </label>\n <input\n id=\"sso-email-domain\"\n type=\"text\"\n className=\"cedros-form-input\"\n value={emailDomain}\n onChange={(e) => setEmailDomain(e.target.value)}\n placeholder=\"company.com\"\n />\n <p className=\"cedros-form-hint\">Restrict to users with emails from this domain</p>\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-checkbox\">\n <input\n type=\"checkbox\"\n checked={allowRegistration}\n onChange={(e) => setAllowRegistration(e.target.checked)}\n />\n <span>Allow new user registration via SSO</span>\n </label>\n </div>\n\n <div className=\"cedros-form-group\">\n <label className=\"cedros-form-checkbox\">\n <input\n type=\"checkbox\"\n checked={enabled}\n onChange={(e) => setEnabled(e.target.checked)}\n />\n <span>Enable this provider</span>\n </label>\n </div>\n </div>\n\n <div className=\"cedros-form-actions\">\n <button\n type=\"button\"\n className=\"cedros-btn cedros-btn-ghost\"\n onClick={onCancel}\n disabled={isLoading}\n >\n Cancel\n </button>\n <button type=\"submit\" className=\"cedros-btn cedros-btn-primary\" disabled={isLoading}>\n {isLoading ? 'Saving...' : isEditing ? 'Save Changes' : 'Add Provider'}\n </button>\n </div>\n </form>\n );\n}\n","/**\n * Drag-and-drop social button order settings with live preview.\n *\n * Uses HTML5 Drag and Drop API (no library needed for 4 items).\n * Reads enabled state from shared settings map (`auth_*_enabled` keys).\n */\nimport { useState, useCallback, useRef, type ReactNode } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface SocialButtonOrderSettingsProps {\n /** Settings map (key -> SystemSetting[]) from useSettingsAutosave */\n settings: Record<string, { key: string; value: string }[]>;\n /** Autosave handler from parent */\n handleChange: (key: string, value: string) => void;\n}\n\ninterface ProviderMeta {\n label: string;\n icon: ReactNode;\n enabledKey: string;\n}\n\n// ---------------------------------------------------------------------------\n// Provider metadata + icons (matching existing button components)\n// ---------------------------------------------------------------------------\n\nfunction GoogleIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\" aria-hidden=\"true\">\n <path 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\" fill=\"#4285F4\" />\n <path 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\" fill=\"#34A853\" />\n <path 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\" fill=\"#FBBC05\" />\n <path 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\" fill=\"#EA4335\" />\n </svg>\n );\n}\n\nfunction AppleIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M13 3.5c.73-.83 1.94-1.46 2.94-1.5.13 1.17-.34 2.35-1.04 3.19-.69.85-1.83 1.51-2.95 1.42-.15-1.15.41-2.35 1.05-3.11z\" />\n </svg>\n );\n}\n\nfunction SolanaIcon() {\n return (\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 128 128\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M25.38 96.04a4.35 4.35 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7l-17.71 17.72a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7l17.71-17.72z\" />\n <path d=\"M25.38 11.81a4.47 4.47 0 0 1 3.07-1.27h91.68c1.93 0 2.9 2.34 1.54 3.7L103.96 31.96a4.35 4.35 0 0 1-3.07 1.27H9.21c-1.93 0-2.9-2.34-1.54-3.7L25.38 11.81z\" />\n <path d=\"M102.62 53.76a4.35 4.35 0 0 0-3.07-1.27H7.87c-1.93 0-2.9 2.34-1.54 3.7l17.71 17.72a4.35 4.35 0 0 0 3.07 1.27h91.68c1.93 0 2.9-2.34 1.54-3.7L102.62 53.76z\" />\n </svg>\n );\n}\n\nfunction PasskeyIcon() {\n return (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M12 10a2 2 0 0 0-2 2c0 1.02-.1 2.51-.26 4\" />\n <path d=\"M14 13.12c0 2.38 0 6.38-1 8.88\" />\n <path d=\"M17.29 21.02c.12-.6.43-2.3.5-3.02\" />\n <path d=\"M2 12a10 10 0 0 1 18-6\" />\n <path d=\"M2 16h.01\" />\n <path d=\"M21.8 16c.2-2 .131-5.354 0-6\" />\n <path d=\"M5 19.5C5.5 18 6 15 6 12a6 6 0 0 1 .34-2\" />\n <path d=\"M8.65 22c.21-.66.45-1.32.57-2\" />\n <path d=\"M9 6.8a6 6 0 0 1 9 5.2v2\" />\n </svg>\n );\n}\n\nconst PROVIDERS: Record<string, ProviderMeta> = {\n webauthn: { label: 'Passkey', icon: <PasskeyIcon />, enabledKey: 'auth_webauthn_enabled' },\n google: { label: 'Google', icon: <GoogleIcon />, enabledKey: 'auth_google_enabled' },\n apple: { label: 'Apple', icon: <AppleIcon />, enabledKey: 'auth_apple_enabled' },\n solana: { label: 'Solana', icon: <SolanaIcon />, enabledKey: 'auth_solana_enabled' },\n};\n\nconst DEFAULT_ORDER = ['webauthn', 'google', 'apple', 'solana'];\n\nconst PREVIEW_LABELS: Record<string, string> = {\n webauthn: 'Continue with Passkey',\n google: 'Continue with Google',\n apple: 'Continue with Apple',\n solana: 'Continue with Solana',\n};\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Read whether a provider is enabled from the flattened settings. */\nfunction isProviderEnabled(\n settings: Record<string, { key: string; value: string }[]>,\n enabledKey: string,\n): boolean {\n for (const group of Object.values(settings)) {\n const found = group.find((s) => s.key === enabledKey);\n if (found) return found.value === 'true';\n }\n return true; // default enabled when setting is absent\n}\n\n/** Read current order from settings map, falling back to default. */\nfunction readOrder(settings: Record<string, { key: string; value: string }[]>): string[] {\n for (const group of Object.values(settings)) {\n const found = group.find((s) => s.key === 'ui_social_button_order');\n if (found && found.value) return found.value.split(',').map((s) => s.trim());\n }\n return DEFAULT_ORDER;\n}\n\n// ---------------------------------------------------------------------------\n// Grab-handle icon\n// ---------------------------------------------------------------------------\n\nfunction GrabHandle() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\" style={{ opacity: 0.4 }}>\n <circle cx=\"5\" cy=\"3\" r=\"1.5\" />\n <circle cx=\"11\" cy=\"3\" r=\"1.5\" />\n <circle cx=\"5\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"11\" cy=\"8\" r=\"1.5\" />\n <circle cx=\"5\" cy=\"13\" r=\"1.5\" />\n <circle cx=\"11\" cy=\"13\" r=\"1.5\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\nexport function SocialButtonOrderSettings({ settings, handleChange }: SocialButtonOrderSettingsProps) {\n const [order, setOrder] = useState<string[]>(() => readOrder(settings));\n const dragIdx = useRef<number | null>(null);\n const [dragOverIdx, setDragOverIdx] = useState<number | null>(null);\n\n const persist = useCallback(\n (newOrder: string[]) => {\n setOrder(newOrder);\n handleChange('ui_social_button_order', newOrder.join(','));\n },\n [handleChange],\n );\n\n const onDragStart = useCallback((idx: number) => {\n dragIdx.current = idx;\n }, []);\n\n const onDragOver = useCallback((e: React.DragEvent, idx: number) => {\n e.preventDefault();\n setDragOverIdx(idx);\n }, []);\n\n const onDrop = useCallback(\n (targetIdx: number) => {\n const fromIdx = dragIdx.current;\n if (fromIdx === null || fromIdx === targetIdx) {\n setDragOverIdx(null);\n return;\n }\n const next = [...order];\n const [moved] = next.splice(fromIdx, 1);\n next.splice(targetIdx, 0, moved);\n persist(next);\n dragIdx.current = null;\n setDragOverIdx(null);\n },\n [order, persist],\n );\n\n const onDragEnd = useCallback(() => {\n dragIdx.current = null;\n setDragOverIdx(null);\n }, []);\n\n return (\n <div className=\"cedros-system-settings\">\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Button Order</h2>\n <p className=\"cedros-settings-page-description\">\n Drag to reorder the social login buttons on your sign-in form.\n </p>\n </div>\n </div>\n\n <div style={{ display: 'flex', gap: '2rem', flexWrap: 'wrap' }}>\n {/* Left: Reorder list */}\n <div style={{ flex: '1 1 260px', minWidth: 260 }}>\n <ul style={{ listStyle: 'none', padding: 0, margin: 0, display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>\n {order.map((id, idx) => {\n const meta = PROVIDERS[id];\n if (!meta) return null;\n const enabled = isProviderEnabled(settings, meta.enabledKey);\n const isDragOver = dragOverIdx === idx;\n return (\n <li\n key={id}\n draggable\n onDragStart={() => onDragStart(idx)}\n onDragOver={(e) => onDragOver(e, idx)}\n onDrop={() => onDrop(idx)}\n onDragEnd={onDragEnd}\n className=\"cedros-btn-order-item\"\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '0.75rem',\n padding: '0.625rem 0.75rem',\n borderRadius: 'var(--cedros-radius, 0.5rem)',\n border: isDragOver\n ? '2px solid var(--cedros-primary, #6366f1)'\n : '1px solid var(--cedros-border, #e5e7eb)',\n background: 'var(--cedros-background, #fff)',\n cursor: 'grab',\n opacity: enabled ? 1 : 0.5,\n transition: 'border-color 0.15s',\n }}\n >\n <GrabHandle />\n <span className=\"cedros-button-icon\" style={{ display: 'flex', alignItems: 'center' }}>\n {meta.icon}\n </span>\n <span style={{ flex: 1, fontWeight: 500, fontSize: '0.875rem' }}>{meta.label}</span>\n <span\n style={{\n fontSize: '0.7rem',\n padding: '0.125rem 0.5rem',\n borderRadius: '9999px',\n background: enabled\n ? 'var(--cedros-primary, #6366f1)'\n : 'var(--cedros-muted, #f3f4f6)',\n color: enabled\n ? 'var(--cedros-primary-foreground, #fff)'\n : 'var(--cedros-muted-foreground, #6b7280)',\n }}\n >\n {enabled ? 'Enabled' : 'Disabled'}\n </span>\n </li>\n );\n })}\n </ul>\n </div>\n\n {/* Right: Live preview */}\n <div style={{ flex: '1 1 280px', minWidth: 280 }}>\n <p style={{ fontSize: '0.75rem', color: 'var(--cedros-muted-foreground, #6b7280)', margin: '0 0 0.75rem' }}>\n This is how your login form buttons will appear:\n </p>\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '0.5rem',\n padding: '1.25rem',\n borderRadius: 'var(--cedros-radius, 0.5rem)',\n border: '1px solid var(--cedros-border, #e5e7eb)',\n background: 'var(--cedros-background, #fff)',\n }}\n >\n {order.map((id) => {\n const meta = PROVIDERS[id];\n if (!meta) return null;\n const enabled = isProviderEnabled(settings, meta.enabledKey);\n if (!enabled) return null;\n return (\n <button\n key={id}\n type=\"button\"\n className=\"cedros-button cedros-button-social\"\n style={{ pointerEvents: 'none', width: '100%' }}\n tabIndex={-1}\n >\n <span className=\"cedros-button-icon\">{meta.icon}</span>\n {PREVIEW_LABELS[id]}\n </button>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n );\n}\n","/**\n * Authentication settings page - configure auth providers with tabs\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';\nimport { SsoProvidersSettings } from './SsoProvidersSettings';\nimport { SocialButtonOrderSettings } from './SocialButtonOrderSettings';\n\ntype AuthTab = 'email' | 'google' | 'apple' | 'solana' | 'passkeys' | 'instantlink' | 'sso' | 'buttonorder' | 'postlogin';\n\ninterface TabConfig {\n id: AuthTab;\n label: string;\n /** Categories to pull settings from (not used for 'sso' tab) */\n categories: string[];\n /** Optional list of specific keys to show (if omitted, show all in categories) */\n keys?: string[];\n /** If true, renders a custom component instead of settings section */\n isCustom?: boolean;\n}\n\nconst TABS: TabConfig[] = [\n { id: 'email', label: 'Email', categories: ['auth.email'],\n keys: ['auth_email_enabled', 'auth_email_require_verification', 'auth_email_block_disposable'] },\n { id: 'google', label: 'Google', categories: ['auth.google'],\n keys: ['auth_google_enabled', 'auth_google_client_id'] },\n { id: 'apple', label: 'Apple', categories: ['auth.apple'],\n keys: ['auth_apple_enabled', 'auth_apple_client_id', 'auth_apple_team_id'] },\n { id: 'solana', label: 'Solana', categories: ['auth.solana'],\n keys: ['auth_solana_enabled', 'auth_solana_challenge_expiry'] },\n { id: 'passkeys', label: 'Passkeys', categories: ['auth.webauthn'],\n keys: ['auth_webauthn_enabled', 'auth_webauthn_rp_id', 'auth_webauthn_rp_name', 'auth_webauthn_rp_origin'] },\n { id: 'instantlink', label: 'Instant Link', categories: ['auth.instantlink'],\n keys: ['auth_instantlink_enabled', 'auth_instantlink_expiry', 'auth_instantlink_rate_limit'] },\n { id: 'sso', label: 'SSO Providers', categories: [], isCustom: true },\n { id: 'buttonorder', label: 'Button Order', categories: [], isCustom: true },\n { id: 'postlogin', label: 'Post-Login', categories: ['postlogin', 'postlogin.welcome', 'postlogin.username', 'postlogin.complete', 'postlogin.wallet'],\n keys: ['postlogin_redirect_url', 'postlogin_welcome_enabled', 'postlogin_welcome_route', 'postlogin_username_enabled', 'postlogin_complete_enabled', 'postlogin_wallet_enroll_enabled', 'postlogin_show_recovery_enabled'] },\n];\n\nexport interface AuthenticationSettingsProps {\n className?: string;\n}\n\nexport function AuthenticationSettings({ className }: AuthenticationSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n } = useSettingsAutosave();\n\n const [activeTab, setActiveTab] = useState<AuthTab>('email');\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get current tab config\n const currentTab = TABS.find((t) => t.id === activeTab);\n\n // Collect settings from all categories for the current tab\n const allTabSettings = useMemo(() => {\n if (!currentTab) return [];\n const allSettings: (typeof settings)[string] = [];\n for (const category of currentTab.categories) {\n const categorySettings = settings[category] ?? [];\n allSettings.push(...categorySettings);\n }\n return allSettings;\n }, [settings, currentTab]);\n\n const currentSettings = useMemo(() => {\n if (!currentTab?.keys) return allTabSettings;\n // Filter and sort by keys order\n return allTabSettings\n .filter((s) => currentTab.keys!.includes(s.key))\n .sort((a, b) => currentTab.keys!.indexOf(a.key) - currentTab.keys!.indexOf(b.key));\n }, [allTabSettings, 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\">Authentication</h2>\n <p className=\"cedros-settings-page-description\">\n Configure authentication providers and methods for user sign-in.\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 {TABS.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 {currentTab?.id === 'buttonorder' ? (\n <SocialButtonOrderSettings settings={settings} handleChange={handleChange} />\n ) : currentTab?.isCustom ? (\n <SsoProvidersSettings />\n ) : currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No settings found for {currentTab?.label ?? 'this provider'}.</p>\n </div>\n ) : (\n <SettingsSection settings={currentSettings} edits={edits} onChange={handleChange} />\n )}\n </div>\n </div>\n );\n}\n"],"names":["useSsoProviders","config","_internal","useCedrosLogin","serverUrl","getAccessTokenRef","useRef","providers","setProviders","useState","total","setTotal","isLoading","setIsLoading","error","setError","getHeaders","useCallback","token","fetchProviders","orgId","limit","offset","params","res","err","data","createProvider","input","provider","prev","updateProvider","id","p","deleteProvider","toggleProvider","enabled","SsoProvidersSettings","className","activeOrg","useOrgs","viewMode","setViewMode","editingProvider","setEditingProvider","formError","setFormError","useEffect","handleAdd","handleEdit","handleCancel","handleDelete","handleToggle","handleSave","jsx","LoadingSpinner","SsoProviderForm","jsxs","ErrorMessage","SsoProviderCard","onEdit","onDelete","onToggle","onSave","onCancel","isEditing","name","setName","issuerUrl","setIssuerUrl","clientId","setClientId","clientSecret","setClientSecret","emailDomain","setEmailDomain","allowRegistration","setAllowRegistration","setEnabled","handleSubmit","e","updates","GoogleIcon","AppleIcon","SolanaIcon","PasskeyIcon","PROVIDERS","DEFAULT_ORDER","PREVIEW_LABELS","isProviderEnabled","settings","enabledKey","group","found","s","readOrder","GrabHandle","SocialButtonOrderSettings","handleChange","order","setOrder","dragIdx","dragOverIdx","setDragOverIdx","persist","newOrder","onDragStart","idx","onDragOver","onDrop","targetIdx","fromIdx","next","moved","onDragEnd","meta","isDragOver","TABS","AuthenticationSettings","edits","autosaveStatus","autosaveError","fetchSettings","useSettingsAutosave","activeTab","setActiveTab","currentTab","t","allTabSettings","useMemo","allSettings","category","categorySettings","currentSettings","a","b","AutosaveStatus","tab","SettingsSection"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime");require("react");const e=require("./AuthenticationSettings-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react/jsx-runtime");require("react");const e=require("./AuthenticationSettings-BBOjHR6j.cjs");function i(){return t.jsx("div",{className:"cedros-dashboard__section",children:t.jsx(e.AuthenticationSettings,{})})}exports.default=i;
|
package/dist/{AuthenticationSettings-BlYOmaEG.cjs.map → AuthenticationSettings-BXZRBZqc.cjs.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuthenticationSettings-
|
|
1
|
+
{"version":3,"file":"AuthenticationSettings-BXZRBZqc.cjs","sources":["../src/admin/sections/AuthenticationSettings.tsx"],"sourcesContent":["/**\n * Authentication Settings Section - Plugin wrapper\n */\n\nimport React from 'react';\nimport { AuthenticationSettings as Settings } from '../../components/admin/settings';\n\nexport default function AuthenticationSettings(): React.JSX.Element {\n return (\n <div className=\"cedros-dashboard__section\">\n <Settings />\n </div>\n );\n}\n"],"names":["AuthenticationSettings","jsx","Settings"],"mappings":"+LAOA,SAAwBA,GAA4C,CAClE,aACG,MAAA,CAAI,UAAU,4BACb,SAAAC,MAACC,EAAAA,yBAAS,EACZ,CAEJ"}
|
|
@@ -2,7 +2,7 @@ import { jsxs as s, jsx as e } from "react/jsx-runtime";
|
|
|
2
2
|
import { useRef as M, useState as y, useCallback as _, useEffect as $, useMemo as O } from "react";
|
|
3
3
|
import { L } from "./LoadingSpinner-6vml-zwr.js";
|
|
4
4
|
import { E as D } from "./ErrorMessage-CcEK0pYO.js";
|
|
5
|
-
import { u as T, A as j, S as F } from "./AutosaveStatus-
|
|
5
|
+
import { u as T, A as j, S as F } from "./AutosaveStatus-DhGM3UUx.js";
|
|
6
6
|
import { u as z } from "./useCedrosLogin-CFfID-0i.js";
|
|
7
7
|
import { u as B } from "./useOrgs-C90KT9KP.js";
|
|
8
8
|
function U() {
|