fix production issues
Build & Push / Pipeline Tests (push) Failing after 59s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Failing after 51s
Test / API Unit Tests (push) Has been skipped
Test / Homepage Unit Tests (push) Has been skipped
Test / Carplace Unit Tests (push) Has been skipped
Test / Admin Unit Tests (push) Has been skipped
Test / Dashboard Unit Tests (push) Has been skipped
Test / API Integration Tests (push) Has been skipped

This commit is contained in:
root
2026-08-12 16:48:41 -04:00
parent 53de25120a
commit 8fc88ffc14
117 changed files with 4717 additions and 1443 deletions
+54
View File
@@ -0,0 +1,54 @@
# Security design updates (Phases 0 & 3)
Summary of application-security design changes from the production-readiness program. Full finding table lives in `docs/ops/RentalDriveGo_Production_Readiness_Plan.md` §3.
## Closed in code (S1S15)
| ID | Design rule now enforced |
|----|---------------------------|
| S1 | Team list/invite responses use safe presenters — never return password hashes or raw reset tokens |
| S2 | Per-tenant Docker/Compose orchestration is **out of production scope** (fail-closed + ADR-001) |
| S3 | Invite tokens hashed at rest (SHA-256) |
| S4 | Employee email unique per company; login fails closed on ambiguity |
| S5 | Post-login redirects limited to safe relative paths |
| S6 | Authenticated payment/subscription return URLs allowlisted |
| S7 | Admin company slugs validated / slugified |
| S8 | Admin presenters strip reset/verification secrets |
| S9 | Forwarded headers scrubbed by default; `TRUSTED_FORWARD_HEADERS=true` only behind a scrubbing edge (`docs/ops/proxy-trust.md`) |
| S10 | Password reset token lookup is hash-only |
| S11 | `reviewToken` is never returned in reservation/review API JSON (still used server-side for email links) |
| S12 | Public booking access: **read** does not burn the token; **payment init** atomically consumes an unused token |
| S13 | Admin money / privileged mutations require 2FA proof newer than `ADMIN_FRESH_2FA_MAX_AGE_MS` |
| S14 | `.gitignore` present for secrets/build artifacts |
| S15 | `npm run security:static` in CI |
## Public booking token (S12) flow
```
createBooking → mint publicAccessToken (hash stored)
├─ GET booking?token=… → validate (used or unused OK until expiry) — do not consume
└─ initPayment(token) → require usedAt IS NULL → updateMany set usedAt → proceed
(second payment attempt with same token → 404)
```
## Fresh admin 2FA (S13)
`requireFreshAdmin2FA` rejects when:
- TOTP not enrolled, or
- JWT lacks `last2faAt`, or
- `now - last2faAt > ADMIN_FRESH_2FA_MAX_AGE_MS` (default 30 minutes)
Wired on finance/support money and high-privilege admin mutations.
## Tenant isolation design
- App-level: every company resource query includes `companyId` from the authenticated session
- Regression suite: `apps/api/src/tests/integration/cross-tenant-isolation.test.ts`
- Postgres RLS: **deferred** (ADR-002) until the app-level suite and worker/migration roles are ready
## Pen-test
Scope pack: `docs/security/pen-test-scope.md`. Reports belong under `security-reports/` (evidence, not design).