mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-12 22:26:13 +00:00
Add ENCRYPTION_KEY_CHECK=warn as an escape hatch for the boot key check
At a first start there is no recorded key yet, so an operator facing a refusal they are certain is false has no row to delete. With ENCRYPTION_KEY_CHECK=warn (default enforce) the check still runs and logs its full outcome, /api/health names a mismatch as a warning field without failing, requests are served, and no key is recorded unless every key id passes. The variable is on the compose whitelist, in both example files, the env manifest, the Unraid and Portainer templates and the published-env guard. The log block, the mismatch page and the self-hosting pages offer it as the last resort after the three real fixes, and say that it disables a safety check.
This commit is contained in:
1 parent
4783711651
commit
69bae8bdb4
24 files changed
+319
-7
No files matched your search
@@ -140,3 +140,26 @@ describe("GET /api/health while the encryption key does not match", () => {
|
||||
expect(body).toEqual({ status: "ok" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("GET /api/health under ENCRYPTION_KEY_CHECK=warn", () => {
|
||||
it("names the mismatch as a warning and stays ok", async () => {
|
||||
const { setKeyMismatchWarning } =
|
||||
await import("@/lib/boot/key-mismatch-state");
|
||||
vi.stubEnv("HEALTHLOG_PROCESS_TYPE", "web");
|
||||
getGlobalBoss.mockReturnValue({});
|
||||
setKeyMismatchWarning({
|
||||
keyIds: ["v1"],
|
||||
detectedAt: "2026-10-03T00:00:00Z",
|
||||
});
|
||||
try {
|
||||
const { response, body } = await health();
|
||||
expect(response.status).toBe(200);
|
||||
expect(body).toEqual({
|
||||
status: "ok",
|
||||
warning: "encryption_key_mismatch",
|
||||
});
|
||||
} finally {
|
||||
setKeyMismatchWarning(null);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import { NextResponse } from "next/server";
|
||||
import { apiHandler } from "@/lib/api-handler";
|
||||
import { annotate } from "@/lib/logging/context";
|
||||
import {
|
||||
getKeyMismatchWarning,
|
||||
isKeyMismatch,
|
||||
KEY_MISMATCH_HEALTH_REASON,
|
||||
} from "@/lib/boot/key-mismatch-state";
|
||||
@@ -31,6 +32,12 @@ export const GET = apiHandler(async () => {
|
||||
// it is the one place a catalog install's status page reads.
|
||||
const keyMismatch = isKeyMismatch();
|
||||
const reason = keyMismatch ? KEY_MISMATCH_HEALTH_REASON : undefined;
|
||||
// Under ENCRYPTION_KEY_CHECK=warn the same finding does not refuse; it is
|
||||
// named as a warning and leaves the status alone.
|
||||
const warning =
|
||||
!keyMismatch && getKeyMismatchWarning()
|
||||
? KEY_MISMATCH_HEALTH_REASON
|
||||
: undefined;
|
||||
const status =
|
||||
!keyMismatch &&
|
||||
dbOk &&
|
||||
@@ -51,6 +58,7 @@ export const GET = apiHandler(async () => {
|
||||
{
|
||||
status,
|
||||
...(reason ? { reason } : {}),
|
||||
...(warning ? { warning } : {}),
|
||||
timestamp: new Date().toISOString(),
|
||||
database: dbOk ? "connected" : "disconnected",
|
||||
worker: worker.running ? "running" : "stopped",
|
||||
@@ -63,7 +71,7 @@ export const GET = apiHandler(async () => {
|
||||
}
|
||||
|
||||
return NextResponse.json(
|
||||
{ status, ...(reason ? { reason } : {}) },
|
||||
{ status, ...(reason ? { reason } : {}), ...(warning ? { warning } : {}) },
|
||||
{ status: statusCode, headers: cacheHeaders },
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user