Files
HiveGrid-Wireframes/hivegrid-cloud/scripts/check-env-drift.test.mjs
T

215 lines
7.0 KiB
JavaScript

import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { afterEach, describe, it } from "vitest";
import { checkEnvDrift, formatEnvDriftResult } from "./check-env-drift.mjs";
const fixtures = [];
const ENV_FIXTURES = {
".env.example": `# Core
APP_NAME=ToolCTRL
DATABASE_URL="postgres://{USER}:{PASSWORD}@{HOST}:{PORT}/{DATABASE}"
SESSION_SECRET=
CRYPTO_SECRET=
APP_BASE_DOMAIN=localhost
WEB_APP_HOST=app.localhost
ADMIN_APP_HOST=admin.localhost
API_HOST=api.localhost
# APP_PROTOCOL=http
API_ACCESS_TOKEN=
JWT_SECRET=
# REDIS_URL is a fallback only when BULLMQ_REDIS_URL is absent; keep it commented if a platform injects it.
# REDIS_URL=redis://localhost:6379/0
SITE_KEY_EXAMPLE_SITE=
`,
".env.local.example": `APP_NAME=ToolCTRL Local
DATABASE_URL="file:./dev.db?connection_limit=1&connect_timeout=30"
SESSION_SECRET=replace-with-local-session-secret
CRYPTO_SECRET=replace-with-local-crypto-secret
APP_BASE_DOMAIN=localhost:3000
WEB_APP_HOST=app.localhost:3000
ADMIN_APP_HOST=admin.localhost:3000
API_HOST=api.localhost:3001
APP_PROTOCOL=http
API_ACCESS_TOKEN=replace-with-local-api-token
JWT_SECRET=replace-with-local-jwt-secret
SITE_KEY_LOCAL=replace-with-local-site-key
`,
".env.production.example": `APP_NAME=ToolCTRL
DATABASE_URL="postgres://{USER}:{PASSWORD}@{HOST}:{PORT}/{DATABASE}"
SESSION_SECRET=
CRYPTO_SECRET=
APP_BASE_DOMAIN=your-domain.invalid
WEB_APP_HOST=app.your-domain.invalid
ADMIN_APP_HOST=admin.your-domain.invalid
API_HOST=api.your-domain.invalid
APP_PROTOCOL=https
API_ACCESS_TOKEN=
JWT_SECRET=
BULLMQ_REDIS_URL=redis://localhost:6379/0
# REDIS_URL=redis://localhost:6379/0
`,
".env.fly.example": `flyctl secrets set APP_NAME=YOUR_APP_NAME \\
DATABASE_URL=postgres://{USER}:{PASSWORD}@{HOST}:{PORT}/{DATABASE} \\
SESSION_SECRET=<session-secret> \\
CRYPTO_SECRET=<crypto-secret> \\
API_ACCESS_TOKEN=<api-access-token> \\
JWT_SECRET=<jwt-secret> \\
APP_BASE_DOMAIN=your-domain.invalid \\
WEB_APP_HOST=app.your-domain.invalid \\
ADMIN_APP_HOST=admin.your-domain.invalid \\
API_HOST=api.your-domain.invalid \\
APP_PROTOCOL=https \\
BULLMQ_REDIS_URL=redis://default:<redis-password>@redis.your-domain.invalid:6379/0 \\
--app YOUR_APP_NAME
# REDIS_URL=redis://default:<redis-password>@redis.your-domain.invalid:6379/0
`,
".env.test": `APP_NAME=ToolCTRL Test
DATABASE_URL="file:./test.db?connection_limit=1&connect_timeout=30"
SESSION_SECRET=test-session-secret-placeholder
CRYPTO_SECRET=test-crypto-secret-placeholder
APP_BASE_DOMAIN=localhost.test
WEB_APP_HOST=app.localhost.test
ADMIN_APP_HOST=admin.localhost.test
API_HOST=api.localhost.test
APP_PROTOCOL=http
API_ACCESS_TOKEN=test-api-access-token-placeholder
JWT_SECRET=test-jwt-secret-placeholder
SITE_KEY_EXAMPLE_SITE=test-site-key-placeholder
`,
};
function writeFile(rootDir, relativePath, content) {
const absolutePath = path.join(rootDir, relativePath);
fs.mkdirSync(path.dirname(absolutePath), { recursive: true });
fs.writeFileSync(absolutePath, content);
}
function createFixture(overrides = {}) {
const rootDir = fs.mkdtempSync(path.join(os.tmpdir(), "env-drift-"));
fixtures.push(rootDir);
for (const [relativePath, content] of Object.entries(ENV_FIXTURES)) {
writeFile(rootDir, relativePath, overrides[relativePath] ?? content);
}
return rootDir;
}
afterEach(() => {
while (fixtures.length > 0) {
fs.rmSync(fixtures.pop(), { recursive: true, force: true });
}
});
describe("check-env-drift", () => {
it("prints PASS output for cataloged env fixtures", () => {
const rootDir = createFixture();
const result = checkEnvDrift(rootDir);
const output = formatEnvDriftResult(result);
assert.deepEqual(result.failures, []);
assert.match(output, /^PASS env drift verification/);
assert.match(output, /PASS \.env\.test: \d+ active keys match catalog/);
assert.match(output, /Summary: \d+ passed, 0 observed, 0 failed/);
});
it("fails for unknown keys", () => {
const rootDir = createFixture({
".env.test": `${ENV_FIXTURES[".env.test"]}UNTRACKED_SECRET=super-secret-value
`,
});
const result = checkEnvDrift(rootDir);
assert.match(result.failures.join("\n"), /\.env\.test:\d+: unknown-key UNTRACKED_SECRET/);
});
it("fails for duplicate keys within one file", () => {
const rootDir = createFixture({
".env.local.example": `${ENV_FIXTURES[".env.local.example"]}APP_NAME=Duplicate
`,
});
const result = checkEnvDrift(rootDir);
assert.match(result.failures.join("\n"), /\.env\.local\.example:\d+: duplicate-key APP_NAME/);
});
it("allows dynamic SITE_KEY-prefixed variables", () => {
const rootDir = createFixture({
".env.test": `${ENV_FIXTURES[".env.test"]}SITE_KEY_CUSTOMER_PORTAL=test-site-key-placeholder
`,
});
const result = checkEnvDrift(rootDir);
assert.deepEqual(result.failures, []);
});
it("fails when production example files keep example.com placeholders", () => {
const rootDir = createFixture({
".env.production.example": ENV_FIXTURES[".env.production.example"].replaceAll("your-domain.invalid", "example.com"),
});
const result = checkEnvDrift(rootDir);
assert.match(result.failures.join("\n"), /\.env\.production\.example:\d+: production-domain-placeholder APP_BASE_DOMAIN/);
});
it("requires production keys in fly secrets examples", () => {
const rootDir = createFixture({
".env.fly.example": ENV_FIXTURES[".env.fly.example"].replace(/JWT_SECRET=<jwt-secret> \\\n/, ""),
});
const result = checkEnvDrift(rootDir);
assert.match(result.failures.join("\n"), /\.env\.fly\.example: missing-required-key JWT_SECRET/);
});
it("redacts values from diagnostics", () => {
const leakedValue = "top-secret-token-value";
const rootDir = createFixture({
".env.test": `${ENV_FIXTURES[".env.test"]}UNTRACKED_SECRET=${leakedValue}
`,
});
const result = checkEnvDrift(rootDir);
const output = formatEnvDriftResult(result);
assert.match(output, /unknown-key UNTRACKED_SECRET/);
assert.doesNotMatch(output, new RegExp(leakedValue));
});
it("CLI exits non-zero without leaking values", () => {
const leakedValue = "super-secret-cli-value";
const rootDir = createFixture({
".env.test": `${ENV_FIXTURES[".env.test"]}UNTRACKED_SECRET=${leakedValue}
`,
});
const scriptPath = path.resolve("scripts/check-env-drift.mjs");
const nodePath = path.resolve("node_modules");
assert.throws(
() => execFileSync(process.execPath, ["--import", path.join(nodePath, "tsx/dist/loader.mjs"), scriptPath], {
cwd: rootDir,
encoding: "utf8",
stdio: "pipe",
}),
(error) => {
assert.equal(error.status, 1);
const output = `${error.stdout}${error.stderr}`;
assert.match(output, /FAIL env drift verification/);
assert.match(output, /unknown-key UNTRACKED_SECRET/);
assert.doesNotMatch(output, new RegExp(leakedValue));
return true;
},
);
});
});