feat: Dark Mode + Zertifikat-Verwaltung im Superadmin
- Dark Mode: ThemeProvider (next-themes), ThemeToggle in Navbar (Hell/Dunkel/System) - Zertifikat-Tab (superadmin only): aktuelles Zertifikat anzeigen, Upload (cert+key), Self-Signed ausstellen, Let's Encrypt/ACME - Backend: /api/admin/cert/* Endpunkte (info, upload, self-signed, acme), nginx reload - HTTPS bereits live auf Server (self-signed RSA-4096, Port 443) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -935,3 +935,64 @@ export async function createLabelRule(
|
||||
export async function deleteLabelRule(id: number): Promise<void> {
|
||||
return request<void>(`/api/admin/label-rules/${id}`, { method: "DELETE" });
|
||||
}
|
||||
|
||||
// ── Certificate Management ────────────────────────────────────────────────
|
||||
|
||||
export interface CertInfo {
|
||||
exists: boolean;
|
||||
subject?: string;
|
||||
issuer?: string;
|
||||
not_before?: string;
|
||||
not_after?: string;
|
||||
dns_names?: string[];
|
||||
ip_addresses?: string[];
|
||||
fingerprint_sha256?: string;
|
||||
is_self_signed?: boolean;
|
||||
days_remaining?: number;
|
||||
}
|
||||
|
||||
export interface SelfSignedRequest {
|
||||
common_name: string;
|
||||
dns_names: string[];
|
||||
ip_addresses: string[];
|
||||
validity_years: number;
|
||||
}
|
||||
|
||||
export interface ACMERequest {
|
||||
domain: string;
|
||||
email: string;
|
||||
}
|
||||
|
||||
export async function getCertInfo(): Promise<CertInfo> {
|
||||
return request<CertInfo>("/api/admin/cert/info");
|
||||
}
|
||||
|
||||
export async function uploadCert(cert: File, key: File): Promise<{ ok: boolean; message: string }> {
|
||||
const form = new FormData();
|
||||
form.append("cert", cert);
|
||||
form.append("key", key);
|
||||
const res = await fetch(`${API_BASE}/api/admin/cert/upload`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
body: form,
|
||||
});
|
||||
if (!res.ok) {
|
||||
const body = await res.text();
|
||||
throw new Error(body || `Upload failed: ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function generateSelfSignedCert(req: SelfSignedRequest): Promise<CertInfo & { ok: boolean }> {
|
||||
return request<CertInfo & { ok: boolean }>("/api/admin/cert/self-signed", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(req),
|
||||
});
|
||||
}
|
||||
|
||||
export async function requestACMECert(req: ACMERequest): Promise<{ ok: boolean; output: string }> {
|
||||
return request<{ ok: boolean; output: string }>("/api/admin/cert/acme", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(req),
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user