Skip to content

Fix/environment separation - #200

Closed
SanaBalaji208 wants to merge 12 commits into
mainfrom
fix/environment-separation
Closed

SanaBalaji208 wants to merge 12 commits into
mainfrom
fix/environment-separation

Conversation

@SanaBalaji208

@SanaBalaji208 SanaBalaji208 commented Aug 18, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Combines the frontend and backend environment-separation work into a single integration branch and fixes the cross-service configuration issues identified during end-to-end testing. This removes unsafe production localhost fallbacks, standardizes environment variable usage, improves production validation, and ensures the React frontend, middleware, ChessServer, StockfishServer, MongoDB, Apache proxy, and Socket.IO work together correctly.

Type of Change

  • New feature
  • Bug fix
  • Refactor
  • Documentation update
  • Style/UI update
  • Performance improvement
  • Other (please specify): Environment and deployment configuration

Key Changes

  • Frontend: Standardized production environment imports and REACT_APP_* configuration.
  • Frontend: Removed production localhost fallbacks for required middleware, ChessServer, and StockfishServer URLs.
  • Frontend: Added Docker build-time ARG/ENV support so Create React App receives production service URLs during the build.
  • Frontend: Fixed the Stockfish environment variable naming mismatch to use REACT_APP_STOCKFISH_SERVER_URL.
  • CI: Updated frontend production environment injection to use the environment file actually imported by the application.
  • Middleware: Added canonical environment configuration and .env.example.
  • Middleware: Removed the duplicate custom-environment-variables.json configuration.
  • Middleware: Added production environment validation and prevented unsafe production MongoDB fallback behavior.
  • Middleware: Added comma-separated CORS allowlist handling.
  • ChessServer and StockfishServer: Added production environment validation and environment-driven CORS allowlists.
  • Docker: Updated development and production Compose environment configuration.
  • Integration: Added support for both http://localhost and http://localhost:3000 during local integrated testing through Apache.
  • Integration: Combined fix/frontend-environment and fix/backend-environment into fix/environment-separation.

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • Manual testing performed
  • All tests pass

Testing completed:

  • React: 27/27 test suites passed, 149/149 tests passed.
  • ChessServer: 3/3 test suites passed, 30/30 tests passed.
  • StockfishServer: 2/2 test suites passed, 12/12 tests passed.
  • React production Docker build passed.
  • Middleware connected successfully to MongoDB.
  • Login with seeded development user passed.
  • Authenticated /leaderboard API request passed.
  • Middleware routing through Apache passed.
  • ChessServer routing through Apache passed.
  • Stockfish health routing through Apache passed.
  • Browser-origin CORS passed for middleware, ChessServer, and StockfishServer.
  • Direct ChessServer Socket.IO connection passed.
  • Direct StockfishServer Socket.IO connection passed.
  • Apache → ChessServer Socket.IO proxy connection passed.
  • git diff --check passed.
  • No unresolved merge conflicts.

Bugs Fixed (if applicable)

  • Fixed production frontend service URLs silently falling back to localhost when required environment variables were missing.
  • Fixed frontend environment variables being supplied at container runtime instead of React build time.
  • Fixed mismatch between REACT_APP_STOCKFISH_URL and REACT_APP_STOCKFISH_SERVER_URL.
  • Fixed middleware CORS configuration not supporting multiple comma-separated origins.
  • Fixed local Apache integration where browser origin http://localhost was rejected by backend services.
  • Fixed duplicate middleware environment configuration.
  • Fixed production startup behavior that could fall back to unsafe development database behavior.
  • Fixed backend production environment variable naming/configuration inconsistencies.

TODO (Follow-up Work)

  • Rotate any credentials or secrets that may have existed in previously committed configuration/history.
  • Move long-term production secret storage to a managed solution such as Azure Key Vault / Azure Container Apps secrets.
  • Continue with CI/CD implementation after this environment-separation PR is reviewed and merged.
  • Review the remaining legacy production frontend/nginx deployment configuration separately before the next production deployment.
  • Review existing repository-wide dependency/security findings separately from this PR.

Additional Notes

config/default.js contains configuration structure and non-secret defaults only. Real production secrets are expected to be supplied through environment variables rather than committed configuration files.

This PR intentionally combines both environment branches into one integration PR so the frontend and backend configuration changes are reviewed and validated together.

sweksha-cloud and others added 8 commits August 14, 2026 04:24
Wraps middlewareURL, stockfishServerURL, chessServerURL, and the Agora
appId so they can be overridden at build time via REACT_APP_MIDDLEWARE_URL,
REACT_APP_STOCKFISH_SERVER_URL, REACT_APP_CHESS_SERVER_URL, and
REACT_APP_AGORA_APP_ID, falling back to the existing placeholder values
when unset. Also adds productionType for parity with environment.js.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…imports

The frontend build step wrote secrets to src/core/environments/environment.ts,
a path nothing in the app imports, so MIDDLEWARE_URL/STOCKFISH_URL/CHESS_SERVER/
APP_ID never reached the built app. Replaced that dead step with REACT_APP_*
env vars on the build step, which environment.prod.js now reads directly.

