Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/sentinel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 2024-06-15 - Add missing security headers and CORS
**Vulnerability:** The Fastify API server lacked essential security configurations (`helmet` for security headers and `cors` for cross-origin access control). Additionally, if CORS was to be configured, there was a risk of insecurely setting `origin: true` instead of explicitly managing trusted origins.
**Learning:** Monorepo API setups often default to open cross-origin access or missing headers if standard security plugins are not explicitly added.
**Prevention:** Always register standard security plugins (`@fastify/helmet` and `@fastify/cors`) in Fastify and enforce explicit allowlists for `origin` rather than `true`.
2 changes: 2 additions & 0 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"typecheck": "cd ../.. && tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@fastify/cors": "~8.5.0",
"@fastify/helmet": "~11.1.1",
"@vooster/contracts": "workspace:*"
}
}
14 changes: 14 additions & 0 deletions apps/api/src/http/server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import Fastify, { type FastifyInstance } from "fastify";
import fastifyCors from "@fastify/cors";
import fastifyHelmet from "@fastify/helmet";
import { healthResponseSchema } from "@vooster/contracts";
import { createMemoryApiKeyStore } from "../infrastructure/memory-api-key-store.js";
import { createMemoryActorStore } from "../infrastructure/memory-actor-store.js";
Expand Down Expand Up @@ -63,6 +65,18 @@ import type { UserStore } from "../ports/user-store.js";
export async function createServer(options: ServerOptions): Promise<FastifyInstance> {
const serverOptions = withGithubOAuthFromEnv(options);
const app = Fastify({ logger: false });

// 🛡️ Sentinel: Add security headers to protect against common web vulnerabilities like XSS, clickjacking, etc.
await app.register(fastifyHelmet);

// 🛡️ Sentinel: Configure CORS strictly using explicit allowed origins.
// Prevents unauthorized cross-origin requests. Fails secure (origin: false) if no origins are configured.
const allowedOriginsRaw = process.env.VSPEC_ALLOWED_ORIGINS;
const allowedOrigins = allowedOriginsRaw ? allowedOriginsRaw.split(",") : [];

await app.register(fastifyCors, {
origin: allowedOrigins.length > 0 ? allowedOrigins : false
});
const state = initialState();
const apiKeyStore = serverOptions.signupStore ?? createMemoryApiKeyStore();
const actorStore = serverOptions.signupStore ?? createMemoryActorStore();
Expand Down
3 changes: 2 additions & 1 deletion apps/api/tests/integration/persistence-matrix-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
...process.env,
DATABASE_URL: databaseUrl,
PORT: String(port),
VSPEC_AUTH_STUB: "1"
VSPEC_AUTH_STUB: "1",
VSPEC_ALLOWED_ORIGINS: "http://127.0.0.1:3000"
},
stdio: ["ignore", "pipe", "pipe"]
});
Expand All @@ -78,7 +79,7 @@

for (let attempt = 0; attempt < 80; attempt += 1) {
if (child.exitCode !== null) {
throw new Error(`server exited early: ${await outputFrom(child)}`);

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > Workspace lookup survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:103:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > Workspace archive survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:78:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > User survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:54:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > Membership survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:29:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > Project survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:193:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > ProjectKey survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:159:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > UseCase survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:131:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > Goal survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:92:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > SpecBranch survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:61:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / verify

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > Actor survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:30:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > Workspace lookup survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:103:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > Workspace archive survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:78:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > User survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:54:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-identity.test.ts > Goal 2 persistence matrix — identity cluster > Membership survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-identity.test.ts:29:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > Project survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:193:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > ProjectKey survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:159:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > UseCase survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:131:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > Goal survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:92:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > SpecBranch survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:61:19

Check failure on line 82 in apps/api/tests/integration/persistence-matrix-helpers.ts

View workflow job for this annotation

GitHub Actions / test (2)

apps/api/tests/integration/persistence-matrix-authoring.test.ts > Goal 2 persistence matrix — authoring cluster > Actor survives a server restart

Error: server exited early: ❯ bootServer apps/api/tests/integration/persistence-matrix-helpers.ts:82:13 ❯ apps/api/tests/integration/persistence-matrix-authoring.test.ts:30:19
}
if (await isHealthy(url)) {
return {
Expand Down
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,31 @@
"homepage": "https://github.com/vibemafiaclub/vooster#readme",
"devDependencies": {
"@eslint/js": "^10.0.1",
"@oclif/core": "^4.11.3",
"@prisma/client": "^5.22.0",
"@stryker-mutator/core": "^9.6.1",
"@stryker-mutator/vitest-runner": "^9.6.1",
"@types/node": "^20.19.41",
"@vitest/coverage-v8": "^4.1.6",
"@vooster/contracts": "workspace:*",
"eslint": "^10.4.0",
"eslint-plugin-boundaries": "^6.0.2",
"prettier": "^3.8.3",
"prisma": "^5.22.0",
"tsx": "^4.22.2",
"typescript": "^5.9.3",
"typescript-eslint": "^8.59.3",
"vitest": "^4.1.6",
"@oclif/core": "^4.11.3",
"argon2": "^0.44.0",
"boxen": "^8.0.1",
"chalk": "^5.6.2",
"cli-table3": "^0.6.5",
"diff": "^9.0.0",
"dotenv": "^17.4.2",
"eslint": "^10.4.0",
"eslint-plugin-boundaries": "^6.0.2",
"fastify": "^4.29.1",
"gray-matter": "^4.0.3",
"marked": "^18.0.3",
"pino": "^10.3.1",
"prettier": "^3.8.3",
"prisma": "^5.22.0",
"tsx": "^4.22.2",
"typescript": "^5.9.3",
"typescript-eslint": "^8.59.3",
"vitest": "^4.1.6",
"zod": "^4.4.3"
}
}
45 changes: 45 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions test_db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
docker pull postgres:16-alpine
docker run --name vspec-db-test -e POSTGRES_USER=vspec -e POSTGRES_PASSWORD=vspec -e POSTGRES_DB=vspec_test -p 5433:5432 -d postgres:16-alpine
sleep 5
export DATABASE_URL="postgresql://vspec:vspec@127.0.0.1:5433/vspec_test"
export TEST_DATABASE_URL="postgresql://vspec:vspec@127.0.0.1:5433/vspec_test"
export NODE_OPTIONS="--max-old-space-size=4096"
export VSPEC_TEST_USE_DIST=1
pnpm --filter @vooster/api run test -- apps/api/tests/integration/persistence-matrix-identity.test.ts
Loading