A modern, secure web-based seat allocation system for JEE counselling with complete authentication and role-based access control. Built with React, TypeScript, Node.js, Express, and MySQL.
- Features
- Quick Start
- Authentication System
- Project Structure
- API Documentation
- User Roles & Permissions
- Contributing
- Testing
- β Role-Based Access Control - Student, Institute, and Administrator roles
- β Secure Authentication - Login/logout with session management
- β Student Portal - View profile, allocations, and manage choice filling
- β Institute Portal - Manage institute information
- β Admin Dashboard - Complete system control
- β Public Data Access - Seat matrix and opening/closing ranks accessible to all
- β Responsive Design - Works seamlessly on desktop and mobile devices
- β RESTful API architecture
- β JWT-ready authentication system
- β SQL injection protection
- β Role-based route protection
- β Automatic session handling
- β Data isolation per user role
- Node.js v16 or higher
- MySQL v8.0 or higher
- npm or yarn package manager
# Login to MySQL
mysql -u root -p
# Create database
CREATE DATABASE jossaDATABASE;
USE jossaDATABASE;
exit
# Import all schemas and sample data
mysql -u root -p jossaDATABASE < DBMS_TermProject.sql
mysql -u root -p jossaDATABASE < authentication.sql
mysql -u root -p jossaDATABASE < insert_sample_data.sqlcd server
npm install
# Create .env file
cat > .env << EOF
PORT=5000
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_mysql_password
DB_NAME=jossaDATABASE
NODE_ENV=development
EOF
# Start the server
npm startThe server will run on http://localhost:5000
cd client
npm install
# Optional: Create .env file for custom API URL
# echo "VITE_API_BASE_URL=http://localhost:5000/api" > .env
# Start the development server
npm run devThe client will run on http://localhost:5173
Open your browser and navigate to http://localhost:5173
The application implements a comprehensive role-based authentication system that controls access to data based on user roles and login status.
User Login β Validate Credentials β Store User Data β Include Auth Headers in Requests
β β
Generate Session Check Role & Permissions
β β
Return User Data Allow/Deny Access
All authenticated requests automatically include:
{
'x-user-id': userID,
'x-user-role': 'Student' | 'Institute' | 'Administrator',
'x-candidate-id': candidateID, // for students
'x-institute-code': instituteCode // for institutes
}- User data stored in browser's localStorage
- Automatic redirect to login on 401 (Unauthorized)
- Session cleared on logout
- Persistent across browser refreshes
project/
βββ client/ # React Frontend
β βββ src/
β β βββ components/ # Reusable components
β β β βββ Header.tsx # Navigation with role-based menu
β β βββ pages/ # Page components
β β β βββ Home.tsx
β β β βββ Login.tsx
β β β βββ Register.tsx
β β β βββ Candidates.tsx # Student profile (protected)
β β β βββ Allocations.tsx # Seat allocations (protected)
β β β βββ ChoiceFilling.tsx # Choice management (student only)
β β β βββ Institutes.tsx # Institute listing
β β β βββ SeatMatrix.tsx # Public seat matrix
β β β βββ Ranks.tsx # Public opening/closing ranks
β β βββ services/
β β β βββ api.ts # API client with auth interceptors
β β βββ utils/
β β βββ auth.ts # Authentication utilities
β βββ package.json
β
βββ server/ # Node.js Backend
β βββ config/
β β βββ database.js # MySQL connection
β βββ controllers/ # Request handlers
β β βββ authController.js # Login/register/logout
β β βββ candidateController.js
β β βββ instituteController.js
β β βββ choiceController.js
β β βββ commonController.js
β βββ middleware/
β β βββ auth.js # Authentication & authorization
β βββ models/ # Database models
β βββ routes/ # API routes
β β βββ auth.js
β β βββ candidates.js # Protected routes
β β βββ institutes.js # Mixed public/protected
β β βββ choices.js # Student-only routes
β β βββ common.js # Mixed routes
β βββ server.js # Express app setup
β
βββ DBMS_TermProject.sql # Main database schema
βββ authentication.sql # Authentication tables
βββ insert_sample_data.sql # Sample data for testing
βββ README.md # This file
β
View Seat Matrix (all seats by institute, program, category)
β
View Opening/Closing Ranks (cutoffs for all programs)
β
View Institutes (basic information, list all IITs/NITs/IIITs)
β
View Programs (available programs and degrees)
β
View Counselling Rounds (active and past rounds)
β View Candidates (requires authentication)
β View Allocations (requires authentication)
β Fill Choices (requires student login)
β
View OWN profile and information
β
Update OWN profile (limited fields: mobile, email)
β
View OWN allocations across all rounds
β
Fill and manage OWN choice list
- Add choices (institute + program combinations)
- Reorder choices (drag and drop priority)
- Delete choices
- Lock/unlock choice list
β
View all public data (seat matrix, ranks, institutes)
β View other students' information
β Edit institutes or system data
β Create allocations
β
View OWN institute detailed information
β
Update OWN institute info (address, phone, website, email)
β
View basic information of other institutes
β
View all public data
β View student personal information
β Edit other institutes
β Access student-specific features
β
Full CRUD access to all candidates
β
Full CRUD access to all institutes
β
View and manage all allocations
β
Create and manage programs
β
Manage seat matrix (add/update seats)
β
Manage opening/closing ranks
β
Create and manage counselling rounds
β
Complete system oversight
POST /api/auth/register
Content-Type: application/json
{
"role": "Student" | "Institute",
// For Student
"candidateID": 123456,
"name": "John Doe",
"email": "john@example.com",
"password": "securepassword",
"dateOfBirth": "2005-01-15",
"gender": "Male",
"mobileNumber": "9876543210",
// ... other student fields
// For Institute
"instituteCode": "INST001",
"instituteName": "Example IIT",
"email": "admin@iit.ac.in",
"password": "securepassword",
// ... other institute fields
}POST /api/auth/login
Content-Type: application/json
{
"identifier": "candidate@email.com" | "123456" | "INST001",
"password": "securepassword"
}
Response:
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"userID": 1,
"username": "john_doe",
"role": "Student",
"email": "john@example.com",
"candidateID": 123456,
// ... other user data
}
}
}GET /api/seat-matrix
GET /api/seat-matrix/institute/IIT001
Response: List of available seats by categoryGET /api/opening-closing-ranks
GET /api/opening-closing-ranks/round/1
GET /api/opening-closing-ranks/search?rank=500&category=OPEN
Response: Rank data for programsGET /api/institutes
GET /api/institutes/IIT001
GET /api/institutes/with-programs
Response: Institute informationAll protected endpoints require authentication headers:
x-user-id: <userID>
x-user-role: Student | Institute | Administrator
x-candidate-id: <candidateID> (for students)
x-institute-code: <instituteCode> (for institutes)GET /api/candidates # Admin: all, Student: own only
GET /api/candidates/:id # Admin/Student (own): view
PUT /api/candidates/:id # Admin: full, Student: limited
DELETE /api/candidates/:id # Admin onlyGET /api/allocations/candidate/:candidateId # Own allocations
GET /api/allocations/round/:roundId # Admin only
POST /api/allocations # Admin onlyGET /api/choices/candidate/:candidateId # View own choices
POST /api/choices # Add choice
PUT /api/choices/:choiceId/order # Reorder
POST /api/choices/lock # Lock choices
DELETE /api/choices/:choiceId # Delete choice- Open
http://localhost:5173 - Navigate to "Seat Matrix" β Should work β
- Navigate to "Ranks" β Should work β
- Navigate to "Institutes" β Should work β
- Try "Candidates" β Should redirect to login π
- Try "Choice Filling" β Should not appear in menu β
- Login with student credentials
- "Choice Filling" appears in navigation menu β
- Go to "Candidates" β See only your profile
- Go to "Allocations" β See only your allocations
- Go to "Choice Filling" β Manage your choices
- Try accessing another student's data β Should be denied
- Login with institute credentials
- "Choice Filling" does NOT appear in menu β
- View your institute details
- Try to edit your institute β Should work
- Try to edit another institute β Should be denied
- Login with admin credentials
- "Choice Filling" does NOT appear in menu β
- Access all pages
- View all data
- Perform CRUD operations
# Test public and protected routes
./test-auth.sh
# The script will test:
# - Public endpoints (should return 200)
# - Protected endpoints without auth (should return 401)Test public access:
curl http://localhost:5000/api/seat-matrix
curl http://localhost:5000/api/opening-closing-ranksTest protected access (should fail):
curl http://localhost:5000/api/candidates
# Expected: 401 UnauthorizedTest with authentication:
# First login to get user data
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"identifier":"student@email.com","password":"password123"}'
# Then use returned userID and role in headers
curl http://localhost:5000/api/candidates/123 \
-H "x-user-id: 1" \
-H "x-user-role: Student" \
-H "x-candidate-id: 123"-
Fork the repository
-
Clone your fork
git clone https://github.com/yourusername/DBMS_Project.git cd DBMS_Project -
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Follow existing code style
- Add comments for complex logic
- Test your changes thoroughly
-
Commit and push
git add . git commit -m "Add: description of your changes" git push origin feature/your-feature-name
-
Create a Pull Request
- Use functional components with hooks
- Type all props and state
- Use meaningful variable names
- Add JSDoc comments for complex functions
- Follow MVC pattern
- Use async/await for database operations
- Add error handling for all routes
- Validate input data
- Use parameterized queries (prevent SQL injection)
- Follow naming conventions: PascalCase for tables, camelCase for fields
- Add indexes for frequently queried columns
- Create controller function (
server/controllers/yourController.js):
exports.yourFunction = async (req, res) => {
try {
// Check user role
if (req.user.role !== 'Student') {
return res.status(403).json({
success: false,
message: 'Access denied'
});
}
// Your logic here
res.json({ success: true, data: result });
} catch (error) {
res.status(500).json({ success: false, message: error.message });
}
};- Add route (
server/routes/yourRoute.js):
const { isAuthenticated } = require('../middleware/auth');
router.get('/your-route', isAuthenticated, yourController.yourFunction);- Create frontend API call (
client/src/services/api.ts):
export const yourAPI = {
getData: () => api.get('/your-route')
};- Create page component (
client/src/pages/YourPage.tsx) - Add route in
App.tsx - Add navigation link in
Header.tsx(with role check if needed)
Error: ER_ACCESS_DENIED_ERROR
Solution: Check your .env file has correct MySQL credentials
Error: listen EADDRINUSE: address already in use :::5000
Solution: Kill process using port or change PORT in .env
# Find and kill process
lsof -ti:5000 | xargs kill -9
# Or change port
PORT=5001 npm startSolution:
- Clear browser localStorage
- Check if user data is being stored after login
- Verify auth headers are being sent in network tab
- Check server logs for authentication errors
Solution:
- Ensure you're logged in
- Check localStorage has 'user' and 'isAuthenticated' keys
- Verify headers are included in request (check Network tab)
Solution:
- Verify candidateID in localStorage matches database
- Check server logs for query errors
- Ensure candidate record exists in database
- User - Authentication (UserID, Username, PasswordHash, Role)
- Candidate - Student information (CandidateID, Name, Email, JEE ranks)
- Institute - College information (InstituteCode, Name, Type)
- Program - Academic programs (ProgramCode, Name, Degree, Duration)
- ChoiceList - Student preferences (ChoiceID, CandidateID, ProgramCode)
- Allocation - Seat assignments (AllocationID, CandidateID, ProgramCode, Round)
- SeatMatrix - Available seats (InstituteCode, ProgramCode, Category, Seats)
- OpeningClosingRanks - Cutoff ranks (ProgramCode, Category, Round, Opening, Closing)
User β Candidate (one-to-one via CandidateID)
User β Institute (one-to-one via InstituteCode)
Candidate β ChoiceList (one-to-many)
Candidate β Allocation (one-to-many)
Institute β Program (one-to-many)
Program β SeatMatrix (one-to-many)
Program β OpeningClosingRanks (one-to-many)
This project is created for educational purposes as part of a Database Management Systems course project.
- Student Project Team
- IIT Jammu
For issues, questions, or contributions, please:
- Check the troubleshooting section
- Review existing issues on GitHub
- Create a new issue with detailed description
π Happy Coding! If you find this project helpful, please give it a star β
| /api/choices | POST | Add new choice |
| /api/auth/profile/:userID | GET/PUT | Profile management |
| /api/auth/password/:userID | PUT | Change password |
Full API docs: See server routes in server/routes/
Main Tables:
Users- Authentication and user managementCandidate- Student information with JEE ranksInstitute- IIT/NIT/IIIT detailsProgram- Academic programsInstitute_Program- Institute-program mappingChoice_List- Candidate preferencesAllocation- Seat allocation resultsSeat_Matrix- Available seats by categoryOpening_Closing_Ranks- Cutoff dataCounselling_Round- Round schedules
CREATE TABLE Users (
UserID INT PRIMARY KEY AUTO_INCREMENT,
Username VARCHAR(255) UNIQUE NOT NULL,
Password VARCHAR(255) NOT NULL, -- Hashed with bcrypt
Role ENUM('Student', 'Institute', 'Administrator') NOT NULL,
Email VARCHAR(255) UNIQUE NOT NULL,
IsActive TINYINT(1) DEFAULT 1,
CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
LastLogin TIMESTAMP NULL,
CandidateID INT UNIQUE NULL, -- For students
InstituteCode VARCHAR(20) UNIQUE NULL, -- For institutes
FOREIGN KEY (CandidateID) REFERENCES Candidate(CandidateID),
FOREIGN KEY (InstituteCode) REFERENCES Institute(InstituteCode)
);- Navigate to
/register - Select "Student" role
- Fill in required fields including Candidate ID
- Create a password (minimum 6 characters)
- Submit the form
- Navigate to
/register - Select "Institute" role
- Fill in institutional details including Institute Code
- Create a password
- Submit the form
- Navigate to
/login - Enter your identifier (Candidate ID, Email, Mobile, Institute Code, or Username)
- Enter your password
- Click Login
- After successful login, you'll see your name and role badge in the header
- Username:
admin - Password:
admin123 β οΈ Important: Change this password immediately after first login!
- Password Hashing: All passwords are hashed using bcrypt with salt rounds
- Role-Based Access: Users are assigned specific roles with different permissions
- Login Attempt Logging: All login attempts (successful and failed) are logged
- Session Management: User data stored in localStorage
- Input Validation: Both frontend and backend validation for all forms
- Check your MySQL credentials in the
.envfile - Ensure MySQL server is running
- Verify database name matches in
.envand schema files
If you encounter bcrypt installation errors:
npm install --global windows-build-tools
npm install bcryptIf port 5000 or 5173 is already in use:
- Change PORT in
server/.env - Update VITE_API_BASE_URL in
client/.envaccordingly
Ensure the backend CORS configuration allows requests from your frontend URL.
- JWT Authentication: Replace localStorage with JWT tokens for better security
- Password Reset: Implement forgot password functionality
- Email Verification: Add email verification for new registrations
- Two-Factor Authentication: Add 2FA for enhanced security
- Role-Based Routing: Create protected routes for different user roles
- Audit Logs: Track all user actions for security and compliance
- Backend runs on
http://localhost:5000 - Frontend runs on
http://localhost:5173 - Sample data includes 5 institutes, 8 programs, 5 candidates
- Update your database password in the
.envfile
DBMS Term Project - JoSAA Seat Allocation System with Authentication
Version: 2.0.0 (with Authentication)
Last Updated: November 9, 2025
Contributors: DBMS Project Team