mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-14 06:40:50 +00:00
Every configured key id now has a canary in encryption_key_canaries, checked at boot. A key that cannot open its canary, or existing data written before the canary existed, puts the process in a refusal state: every API route answers 503 encryption.key_mismatch, /api/health reports reason encryption_key_mismatch, the pages render one explanation, and neither the queue producer nor the worker starts. The process stays up so the reason is visible instead of hiding in a crash loop. The admin Encryption page gains a "Back up your encryption key" step: key id and fingerprint (never the key), where the key lives per platform, a check of a pasted copy that is compared and discarded, and a confirmation bound to the active key id and fingerprint. The overview gets a tile and admins get a dashboard banner while it is due. HEALTHLOG_PLATFORM picks the platform the step opens on. Adds the TrueNAS self-hosting page and key backup sections in the docs.
37 lines
1.0 KiB
TypeScript
37 lines
1.0 KiB
TypeScript
"use client";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { apiGet } from "@/lib/api/api-fetch";
|
|
import { queryKeys } from "@/lib/query-keys";
|
|
|
|
export type KeyBackupPlatform =
|
|
"compose" | "truenas" | "coolify" | "unraid" | "portainer";
|
|
|
|
/** `GET /api/admin/encryption/key-backup`; key id and fingerprint only. */
|
|
export interface KeyBackupStatus {
|
|
due: boolean;
|
|
activeKeyId: string;
|
|
fingerprint: string;
|
|
confirmedAt: string | null;
|
|
confirmedKeyId: string | null;
|
|
confirmedFingerprint: string | null;
|
|
confirmedBy: { id: string; email: string | null } | null;
|
|
platformHint: KeyBackupPlatform;
|
|
}
|
|
|
|
/**
|
|
* The key backup step's state. `enabled` lets the dashboard banner ask only
|
|
* for an admin; the route itself is admin-only and cookie-only.
|
|
*/
|
|
export function useKeyBackupStatus(enabled = true) {
|
|
return useQuery({
|
|
queryKey: queryKeys.adminEncryptionKeyBackup(),
|
|
queryFn: () =>
|
|
apiGet<KeyBackupStatus>("/api/admin/encryption/key-backup", {
|
|
credentials: "include",
|
|
}),
|
|
enabled,
|
|
staleTime: 60_000,
|
|
});
|
|
}
|