feat: add ConfigModule startup validation with Joi schema#118
feat: add ConfigModule startup validation with Joi schema#118GitAddRemote merged 10 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces startup-time environment variable validation for the NestJS backend via a Joi schema, ensuring misconfigurations fail fast before the app boots. It also includes a significant (and currently undocumented) shift in auth token handling toward httpOnly cookies.
Changes:
- Add
envValidationSchema(Joi) and wire it intoConfigModule.forRoot()withabortEarly: false. - Update example/test env files to reflect new required variables (notably
JWT_REFRESH_SECRET). - Migrate auth token transport toward cookies (adds
cookie-parser, JWT extraction from cookies, refresh token guard reads cookie, and login/refresh set cookies).
Reviewed changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds joi + cookie-parser, removes passport-http-bearer and related typings. |
| backend/package.json | Declares new runtime deps (joi, cookie-parser) and typings. |
| backend/src/config/env.validation.ts | New Joi schema defining required/optional env vars and defaults. |
| backend/src/app.module.ts | Enables ConfigModule validation using the new schema and options. |
| backend/src/main.ts | Registers cookie parser, tightens CORS for credentialed requests, retains Swagger bearer auth config. |
| backend/src/modules/auth/jwt.strategy.ts | Switches JWT extraction to cookie-based extractor. |
| backend/src/modules/auth/refresh-token-auth.guard.ts | Replaces Passport guard with cookie-based refresh token guard. |
| backend/src/modules/auth/auth.controller.ts | Sets access/refresh tokens as httpOnly cookies; login/refresh responses changed. |
| backend/src/modules/auth/auth.service.ts | Returns camelCase token fields from login/refresh. |
| backend/src/modules/auth/auth.module.ts | Removes refresh-token Passport strategy provider. |
| backend/src/modules/auth/refresh-token.strategy.ts | Deletes Bearer refresh token strategy (passport-http-bearer). |
| backend/.env.example | Documents all schema variables and adds JWT refresh secret. |
| backend/.env.test | Adds JWT_REFRESH_SECRET and lengthens JWT secrets to satisfy schema. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Moves access and refresh tokens out of the response body and into httpOnly cookies to prevent XSS-based token theft. Changes: - Register cookie-parser middleware in main.ts - CORS configured with credentials: true for cross-origin cookie support - JwtStrategy extracts access_token from req.cookies - login sets access_token (15m) and refresh_token (7d) as httpOnly cookies - refresh rotates both cookies; logout clears them - RefreshTokenAuthGuard rewritten as CanActivate reading refresh_token cookie - Remove passport-http-bearer dependency (no longer needed) Closes #93
Adds environment variable validation at boot time so misconfigured deployments fail immediately with a clear error rather than silently booting and crashing at runtime on first usage. Changes: - Install joi - Add src/config/env.validation.ts with Joi schema covering all vars - JWT_SECRET and JWT_REFRESH_SECRET required, minimum 32 chars enforced - DATABASE_* credentials required; connection config defaults provided - REDIS, CORS, and FRONTEND_URL have sensible local defaults - UEX sync vars all optional with defaults (service degrades gracefully) - validationOptions.abortEarly: false reports all missing vars at once - Update .env.example to document every variable in the schema - Update .env.test to satisfy the new required JWT_REFRESH_SECRET Closes #97
f25b084 to
4fdd24d
Compare
- Extend JWT_SECRET to 32+ chars in all CI jobs to satisfy Joi min(32) - Add JWT_REFRESH_SECRET to all CI jobs (now required by env validation) - Add USE_REDIS_CACHE=false to unit and E2E test jobs - Replace Bearer token auth with httpOnly cookie auth in all E2E test files (roles, organizations, user-organization-roles, auth-password-reset) - Add cookie-parser middleware to all E2E test app instances
There was a problem hiding this comment.
Pull request overview
Adds startup environment validation to the NestJS ConfigModule using a Joi schema so misconfigured deployments fail fast, and updates test/CI env files accordingly. The PR also changes authentication to rely on httpOnly cookies (access/refresh tokens) and updates e2e tests to match.
Changes:
- Introduces
envValidationSchemaand wires it intoConfigModule.forRoot()withabortEarly: false. - Updates
.env.example,.env.test, and GitHub Actions env to satisfy the new required variables (notablyJWT_REFRESH_SECRET) and document all schema vars. - Switches auth flows/strategies/guards and e2e tests from Bearer headers to cookie-based tokens (adds
cookie-parserand enables CORS credentials).
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds joi and cookie-parser (and types) to the lockfile; removes passport-http-bearer entries. |
| backend/package.json | Adds joi, cookie-parser, @types/cookie-parser; removes passport-http-bearer + types. |
| backend/src/config/env.validation.ts | New Joi schema defining required/defaulted environment variables. |
| backend/src/app.module.ts | Applies Joi validation schema/options to global ConfigModule. |
| backend/src/main.ts | Registers cookie-parser, switches config reads to ConfigService, enables credentialed CORS, updates Swagger bearer config. |
| backend/src/modules/auth/refresh-token.strategy.ts | Removes the passport-http-bearer refresh-token strategy implementation. |
| backend/src/modules/auth/refresh-token-auth.guard.ts | Replaces Passport guard with a custom cookie-based refresh token guard. |
| backend/src/modules/auth/jwt.strategy.ts | Changes JWT extraction to read from access_token cookie. |
| backend/src/modules/auth/auth.service.ts | Renames token fields to accessToken/refreshToken in service return types. |
| backend/src/modules/auth/auth.module.ts | Drops RefreshTokenStrategy from providers. |
| backend/src/modules/auth/auth.controller.ts | Sets/clears auth cookies on login/refresh/logout; updates route descriptions accordingly. |
| backend/test/user-organization-roles.e2e-spec.ts | Updates e2e auth to use cookies; still references loginResponse.body.userId. |
| backend/test/roles.e2e-spec.ts | Updates e2e auth to use cookies. |
| backend/test/organizations.e2e-spec.ts | Updates e2e auth to use cookies. |
| backend/test/auth-password-reset.e2e-spec.ts | Updates e2e auth to use cookies for change-password tests. |
| backend/.env.test | Adds JWT_REFRESH_SECRET and lengthens JWT_SECRET to satisfy schema. |
| backend/.env.example | Documents all env vars in the Joi schema (including JWT refresh secret and UEX settings). |
| .github/workflows/backend-ci.yml | Updates CI env to include JWT_REFRESH_SECRET and uses longer JWT secrets. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Use Joi.boolean() for UEX_*_SYNC_ENABLED vars so env strings like
'false' are coerced to actual booleans; configService.get<boolean>()
in the UEX sync scheduler would treat string 'false' as truthy
- Refactor auth cookie options into a private cookieOptions(maxAge) helper
to eliminate duplication across login/refresh/logout; change sameSite
from 'lax' to 'strict' to minimize CSRF surface
- Derive clearCookie options from cookieOptions() to keep security flags
in sync; clear with same httpOnly/secure/sameSite as when setting
- Return { message, username } from login so clients can identify the
authenticated user without a separate round-trip
- Add Authorization: Bearer header as fallback extractor in JwtStrategy
(after cookie) so Swagger UI and non-browser clients continue to work
- Align @ApiBearerAuth decorator with Swagger scheme name 'access-token'
- Capture userId from /auth/register response instead of login body since
login no longer returns userId in the response
There was a problem hiding this comment.
Pull request overview
This PR introduces startup-time environment variable validation for the NestJS backend using a centralized Joi schema, ensuring misconfigurations are caught before the app boots. It also includes supporting updates to authentication (cookie-based token transport) and test/CI env configuration to remain compatible with the new validation requirements.
Changes:
- Add a Joi
envValidationSchemaand wire it intoConfigModule.forRoot()withabortEarly: false. - Update backend auth flow and E2E tests to use httpOnly cookies (
access_token/refresh_token) and registercookie-parser. - Update
.env.example,.env.test, and backend CI workflow env vars to satisfy new required secrets and defaults.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds joi and cookie-parser dependencies; removes passport-http-bearer. |
| backend/package.json | Declares joi, cookie-parser, and @types/cookie-parser; removes passport-http-bearer typings. |
| backend/src/config/env.validation.ts | Introduces Joi schema covering required/optional env vars with defaults and constraints. |
| backend/src/app.module.ts | Enables ConfigModule validation (validationSchema, abortEarly:false) during bootstrap. |
| backend/src/main.ts | Uses ConfigService, registers cookie-parser, and configures CORS for credentialed requests. |
| backend/src/modules/auth/jwt.strategy.ts | Extracts JWT from cookie first, then Authorization header as fallback. |
| backend/src/modules/auth/refresh-token-auth.guard.ts | Switches refresh token extraction to refresh_token cookie. |
| backend/src/modules/auth/auth.service.ts | Renames token response fields to camelCase (accessToken, refreshToken). |
| backend/src/modules/auth/auth.controller.ts | Sets/clears auth cookies on login/refresh/logout; updates Swagger auth decorator usage. |
| backend/src/modules/auth/auth.module.ts | Removes RefreshTokenStrategy provider (no longer needed). |
| backend/src/modules/auth/refresh-token.strategy.ts | Deletes unused bearer-based refresh strategy. |
| backend/test/auth-password-reset.e2e-spec.ts | Updates auth to use cookie-based access token and registers cookie-parser. |
| backend/test/organizations.e2e-spec.ts | Updates authenticated requests to send Cookie: access_token=.... |
| backend/test/roles.e2e-spec.ts | Updates authenticated requests to send Cookie: access_token=.... |
| backend/test/user-organization-roles.e2e-spec.ts | Uses cookie auth and fixes userId derivation from register response. |
| backend/.env.example | Documents all env vars covered by the Joi schema with clearer grouping/comments. |
| backend/.env.test | Adds JWT_REFRESH_SECRET and ensures secrets meet min length requirements. |
| .github/workflows/backend-ci.yml | Adds/extends required JWT secrets (and disables Redis cache in test jobs). |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
configService.get<number>() combined with the Joi schema (Joi.number()) returns a proper number; the string fallback could cause Node to treat a numeric string as a named pipe path.
- Configure Helmet with explicit CSP directives that allow Swagger UI's inline scripts and styles (unsafe-inline on scriptSrc/styleSrc); default Helmet CSP blocks Swagger and leaves the docs page blank - Extract ALLOWED_ORIGIN into a variable with a localhost fallback so CORS never silently falls back to permissive defaults when the env var is unset; origin validation is enforced at startup in PR #118 - Remove cookie-parser, @types/cookie-parser, and joi from package.json as they are unused on this branch; those deps are introduced in the cookie auth (#117) and env validation (#118) PRs respectively
There was a problem hiding this comment.
Pull request overview
Adds startup environment validation for the NestJS backend via ConfigModule.forRoot() + a Joi schema, and updates auth to rely on httpOnly cookies (with test/CI updates) so misconfigured deployments fail fast.
Changes:
- Add
envValidationSchema(Joi) and enable ConfigModule startup validation withabortEarly: false. - Migrate auth flows to cookie-based tokens (cookie-parser middleware, cookie extractors/guards) and update e2e specs accordingly.
- Update
.env.example,.env.test, and CI workflow env vars to satisfy the new validation requirements.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds Joi + cookie-parser deps (and removes passport-http-bearer), updating the lockfile accordingly. |
| backend/package.json | Adds joi and cookie-parser (and types), removes passport-http-bearer. |
| backend/src/config/env.validation.ts | Introduces a Joi schema covering required/optional environment variables with defaults. |
| backend/src/app.module.ts | Enables ConfigModule Joi validation on startup (abortEarly: false). |
| backend/src/main.ts | Uses ConfigService for PORT/APP_NAME, registers cookie-parser, and enables credentialed CORS. |
| backend/src/modules/auth/jwt.strategy.ts | Extracts JWT from access_token cookie with Authorization header fallback; tightens payload typing. |
| backend/src/modules/auth/refresh-token-auth.guard.ts | Switches refresh-token handling to read refresh_token from cookies. |
| backend/src/modules/auth/refresh-token.strategy.ts | Removes the passport-http-bearer refresh token strategy. |
| backend/src/modules/auth/auth.service.ts | Renames token return fields (accessToken/refreshToken) and tightens login() input typing. |
| backend/src/modules/auth/auth.module.ts | Removes refresh strategy provider wiring. |
| backend/src/modules/auth/auth.controller.ts | Sets/clears auth cookies on login/refresh/logout; updates Swagger annotations. |
| backend/test/auth-password-reset.e2e-spec.ts | Updates auth in tests to use cookies rather than Authorization headers. |
| backend/test/organizations.e2e-spec.ts | Updates auth in tests to use cookies rather than Authorization headers. |
| backend/test/roles.e2e-spec.ts | Updates auth in tests to use cookies rather than Authorization headers. |
| backend/test/user-organization-roles.e2e-spec.ts | Updates auth in tests to use cookies; fixes userId source to come from registration response. |
| backend/.env.test | Adds JWT_REFRESH_SECRET and lengthens JWT_SECRET to satisfy Joi validation. |
| backend/.env.example | Documents all env vars covered by the Joi schema (including new/required ones). |
| .github/workflows/backend-ci.yml | Updates CI env to satisfy new JWT secret requirements and adds refresh secret. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Remove unused JWT_REFRESH_SECRET from Joi schema and CI env vars; refresh tokens are opaque DB tokens, not JWTs signed with a secret - Downgrade joi from ^18.1.2 (requires Node >= 20) to ^17.13.3 which is compatible with the project's Node >= 18 requirement - Add @httpcode(HttpStatus.OK) to all auth POST endpoints that document 200 (login, refresh, logout, forgot/reset/change-password) so Swagger docs match actual HTTP status codes - Update e2e tests to expect 200 on those endpoints
There was a problem hiding this comment.
Pull request overview
Adds startup-time environment validation to the NestJS backend via ConfigModule.forRoot() + Joi, while also completing a shift toward httpOnly cookie-based auth (and updating E2E tests/CI env accordingly) so misconfigurations are caught early and auth flows remain testable.
Changes:
- Introduce
envValidationSchema(Joi) and enable ConfigModule startup validation withabortEarly: false. - Register
cookie-parser, read JWTs from cookies (with Bearer-header fallback), and adjust refresh-token handling to use cookies. - Update E2E tests,
.envtemplates, and backend CI env vars to satisfy the new startup validation + auth behavior.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds Joi + cookie-parser dependencies and removes passport-http-bearer. |
| backend/package.json | Declares joi and cookie-parser (+ types) in backend deps. |
| backend/src/config/env.validation.ts | Adds Joi schema for env var validation at startup. |
| backend/src/app.module.ts | Wires validationSchema/validationOptions into ConfigModule.forRoot(). |
| backend/src/main.ts | Uses ConfigService for PORT, registers cookie parser, enables CORS credentials, keeps Swagger bearer scheme. |
| backend/src/modules/auth/jwt.strategy.ts | Extracts JWT from access_token cookie first, then Authorization bearer header. |
| backend/src/modules/auth/refresh-token-auth.guard.ts | Replaces passport strategy guard with cookie-based refresh-token guard. |
| backend/src/modules/auth/refresh-token.strategy.ts | Removes unused passport-http-bearer refresh token strategy. |
| backend/src/modules/auth/auth.service.ts | Renames token return shape to { accessToken, refreshToken }. |
| backend/src/modules/auth/auth.module.ts | Removes RefreshTokenStrategy provider. |
| backend/src/modules/auth/auth.controller.ts | Sets/clears auth cookies and normalizes POST auth endpoints to return HTTP 200. |
| backend/test/auth-password-reset.e2e-spec.ts | Updates tests to use cookies and expect 200 statuses. |
| backend/test/organizations.e2e-spec.ts | Updates tests to use cookies for authenticated requests. |
| backend/test/roles.e2e-spec.ts | Updates tests to use cookies for authenticated requests. |
| backend/test/user-organization-roles.e2e-spec.ts | Updates tests to use cookies and fixes userId sourcing from register response. |
| backend/.env.example | Expands env documentation/comments to match intended schema usage. |
| backend/.env.test | Updates JWT secret(s) used in tests. |
| .github/workflows/backend-ci.yml | Updates CI env vars to satisfy startup validation and avoid Redis dependency in tests. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Aligns docs with the Joi schema which no longer validates this var. Refresh tokens are opaque DB strings, not JWTs, so there is no refresh secret to configure.
There was a problem hiding this comment.
Pull request overview
Adds startup environment validation to the NestJS backend via a centralized Joi schema, so required configuration is checked before the app boots. This PR also includes the (stacked) move toward cookie-based auth by registering cookie-parser, updating JWT extraction, and adjusting E2E tests accordingly.
Changes:
- Introduce
envValidationSchema(Joi) and wire it intoConfigModule.forRoot()withabortEarly: false. - Register
cookie-parser, prefer JWT extraction fromaccess_tokencookie (with Bearer header fallback), and update refresh-token guarding to readrefresh_tokenfrom cookies. - Update E2E tests, example env files, and CI env to satisfy the new configuration requirements and cookie-based auth flow.
Reviewed changes
Copilot reviewed 17 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
backend/src/config/env.validation.ts |
Adds Joi schema covering backend env vars and defaults. |
backend/src/app.module.ts |
Enables ConfigModule startup validation with the Joi schema. |
backend/src/main.ts |
Uses ConfigService for port/name; registers cookie-parser; configures CORS for credentialed cookie auth. |
backend/src/modules/auth/auth.controller.ts |
Sets httpOnly auth cookies on login/refresh; clears them on logout; aligns HTTP status codes. |
backend/src/modules/auth/jwt.strategy.ts |
Extracts JWT from cookies first, with Bearer header fallback; tightens payload typing. |
backend/src/modules/auth/refresh-token-auth.guard.ts |
Reads refresh token from refresh_token cookie (removes passport-http-bearer strategy dependency). |
backend/src/modules/auth/auth.service.ts |
Normalizes token return shape to { accessToken, refreshToken }. |
backend/src/modules/auth/auth.module.ts |
Removes RefreshTokenStrategy provider. |
backend/src/modules/auth/refresh-token.strategy.ts |
Deletes the old bearer refresh-token strategy. |
backend/test/*.e2e-spec.ts |
Updates E2E auth flows to use cookies; updates expected status codes. |
backend/package.json |
Adds joi + cookie-parser; removes passport-http-bearer; adds types for cookie-parser. |
pnpm-lock.yaml |
Lockfile updates for new/removed dependencies. |
backend/.env.example |
Documents all schema vars (including new defaults). |
backend/.env.test |
Updates JWT secret value to satisfy stronger validation. |
.github/workflows/backend-ci.yml |
Updates CI JWT secret and disables Redis cache for test jobs. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…vice, type safety
- Make ALLOWED_ORIGIN and FRONTEND_URL required via Joi when('NODE_ENV')
conditional so production deployments fail fast at startup if either
is unset, while keeping localhost defaults for dev/test
- Inject ConfigService into AuthController and use it in cookieOptions()
instead of process.env.NODE_ENV so cookie security flags come from
the same validated config source as the rest of the app
- Fix LocalStrategy.validate() return type: Omit<UserDto, 'password'>
→ Omit<User, 'password'> (matches what validateUser() actually
returns); replace the indirect Parameters<> cast in the controller
with the direct Omit<User, 'password'> type
- Replace Joi.default() root calls (not valid in joi@17) with Joi.string().uri().default() in the otherwise clause of Joi.when() - Add ConfigService mock provider to auth.controller.spec.ts — required after AuthController gained a ConfigService constructor dependency
There was a problem hiding this comment.
Pull request overview
This PR introduces startup environment validation for the NestJS backend via ConfigModule.forRoot() using a centralized Joi schema, and (as part of the stacked branch) migrates auth flows to use httpOnly cookies (with corresponding guard/strategy/test updates).
Changes:
- Add
envValidationSchema(Joi) and wire it intoConfigModule.forRoot()withabortEarly: falseto fail fast on misconfiguration. - Switch auth token handling toward cookies (
cookie-parser, JWT extractor supports cookie + Bearer fallback; refresh token guard reads cookie). - Update CI/test envs and multiple e2e tests to align with the new auth response/cookie behavior and status codes.
Reviewed changes
Copilot reviewed 19 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds joi and cookie-parser (and types) dependencies; removes passport-http-bearer. |
| backend/package.json | Declares joi, cookie-parser, and @types/cookie-parser; removes passport-http-bearer deps. |
| backend/src/config/env.validation.ts | New Joi schema defining required/defaulted environment variables. |
| backend/src/app.module.ts | Enables ConfigModule validation schema + options at startup. |
| backend/src/main.ts | Registers cookie parsing, config-driven CORS with credentials, and minor logging/swagger adjustments. |
| backend/src/modules/auth/refresh-token.strategy.ts | Removes bearer-based refresh-token passport strategy. |
| backend/src/modules/auth/refresh-token-auth.guard.ts | Reads refresh token from refresh_token cookie and attaches it to req.user. |
| backend/src/modules/auth/local.strategy.ts | Adjusts local strategy typing to User entity-based type. |
| backend/src/modules/auth/jwt.strategy.ts | Extracts JWT from cookie first, with Bearer header fallback; tightens payload typing. |
| backend/src/modules/auth/auth.service.ts | Renames token fields to camelCase in returned token objects. |
| backend/src/modules/auth/auth.module.ts | Removes RefreshTokenStrategy provider registration. |
| backend/src/modules/auth/auth.controller.ts | Sets/clears auth cookies on login/refresh/logout; normalizes POST auth endpoints to HTTP 200; Swagger annotations updated. |
| backend/src/modules/auth/auth.controller.spec.ts | Adds ConfigService provider for updated controller constructor. |
| backend/test/auth-password-reset.e2e-spec.ts | Updates to cookie-based auth and aligns expected status codes with controller. |
| backend/test/organizations.e2e-spec.ts | Updates auth flow to use access_token cookie and registers cookie-parser in test app. |
| backend/test/roles.e2e-spec.ts | Updates auth flow to use access_token cookie and registers cookie-parser in test app. |
| backend/test/user-organization-roles.e2e-spec.ts | Updates auth flow to use cookie auth; captures userId from register response. |
| backend/.env.test | Updates JWT_SECRET to meet minimum length expectation. |
| backend/.env.example | Documents all env vars covered by the Joi schema (including defaults). |
| .github/workflows/backend-ci.yml | Updates CI env vars (e.g., longer JWT_SECRET, disables Redis cache where needed). |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Resolved conflicts across auth, main bootstrap, and e2e tests: - backend/.env.example: keep PR-118 section formatting + FRONTEND_URL; drop duplicate Application/CORS block from main - backend/package.json: keep both helmet (main) and joi (PR-118) - backend/src/main.ts: use main's version — dotenv/config first import, helmet middleware, NODE_ENV validation, isProduction-aware CORS - backend/src/modules/auth/auth.controller.ts: keep ConfigService injection + configService-based cookieOptions from PR-118; add Get import and me() endpoint from main; remove duplicate cookieOptions - backend/src/modules/auth/auth.service.ts: drop redundant inline comment; keep main's cleaner body - backend/src/modules/auth/jwt.strategy.ts: keep main's comments explaining cookie-first / Bearer fallback extraction order - backend/test/*: keep main's explicit array/cookie assertions (expect(Array.isArray), expect(accessTokenCookie).toBeDefined()) over PR-118's silent ?? '' fallbacks - pnpm-lock.yaml: checkout --theirs + pnpm install to add joi entry
There was a problem hiding this comment.
Pull request overview
Adds centralized environment-variable validation to the NestJS backend so misconfigurations fail fast at startup (with aggregated Joi errors), and updates supporting runtime/test/config files accordingly.
Changes:
- Introduces a Joi-based
envValidationSchemaand wires it intoConfigModule.forRoot()withabortEarly: false. - Ensures
.envis loaded before module evaluation inmain.ts, and updates a runtimeprocess.envread to useConfigService. - Updates CI/test/example envs to satisfy the new validation constraints (notably
JWT_SECRETmin length).
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds joi (and transitive deps) to the lockfile. |
| backend/package.json | Adds joi dependency to backend. |
| backend/src/config/env.validation.ts | New Joi schema defining required/defaulted env vars (incl. boolean coercion for UEX flags). |
| backend/src/app.module.ts | Enables ConfigModule startup validation using the new schema. |
| backend/src/main.ts | Loads dotenv at first import to populate process.env early; removes explicit dotenv.config(). |
| backend/src/modules/auth/auth.controller.ts | Uses ConfigService for NODE_ENV when setting cookie secure flag. |
| backend/src/modules/auth/auth.controller.spec.ts | Mocks ConfigService to satisfy new controller dependency in unit tests. |
| backend/test/auth-password-reset.e2e-spec.ts | Updates a comment to reflect cookie-based auth. |
| backend/.env.test | Updates JWT_SECRET to meet Joi minimum length. |
| backend/.env.example | Documents all env vars covered by the validation schema. |
| .github/workflows/backend-ci.yml | Updates CI env values to satisfy validation (JWT secret length; disables Redis cache where needed). |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Summary
Test plan
Closes #97