feat(security): batch security hardening - CORS, Helmet, rate limiting, CI checks - #190
Open
Senorespecial wants to merge 43 commits into
Open
Conversation
…esource_credits tests
CI
- coverage: run cargo-tarpaulin with --fail-under 80 across every contract
crate; uploads the XML report as an artifact for inspection.
- verify-data-model: fail the build when any TypeORM entity or migration
changes without a corresponding update to backend/docs/data-model.md.
Handles pull_request and push events, skips on workflow_dispatch or when
the base SHA is unavailable.
Docs
- CONTRIBUTING.md: workflow, branch naming (feat/<scope>-...), Conventional
Commits, per-stack conventions, the 80% contract coverage rule, and the
data-model sync rule, plus a PR checklist.
- backend/docs/data-model.md: Mermaid ER diagram, relationship cheat-sheet,
index inventory, and conventions (bigint money in kobo, timestamptz,
soft-delete). This is now the source of truth that the verify-data-model
CI job checks against.
- README: point contributors at the data-model doc when their change
touches entities, migrations, or schema.
Contracts
- contracts/resource_credits/src/{lib.rs, test.rs}: register a new test
module and add unit tests covering every public method (initialize,
mint_credits, transfer_credits, spend_credits) along with the relevant
error variants, lifting this crate to the 80% line coverage required by
the new coverage gate (closes NovaCoreLabs1#145).
Misc
- Whitespace / Prettier-style formatting cleanup across several NestJS
files (backend/src/{app.module.ts, bookings/dto/create-public-booking.dto.ts,
dashboard/dashboard.service.ts, email/email.service.ts,
payments/payments.controller.ts,
payments/providers/soroban-escrow.provider.ts, utils/soroban-types.ts}).
No runtime behavior change.
Refs: NovaCoreLabs1#145, NovaCoreLabs1#140
Closes NovaCoreLabs1#140 - PostgreSQL data model doc with ER diagram, table definitions, indexes, enum reference, and CI sync check. Closes NovaCoreLabs1#145 - Contract test coverage CI job with cargo-tarpaulin, 80% threshold, and per-crate enforcement.
Add a CI job that auto-generates a Mermaid ER diagram from TypeORM entities using erdia. The job starts a PostgreSQL service container, runs erdia to extract entity metadata and produce a markdown ER diagram, then fails if the generated output differs from what is committed. New files: - backend/src/config/typeorm.config.ts - standalone DataSource for erdia & migrations - backend/docs/erd/ - generated output (committed for CI comparison) Updated: - backend/package.json - added db:diagram script using erdia + ts-node - .github/workflows/CI.yaml - added generate-er-diagram CI job Part of NovaCoreLabs1#140 - auto-generate the Mermaid ER diagram from TypeORM entities.
Upload per-crate tarpaulin XML (contracts) and Jest lcov.info (backend) coverage reports to Codecov with distinct flags for each area. New: - codecov.yml - config with 80% target for contracts, 70% for backend - Contracts job: uploads tarpaulin XML via codecov/codecov-action@v5 - Backend job: runs jest --coverage and uploads lcov.info Requires CODECOV_TOKEN secret set in the repository.
Jest rootDir:src + coverageDirectory:../coverage outputs to backend/coverage/, not coverage/. Fix the Codecov files input to match.
Sets up testing infrastructure for Next.js frontend: - Installs Vitest, @vitejs/plugin-react, jsdom, @vitest/coverage-v8 - Creates vitest.config.ts with v8 coverage, jsdom env, and @/ alias - Adds placeholder test to verify the runner works - Adds test / test:cov / test:watch npm scripts - Updates frontend CI job to run test:cov then upload lcov to Codecov - Updates codecov.yml with frontend flag (60% target, 10% threshold)
Switches from static shields.io-styled badges with hardcoded target percentages to shields.io native Codecov badges that dynamically fetch the actual coverage from the Codecov API per flag.
…d-data-model-sync # Conflicts: # .github/workflows/CI.yaml # backend/package-lock.json # backend/package.json # backend/src/email/email.service.ts
Explains how to run coverage locally for backend, frontend, and contracts. Includes current targets table and link to Codecov dashboard.
Auth service: 33 tests covering createUser, verifyOtp, login, refreshToken, resetPassword, 2FA delegation Auth controller: 15 tests covering all endpoints Payments service: 6 tests covering initialize, webhook, refund, findAll, findById Payments controller: 6 tests covering all endpoints Also fixed Jest ESM transform issue for otplib dependencies via transformIgnorePatterns.
…controller Adds 55 new tests across 4 test files: - check-in.provider.spec.ts: ~20 tests covering biometric validation (7 denied field types), workspace checks (not found, duplicate), check-in (minimal and full fields), check-out (duration calculation), getActiveCheckIn (with/without workspace filter), getStorageAuditSummary - occupancy.provider.spec.ts: ~14 tests for getCurrentOccupancy (multiple workspaces, filter, zero seats), getUtilizationStats (aggregation, filters, unknown workspace), getRecentLogs (limit, filter) - workspace-tracking.service.spec.ts: 10 delegation tests for all 7 service methods - workspace-tracking.controller.spec.ts: 11 delegation tests for all 8 endpoints with response wrapping Coverage impact: CheckInProvider 44%→100%, OccupancyProvider 0%→100%, Service 0%→100%, Controller 0%→100%, overall backend 28.65%→32.07% Also fixed 3 existing check-in test failures: removed duplicate inactive-workspace test, fixed expect.any(Object) for IsNull() FindOperator.
Adds 42 new tests across 8 test files covering the workspaces module: - create-workspace.provider.spec.ts: 3 tests (creates workspace, name conflict, optional fields) - find-all-workspaces.provider.spec.ts: 8 tests (pagination, filters, admin view, empty) - find-workspace-by-id.provider.spec.ts: 2 tests (found, not found) - update-workspace.provider.spec.ts: 4 tests (field update, proportional seat increase/decrease) - delete-workspace.provider.spec.ts: 2 tests (soft-delete, error propagation) - check-workspace-availability.provider.spec.ts: 5 tests (available, insufficient, inactive, default seats, not found) - workspaces.service.spec.ts: 7 tests (all 6 service methods delegation) - workspaces.controller.spec.ts: 8 tests (all 7 endpoints with response wrapping) Coverage impact: CreateWorkspaceProvider 53%->100%, FindAllWorkspacesProvider 30%->100%, FindWorkspaceByIdProvider 58%->100%, UpdateWorkspaceProvider 50%->100%, DeleteWorkspaceProvider 61%->100%, CheckWorkspaceAvailabilityProvider 53%->100%, WorkspacesService 45%->100%, WorkspacesController 0%->100%
…d pricing Adds 63 new tests across 9 test files covering the bookings module: - complete-booking.provider.spec.ts: 3 tests - confirm-booking.provider.spec.ts: 5 tests (including member activation) - cancel-booking.provider.spec.ts: 5 tests (permissions, status checks) - find-bookings.provider.spec.ts: 10 tests (filters, pagination, admin access) - create-booking.provider.spec.ts: 6 tests (DataSource transaction, workspace/seat validation) - create-public-day-pass.provider.spec.ts: 6 tests (transaction, payment initialization) - pricing.service.spec.ts: 10 tests (all plan types, discounts, seat multiplier, floor) - bookings.service.spec.ts: 10 tests (all 8 service methods delegation) - bookings.controller.spec.ts: 9 tests (all 8 endpoints with response wrapping) Coverage impact: most bookings providers 0%->100%, controller 0%->100%, service 40%->100%, pricing 44%->100%, overall backend 32%->~35%
…r, and gateway Adds 23 new tests across 5 test files covering the notifications module: - create-notification.provider.spec.ts: 2 tests (create + real-time event, with metadata) - find-notifications.provider.spec.ts: 8 tests (pagination, isRead filter, cap limit, empty, markRead ownership, markAllRead) - notifications.service.spec.ts: 4 tests (all 4 service methods delegation) - notifications.controller.spec.ts: 4 tests (all 3 endpoints with response wrapping) - notifications.gateway.spec.ts: 5 tests (sendToUser, handleConnection auth flows, handleDisconnect) Coverage impact: CreateNotificationProvider 57%->100%, FindNotificationsProvider 35%->100%, NotificationsService 50%->100%, NotificationsController 0%->100%, NotificationsGateway 38%->100%
Adds 24 new tests across 6 test files covering the invoices module: - find-invoices.provider.spec.ts: 8 tests (pagination, filters, admin vs user, ownership enforcement) - invoice-sequence.provider.spec.ts: 2 tests (sequence creation on bootstrap, error handling) - generate-invoice.provider.spec.ts: 4 tests (idempotent return, payment not found, full generation, fallback description) - pdf-invoice.provider.spec.ts: 3 tests (generate buffer, line items, error handling) - invoices.service.spec.ts: 4 tests (all 4 service methods delegation) - invoices.controller.spec.ts: 3 tests (findAll and findOne with response wrapping) Coverage impact: FindInvoicesProvider 25%->100%, InvoiceSequenceProvider 0%->100%, GenerateInvoiceProvider 31%->100%, PdfInvoiceProvider 12%->100%, InvoicesService 43%->100%, InvoicesController 0%->100%
Adds 8 tests covering uploadImage (default folder, custom folder, error handling), deleteImage (success, error -> BadRequestException), and extractPublicIdFromUrl (with/without extension). Fixes jest.mock hoisting issue by using inline factory and direct import references.
- 38 spec files for audit-log, common, contact, dashboard, email, newsletter, users - Fix async throw in audit-log interceptor tap error handler
- Add tests for Providers, ReactQueryProvider, AuthInitializerProvider - Add tests for useAuthInit, useErrorHandler, useLogin hooks - Add comprehensive authStore (Zustand) tests - Add mutationKeys and queryKeys tests
…rkspace, tracking, booking, invoice, payment, notification, dashboard)
…onboarding guide - Remove placeholder test file (frontend/app/__tests__/placeholder.test.ts) - Add root .gitignore with standard ignores - Update CI.yaml: add no-placeholder-tests check, fix formatting - Raise Codecov targets: backend 30% to 80%, frontend 10% to 20% - Update CONTRIBUTING.md and README.md with new coverage targets - Expand backend/docs/data-model.md with biometric fields, audit log, token rotation - Generate erdia ER diagram (backend/docs/erd/backend.md, backend/erdiadb.json) - Update docs/THREAT-MODEL.md with biometric privacy controls - Expand docs/onboarding-guide.md with comprehensive setup guide - Fix backend/package.json erdia CLI path for CJS compatibility - Apply prettier formatting across backend test files Closes NovaCoreLabs1#140 (Document PostgreSQL data model) Closes NovaCoreLabs1#145 (Contract test coverage threshold + CI gate)
…g guide (NovaCoreLabs1#170) Closes NovaCoreLabs1#140 - Document PostgreSQL data model Closes NovaCoreLabs1#145 - Contract test coverage threshold + CI gate
- Restrict WebSocket CORS from wildcard to specific origins per NODE_ENV\n- Add Helmet middleware for security headers (CSP, HSTS, X-Frame-Options, etc.)\n- Add per-endpoint rate limiting on all 12 public auth endpoints\n- Re-enable gitleaks secrets scanning CI workflow\n- Re-enable semgrep reentrancy guard CI job\n\nCloses NovaCoreLabs1#109, NovaCoreLabs1#110, NovaCoreLabs1#111, NovaCoreLabs1#115, NovaCoreLabs1#119, NovaCoreLabs1#122
The upgradeInsecureRequests CSP directive is now only applied in production to avoid edge cases in local development over plain HTTP (e.g. hot-reload servers).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked Issue\nCloses #109, #110, #111, #115, #119, #122\n\n## Description\nBatch of security hardening improvements across the backend:\n\n- WebSocket CORS restriction: Replaced permissive cors: { origin: '*' } on the notifications gateway with environment-specific allowed origins matching the HTTP CORS policy.\n- Helmet security headers: Added Helmet middleware with CSP configuration for Swagger UI compatibility. Includes HSTS, X-Frame-Options, X-Content-Type-Options, and other security headers.\n- Auth endpoint rate limiting: Added per-endpoint @Throttle() decorators to all 12 public auth endpoints (login: 5/min, register: 3/min, forgot-password: 3/min, OTP: 5/min, etc.).\n- Re-enabled secrets scan CI: Uncommented the gitleaks workflow triggers (push, PR, daily schedule, manual dispatch).\n- Re-enabled semgrep CI: Uncommented the reentrancy guard enforcement job.\n- Production-only CSP directive: Made upgradeInsecureRequests conditional on NODE_ENV === 'production' to avoid dev edge cases.\n\n## Test Plan\n- cd backend && npm run build — passes\n- cd backend && npm test — all 92 suites, 682 tests pass\n\n## Breaking Changes\nNo breaking changes.