Skip to content

feat(backend): implement BE-136, BE-131, BE-130, BE-129 - #1108

Open
Mkalbani wants to merge 2 commits into
CodeGirlsInc:mainfrom
Mkalbani:feat/be136-be131-be130-be129-hardening
Open

feat(backend): implement BE-136, BE-131, BE-130, BE-129#1108
Mkalbani wants to merge 2 commits into
CodeGirlsInc:mainfrom
Mkalbani:feat/be136-be131-be130-be129-hardening

Conversation

@Mkalbani

Copy link
Copy Markdown
Contributor

Closes #966
Closes #990
Closes #989
Closes #988

Summary

This PR implements the four backend hardening tickets together because they all touch request handling, logging, and configuration.

BE-136 — Add request correlation IDs to Winston logging

  • Added CorrelationIdMiddleware to generate or honor inbound X-Request-Id, attach it to the request, and echo it back on responses.
  • Added AsyncLocalStorage based correlationId.storage.ts so any log line can pick up the current request ID without threading it through every call.
  • Updated Winston formatting to inject requestId into every JSON log line.
  • Propagated the correlation ID into BullMQ job payloads and restored it inside DocumentProcessor workers.
  • Included requestId in HttpExceptionFilter error responses.
  • Added redaction for authorization, cookie, password, token, and any *_token / *_secret / *_password / *_key fields.

BE-131 — Document secrets management and rotation procedure

  • Added backend/docs/SECRETS.md.
  • Inventoried every backend secret with purpose and blast radius.
  • Documented storage per environment (local .env, platform secret manager, CI secrets).
  • Wrote rotation runbooks for JWT, database, Redis, OAuth, mail, and Stellar secrets.
  • Included a JWT key-id / multi-secret grace-period approach so existing sessions survive rotation.
  • Defined rotation cadence, incident response steps, and contributor dev-credential guidance.

BE-130 — Validate uploaded document files by content

  • Added FileValidationPipe with max-size enforcement, MIME allowlist, and magic-byte sniffing.
  • Rejects archives, executables, and any declared MIME that does not match actual content.
  • Detects PDF active content (embedded files, page actions) via pdf-lib.
  • Strips image metadata with sharp.
  • Switched document storage to randomized UUID keys so the client filename is never a path component.
  • Added GET /documents/:id/download serving with Content-Disposition: attachment, correct Content-Type, and X-Content-Type-Options: nosniff.

BE-129 — Harden CORS configuration

  • Replaced the loose FRONTEND_URL || localhost origin with an exact-origin allowlist.
  • Production startup now throws if FRONTEND_URL is missing.
  • Supports comma-separated FRONTEND_URL values.
  • Restricted allowed methods and headers to what the frontend actually uses.
  • Updated OAuth redirect helper to use the same allowlist-aware resolver.

Verification

  • cd backend && npx tsc --noEmit passes.
  • cd backend && npx jest --no-coverage passes: 45 tests, 12 suites.

Notes for reviewers

  • sharp was added for image metadata stripping; a small local type declaration (backend/src/types/sharp.d.ts) is included because the installed sharp types resolve incorrectly under the project's moduleResolution: node setting.
  • file-type was not added; magic-byte detection is implemented inline to keep dependencies minimal and avoid ESM/CJS interop issues.

- BE-136: request correlation IDs via async local storage, propagated to logs and BullMQ jobs, with log redaction
- BE-131: secrets inventory and rotation runbook
- BE-130: content-based upload validation, randomized storage keys, attachment downloads
- BE-129: hardened CORS with explicit production origin and allowlist
@vercel

vercel Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

@Mkalbani is attempting to deploy a commit to the Mftee's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@Mkalbani Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant