import assert from "node:assert/strict";
import test from "node:test";
import { mkdtempSync, readdirSync, readFileSync, rmSync, statSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, relative } from "node:path";
import { fileURLToPath } from "node:url";
import { createMetadataStore } from "../packages/metadata/dist/index.js";
import { loadPasswordAuthConfig } from "../apps/api/dist/auth/config.js";
const ROOT = fileURLToPath(new URL("..", import.meta.url));
const FORBIDDEN = [
"DATAFOUNDRY_AUTH_MODE",
"NEXT_PUBLIC_DATAFOUNDRY_AUTH_MODE",
"X-Dev-Token",
"dev-token",
"DEFAULT_DEV_USER",
"upsertDevUser",
"getByDevToken",
"DemoCopilotKitClient",
"--demo",
];
const CODE_ROOTS = ["apps", "packages", "scripts"];
const CODE_EXTENSIONS = new Set([".ts", ".tsx", ".js", ".mjs", ".cjs", ".json"]);
const ENV_FILES = [".env.example", "apps/web/.env.example"];
const EXCLUDED_DIR_NAMES = new Set([
"node_modules",
"dist",
".next",
"coverage",
".git",
"storage",
"superpowers",
]);
function isAllowlistedSource(relativePath) {
const normalized = relativePath.replaceAll("\\", "/");
if (normalized === "scripts/password-only-cutover.test.mjs") return true;
if (normalized === "scripts/lib/metadata-test-identity.test.mjs") return true;
if (normalized === "scripts/auth-foundation.test.mjs") return true;
if (normalized === "scripts/deploy/cli.test.mjs") return true;
if (normalized === "scripts/deploy/config.test.mjs") return true;
if (normalized === "scripts/deploy/config.mjs") return true;
if (normalized === "apps/tui/src/no-bare-fetch.guard.test.ts") return true;
if (normalized === "apps/api/src/auth/config.ts") return true;
if (normalized === "apps/api/dist/auth/config.js") return true;
if (normalized.startsWith("packages/metadata/src/index.ts")) return true;
if (normalized.startsWith("packages/metadata/dist/index.js")) return true;
if (normalized.startsWith("docs/")) return true;
if (normalized === "README.md" || normalized === "README_zh.md") return true;
return false;
}
function walkFiles(dir, out = []) {
for (const entry of readdirSync(dir)) {
if (EXCLUDED_DIR_NAMES.has(entry)) continue;
const full = join(dir, entry);
const st = statSync(full);
if (st.isDirectory()) {
walkFiles(full, out);
continue;
}
const ext = entry.includes(".") ? `.${entry.split(".").pop()}` : "";
if (CODE_EXTENSIONS.has(ext) || entry.endsWith(".yml") || entry.endsWith(".yaml")) {
out.push(full);
}
}
return out;
}
function extractFencedBlocks(markdown) {
const blocks = [];
const re = /```[^\n]*\n([\s\S]*?)```/g;
let match;
while ((match = re.exec(markdown))) {
blocks.push(match[1]);
}
return blocks;
}
test("product code and scripts have no runnable development auth bypasses", () => {
const violations = [];
for (const rootName of CODE_ROOTS) {
const root = join(ROOT, rootName);
for (const full of walkFiles(root)) {
const rel = relative(ROOT, full);
if (isAllowlistedSource(rel)) continue;
const source = readFileSync(full, "utf8");
for (const token of FORBIDDEN) {
if (source.includes(token)) {
violations.push(`${rel}: ${token}`);
}
}
}
}
for (const envFile of ENV_FILES) {
const full = join(ROOT, envFile);
const source = readFileSync(full, "utf8");
for (const token of FORBIDDEN) {
if (source.includes(token)) {
violations.push(`${envFile}: ${token}`);
}
}
}
assert.deepEqual(violations, [], `Forbidden development auth tokens remain:\n${violations.join("\n")}`);
});
test("CI workflow does not set DATAFOUNDRY_AUTH_MODE", () => {
const ci = readFileSync(join(ROOT, ".github/workflows/ci.yml"), "utf8");
assert.equal(ci.includes("DATAFOUNDRY_AUTH_MODE"), false);
});
test("loadPasswordAuthConfig rejects removed auth modes and requires password settings", () => {
assert.doesNotThrow(() =>
loadPasswordAuthConfig({
DATAFOUNDRY_AUTH_MODE: "password",
AUTH_SESSION_SECRET: "x".repeat(32),
AUTH_PUBLIC_BASE_URL: "http://127.0.0.1:3000",
AUTH_REGISTRATION_MODE: "open",
AUTH_EMAIL_DELIVERY: "test",
})
);
assert.throws(
() =>
loadPasswordAuthConfig({
DATAFOUNDRY_AUTH_MODE: "dev",
AUTH_SESSION_SECRET: "x".repeat(32),
AUTH_PUBLIC_BASE_URL: "http://127.0.0.1:3000",
AUTH_REGISTRATION_MODE: "open",
AUTH_EMAIL_DELIVERY: "test",
}),
/DATAFOUNDRY_AUTH_MODE/
);
assert.throws(
() =>
loadPasswordAuthConfig({
AUTH_PUBLIC_BASE_URL: "http://127.0.0.1:3000",
AUTH_REGISTRATION_MODE: "open",
AUTH_EMAIL_DELIVERY: "test",
}),
/AUTH_SESSION_SECRET/
);
});
test("fresh metadata schema has no dev_token and no default user", () => {
const root = mkdtempSync(join(tmpdir(), "password-only-schema-"));
try {
const store = createMetadataStore({ database_path: join(root, "metadata.sqlite") });
const columns = store.db.prepare("PRAGMA table_info(users)").all().map((row) => row.name);
assert.ok(!columns.includes("dev_token"));
assert.equal(store.users.list().length, 0);
store.close();
} finally {
rmSync(root, { recursive: true, force: true });
}
});
function walkMarkdownFiles(dir, out = []) {
for (const entry of readdirSync(dir)) {
if (EXCLUDED_DIR_NAMES.has(entry)) continue;
const full = join(dir, entry);
const st = statSync(full);
if (st.isDirectory()) {
walkMarkdownFiles(full, out);
continue;
}
if (entry.endsWith(".md")) out.push(full);
}
return out;
}
test("markdown fenced blocks omit runnable DATAFOUNDRY_AUTH_MODE examples", () => {
const violations = [];
const files = [join(ROOT, "README.md"), join(ROOT, "README_zh.md")];
walkMarkdownFiles(join(ROOT, "docs"), files);
for (const full of files) {
const rel = relative(ROOT, full);
const source = readFileSync(full, "utf8");
for (const block of extractFencedBlocks(source)) {
if (block.includes("DATAFOUNDRY_AUTH_MODE") || block.includes("NEXT_PUBLIC_DATAFOUNDRY_AUTH_MODE")) {
violations.push(rel);
break;
}
}
}
assert.deepEqual(violations, [], `Runnable auth-mode examples remain in fenced docs:\n${violations.join("\n")}`);
});
const FORBIDDEN_DOC_PHRASES = [
"switch local development users",
"switch local dev users",
"Local development identity",
"Default local identity",
"切换本地开发用户",
"本地开发身份",
"本地默认身份",
];
test("public docs do not describe removed development identity UX", () => {
const violations = [];
const files = [join(ROOT, "README.md"), join(ROOT, "README_zh.md")];
walkMarkdownFiles(join(ROOT, "docs"), files);
for (const full of files) {
const rel = relative(ROOT, full);
const source = readFileSync(full, "utf8");
for (const phrase of FORBIDDEN_DOC_PHRASES) {
if (source.includes(phrase)) {
violations.push(`${rel}: ${phrase}`);
}
}
}
assert.deepEqual(
violations,
[],
`Docs still describe removed development identity UX:\n${violations.join("\n")}`
);
});