Files
SnapOtter/vitest.config.ts
T
Siddharth Kumar Sah 432cc92471 feat: harden auth, security headers, SVG sanitization, and pipeline ownership
- Add password strength validation (8+ chars, uppercase, lowercase, number)
- Add username validation rules
- Optimize API key lookup with SHA-256 prefix (O(1) vs O(n) scan)
- Require password change on default admin first login
- Revoke API keys on password change
- Add session cleanup cron (hourly expired session purge)
- Add Permissions-Policy, HSTS, and CSP security headers in production
- Strengthen SVG sanitizer: block XInclude, foreignObject, processing
  instructions, javascript/data/file URI schemes
- Add userId ownership to pipelines with authorization checks
- Add keyPrefix column to api_keys table
- Update integration tests for new auth behavior
2026-03-24 21:38:06 +08:00

83 lines
3.0 KiB
TypeScript

import { defineConfig } from "vitest/config";
import path from "node:path";
import os from "node:os";
import crypto from "node:crypto";
// Resolve api-workspace packages that pnpm only exposes under apps/api/node_modules.
const apiNodeModules = path.resolve(__dirname, "apps/api/node_modules");
// Temp dir for integration test DB + workspace (set BEFORE any app code loads)
const testDir = path.join(os.tmpdir(), `stirling-test-${crypto.randomUUID().slice(0, 8)}`);
export default defineConfig({
test: {
globals: true,
testTimeout: 30_000,
hookTimeout: 30_000,
// These env vars are injected into process.env BEFORE test files are
// imported, ensuring apps/api/src/config.ts picks them up correctly.
env: {
AUTH_ENABLED: "true",
DEFAULT_USERNAME: "admin",
DEFAULT_PASSWORD: "Adminpass1",
DB_PATH: path.join(testDir, "test.db"),
WORKSPACE_PATH: path.join(testDir, "workspace"),
MAX_UPLOAD_SIZE_MB: "10",
MAX_BATCH_SIZE: "10",
RATE_LIMIT_PER_MIN: "10000",
MAX_MEGAPIXELS: "100",
CONCURRENT_JOBS: "3",
FILE_MAX_AGE_HOURS: "1",
CLEANUP_INTERVAL_MINUTES: "60",
},
coverage: {
provider: "v8",
reporter: ["text", "html", "lcov"],
include: [
"packages/image-engine/src/**",
"apps/api/src/**",
"apps/web/src/stores/**",
"apps/web/src/lib/**",
],
exclude: [
"**/*.d.ts",
"**/node_modules/**",
"**/dist/**",
"apps/api/src/db/migrate.ts",
"apps/api/src/index.ts",
],
},
},
resolve: {
alias: {
"@": path.resolve(__dirname, "apps/web/src"),
"@stirling-image/image-engine": path.resolve(
__dirname,
"packages/image-engine/src/index.ts",
),
"@stirling-image/shared": path.resolve(
__dirname,
"packages/shared/src/index.ts",
),
// Map api-only dependencies so integration tests (and transitive imports
// from apps/api/src) can resolve them from the root vitest runner.
"fastify": path.join(apiNodeModules, "fastify"),
"@fastify/cors": path.join(apiNodeModules, "@fastify/cors"),
"@fastify/multipart": path.join(apiNodeModules, "@fastify/multipart"),
"@fastify/rate-limit": path.join(apiNodeModules, "@fastify/rate-limit"),
"@fastify/static": path.join(apiNodeModules, "@fastify/static"),
"@fastify/swagger": path.join(apiNodeModules, "@fastify/swagger"),
"@fastify/swagger-ui": path.join(apiNodeModules, "@fastify/swagger-ui"),
"better-sqlite3": path.join(apiNodeModules, "better-sqlite3"),
"drizzle-orm": path.join(apiNodeModules, "drizzle-orm"),
"archiver": path.join(apiNodeModules, "archiver"),
"p-queue": path.join(apiNodeModules, "p-queue"),
"dotenv": path.join(apiNodeModules, "dotenv"),
"potrace": path.join(apiNodeModules, "potrace"),
"qrcode": path.join(apiNodeModules, "qrcode"),
"jsqr": path.join(apiNodeModules, "jsqr"),
"pdfkit": path.join(apiNodeModules, "pdfkit"),
},
},
});