Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Introduced new components for managing admin settings, including AdminListControls, AdminSettingsCard, and TechBrandSelectLabel. - Implemented dynamic loading for admin settings sections to optimize performance. - Enhanced the layout of various admin settings sections for better user experience. - Updated the AiAssistantSection to include LLM provider management and improved model selection. - Refactored authentication settings to streamline configuration and improve accessibility.
145 lines
6.2 KiB
TypeScript
145 lines
6.2 KiB
TypeScript
"use client"
|
|
|
|
import { useCallback, useRef } from "react"
|
|
import { OrgSettingsSection } from "@/components/admin/settings/org-settings-form"
|
|
import { AdminSettingsCard } from "@/components/admin/settings/admin-settings-card"
|
|
import { FieldGroup } from "@/components/admin/settings/field-group"
|
|
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 { Card, CardContent } from "@/components/ui/card"
|
|
import { Input } from "@/components/ui/input"
|
|
import { Label } from "@/components/ui/label"
|
|
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}>
|
|
<Card className="gap-0 py-0">
|
|
<CardContent className="py-4">
|
|
<div className="flex items-start gap-4">
|
|
<div className="min-w-0 flex-1">
|
|
<p className="font-medium">Authentik</p>
|
|
<p className="mt-1 text-sm text-muted-foreground">
|
|
Connexion via le fournisseur d'identité organisationnel.
|
|
</p>
|
|
{enabledLocked ? <DeployLockedHint section="authentik" field="enabled" /> : null}
|
|
</div>
|
|
<Switch
|
|
checked={enabled}
|
|
disabled={enabledLocked}
|
|
onCheckedChange={(v) => setAuthentik({ enabled: v })}
|
|
/>
|
|
</div>
|
|
|
|
<div className="mt-4 space-y-4 border-t pt-4">
|
|
<FieldGroup>
|
|
<Label>URL API Authentik</Label>
|
|
<Input
|
|
className="h-9"
|
|
value={apiURL}
|
|
disabled={apiLocked}
|
|
onChange={(e) => setAuthentik({ api_url: e.target.value })}
|
|
placeholder="https://auth.example.com/api/v3"
|
|
/>
|
|
{apiLocked ? <DeployLockedHint section="authentik" field="api_url" /> : null}
|
|
</FieldGroup>
|
|
|
|
<div className="grid min-w-0 gap-4">
|
|
<FieldGroup>
|
|
<Label>Slug application</Label>
|
|
<Input
|
|
className="h-9"
|
|
value={authentik.slug}
|
|
onChange={(e) => setAuthentik({ slug: e.target.value })}
|
|
/>
|
|
</FieldGroup>
|
|
<FieldGroup>
|
|
<Label>Client ID OIDC</Label>
|
|
<Input
|
|
className="h-9"
|
|
value={clientID}
|
|
disabled={clientLocked}
|
|
onChange={(e) => setAuthentik({ client_id: e.target.value })}
|
|
/>
|
|
{clientLocked ? <DeployLockedHint section="authentik" field="client_id" /> : null}
|
|
</FieldGroup>
|
|
</div>
|
|
|
|
<FieldGroup>
|
|
<Label>Groupes par défaut (séparés par des virgules)</Label>
|
|
<Input
|
|
className="h-9"
|
|
value={authentik.default_groups}
|
|
onChange={(e) => setAuthentik({ default_groups: e.target.value })}
|
|
/>
|
|
</FieldGroup>
|
|
|
|
<label className="flex items-center justify-between gap-4 rounded-lg border p-3">
|
|
<FieldGroup>
|
|
<p className="text-sm font-medium">Forcer le SSO</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
Désactive la connexion locale sauf pour les administrateurs.
|
|
</p>
|
|
</FieldGroup>
|
|
<Switch
|
|
checked={authentik.enforce_sso}
|
|
onCheckedChange={(enforce_sso) => setAuthentik({ enforce_sso })}
|
|
/>
|
|
</label>
|
|
|
|
<label className="flex items-center justify-between gap-4 rounded-lg border p-3">
|
|
<FieldGroup>
|
|
<p className="text-sm font-medium">Mot de passe local de secours</p>
|
|
<p className="text-xs text-muted-foreground">
|
|
Autoriser un fallback mot de passe si Authentik est indisponible.
|
|
</p>
|
|
</FieldGroup>
|
|
<Switch
|
|
checked={authentik.allow_password_fallback}
|
|
onCheckedChange={(allow_password_fallback) =>
|
|
setAuthentik({ allow_password_fallback })
|
|
}
|
|
/>
|
|
</label>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<AdminSettingsCard
|
|
title="Fournisseurs d'identité"
|
|
description="Sources upstream Authentik (OAuth, SAML, LDAP) avec restrictions d'accès."
|
|
>
|
|
<IdentityProvidersPanel onRegisterBeforeSave={registerIdentityBeforeSave} />
|
|
</AdminSettingsCard>
|
|
</AutomationTabMasonry>
|
|
</OrgSettingsSection>
|
|
)
|
|
}
|