Some checks are pending
E2E / Playwright e2e (push) Waiting to run
- Updated login and signup components to utilize AuthCard for better user experience during redirection. - Introduced AuthentikEmbedDialog for seamless integration of Authentik's identity portal within the application. - Enhanced password recovery and signup flows with dynamic theme handling and improved loading states. - Refactored existing components to streamline authentication processes and improve maintainability.
205 lines
8.2 KiB
TypeScript
205 lines
8.2 KiB
TypeScript
"use client"
|
|
|
|
import { useEffect, useState } from "react"
|
|
import { OrgSettingsSection } from "@/components/admin/settings/org-settings-form"
|
|
import {
|
|
SettingsCard,
|
|
SettingsField,
|
|
SettingsGrid,
|
|
SettingsHint,
|
|
SettingsToggleRow,
|
|
} from "@/components/settings/settings-kit"
|
|
import { AutomationTabMasonry } from "@/components/gmail/settings/automation/automation-tab-masonry"
|
|
import { useOrgSettingsStore } from "@/lib/admin-settings/org-settings-store"
|
|
import { Input } from "@/components/ui/input"
|
|
import {
|
|
InputGroup,
|
|
InputGroupAddon,
|
|
InputGroupInput,
|
|
InputGroupText,
|
|
} from "@/components/ui/input-group"
|
|
import { Textarea } from "@/components/ui/textarea"
|
|
import {
|
|
Select,
|
|
SelectContent,
|
|
SelectItem,
|
|
SelectTrigger,
|
|
SelectValue,
|
|
} from "@/components/ui/select"
|
|
import { DriveOrgFoldersSection } from "@/components/admin/settings/sections/drive-org-section"
|
|
import { DriveOrgWebDAVSection } from "@/components/admin/settings/sections/drive-org-webdav-section"
|
|
import { DriveMountOAuthSection } from "@/components/admin/settings/sections/drive-mount-oauth-section"
|
|
|
|
export function FilePoliciesSection() {
|
|
const filePolicies = useOrgSettingsStore((s) => s.filePolicies)
|
|
const setFilePolicies = useOrgSettingsStore((s) => s.setFilePolicies)
|
|
const [mountOAuthDraft, setMountOAuthDraft] = useState(filePolicies.mount_oauth)
|
|
const vtKeyConfigured = useOrgSettingsStore(
|
|
(s) => s.meta?.secrets?.virustotal_api_key?.configured ?? false
|
|
)
|
|
const vtKeyMissing =
|
|
filePolicies.virus_scan_enabled &&
|
|
!vtKeyConfigured &&
|
|
!(filePolicies.virustotal_api_key ?? "").trim()
|
|
|
|
useEffect(() => {
|
|
setMountOAuthDraft(filePolicies.mount_oauth)
|
|
}, [filePolicies.mount_oauth])
|
|
|
|
return (
|
|
<OrgSettingsSection
|
|
title="Politiques fichiers"
|
|
description="Règles d'upload, partage externe et rétention pour UltiDrive."
|
|
policySection="file_policies"
|
|
beforeSave={() => setFilePolicies({ mount_oauth: mountOAuthDraft })}
|
|
>
|
|
<AutomationTabMasonry columns={2}>
|
|
<SettingsCard
|
|
title="Politiques UltiDrive"
|
|
description="Limites d'upload, partage externe, extensions et analyse antivirus."
|
|
>
|
|
<SettingsGrid columns={1} className="space-y-4">
|
|
<SettingsGrid columns={2} className="sm:grid-cols-3">
|
|
<SettingsField label="Taille max upload">
|
|
<InputGroup className="w-fit max-w-full">
|
|
<InputGroupInput
|
|
type="number"
|
|
min={1}
|
|
className="w-20 flex-none tabular-nums"
|
|
value={filePolicies.max_upload_mib}
|
|
onChange={(e) =>
|
|
setFilePolicies({ max_upload_mib: Number(e.target.value) || 1 })
|
|
}
|
|
/>
|
|
<InputGroupAddon align="inline-end">
|
|
<InputGroupText>Mo</InputGroupText>
|
|
</InputGroupAddon>
|
|
</InputGroup>
|
|
</SettingsField>
|
|
<SettingsField label="Expiration liens par défaut">
|
|
<InputGroup className="w-fit max-w-full">
|
|
<InputGroupInput
|
|
type="number"
|
|
min={1}
|
|
className="w-20 flex-none tabular-nums"
|
|
value={filePolicies.default_link_expiry_days}
|
|
onChange={(e) =>
|
|
setFilePolicies({
|
|
default_link_expiry_days: Number(e.target.value) || 1,
|
|
})
|
|
}
|
|
/>
|
|
<InputGroupAddon align="inline-end">
|
|
<InputGroupText>jours</InputGroupText>
|
|
</InputGroupAddon>
|
|
</InputGroup>
|
|
</SettingsField>
|
|
<SettingsField label="Rétention corbeille">
|
|
<InputGroup className="w-fit max-w-full">
|
|
<InputGroupInput
|
|
type="number"
|
|
min={1}
|
|
className="w-20 flex-none tabular-nums"
|
|
value={filePolicies.retention_trash_days}
|
|
onChange={(e) =>
|
|
setFilePolicies({ retention_trash_days: Number(e.target.value) || 1 })
|
|
}
|
|
/>
|
|
<InputGroupAddon align="inline-end">
|
|
<InputGroupText>jours</InputGroupText>
|
|
</InputGroupAddon>
|
|
</InputGroup>
|
|
</SettingsField>
|
|
</SettingsGrid>
|
|
<SettingsField label="Partage externe">
|
|
<Select
|
|
value={filePolicies.external_sharing}
|
|
onValueChange={(external_sharing) =>
|
|
setFilePolicies({
|
|
external_sharing: external_sharing as typeof filePolicies.external_sharing,
|
|
})
|
|
}
|
|
>
|
|
<SelectTrigger className="h-9 w-full min-w-0">
|
|
<SelectValue />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="disabled">Désactivé</SelectItem>
|
|
<SelectItem value="authenticated">Utilisateurs authentifiés</SelectItem>
|
|
<SelectItem value="public_link">Liens publics autorisés</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
</SettingsField>
|
|
<SettingsField label="Extensions autorisées (vide = toutes)">
|
|
<Textarea
|
|
className="min-h-[80px] font-mono text-xs"
|
|
value={filePolicies.allowed_extensions}
|
|
onChange={(e) => setFilePolicies({ allowed_extensions: e.target.value })}
|
|
placeholder="pdf, docx, png, jpg"
|
|
/>
|
|
</SettingsField>
|
|
</SettingsGrid>
|
|
|
|
<SettingsToggleRow
|
|
title="Bloquer les exécutables"
|
|
description="exe, bat, sh, app, etc."
|
|
checked={filePolicies.block_executable}
|
|
onCheckedChange={(block_executable) => setFilePolicies({ block_executable })}
|
|
/>
|
|
|
|
<SettingsToggleRow
|
|
title="Analyse antivirus à l'upload"
|
|
description="VirusTotal — scan synchrone à l'upload Drive et pièces jointes mail"
|
|
checked={filePolicies.virus_scan_enabled}
|
|
onCheckedChange={(virus_scan_enabled) => setFilePolicies({ virus_scan_enabled })}
|
|
/>
|
|
|
|
{filePolicies.virus_scan_enabled ? (
|
|
<SettingsField label="Clé API VirusTotal">
|
|
<Input
|
|
className="h-9"
|
|
type="password"
|
|
autoComplete="off"
|
|
value={filePolicies.virustotal_api_key ?? ""}
|
|
onChange={(e) => setFilePolicies({ virustotal_api_key: e.target.value })}
|
|
placeholder={
|
|
vtKeyConfigured ? "•••••••• (laisser vide pour conserver)" : "Coller la clé API"
|
|
}
|
|
/>
|
|
{vtKeyConfigured && !(filePolicies.virustotal_api_key ?? "").trim() ? (
|
|
<SettingsHint>Clé configurée</SettingsHint>
|
|
) : null}
|
|
{vtKeyMissing ? (
|
|
<SettingsHint tone="warning">
|
|
Analyse activée sans clé API — les uploads ne seront pas scannés.
|
|
</SettingsHint>
|
|
) : null}
|
|
</SettingsField>
|
|
) : null}
|
|
</SettingsCard>
|
|
|
|
<SettingsCard
|
|
title="Connexion cloud (OAuth)"
|
|
description="Permet aux utilisateurs de monter Google Drive, Dropbox ou OneDrive depuis UltiDrive."
|
|
>
|
|
<DriveMountOAuthSection draft={mountOAuthDraft} onChange={setMountOAuthDraft} embedded />
|
|
</SettingsCard>
|
|
|
|
<SettingsCard
|
|
title="Montages WebDAV d'organisation"
|
|
description="Serveur WebDAV partagé (NAS, Nextcloud externe) visible par tous les utilisateurs UltiDrive."
|
|
>
|
|
<DriveOrgWebDAVSection embedded />
|
|
</SettingsCard>
|
|
|
|
<SettingsCard
|
|
title="Dossiers d'organisation"
|
|
description="Espaces de stockage internes (group folders Nextcloud) liés aux organisations Authentik."
|
|
>
|
|
<DriveOrgFoldersSection embedded />
|
|
</SettingsCard>
|
|
</AutomationTabMasonry>
|
|
</OrgSettingsSection>
|
|
)
|
|
}
|