The User Management System is a full-stack web application that streamlines user authentication and software access control within an organization.
- User Registration β Create new user accounts.
- Secure Login & JWT Authentication β Protect access using industry-standard JSON Web Tokens.
- Software Access Requests β Users can request access to available software.
- Managerial Approvals β Managers can approve or reject access requests.
- Software Listing & Management β View and manage available software options.
- Backend: Node.js, Express.js
- Frontend: React
- Database: PostgreSQL
- ORM: TypeORM
- Authentication: JWT (JSON Web Token)
- Tooling & Libraries:
bcryptβ For password hashingdotenvβ For environment variable managementnodemonβ For auto-restarting the development server
Follow these steps to set up PostgreSQL for this project:
- Download the installer from the official website.
- Run the installer and follow the setup steps.
- Remember your username, password, and port (default is
5432).
brew install postgresql
brew services start postgresqlAccess the PostgreSQL shell:
bash psql -U postgres
Then run:
CREATE DATABASE user_management;
CREATE USER myuser WITH ENCRYPTED PASSWORD 'mypassword';
GRANT ALL PRIVILEGES ON DATABASE user_management TO myuser;In the file bash user-access-backend\src\config\data-source.ts change username, password, and database to your username, password and database.
Create a .env file in user-access-backend and add the following environment variables:
- JWT Secret Key
JWT_SECRET_KEY=your_super_secret_key
Run the following commands in user_access_backend:
npm install
npm run dev
Backend setup is ready
Run the following commands in user_access_frontend:
npm install
npm run dev
Frontend setup is ready
The application is organized into four main route files, each serving a specific purpose:
- Purpose: Health check endpoint to verify the server is running.
- Example Endpoint:
GET /api/health
- Purpose: Handles user authentication.
- Endpoints:
POST /api/auth/signupβ Register a new user, with default role as EmployeePOST /api/auth/loginβ Authenticate user and return JWT and role
- Purpose: Manage software access requests.
- Endpoints:
POST /api/requestsβ Create a new request (Employee only)GET /api/requests/pendingβ View all pending requests (Manager only)PUT /api/requests/:idβ Approve or reject a request (Manager only)
- Purpose: Manage software entries.
- Endpoints:
POST /api/softwareβ Create new softwareGET /api/software/list-softwaresβ List all available software
π Note: Role-based access control is enforced on the routes using middlewares (e.g., only managers can approve/reject requests).
The system uses several middlewares to ensure data integrity, authentication, and role-based access control.
- Purpose: Validates user input during signup and login using Zod.
- Checks:
usernameandpasswordmust be present.- Ensures the input meets expected format and constraints.
- Purpose: Enforces role-based access control.
- Example Use Case:
- Only users with the Admin role can create or list software.
- If a user with insufficient privileges attempts access, a
401 Unauthorizederror is returned.
- Purpose: Verifies that the user is authenticated.
- Checks:
- Validates JWT token and decodes user information.
- Confirms the user exists in the database.
- Blocks access if the user is not registered or token is invalid.
β These middlewares help secure the application and ensure only valid, authorized actions are performed.
After passing through the middlewares and validations, requests are handled by their respective controllers. Each controller is responsible for coordinating logic by invoking the appropriate service functions and returning responses.
Handles user authentication logic.
signup: Handles new user registration.login: Authenticates existing users.
Each method calls its respective service, and any errors during execution are properly caught and thrown.
Manages software access request-related operations.
-
createRequest:- Accessible by Employees.
- Submits a new software access request.
-
getAllPendingRequests:- Accessible by Managers.
- Retrieves a list of all pending access requests.
-
updateRequestStatus:- Accessible by Managers.
- Approves or rejects a request based on the status update.
Responsible for software management.
-
createSoftware:- Accessible by Admins only.
- Adds a new software entry to the system.
-
getAllSoftware:- Accessible by Admins only.
- Retrieves a list of all available software.
βοΈ Each controller is designed to be lean, delegating core business logic to dedicated service functions for maintainability and separation of concerns.
Service classes encapsulate the core business logic of the application. They interact with the database (via DAO functions) and handle processing, validation, and response preparation.
Handles user registration and login logic.
-
signup:- Hashes the password using
bcrypt. - Calls
userDaoto save the user in the database.
- Hashes the password using
-
login:- Fetches the user using
findUserByUsernamefromuserDao. - If the user is not found, throws a User Not Found error.
- Compares passwords using
bcrypt.compare(). - Retrieves
JWT_SECRET_KEYfrom environment variables. - If the secret key is missing, throws an error.
- If everything is valid, generates a JWT token using
jwt.sign()and returns the token along with the user's role.
- Fetches the user using
Manages logic related to software access requests.
createAccessRequest: Submits a new access request (Employee role).getAllPendingRequests: Fetches all pending requests (Manager role).updateRequestStatus: Updates request status to approved/rejected (Manager role).
Handles operations related to software records.
createSoftware: Adds a new software entry (Admin role).getAllSoftware: Retrieves the list of all available software (Admin role).
π§© Services promote modularity, making business logic reusable and testable across the application.
DAO modules abstract and encapsulate all interactions with the database. They provide clean interfaces for querying, inserting, updating, or deleting data, keeping database logic separate from business logic.
Each DAO function is typically used by a corresponding service class to perform operations such as fetching users, saving requests, or updating statuses.
Handles all database operations related to users.
-
saveUser(userData)
Inserts a new user into the database using the provided data. -
findUserByUsername(username)
Fetches a user by their username. Used during login and to prevent duplicate registrations.
Handles operations related to access requests.
-
saveAccessRequest(requestData)
Inserts a new access request into the database. -
getAllPendingRequests()
Retrieves all access requests with a status of"PENDING". -
updateRequestStatus(requestId, status)
Updates the status of a specific request to either"APPROVED"or"REJECTED".
Manages software-related database tasks.
-
saveSoftware(softwareData)
Inserts a new software record into the database. -
getAllSoftware()
Retrieves all software entries from the database.
π§± DAOs enforce a separation of concerns, enabling services to focus on business logic while keeping database operations consistent and maintainable.