ultisuite-client/components/admin/settings/sections/authentication-section.tsx
R3D347HR4Y 8f81d7aba1
Some checks are pending
E2E / Playwright e2e (push) Waiting to run
feat(admin-settings): refactor admin settings components for improved usability and consistency
- Replaced legacy components with new `SettingsCard`, `SettingsField`, and `SettingsToggleRow` for a unified design.
- Enhanced `AdminListControls` to support compact mode and improved pagination controls.
- Updated various sections including `AiAssistantSection`, `AuthenticationSection`, and `DriveMountOAuthSection` to utilize new components, streamlining the settings interface.
- Improved accessibility and user experience across admin settings with clearer labels and hints.
- Deprecated old components while maintaining backward compatibility for existing admin sections.
2026-06-15 11:10:17 +02:00

129 lines
5.0 KiB
TypeScript

"use client"
import { useCallback, useRef } from "react"
import { OrgSettingsSection } from "@/components/admin/settings/org-settings-form"
import {
SettingsCard,
SettingsField,
SettingsGrid,
SettingsToggleRow,
} from "@/components/settings/settings-kit"
import { IdentityProvidersPanel } from "@/components/admin/settings/sections/identity-providers-section"
import { AutomationTabMasonry } from "@/components/gmail/settings/automation/automation-tab-masonry"
import { DeployLockedHint, useDeployFieldLocked } from "@/components/admin/settings/deploy-locked-hint"
import { useOrgSettingsStore } from "@/lib/admin-settings/org-settings-store"
import { Input } from "@/components/ui/input"
import { Switch } from "@/components/ui/switch"
export function AuthenticationSection() {
const authentik = useOrgSettingsStore((s) => s.authentik)
const setAuthentik = useOrgSettingsStore((s) => s.setAuthentik)
const effective = useOrgSettingsStore((s) => s.meta?.effective.authentik)
const enabledLocked = useDeployFieldLocked("authentik", "enabled")
const apiLocked = useDeployFieldLocked("authentik", "api_url")
const clientLocked = useDeployFieldLocked("authentik", "client_id")
const enabled = enabledLocked ? (effective?.enabled ?? authentik.enabled) : authentik.enabled
const apiURL = apiLocked ? (effective?.api_url ?? authentik.api_url) : authentik.api_url
const clientID = clientLocked ? (effective?.client_id ?? authentik.client_id) : authentik.client_id
const identityBeforeSaveRef = useRef<(() => void) | null>(null)
const registerIdentityBeforeSave = useCallback((fn: (() => void) | null) => {
identityBeforeSaveRef.current = fn
}, [])
return (
<OrgSettingsSection
title="Authentification"
description="SSO Authentik, provisionnement des comptes Ultimail et fournisseurs d'identité upstream."
policySection={["authentik", "identity_providers"]}
beforeSave={async () => {
identityBeforeSaveRef.current?.()
}}
>
<AutomationTabMasonry columns={2}>
<SettingsCard
title="Authentik"
description="Connexion via le fournisseur d'identité organisationnel."
hint={enabledLocked ? <DeployLockedHint section="authentik" field="enabled" /> : null}
action={
<Switch
checked={enabled}
disabled={enabledLocked}
onCheckedChange={(v) => setAuthentik({ enabled: v })}
/>
}
>
<SettingsField
label="URL API Authentik"
hint={apiLocked ? <DeployLockedHint section="authentik" field="api_url" /> : undefined}
>
<Input
className="h-9"
value={apiURL}
disabled={apiLocked}
onChange={(e) => setAuthentik({ api_url: e.target.value })}
placeholder="https://auth.example.com/api/v3"
/>
</SettingsField>
<SettingsGrid columns={1}>
<SettingsField label="Slug application">
<Input
className="h-9"
value={authentik.slug}
onChange={(e) => setAuthentik({ slug: e.target.value })}
/>
</SettingsField>
<SettingsField
label="Client ID OIDC"
hint={
clientLocked ? <DeployLockedHint section="authentik" field="client_id" /> : undefined
}
>
<Input
className="h-9"
value={clientID}
disabled={clientLocked}
onChange={(e) => setAuthentik({ client_id: e.target.value })}
/>
</SettingsField>
</SettingsGrid>
<SettingsField label="Groupes par défaut (séparés par des virgules)">
<Input
className="h-9"
value={authentik.default_groups}
onChange={(e) => setAuthentik({ default_groups: e.target.value })}
/>
</SettingsField>
<SettingsToggleRow
title="Forcer le SSO"
description="Désactive la connexion locale sauf pour les administrateurs."
checked={authentik.enforce_sso}
onCheckedChange={(enforce_sso) => setAuthentik({ enforce_sso })}
/>
<SettingsToggleRow
title="Mot de passe local de secours"
description="Autoriser un fallback mot de passe si Authentik est indisponible."
checked={authentik.allow_password_fallback}
onCheckedChange={(allow_password_fallback) =>
setAuthentik({ allow_password_fallback })
}
/>
</SettingsCard>
<SettingsCard
title="Fournisseurs d'identité"
description="Sources upstream Authentik (OAuth, SAML, LDAP) avec restrictions d'accès."
>
<IdentityProvidersPanel onRegisterBeforeSave={registerIdentityBeforeSave} />
</SettingsCard>
</AutomationTabMasonry>
</OrgSettingsSection>
)
}