A complete, production-ready, deployable online examination system for national-level team-based MCQ exams with strict security, anti-cheat, and audit requirements.
- Backend API - Node.js + Express + PostgreSQL + Prisma
- Participant Exam Client - React + TypeScript (Port 3001)
- Unified Dashboard Client - React + TypeScript (Port 3000)
- Frontend: React + TypeScript, Vite, WebSocket client
- Backend: Node.js + Express, PostgreSQL, Prisma ORM, JWT auth with refresh tokens, WebSocket server (Socket.IO)
- Infrastructure: Docker-ready deployment with docker-compose
- DEV: System owner (super-admin) - manages users and system configuration
- ADMIN: Exam creators (executive committee) - manages exams, questions, and teams
- PROCTOR: Human invigilators - monitors exams and verifies compliance
- PARTICIPANT: Team members (CAPTAIN or MEMBER) - takes exams
- β Server-side enforcement mandatory - all permissions validated on backend
- β Frontend role hiding is NOT security
- β JWT-based authentication with role claims
- Teams consist of 3β4 members
- Members may be in different locations
- Each participant has individual login credentials
- Each participant belongs to exactly ONE team
- CAPTAIN: Only role allowed to submit final answers
- MEMBER: Can view questions and suggest answers
- Participants join Google Meet (user-initiated):
- Camera ON
- Microphone ON
- Screen sharing ON
- Human proctor visually verifies compliance
- Proctor marks team as "Meet Verified" in the system
- β Forced fullscreen mode
- β Tab switching detection
- β Right-click disabled
- β Keyboard shortcuts blocked
- β Desktop browsers only (mobile blocked)
- β Exam locked until proctor verification
- MCQ exam with server-side timer
- Auto-save on every selection
- Captain submits final answers
- Auto-submit on timeout
- β Question order randomized per team
- β Option order randomized per team
- β Same order shared across all team members
- β Single-correct MCQs
- β Questions may include images
- β Images clickable to enlarge
- β Opens in in-page modal (no new tabs)
- β Right-click and download disabled on images
- β Auto-save on selection
- β Only captain can submit
- β Auto-submit on timeout
- β Fullscreen enforcement
- β Focus/blur detection
- β Copy/paste disabled
- β Context menu disabled
- β Shortcut blocking (best-effort)
- β All violations logged server-side
- β Violation scoring system with severity levels
- β Threshold-based warnings
- β Proctor/admin alerts via WebSocket
- β Real-time monitoring dashboard
- β Tab switches
- β Fullscreen exits
- β Page reloads
- β DevTools attempts
- β IP changes (can be detected via metadata)
- β Session conflicts (multiple simultaneous logins)
- β Copy/paste attempts
- β Right-click attempts
- β Focus loss
- Client-side AI using MediaPipe or TensorFlow.js (implementation ready)
- Face presence detection
- Multiple faces detection
- Face missing duration tracking
- β Client-side only (no server video processing)
- β Generate events only (no storage of video/images)
- β NEVER auto-disqualify
- β Assistive only for human proctors
FACE_MISSINGMULTIPLE_FACES_DETECTEDFACE_OUT_OF_FRAME
/dev- DEV dashboard (user management)/admin- ADMIN dashboard (exam/team management)/proctor- PROCTOR dashboard (live monitoring)/login- Login page with role-based redirection
After login, automatically routed based on JWT role claim.
Can:
- β Create/edit/delete exams
- β Add/edit/delete MCQs
- β Edit answer options
- β Upload question images
- β Modify question scores/weightage
- β Enable/disable questions
- β Create/edit teams
- β Add/remove team members
- β Assign/change captains
- β Export results
Cannot:
- β Modify submitted answers
- β Modify violation logs
- β Disable audit logging
Can:
- β View live exam status
- β View team activity
- β View violation logs
- β Mark Meet compliance ("Meet Verified" flag)
- β Flag suspicious behavior
- β Add notes to violations
Cannot:
- β Edit exams
- β Edit questions
- β Edit teams
- β Edit scores
Can:
- β Manage admins and proctors
- β View full system logs
- β Modify global configuration
- β Create users of any role
Cannot:
- β Participate in exams
- β Modify submitted answers
Implements internal cryptographic immutability using a hash chain (NO public blockchain).
- β
Every critical action generates a hash:
- Exam start
- Answer save
- Answer submission
- Auto-submit
- Admin force-submit
SHA-256(action_payload + timestamp + previous_hash)
- β Append-only per exam attempt
- β
Store
current_hashandprevious_hash - β Server-generated ONLY
- β Tampering breaks chain
- Admins/Proctors/Devs can only VIEW integrity status
- Cannot edit or regenerate hashes
GET /api/attempts/:attemptId/verify-integrityReturns:
{
"attemptId": "...",
"isValid": true,
"chainLength": 42,
"violations": [],
"message": "Integrity verified"
}Complete schemas implemented for:
- β Users (with role enum)
- β Teams
- β TeamMembers (with team role: CAPTAIN/MEMBER)
- β Exams
- β Questions (with image support)
- β QuestionOptions
- β Attempts (exam attempts by teams)
- β Answers (with auto-save history)
- β Violations (with type, severity, timestamp)
- β AuditLogs (comprehensive audit trail)
- β ExamIntegrityChain (hash chain records)
- β Proper foreign keys
- β Cascading deletes where appropriate
- β Indexes for performance
- Docker & Docker Compose
- Node.js 18+ (for local development)
- PostgreSQL 15+ (for local development)
- Clone the repository
git clone <repository-url>
cd exam-system- Configure environment variables
# Backend
cp backend/.env.example backend/.env
# Edit backend/.env with your configuration
# Dashboard
cp frontend-dashboard/.env.example frontend-dashboard/.env
# Participant
cp frontend-participant/.env.example frontend-participant/.env- Start all services
docker-compose up -d- Run database migrations
docker-compose exec backend npx prisma migrate deploy- Create initial DEV user
docker-compose exec backend npx prisma db seed
# Or manually via API after starting- Access the applications
- Dashboard: http://localhost:3000
- Participant: http://localhost:3001
- Backend API: http://localhost:5000
cd backend
npm install
cp .env.example .env
# Edit .env with local database URL
npx prisma generate
npx prisma migrate dev
npm run devcd frontend-dashboard
npm install
cp .env.example .env
npm run devcd frontend-participant
npm install
cp .env.example .env
npm run devUse prisma migrate dev for local development. This creates new migration files:
cd backend
npx prisma migrate dev --name migration_nameUse prisma migrate deploy for production. This applies existing migrations:
docker-compose exec backend npx prisma migrate deployImportant: Never run prisma migrate dev in production as it can reset data.
DATABASE_URL="postgresql://user:password@localhost:5432/exam_system?schema=public"
JWT_SECRET="your-super-secret-jwt-key-change-in-production"
JWT_REFRESH_SECRET="your-super-secret-refresh-key-change-in-production"
JWT_EXPIRES_IN="15m"
JWT_REFRESH_EXPIRES_IN="7d"
PORT=5000
NODE_ENV="development"
CORS_ORIGIN="http://localhost:3000,http://localhost:3001"
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100VITE_API_URL=http://localhost:5000/api
VITE_WS_URL=http://localhost:5000POST /api/auth/login
POST /api/auth/refresh
POST /api/auth/logout
POST /api/users
GET /api/users
GET /api/users/:id
PUT /api/users/:id
DELETE /api/users/:id
POST /api/teams
GET /api/teams
GET /api/teams/:id
PUT /api/teams/:id
DELETE /api/teams/:id
POST /api/teams/:id/members
DELETE /api/teams/:id/members/:memberId
POST /api/exams
GET /api/exams
GET /api/exams/:id
PUT /api/exams/:id
PATCH /api/exams/:id/status
DELETE /api/exams/:id
POST /api/exams/:id/questions
PUT /api/exams/:id/questions/:questionId
DELETE /api/exams/:id/questions/:questionId
POST /api/exams/:examId/attempt
GET /api/attempts/:attemptId
POST /api/attempts/:attemptId/answers
POST /api/attempts/:attemptId/submit
GET /api/attempts/:attemptId/verify-integrity
POST /api/proctor/violations
GET /api/proctor/violations
PATCH /api/proctor/violations/:id/flag
GET /api/proctor/violations/:attemptId/summary
GET /api/proctor/active-attempts
socket.emit('join:attempt', attemptId);
socket.emit('join:proctor');
socket.emit('violation:detected', violationData);
socket.emit('ai-proctor:event', aiEventData);socket.on('violation:new', (data) => { /* ... */ });
socket.on('ai-proctor:alert', (data) => { /* ... */ });- β JWT-based authentication with access and refresh tokens
- β Access token: 15 minutes expiry
- β Refresh token: 7 days expiry
- β Secure token storage (localStorage)
- β Automatic token refresh on 401
- β bcrypt hashing with salt rounds
- β No plain text passwords stored
- β Helmet.js security headers
- β CORS configuration
- β Rate limiting (100 requests per 15 minutes)
- β Input validation
- β SQL injection protection via Prisma
- β HTTPS recommended for production
- β Environment variables for secrets
- β No hardcoded credentials
The exam interface implements multiple deterrents:
- Fullscreen API enforcement
- Visibility API for tab detection
- Event listeners for context menu, copy, paste
- Keyboard shortcut blocking
- DevTools detection (F12, Ctrl+Shift+I/J/C)
All client-side violations are:
- Detected on client
- Sent via WebSocket to server
- Stored in database with severity
- Displayed to proctors in real-time
- Included in audit trail
- LOW: Right-click attempts, minor focus loss
- MEDIUM: Tab switches, copy/paste attempts
- HIGH: Fullscreen exits, DevTools attempts
- CRITICAL: Session conflicts, IP changes
Proctors can:
- View all violations in real-time
- Add notes to specific violations
- Flag suspicious behavior
- Mark violations as resolved
- Contact team via Google Meet
Each exam attempt maintains a hash chain:
Entry 1: ATTEMPT_STARTED
previousHash: null
currentHash: SHA-256(payload + timestamp + null)
Entry 2: ANSWER_SAVED
previousHash: <hash from Entry 1>
currentHash: SHA-256(payload + timestamp + previousHash)
Entry 3: ANSWER_SAVED
previousHash: <hash from Entry 2>
currentHash: SHA-256(payload + timestamp + previousHash)
Entry N: ANSWER_SUBMITTED
previousHash: <hash from Entry N-1>
currentHash: SHA-256(payload + timestamp + previousHash)
The integrity verification endpoint:
- Fetches all chain entries for an attempt
- Verifies each hash against its payload and previous hash
- Checks chain continuity
- Returns validation status and any violations
If any entry is modified:
- Its hash won't match the computed hash
- The next entry's previous hash won't match
- The chain is broken and reported as compromised
- Post-exam audits
- Dispute resolution
- Compliance verification
- Forensic analysis
- Prepare environment
# Set production environment variables
# Use strong secrets for JWT
# Configure production database
# Set NODE_ENV=production- Build Docker images
docker-compose build- Deploy with docker-compose
docker-compose up -d- Run migrations
docker-compose exec backend npx prisma migrate deploy- Create initial users
# Create DEV user via direct database access or API- Configure reverse proxy (Nginx/Apache)
# Example Nginx configuration
server {
listen 80;
server_name exam.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
server {
listen 80;
server_name exam-participant.example.com;
location / {
proxy_pass http://localhost:3001;
}
}
server {
listen 80;
server_name api.exam.example.com;
location / {
proxy_pass http://localhost:5000;
}
}- Enable HTTPS with Let's Encrypt
certbot --nginx -d exam.example.com- Change all default secrets
- Enable HTTPS
- Configure firewall
- Set up database backups
- Configure log aggregation
- Set up monitoring (CPU, memory, disk)
- Test disaster recovery
- Document incident response procedures
cd backend
npm test- User registration and login
- Role-based access control
- Team creation and management
- Exam creation and configuration
- Question and option management
- Exam start with proctor verification
- Answer auto-save
- Captain-only submission
- Violation detection and logging
- Real-time proctor dashboard
- Hash chain integrity verification
exam-system/
βββ backend/
β βββ src/
β β βββ config/ # Database configuration
β β βββ controllers/ # Route controllers
β β βββ middlewares/ # Auth, RBAC middleware
β β βββ routes/ # API routes
β β βββ services/ # Business logic
β β βββ utils/ # Utilities (JWT, hash chain, logger)
β β βββ index.ts # Server entry point
β βββ prisma/
β β βββ schema.prisma # Database schema
β βββ package.json
βββ frontend-dashboard/
β βββ src/
β β βββ components/ # Reusable components
β β βββ contexts/ # React contexts (Auth)
β β βββ pages/ # Page components
β β βββ services/ # API client
β β βββ types/ # TypeScript types
β β βββ App.tsx # Main app component
β βββ package.json
βββ frontend-participant/
β βββ src/
β β βββ components/ # Reusable components
β β βββ contexts/ # React contexts
β β βββ hooks/ # Custom hooks (socket, anti-cheat)
β β βββ pages/ # Exam pages
β β βββ services/ # API client
β β βββ App.tsx
β βββ package.json
βββ docker-compose.yml
βββ README.md
This is a production system. All changes must:
- Be security-reviewed
- Include tests
- Update documentation
- Follow existing code style
- Not break RBAC or audit trail
[Add your license here]
For issues or questions:
- Check this README
- Review API documentation
- Check application logs
- Contact system administrator
- β Desktop browsers: Chrome, Firefox, Safari, Edge
- β Mobile browsers: Not supported (security restrictions)
- Meet joining is user-initiated (cannot be forced programmatically)
- Browser security prevents automatic camera/mic access
- Proctor must manually verify via visual inspection
- Users can still exit fullscreen (ESC key, F11)
- Exits are detected and logged
- Provide clear warnings to participants
- Best-effort detection only
- Cannot be 100% reliable
- Violations logged for proctor review
- Runs entirely client-side
- No video/images sent to server
- Assistive only, not definitive
- Provides tamper evidence, not prevention
- Cannot stop determined attackers
- Audit trail for post-exam verification
This system provides enterprise-grade security and integrity for online examinations. All requirements from the specification have been implemented with production-ready code quality.
Key Features:
- β Complete RBAC system
- β Team-based collaboration
- β Comprehensive anti-cheat
- β Real-time monitoring
- β Cryptographic audit trail
- β Docker deployment ready
- β Comprehensive documentation
For production deployment, ensure all security best practices are followed and conduct thorough testing.