Also adds a workflow_dispatch trigger so this workflow can be run manually
against any branch going forward, without changing existing push/pull_request
behavior.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every consumer builds requests as `${middlewareURL}/path`, adding its own
leading slash. The placeholder fallbacks had a trailing slash too, which
would produce a double slash (e.g. middleware//auth/login) in any build
that reaches these fallbacks. Dropped the trailing slash to match the
no-trailing-slash convention every call site assumes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Saritahimthani
Saritahimthani previously approved these changes Aug 22, 2026
@Saritahimthani

Copy link
Copy Markdown
Collaborator

Hey Sahana
Why PR #200 now conflicts
Root cause: Two people fixed the same vulnerability in the same file at the same time.

stockfishServer/src/index.js had wide-open CORS (origin: "*", app.use(cors())) — a real security hole.
You fixed it in PR #200 (part of the broader env-separation work).
ToldYO (Ahmad Nakhala) independently fixed the exact same hole in the exact same file in PR #199 ("protect backend routes and add authentication/authorization guards").
PR #199 merged into main yesterday (Aug 23). PR #200 was opened before that and never rebased, so as of today it conflicts against the version now sitting on main.
The only conflicting file: stockfishServer/src/index.js, lines ~11–72 (the CORS/allowedOrigins setup block). Everything else in the PR — CI, Docker, middlewareNode, chessServer, the frontend — merges clean.
so pull the changes and then resolve the conflucts and then update the pr

@sweksha-cloud sweksha-cloud self-assigned this Aug 25, 2026
…ation

# Conflicts:
#	stockfishServer/src/index.js
sweksha-cloud and others added 2 commits August 25, 2026 16:02
callback(new Error(...)) in the origin function makes cors call
next(err), and no error-handling middleware is registered, so a
mismatched Origin produced an unhandled 500 (with a leaked stack
trace outside production) instead of just omitting CORS headers.
Matches the callback(null, false) pattern already used in
chessServer/stockfishServer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
credentials: true was unconditional even when allowedOrigins includes
"*", which is an unsafe combination (credentialed requests with a
wildcard origin). Brings this in line with the equivalent guard
already applied to stockfishServer: computes hasWildcard once and
sets credentials: !hasWildcard.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@sweksha-cloud

Copy link
Copy Markdown
Collaborator

Merge conflict resolved + two additional fixes from today's review pass

Following up on the conflict flagged above — pulled main, resolved the conflict in stockfishServer/src/index.js, and pushed (a54ddbc). Also found and fixed two related issues while in there. Summary:

  1. Merge conflict fixed (stockfishServer/src/index.js)
    Reconciled feat(security): protect backend routes and add authentication/authori… #199's and Fix/environment separation #200's independent CORS fixes into one version:
  1. Fixed: unhandled 500 on CORS rejection (middlewareNode/src/server.js)
    Same root cause as the conflict above — callback(new Error(...)) with no registered error handler, so any request with a disallowed Origin header threw a 500 (leaking a stack trace outside production) instead of a clean CORS rejection. Changed to callback(null, false). Added middlewareNode/tests/cors.test.js to cover it going forward — nothing in the existing suite touched CORS behavior before this.

  2. Fixed: unsafe wildcard+credentials combination (chessServer/src/index.js)
    credentials: true was unconditional, even when allowedOrigins includes "*". Brought this in line with the same guard now in stockfishServer — credentials: !hasWildcard. Added chessServer/src/tests/cors.test.js to cover it.

Both fixes pushed (77d6034, 9be2645). Full test counts unchanged from what's in the PR description (React 27/27, chessServer now 33/33 with the new test, stockfishServer 12/12, middlewareNode 204/204 with the new test) — no regressions from any of this.

Separately flagged, not fixed here: sent Sahana a question about whether dropping chessClientURL from environment.prod.js was intentional (it looks like it was already dead/placeholder config tied to a TODO(merge-chessclient-refactor) comment in PlayStudent.tsx, not an active regression, but wanted to confirm before touching it).

Logged as a follow-up, not blocking this PR: chessServer and stockfishServer each maintain their own copy of the CORS allowlist/wildcard logic — the duplication that let #199 and #200 collide in the first place. A real shared-module fix isn't trivial here since each service's Docker build context is scoped to its own directory (context: ../../chessServer, etc.), so it'd also mean restructuring the Docker build, not just the CORS code. Recommend scoping that as its own task rather than folding it into an already-large PR.

@sweksha-cloud

Copy link
Copy Markdown
Collaborator

Closing this in favor of a new PR with SSH-signed commits, since branch protection requires signed commits and these predate that being set up.
▎
▎ Same final changes, rebased onto the latest main and squashed into one signed commit: #208
▎
▎ This branch (fix/environment-separation) is left as-is if we need to reference the original commit history — no need to delete it yet.

@sweksha-cloud sweksha-cloud mentioned this pull request Aug 27, 2026
5 of 13 tasks
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.

4 participants