A comprehensive REST API backend for managing an automobile service system with role-based authentication using JWT tokens.
- Features
- Tech Stack
- Prerequisites
- Installation & Setup
- Configuration
- Running the Application
- API Documentation
- User Roles & Flow
- Testing
- Project Structure
- Security
- License
- JWT Authentication - Secure token-based authentication
- Role-Based Access Control - Three user roles (Admin, Customer, Employee)
- π Real-Time Notifications - WebSocket-based live notifications (NEW!)
- Email Notifications - Automated email for employee activation
- Password Management - Reset, change, and secure password storage with BCrypt
- RESTful API - Clean and well-documented endpoints
- Exception Handling - Global error handling with meaningful responses
- Input Validation - Bean validation on all inputs
- PostgreSQL Database - Reliable data persistence
- WebSocket Support - Real-time notifications without page refresh
- User-Specific Notifications - Personalized notification delivery
- Appointment Updates - Instant alerts for appointment status changes
- Admin Broadcasts - System-wide notifications for administrators
- Notification History - REST API for fetching historical notifications
- Read/Unread Tracking - Mark notifications as read, get unread count
| Technology | Version | Purpose |
|---|---|---|
| Java | 17+ | Programming Language |
| Spring Boot | 3.5.6 | Application Framework |
| Spring Security | 3.x | Security & Authentication |
| Spring Data JPA | 3.x | Data Access Layer |
| Spring WebSocket | 3.x | Real-Time Notifications (NEW!) |
| PostgreSQL | Latest | Database |
| JWT (jjwt) | 0.11.5 | Token Generation |
| Lombok | Latest | Boilerplate Reduction |
| Maven | 3.6+ | Build Tool |
| JavaMailSender | Latest | Email Service |
Before you begin, ensure you have the following installed:
- JDK 17 or higher - Download
- PostgreSQL - Download
- Maven (Optional - wrapper included) - Download
- Git - Download
git clone https://github.com/yourusername/ASMS_Backend.git
cd ASMS_Backend-- Open PostgreSQL terminal
psql -U postgres
-- Create database
CREATE DATABASE asms_db;
-- Verify
\l
-- Exit
\qUpdate src/main/resources/application.properties:
# Database Configuration
spring.datasource.url=jdbc:postgresql://localhost:5432/asms_db
spring.datasource.username=your_postgres_username
spring.datasource.password=your_postgres_password
# Email Configuration (Gmail Example)
spring.mail.username=your-email@gmail.com
spring.mail.password=your-gmail-app-passwordNote: For Gmail, you need to generate an App Password:
- Enable 2-Step Verification
- Go to Security β App passwords
- Generate password for "Mail"
- Use generated password in configuration
# Using Maven wrapper (recommended)
./mvnw clean install
# Or using installed Maven
mvn clean install# Server Configuration
server.port=8080
# JWT Configuration
jwt.secret=your-secret-key-here
jwt.expiration=86400000 # 24 hours in milliseconds
# Admin Credentials (Hardcoded)
admin.username=admin
admin.password=admin123
admin.email=admin@asms.com
# Application URL
app.url=http://localhost:8080For production, use environment variables:
export DB_USERNAME=postgres
export DB_PASSWORD=yourpassword
export MAIL_USERNAME=youremail@gmail.com
export MAIL_PASSWORD=yourapppassword./mvnw spring-boot:run# Build JAR
./mvnw clean package
# Run JAR
java -jar target/demo-0.0.1-SNAPSHOT.jarcurl http://localhost:8080/api/auth/loginExpected: JSON response (not 404)
http://localhost:8080
POST /api/auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin123"
}Response:
{
"token": "eyJhbGciOiJIUzUxMiJ9...",
"username": "admin",
"email": "admin@asms.com",
"role": "ADMIN",
"message": "Login successful"
}POST /api/auth/signup
Content-Type: application/json
{
"username": "john_doe",
"email": "john@example.com",
"password": "password123",
"firstName": "John",
"lastName": "Doe",
"phoneNumber": "1234567890",
"address": "123 Main St"
}GET /api/auth/verify-token?token={uuid-from-email}Response:
{
"success": true,
"message": "Token is valid. Please set your password.",
"data": {
"username": "employee1",
"email": "employee1@example.com",
"firstName": "Jane",
"lastName": "Smith"
}
}POST /api/auth/set-password
Content-Type: application/json
{
"token": "uuid-from-email",
"newPassword": "newPassword123"
}POST /api/auth/change-password
Authorization: Bearer {jwt-token}
Content-Type: application/json
{
"oldPassword": "currentPassword",
"newPassword": "newPassword123"
}Note: All admin endpoints require
Authorization: Bearer {admin-token}header
POST /api/admin/employees
Authorization: Bearer {admin-token}
Content-Type: application/json
{
"username": "employee1",
"email": "employee1@example.com",
"firstName": "Jane",
"lastName": "Smith",
"phoneNumber": "9876543210"
}GET /api/admin/employees
Authorization: Bearer {admin-token}GET /api/admin/customers
Authorization: Bearer {admin-token}GET /api/admin/users/{id}
Authorization: Bearer {admin-token}PUT /api/admin/users/{id}/activate
PUT /api/admin/users/{id}/deactivate
Authorization: Bearer {admin-token}POST /api/admin/employees/{id}/resend-activation
Authorization: Bearer {admin-token}Note: Requires
Authorization: Bearer {employee-token}header
GET /api/employee/profile
GET /api/employee/dashboard
Authorization: Bearer {employee-token}Note: Requires
Authorization: Bearer {customer-token}header
GET /api/customer/profile
GET /api/customer/dashboard
Authorization: Bearer {customer-token}Note: All notification endpoints require
Authorization: Bearer {token}header
GET /api/notifications
Authorization: Bearer {token}Response:
{
"success": true,
"message": "Notifications retrieved successfully",
"data": [
{
"id": 1,
"title": "Appointment Created",
"message": "Your appointment for Toyota Camry has been created",
"type": "APPOINTMENT_CREATED",
"recipientId": 5,
"appointmentId": 10,
"isRead": false,
"createdAt": "2025-11-07T14:30:00",
"readAt": null
}
]
}GET /api/notifications/unread
Authorization: Bearer {token}GET /api/notifications/unread/count
Authorization: Bearer {token}Response:
{
"success": true,
"message": "Unread count retrieved successfully",
"data": 5
}PUT /api/notifications/{notificationId}/read
Authorization: Bearer {token}PUT /api/notifications/read-all
Authorization: Bearer {token}DELETE /api/notifications/{notificationId}
Authorization: Bearer {token}// WebSocket URL
ws://localhost:8080/ws/notifications?token={jwt-token}
// Subscribe to user-specific topic
/topic/notifications/user.{userId}
// Admins also subscribe to
/topic/notifications/adminSee detailed integration guides:
- π Complete Guide: WEBSOCKET_NOTIFICATION_GUIDE.md
- β‘ Quick Start: QUICK_START_NOTIFICATIONS.md
- π§ͺ Test Tool: Open
websocket-test.htmlin browser
APPOINTMENT_CREATED- Customer creates appointmentAPPOINTMENT_CONFIRMED- Admin confirms appointmentAPPOINTMENT_CANCELLED- Appointment cancelledEMPLOYEE_ASSIGNED- Employee assigned to appointmentSTATUS_CHANGED_IN_SERVICE- Status changed to IN_SERVICESTATUS_CHANGED_READY- Status changed to READYSTATUS_CHANGED_COMPLETED- Status changed to COMPLETEDGENERAL- General notification
{
"notificationId": 123,
"title": "Appointment Confirmed",
"message": "Your appointment for Toyota Camry has been confirmed",
"type": "APPOINTMENT_CONFIRMED",
"appointmentId": 45,
"recipientId": 5,
"timestamp": "2025-11-07T14:30:00"
}import { Client } from '@stomp/stompjs';
import SockJS from 'sockjs-client';
const token = localStorage.getItem('authToken');
const userId = localStorage.getItem('userId');
const client = new Client({
webSocketFactory: () =>
new SockJS(`http://localhost:8080/ws/notifications?token=${token}`),
onConnect: () => {
client.subscribe(`/topic/notifications/user.${userId}`, (message) => {
const notification = JSON.parse(message.body);
console.log('π¬ New notification:', notification);
// Update your UI here
});
}
});
client.activate();- Access: Hardcoded credentials (
admin/admin123) - Capabilities:
- Login to system
- Create employee accounts
- Manage users (activate/deactivate)
- View all customers and employees
- Resend activation emails
Flow:
Login β Add Employee β System sends activation email β Manage users
- Access: Public registration via
/api/auth/signup - Capabilities:
- Self-registration
- Login to system
- View profile
- Access customer dashboard
- Change password
Flow:
Signup β Login β Get JWT Token β Access Customer Features
- Access: Created by Admin only
- Capabilities:
- Receive activation email
- Set password via token
- Login to system
- View profile
- Access employee dashboard
- Change password
Flow:
Admin creates account β Receive email β Click link/Use token β Set password β Login β Access Employee Features
# 1. Admin Login
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'
# 2. Customer Signup
curl -X POST http://localhost:8080/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"username":"testuser",
"email":"test@example.com",
"password":"password123",
"firstName":"Test",
"lastName":"User",
"phoneNumber":"1234567890",
"address":"Test Address"
}'
# 3. Add Employee (use admin token)
curl -X POST http://localhost:8080/api/admin/employees \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN" \
-d '{
"username":"employee1",
"email":"employee1@example.com",
"firstName":"Jane",
"lastName":"Smith",
"phoneNumber":"9876543210"
}'- Import the provided Postman collection:
ASMS_API_Collection.postman_collection.json - Set variables after login:
admin_tokencustomer_tokenemployee_token
- Test all endpoints
ASMS_Backend/
βββ src/
β βββ main/
β β βββ java/com/example/demo/
β β β βββ config/ # Security & app configuration
β β β β βββ SecurityConfig.java
β β β βββ controller/ # REST API endpoints
β β β β βββ AdminController.java
β β β β βββ AuthController.java
β β β β βββ CustomerController.java
β β β β βββ EmployeeController.java
β β β βββ dto/ # Data Transfer Objects
β β β β βββ ApiResponse.java
β β β β βββ LoginRequest.java
β β β β βββ LoginResponse.java
β β β β βββ ...
β β β βββ exception/ # Exception handling
β β β β βββ GlobalExceptionHandler.java
β β β β βββ BadRequestException.java
β β β β βββ ResourceNotFoundException.java
β β β βββ model/ # JPA Entities
β β β β βββ User.java
β β β β βββ Role.java
β β β βββ repository/ # Database access
β β β β βββ UserRepository.java
β β β βββ security/ # JWT & Authentication
β β β β βββ JwtTokenProvider.java
β β β β βββ JwtAuthenticationFilter.java
β β β β βββ CustomUserDetailsService.java
β β β βββ service/ # Business logic
β β β β βββ AuthService.java
β β β β βββ AdminService.java
β β β β βββ EmailService.java
β β β β βββ UserService.java
β β β βββ AsmsBackendApplication.java
β β βββ resources/
β β βββ application.properties
β βββ test/
βββ pom.xml
βββ .gitignore
βββ README.md
βββ ASMS_API_Collection.postman_collection.json
- JWT Tokens: Stateless authentication with 24-hour expiration
- BCrypt Hashing: Password encryption with salt
- Role-Based Access: Endpoint protection by user role
- Token Validation: Automatic token verification on each request
- CSRF Protection: Disabled for stateless API (using JWT)
- Input Validation: Bean validation on all request DTOs
- Change Default Admin Password in production
- Use Environment Variables for sensitive configuration
- Generate Strong JWT Secret (at least 256 bits)
- Enable HTTPS in production
- Implement Rate Limiting for authentication endpoints
- Regular Security Audits of dependencies
Username: admin
Password: admin123
Email: admin@asms.com
β οΈ Important: Change these credentials before deploying to production!
# Check if PostgreSQL is running
sudo service postgresql status
# Verify database exists
psql -U postgres -l | grep asms_dbChange port in application.properties:
server.port=8081- Verify Gmail App Password (not regular password)
- Check spam folder
- Ensure 2-Step Verification is enabled
- Check application logs for errors
- Token validity: 24 hours
- Login again to get new token
- Or increase
jwt.expirationvalue
# Verify backend is running
curl http://localhost:8080/api/notifications
# Check if token is valid (not expired)
# Token must include userId claim
# Ensure correct WebSocket URL format:
ws://localhost:8080/ws/notifications?token=YOUR_JWT_TOKEN- β
Check if subscribed to correct topic:
/topic/notifications/user.{YOUR_USER_ID} - β Verify userId in JWT token matches your user ID
- β Ensure WebSocket connection is active (check connection status)
- β
Test using
websocket-test.htmltool - β Check browser console for errors
- Verify user is authenticated (valid JWT token)
- Check database connection
- Review application logs for stack traces
{
"success": true,
"message": "Operation successful",
"data": { ... }
}{
"success": false,
"message": "Error description",
"data": null
}200 OK- Successful request400 Bad Request- Validation error401 Unauthorized- Invalid/missing token403 Forbidden- Insufficient permissions404 Not Found- Resource not found500 Internal Server Error- Server error
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Your Name
- GitHub: @yourusername
- Email: your.email@example.com
- Spring Boot Team for the amazing framework
- JWT.io for authentication standard
- PostgreSQL community
- All contributors
β Star this repository if you find it helpful!
π§ Questions? Open an issue or contact the maintainer.
π Happy Coding!