added db guard changes to prevent deletion
This commit is contained in:
@@ -30,11 +30,48 @@ function resolveDatabaseUrl(): string {
|
||||
if (dbUrl) return dbUrl.replace("@postgres:", "@127.0.0.1:");
|
||||
}
|
||||
|
||||
return "postgres://app:app@127.0.0.1:5432/skymoney";
|
||||
return "postgres://app:app@127.0.0.1:5432/skymoney_test";
|
||||
}
|
||||
|
||||
function parseDbName(url: string): string {
|
||||
const parsed = new URL(url);
|
||||
const dbName = parsed.pathname.replace(/^\/+/, "");
|
||||
if (!dbName) throw new Error(`DATABASE_URL has no database name: ${url}`);
|
||||
return dbName;
|
||||
}
|
||||
|
||||
function assertSafeDbTarget(url: string): void {
|
||||
const requireTestDbName = process.env.REQUIRE_TEST_DB_NAME === "1";
|
||||
const protectedNamesRaw =
|
||||
process.env.PROTECTED_DB_NAMES ??
|
||||
process.env.EXPECTED_PROD_DB_NAME ??
|
||||
"skymoney,postgres,template0,template1";
|
||||
const protectedNames = new Set(
|
||||
protectedNamesRaw
|
||||
.split(",")
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean)
|
||||
);
|
||||
const dbName = parseDbName(url);
|
||||
|
||||
if (protectedNames.has(dbName)) {
|
||||
throw new Error(
|
||||
`Refusing to run DB tests against protected database '${dbName}'. ` +
|
||||
"Set TEST_DATABASE_URL to a dedicated test database."
|
||||
);
|
||||
}
|
||||
|
||||
if (requireTestDbName && !/(test|ci|sandbox|staging|shadow|tmp)/i.test(dbName)) {
|
||||
throw new Error(
|
||||
`Refusing to run DB tests against '${dbName}' because it does not look like a test database. ` +
|
||||
"Set REQUIRE_TEST_DB_NAME=0 only for intentional local exceptions."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || "test";
|
||||
process.env.DATABASE_URL = resolveDatabaseUrl();
|
||||
assertSafeDbTarget(process.env.DATABASE_URL);
|
||||
process.env.PORT = process.env.PORT || "8081";
|
||||
process.env.HOST ??= "127.0.0.1";
|
||||
process.env.CORS_ORIGIN = process.env.CORS_ORIGIN || "";
|
||||
|
||||
@@ -31,4 +31,16 @@ describe("A03 Software Supply Chain Failures", () => {
|
||||
|
||||
expect(deployWorkflow).toMatch(/uses:\s*actions\/checkout@v\d+\.\d+\.\d+/);
|
||||
});
|
||||
|
||||
it("guards DB-backed security tests from targeting production database", () => {
|
||||
const repoRoot = resolve(__dirname, "..", "..");
|
||||
const securityWorkflow = readFileSync(
|
||||
resolve(repoRoot, ".gitea/workflows/security.yml"),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
expect(securityWorkflow).toContain("name: Guard TEST_DATABASE_URL target");
|
||||
expect(securityWorkflow).toContain("bash ./scripts/validate-test-db-target.sh");
|
||||
expect(securityWorkflow).toContain("TEST_DATABASE_URL: ${{ secrets.TEST_DATABASE_URL }}");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user