Skip to content

fix: Standardize API errors, add Vercel/Render deployment guide, secure JWT secrets#585

Merged
Wilfred007 merged 2 commits intoGildado:mainfrom
leojay-net:fix/439-438-457-api-errors-deployment-guide-jwt-security
Apr 22, 2026
Merged

fix: Standardize API errors, add Vercel/Render deployment guide, secure JWT secrets#585
Wilfred007 merged 2 commits intoGildado:mainfrom
leojay-net:fix/439-438-457-api-errors-deployment-guide-jwt-security

Conversation

@leojay-net
Copy link
Copy Markdown
Contributor

Summary

Closes #439 | Closes #438 | Closes #457


#439 – Standardize API Error Response Format

Problem: API errors were inconsistent across the codebase — various shapes like { error }, { error, details }, { message }.

Solution:

  • Added backend/src/utils/apiError.ts with apiErrorResponse(code, message, details) helper and ErrorCodes constants
  • All errors now return { code: string, message: string, details: unknown[] }
  • Updated global 404/500 handlers in app.ts
  • Updated middlewares/auth.ts JWT authentication errors
  • Updated authController.ts (register, login, 2FA setup/verify/disable, refresh)
  • Updated employeeController.ts (create, getAll, getOne, update, delete)
  • Updated affected tests to assert code and message fields
  • Added 9 unit tests in backend/src/utils/__tests__/apiError.test.ts

#438 – Detailed Deployment Guide for Vercel/Render

Problem: No step-by-step cloud deployment documentation existed.

Solution:

  • Added DEPLOYMENT_GUIDE_CLOUD.md at the repository root covering:
    1. Generating cryptographically strong secrets
    2. Creating PostgreSQL + Redis on Render
    3. Configuring the Render web service (build/start commands, env vars)
    4. Running DB migrations post-deploy
    5. Deploying the Vite frontend to Vercel
    6. Wiring CORS between backend and frontend
    7. Post-deployment smoke tests
  • Includes env vars reference table, JWT secret rotation section, and troubleshooting

#457 – Secure JWT Keys with Environment Variables

Problem: If JWT secrets were left as placeholders, the server started silently with insecure tokens.

Solution:

  • Added backend/src/utils/jwtSecurity.ts with:
    • validateJwtSecret() — rejects missing, short, or placeholder values
    • validateSecretsAreDistinct() — rejects reuse of the same secret for both tokens
    • assertJwtSecretsSecure() — logs actionable errors and calls process.exit(1) if insecure
  • Wired assertJwtSecretsSecure(process.env) into src/index.ts — server aborts before binding
  • Added 17 unit tests in backend/src/utils/__tests__/jwtSecurity.test.ts

Test Results

PASS src/utils/__tests__/apiError.test.ts        (9 tests)
PASS src/utils/__tests__/jwtSecurity.test.ts     (17 tests)
PASS src/controllers/__tests__/authController.test.ts    (6 tests)
PASS src/controllers/__tests__/employeeController.test.ts  (10 tests)

Pre-existing failures in the repo (e.g. env.test.ts STELLAR_NETWORK_PASSPHRASE, logger.test.ts) are unrelated to this PR and existed on main before these changes.

… deployment guide, secure JWT secrets

## Gildado#439 – Standardize API Error Response Format

- Add src/utils/apiError.ts with apiErrorResponse() helper and ErrorCodes constants
- All errors now return { code: string, message: string, details: unknown[] }
- Update global 404 and 500 handlers in app.ts
- Update authenticateJWT middleware to use standardized format
- Update authController.ts (register, login, 2FA setup/verify/disable, refresh)
- Update employeeController.ts (create, getAll, getOne, update, delete)
- Update authController tests and employeeController tests to match new format
- Add unit tests: src/utils/__tests__/apiError.test.ts (9 cases)

## Gildado#438 – Detailed Deployment Guide for Vercel/Render

- Add DEPLOYMENT_GUIDE_CLOUD.md with step-by-step cloud hosting instructions
- Covers: Vercel (frontend) + Render (backend + PostgreSQL + Redis)
- Includes: environment variables table, CORS config, DB migrations, post-deploy checks
- JWT secret rotation section with zero-downtime strategy
- Troubleshooting section (CORS, DB connection, Render sleep tier)

## Gildado#457 – Secure JWT Keys with Environment Variables

- Add src/utils/jwtSecurity.ts with validateJwtSecret() / checkJwtSecrets() / assertJwtSecretsSecure()
- Server aborts at startup (process.exit(1)) when JWT_SECRET / JWT_REFRESH_SECRET are missing,
  too short, are known placeholder values, or are identical to each other
- Wire assertJwtSecretsSecure() call into src/index.ts before server bind
- Add unit tests: src/utils/__tests__/jwtSecurity.test.ts (17 cases)
- env.ts already enforces secrets via Zod schema; this layer adds human-readable log output

Closes Gildado#439
Closes Gildado#438
Closes Gildado#457
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 22, 2026

@leojay-net 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

@Wilfred007 Wilfred007 merged commit 8f63417 into Gildado:main Apr 22, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

#160: Secure JWT Keys with Environment Variables #145: Standardize API Error Response Format #197: Detailed Deployment Guide for Vercel/Render

2 participants