Chess Masters is a small multiplayer chess web app built with Express + EJS, real-time gameplay via Socket.IO, and persistent user accounts stored in MongoDB. The server validates moves using the chess.js library. Authentication uses JWT stored in an HTTP-only cookie.
- Node.js + Express (app.js)
- EJS templates (views/index.ejs, views/login.ejs, views/signup.ejs, views/profile.ejs)
- MongoDB + Mongoose (model:
User) - JWT authentication via cookies (middleware:
auth) - Real-time comms with Socket.IO (server: app.js, client: public/javascripts/chessgame.js)
- chess.js for move validation
- TailwindCSS + custom CSS (public/stylesheets/style.css)
- Client-side JS for auth (public/javascripts/auth.js)
- Install dependencies:
npm install- Ensure MongoDB is running and accessible. Default URI is in the project's .env file:
- MONGODB_URI (default:
mongodb://localhost:27017/chess-app) - JWT_SECRET
- PORT (optional)
- Start the server:
node app.jsOpen http://localhost:3000 (or your configured PORT).
Note: package.json does not include a
startscript by default — start withnode app.jsor add a script.
- Main server: app.js
- User model:
User - Authentication middleware:
auth - Client auth handling: public/javascripts/auth.js
- Client game logic: public/javascripts/chessgame.js
- Styles: public/stylesheets/style.css
- Views: views/index.ejs, views/login.ejs, views/signup.ejs, views/profile.ejs
- Data placeholder: data/users.json
- Project deps: package.json
- Env file: .env
Public (no auth):
- GET /login — login page (views/login.ejs)
- GET /signup — signup page (views/signup.ejs)
- POST /api/login — authenticate (implemented in app.js)
- POST /api/signup — create user (implemented in app.js)
Protected (requires JWT cookie, enforced by auth):
- GET / — main game page (views/index.ejs)
- GET /logout — clears cookie (note: route is GET
/logoutin server)
Client side code:
- public/javascripts/auth.js calls
/api/login,/api/signupand attempts/api/logout(see Known issues).
- Signup/login endpoints create or verify a user via
User. - On success the server signs a JWT with
JWT_SECRETand sets it as an HTTP-only cookie namedtoken. - The
authmiddleware reads the cookie, verifies the JWT, loads the user from DB and attachesreq.userfor protected routes. - Views use
req.user(e.g., views/index.ejs showsuser.username).
- On Socket.IO connection (app.js), the server assigns roles: white, black, or spectator.
- The chess game state is managed server-side using chess.js (
new Chess()in app.js). - Client emits
"move"with coordinates (client: public/javascripts/chessgame.js). Server validates with chess.js, broadcasts"move"and"boardState"(FEN) to all clients. - Client listens for
"boardState"and"move"to update the UI.
- Drag-and-drop UI and coordinate mapping live in public/javascripts/chessgame.js.
- Authentication UI (login/signup forms, alerts) lives in public/javascripts/auth.js.
- Logout mismatch: client logout in public/javascripts/auth.js posts to
/api/logout(POST), but the server exposesGET /logout. Update either client or server for consistency. - No
startscript in package.json — add"start": "node app.js"if desired. - Consider rate limiting, stronger JWT secret management, HTTPS in production, and CSRF protections for added security.
- The server currently assigns player roles purely by connection order and does not persist games or reconnect players to prior roles.
- JWT secret is stored in
.env— do not commit secrets to git. - Cookies are HTTP-only; in production they are marked
securewhen NODE_ENV isproduction. - Passwords are hashed with bcrypt (see
User).
- Server entry: app.js
- Authentication:
Userandauth - Client game UI: public/javascripts/chessgame.js
- Client auth: public/javascripts/auth.js
- Views: views/index.ejs, views/login.ejs, views/signup.ejs, views/profile.ejs