Add test suite for CORS and CSP validation in Express app
This commit is contained in:
63
test-backend/test/run-tests.ts
Normal file
63
test-backend/test/run-tests.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import http from "http"
|
||||||
|
import fetch from "node-fetch"
|
||||||
|
import app from "../app"
|
||||||
|
|
||||||
|
async function listenOnRandomPort() {
|
||||||
|
return new Promise<{ server: http.Server; port: number }>(
|
||||||
|
(resolve, reject) => {
|
||||||
|
const server = http.createServer(app)
|
||||||
|
server.listen(0, () => {
|
||||||
|
// @ts-ignore
|
||||||
|
const addr = server.address()
|
||||||
|
if (!addr || typeof addr === "string")
|
||||||
|
return reject(new Error("Failed to get server address"))
|
||||||
|
resolve({ server, port: addr.port })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function run() {
|
||||||
|
const FRONTEND = process.env.FRONTEND_URL || "http://localhost:5173"
|
||||||
|
const { server, port } = await listenOnRandomPort()
|
||||||
|
const base = `http://localhost:${port}`
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1) Allowed origin
|
||||||
|
const allowed = await fetch(base + "/api/meters", {
|
||||||
|
headers: { Origin: FRONTEND },
|
||||||
|
})
|
||||||
|
console.log("Allowed origin status:", allowed.status)
|
||||||
|
const csp = allowed.headers.get("content-security-policy")
|
||||||
|
const nonce = allowed.headers.get("x-csp-nonce")
|
||||||
|
console.log("CSP header present:", !!csp)
|
||||||
|
console.log("X-CSP-Nonce present:", !!nonce)
|
||||||
|
|
||||||
|
if (allowed.status !== 200) throw new Error("Allowed origin request failed")
|
||||||
|
if (!csp) throw new Error("CSP header missing")
|
||||||
|
if (!nonce) throw new Error("X-CSP-Nonce missing")
|
||||||
|
|
||||||
|
// 2) Disallowed origin
|
||||||
|
const disallowed = await fetch(base + "/api/meters", {
|
||||||
|
headers: { Origin: "https://evil.com" },
|
||||||
|
})
|
||||||
|
console.log("Disallowed origin status:", disallowed.status)
|
||||||
|
if (disallowed.status !== 403)
|
||||||
|
throw new Error("Disallowed origin not rejected")
|
||||||
|
|
||||||
|
// 3) Missing origin -> should be rejected now
|
||||||
|
const missing = await fetch(base + "/api/meters")
|
||||||
|
console.log("Missing origin status:", missing.status)
|
||||||
|
if (missing.status !== 403)
|
||||||
|
throw new Error("Request without Origin header should be rejected")
|
||||||
|
|
||||||
|
console.log("\nAll tests passed")
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Test failure:", err)
|
||||||
|
process.exitCode = 1
|
||||||
|
} finally {
|
||||||
|
server.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
Reference in New Issue
Block a user