import { useEffect, useState } from "react"; import { Button, DismissibleAlert, hasScope, useGuardedNavigate, usePlatformModuleInstalled } from "@govoplan/core-webui"; import type { ApiSettings, AuthInfo } from "../../../types"; import { getCampaignArchiveEncryptionPolicy, type CampaignArchiveEncryptionPolicy } from "../../../api/campaigns"; export const UNAVAILABLE_ARCHIVE_POLICY: CampaignArchiveEncryptionPolicy = { available: false, allowed_password_encryption_methods: ["aes"], allowed_password_delivery_channels: ["separate_mail", "sms", "letter", "phone", "in_person"], policy_hash: "", source_path: [], reason: "Archive-encryption policy is loading. Legacy ZipCrypto remains blocked.", diagnostics: [], legacy_label: "Legacy ZipCrypto — Windows-compatible, weak encryption" }; export default function CampaignArchiveEncryptionPolicyNotice({ settings, auth, campaignId, onPolicyChange }: { settings: ApiSettings; auth: AuthInfo; campaignId: string; onPolicyChange?: (policy: CampaignArchiveEncryptionPolicy) => void; }) { const navigate = useGuardedNavigate(); const policyInstalled = usePlatformModuleInstalled("policy"); const [policy, setPolicy] = useState(UNAVAILABLE_ARCHIVE_POLICY); const [loading, setLoading] = useState(true); const [refresh, setRefresh] = useState(0); const allowed = policy.available && policy.allowed_password_encryption_methods.includes("zip_standard"); const canReadPolicy = policyInstalled && hasScope(auth, "admin:policies:read"); const canUseLegacy = hasScope(auth, "campaigns:archive:use_legacy_zipcrypto"); useEffect(() => { let cancelled = false; setLoading(true); setPolicy(UNAVAILABLE_ARCHIVE_POLICY); void getCampaignArchiveEncryptionPolicy(settings, campaignId) .then((loaded) => { if (!cancelled) setPolicy(loaded); }) .catch((cause) => { if (!cancelled) setPolicy({ ...UNAVAILABLE_ARCHIVE_POLICY, reason: cause instanceof Error ? cause.message : String(cause) }); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [campaignId, refresh, settings.accessToken, settings.apiBaseUrl, settings.apiKey]); useEffect(() => { onPolicyChange?.(policy); }, [onPolicyChange, policy]); return {policy.legacy_label}: {policy.reason} {policy.source_path.length > 0 &&

{policy.source_path.map((step) => step.label).join(" → ")}

}

i18n:govoplan-campaign.archive_policy_enable_guidance

{!canUseLegacy &&

i18n:govoplan-campaign.archive_policy_permission_missing

} {!policyInstalled &&

i18n:govoplan-campaign.archive_policy_module_missing

} {canReadPolicy && } {canReadPolicy && }
; }