"use client" import { useEffect, useMemo, useState } from "react" import type { IpsecCertBundle } from "@mmapp/contracts/ipsec" import { FormField, SectionTitle } from "@/components/form-kit" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose, } from "@/components/ui/sheet" import { toast } from "sonner" import { DownloadIcon, CopyIcon, RefreshCwIcon } from "lucide-react" function downloadBlob(filename: string, blob: Blob) { const url = URL.createObjectURL(blob) const a = document.createElement("a") a.href = url a.download = filename a.click() URL.revokeObjectURL(url) } function downloadText(filename: string, content: string) { downloadBlob(filename, new Blob([content], { type: "text/plain;charset=utf-8" })) } function downloadB64(filename: string, b64: string, mime: string) { const bin = atob(b64) const bytes = new Uint8Array(bin.length) for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i) downloadBlob(filename, new Blob([bytes], { type: mime })) } function randomPassphrase(): string { const bytes = new Uint8Array(9) crypto.getRandomValues(bytes) let s = "" for (const b of bytes) s += "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789"[b % 56] return s } function IpsecCertSheet({ open, onOpenChange, bundle, busy, onReexport, }: { open: boolean onOpenChange: (v: boolean) => void bundle: IpsecCertBundle | null busy?: boolean /** Перекачка с новой passphrase (серийник ключа остаётся на роутере). */ onReexport?: (passphrase: string) => void | Promise }) { const [passphrase, setPassphrase] = useState("") useEffect(() => { if (!open) return const initial = bundle?.passphrase ?? "" queueMicrotask(() => setPassphrase(initial)) }, [open, bundle]) const canDownload = useMemo(() => Boolean(bundle && passphrase.trim().length >= 4), [bundle, passphrase]) return ( Сертификат клиента {bundle ? `«${bundle.user}»` : ""} .p12 для Windows/macOS/iOS · .sswan для strongSwan (Android/iOS)
{!bundle ? (

Бандл сертификата пуст — перезапустите экспорт с новой парольной фразой.

) : ( <>
Пароль архива .p12
setPassphrase(e.target.value)} />
{bundle.serverEndpoint ? (

Сервер: {bundle.serverEndpoint}

) : null}
Файлы {bundle.sswanContent && bundle.sswanFilename ? ( ) : null} {bundle.instructions ? ( ) : null}
{bundle.instructions ? (
                  {bundle.instructions}
                
) : null} )}
}> Закрыть
) } export { IpsecCertSheet, downloadText, downloadB64 }