User Management System is a web-based application that manages user records and provides secure role-based access for users and administrators. Built with Laravel 12, it features a modern interface using Blade and Tailwind CSS (RetroUI) and ensures data integrity with a MySQL database.
- Project Name: Laravel User Management System
- Database: MySQL
- Backend: Laravel 12 (Eloquent ORM)
- Frontend: Blade Templates + Tailwind CSS (RetroUI Design System)
- Authentication: Custom Laravel Auth with Sanctum for API
This module handles all standard user interactions, ensuring a smooth and secure experience.
- User Registration: New users can create an account to access the system.
- User Login: Registered users can securely log in to their personal dashboard.
- Forgot Password: Users can recover their account via an email-based password reset link (configured via SMTP/Gmail).
A dedicated control center for administrators to manage the application and its users.
- Admin Login: Secure entry point for administrative access.
- Manage Users: View a complete list of all registered users.
- Edit User Information: Update user details such as name, email, and role.
- Delete Users: Remove user accounts from the system permanently.
- Change Admin Password: Administrators can securely update their own credentials.
This project is configured to run with Laravel Sail, a light-weight command-line interface for interacting with Laravel's default Docker development environment.
-
Clone the repository
git clone https://github.com/prayangshu/laravel-user-management.git cd laravel-user-management -
Install Dependencies If you have PHP and Composer installed locally:
composer install
If you do not have PHP/Composer installed locally, you can use a small Docker container to install dependencies:
docker run --rm \ -u "$(id -u):$(id -g)" \ -v "$(pwd):/var/www/html" \ -w /var/www/html \ laravelsail/php84-composer:latest \ composer install --ignore-platform-reqs -
Configure Environment Copy the example environment file. It is already pre-configured for Sail.
cp .env.example .env
-
Start Sail This will build the containers and start the application.
./vendor/bin/sail up -d
-
Generate Key & Migrate Run these commands inside the Sail container:
./vendor/bin/sail artisan key:generate ./vendor/bin/sail artisan migrate --seed
-
Install Frontend Assets
./vendor/bin/sail npm install ./vendor/bin/sail npm run build
Access the app at
http://localhost.
- Start containers:
./vendor/bin/sail up -d - Stop containers:
./vendor/bin/sail down - Run Artisan commands:
./vendor/bin/sail artisan <command> - Run Composer:
./vendor/bin/sail composer <command> - Run NPM:
./vendor/bin/sail npm <command> - Run Tests:
./vendor/bin/sail test
Follow these steps to set up the project on your local machine without Docker:
-
Clone the repository
git clone https://github.com/prayangshu/laravel-user-management.git cd laravel-user-management -
Install dependencies
composer install npm install
-
Configure environment Copy the example environment file and update your database and mail settings.
cp .env.example .env
-
Generate application key
php artisan key:generate
-
Setup database Run migrations and seed the database with initial data.
php artisan migrate --seed
-
Run the application Start the development server and compile assets.
npm run build php artisan serve
Access the app at
http://localhost:8000.
- Functionality: Validates user input (name, email, password), creates a new user record with the default 'user' role, hashes the password, and redirects to the login page upon success.
- Routes:
GET /register: Displays the registration form.POST /register: Handles the form submission and user creation.
- Functionality: Authenticates users using email and password. Protects routes using the
authmiddleware. Handles session regeneration to prevent session fixation attacks. - Routes:
GET /login: Displays the login form.POST /login: Authenticates the user.POST /logout: Logs the user out and invalidates the session.
- Functionality: Accepts a user's email address, generates a random new password, updates the database, and sends the new password to the user via SMTP email.
- Routes:
GET /forgot-password: Displays the email input form.POST /forgot-password: Processes the request and sends the email.
- Functionality: Adds a
rolecolumn to the users table. Implements anAdminMiddlewareto restrict access to administrative routes. - Routes:
- Middleware
adminapplied to all/admin/*routes.
- Middleware
- Functionality: Provides a protected view accessible only to users with the 'admin' role. Displays quick links to administrative tasks.
- Routes:
GET /admin: Displays the admin dashboard.
- Functionality: Allows admins to view a list of all users, edit user details (name, email, role), and delete users from the system. Includes confirmation dialogs for destructive actions.
- Routes:
GET /admin/users: Lists all users.GET /admin/users/{user}/edit: Displays the user edit form.PUT /admin/users/{user}: Updates the user record.DELETE /admin/users/{user}: Removes the user from the database.
- Functionality: Validates the current password before allowing a change. Updates the password hash in the database upon successful validation.
- Routes:
GET /admin/password/change: Displays the password change form.PUT /admin/password/change: Handles the password update logic.
- RetroUI Design System: All pages utilize the Neo-Brutalism aesthetic with thick borders, hard shadows, and high contrast.
- Typography: Consistent use of the 'Inter' font family with uppercase headers and bold weights.
- Component Library: Reusable Blade components (
<x-ui.card>,<x-ui.button>,<x-ui.input>,<x-ui.icon>) are used exclusively. - Responsive Layouts: Both the public/user layout and the admin sidebar layout are fully responsive on mobile and desktop.
- Flash Messages: Success and error alerts share a unified RetroUI style with icons.
- Empty States: A dedicated empty state component handles "no data" scenarios gracefully.
- Iconography: A centralized SVG icon system ensures visual consistency without external dependencies.
- Code Quality: Controllers are thin, readable, and follow MVC principles. No debug dumps found.
- Security: Passwords are hashed, CSRF protection is enabled, and admin routes are middleware-protected.
- Database: Eloquent ORM is used exclusively. Migrations and seeders are robust and reversible.
- Environment: Configuration is secure and environment-agnostic.
- UI/UX: RetroUI design system is applied consistently across all views.
- Performance: Tailwind CSS is configured for production purging. Assets compile cleanly.
- Routing: All routes are named, used, and correctly protected based on roles.
- Documentation: README is accurate and reflects the current state of the application.
- Strict Eloquent Usage: All database interactions use Eloquent models. No raw SQL or query builder misuse.
- Clean Architecture: Controllers are thin (Request → Service → Response). Business logic is encapsulated in Service classes.
- Form Requests: Validation logic is moved to dedicated Form Request classes.
- Type Safety: Strict typing applied to method signatures and properties.
- Code Style: Follows Laravel best practices and conventions.
[ HTTP Request ]
│
▼
+--------------------+
| Routes |
+--------------------+
│
▼
+--------------------+ +------------------+
| Controllers | ◄─── | Form Requests |
+--------------------+ +------------------+
│
│ (Calls)
▼
+--------------------+
| Services |
+--------------------+
│
│ (Uses)
▼
+--------------------+
| Models |
+--------------------+
│
│ (Queries)
▼
+--------------------+
| Database |
+--------------------+
... (Data returns up to Controller) ...
│
▼
+--------------------+
| Blade Views |
+--------------------+
│
▼
[ HTTP Response ]
- Thin Controllers: Controllers act solely as traffic directors. They validate input using Form Requests and delegate business logic to Services, ensuring they remain lightweight and readable.
- Service Layer: All complex business logic (e.g., user registration, password resets) is encapsulated in dedicated Service classes. This promotes reusability and keeps the core logic independent of the HTTP layer.
- Strict Eloquent ORM: Database interactions are strictly handled via Eloquent Models. This ensures security, type safety, and maintainability by avoiding raw SQL queries.
This project prioritizes testing the Service Layer to ensure business logic is robust, independent of the HTTP layer, and free from side effects.
- What to Test:
- Core business logic (e.g., calculations, data transformations).
- Database interactions (creation, updates, deletions) via Eloquent.
- External service integrations (e.g., Mail sending).
- What NOT to Test:
- HTTP redirects or responses (Controller responsibility).
- Form validation rules (Form Request responsibility).
- Blade view rendering.
-
Database Testing:
- Use
RefreshDatabasetrait to ensure a clean state for every test. - Assert against the database state to verify CRUD operations.
- Use
-
Mocking:
- Mock external services (like
Mail) to prevent actual execution during tests. - Do not mock Eloquent models unless absolutely necessary for performance; prefer real database assertions for accuracy.
- Mock external services (like
// tests/Unit/Services/AuthServiceTest.php
class AuthServiceTest extends TestCase
{
use RefreshDatabase;
public function test_it_registers_a_new_user()
{
// Arrange
$data = [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'secret123',
];
$service = new AuthService();
// Act
$user = $service->registerUser($data);
// Assert
$this->assertInstanceOf(User::class, $user);
$this->assertDatabaseHas('users', ['email' => 'john@example.com']);
$this->assertTrue(Hash::check('secret123', $user->password));
}
}This application implements a multi-layered security strategy to protect user data and prevent common vulnerabilities.
- Middleware Protection: All sensitive routes are protected by the
authmiddleware. Administrative routes are further secured by theadminmiddleware, ensuring strict role-based access control. - Guest Middleware: Registration and login pages are restricted to unauthenticated users via the
guestmiddleware to prevent session confusion. - Privilege Escalation Prevention: Form Requests explicitly check user roles (e.g.,
Auth::user()->role === 'admin') before authorizing administrative actions, preventing horizontal and vertical privilege escalation.
- Rate Limiting: Login and password reset endpoints are protected by Laravel's
throttlemiddleware (5 attempts per minute for login, 3 for password reset) to mitigate brute-force attacks. - Input Validation: All incoming data is rigorously validated using dedicated Form Request classes. No raw input is ever trusted.
- CSRF Protection: All forms include CSRF tokens to prevent cross-site request forgery.
- Password Hashing: All passwords are hashed using Bcrypt before storage.
- Session Security: Sessions are regenerated upon login to prevent session fixation attacks.
- Safe Error Handling: Error messages are generic (e.g., "The provided credentials do not match our records") to avoid leaking user enumeration data.
This application is designed to scale horizontally and vertically with minimal refactoring. The following strategies outline the path from a single server to a high-traffic distributed system.
- Indexing: Ensure all foreign keys and frequently queried columns (e.g.,
email,role) are indexed to maintain fast read performance as the dataset grows. - Read/Write Separation: Configure Laravel to use separate database connections for
read(SELECT) andwrite(INSERT/UPDATE/DELETE) operations. This allows distributing read traffic across multiple read replicas. - Connection Pooling: Use a connection pooler (like PgBouncer or ProxySQL) to manage database connections efficiently under high concurrency.
- Application Cache: Utilize Redis or Memcached to cache expensive queries and computed data.
- Session Storage: Move session storage from
filetoredisordatabaseto support horizontal scaling (multiple application servers sharing sessions). - Config & Route Caching: Always run
php artisan config:cacheandphp artisan route:cachein production to reduce boot time.
- Queue System: Offload time-consuming tasks (like sending emails) to a background queue worker. Use Redis or SQS as the queue driver instead of
sync. - Job Batches: For bulk operations (e.g., mass user updates), use Laravel's job batching to process tasks in parallel without blocking the main thread.
- Statelessness: The application is designed to be stateless. By moving sessions and cache to a shared store (Redis), you can add multiple application servers behind a load balancer without issues.
- Asset Delivery: Offload static assets (CSS, JS, Images) to a CDN (Content Delivery Network) to reduce server load and improve load times for global users.
- Rate Limiting: Implement strict API rate limiting (using Laravel Sanctum or Throttle middleware) to prevent abuse and ensure fair usage.
- Pagination: Enforce pagination on all list endpoints (e.g.,
User::paginate()) to prevent memory exhaustion when retrieving large datasets.
The application provides a RESTful API for external integrations. The API uses Laravel Sanctum for authentication and follows standard HTTP status codes.
All API requests (except login) require a Bearer Token in the Authorization header.
Header:
Authorization: Bearer <your-token>
Authenticates a user and returns an access token.
- URL:
POST /api/login - Auth: None
- Body:
{ "email": "admin@example.com", "password": "password" } - Response:
{ "success": true, "message": "Login successful.", "data": { "user": { "id": 1, "name": "Admin User", "email": "admin@example.com", "role": "admin", "created_at": "2023-10-27T10:00:00+00:00", "updated_at": "2023-10-27T10:00:00+00:00" }, "token": "1|laravel_sanctum_token_string..." } }
Revokes the current access token.
- URL:
POST /api/logout - Auth: Bearer Token
- Response:
{ "success": true, "message": "Logged out successfully.", "data": null }
Retrieves the authenticated user's profile.
- URL:
GET /api/user - Auth: Bearer Token
- Response:
{ "success": true, "message": "Success", "data": { "id": 1, "name": "Admin User", "email": "admin@example.com", "role": "admin", ... } }
Retrieves a list of all registered users.
- URL:
GET /api/admin/users - Auth: Bearer Token (Admin Role Required)
- Response:
{ "success": true, "message": "Success", "data": [ { "id": 2, "name": "John Doe", "email": "john@example.com", "role": "user", ... }, ... ] }
Updates a user's details.
- URL:
PUT /api/admin/users/{id} - Auth: Bearer Token (Admin Role Required)
- Body:
{ "name": "Jane Doe", "email": "jane@example.com", "role": "user" } - Response:
{ "success": true, "message": "User updated successfully.", "data": { "id": 2, "name": "Jane Doe", ... } }
Removes a user from the system.
- URL:
DELETE /api/admin/users/{id} - Auth: Bearer Token (Admin Role Required)
- Response:
{ "success": true, "message": "User deleted successfully.", "data": null }
This checklist outlines the essential steps to secure this application in a production environment.
- APP_ENV: Set to
production. - APP_DEBUG: Set to
false. - APP_KEY: Generate a unique key using
php artisan key:generate. - .env File: Ensure
.envis never committed to version control. - Permissions: Set correct file permissions (e.g.,
chmod -R 775 storage bootstrap/cache).
- Passwords: Enforce strong password requirements (min 8 chars, mixed case, numbers).
- Admin Access: Ensure all admin routes are protected by the
adminmiddleware. - Privilege Escalation: Verify no paths exist for users to elevate their own privileges.
- API Auth: Ensure Sanctum tokens are scoped correctly and revoked on logout.
- Secure Cookies: Enable
SESSION_SECURE_COOKIE=truein.env(requires HTTPS). - HTTP Only: Ensure
SESSION_HTTP_ONLY=true. - SameSite: Configure
SESSION_SAME_SITE=laxorstrict. - Regeneration: Verify session ID regeneration on login (
Session::regenerate()).
- Dedicated User: Use a separate database user with limited privileges (no
DROPorGRANT). - Credentials: Never reuse production database credentials in local or staging environments.
- Backups: Enable automated, encrypted database backups.
- Indexing: Ensure indexes are applied to sensitive lookup fields (e.g.,
email,role).
- Login: Ensure login endpoint is rate-limited (default: 5 attempts/min).
- Password Reset: Rate limit password reset requests to prevent spam.
- API: Configure
ThrottleRequestsmiddleware for all API endpoints. - Limits: Define sensible limits that prevent abuse without locking out legitimate users.
- Hashing: Ensure all passwords are hashed using Bcrypt or Argon2.
- Logging: Verify that no sensitive data (passwords, tokens, PII) is written to logs.
- Error Messages: Use generic error messages for authentication failures ("Invalid credentials").
- HTTPS: Enforce HTTPS for all traffic (
ForceHTTPSmiddleware or server config).
- Composer Audit: Run
composer auditregularly to check for PHP vulnerabilities. - NPM Audit: Run
npm auditto check for frontend vulnerabilities. - Updates: Keep framework and dependencies up to date.
- Lock Files: Commit
composer.lockandpackage-lock.jsonand review changes.
- Vulnerability Blocking: Configure CI to block builds with critical dependency vulnerabilities.
- Test Blocking: Ensure CI blocks deployment if tests fail.
- Secrets: Store production secrets in CI/CD variables, never in the repo.
- Approval: Require manual approval for production deployments.
- Firewall: Enable a firewall (e.g., UFW) and close all unused ports.
- Headers: Configure web server (Nginx/Apache) to hide framework headers (
X-Powered-By). - PHP Version: Use a supported, secure PHP version (currently 8.2+).
- SSL/TLS: Install a valid SSL certificate (e.g., Let's Encrypt).
This project has undergone a complete end-to-end audit to ensure it meets professional engineering standards.
- ORM Integrity: All database access uses Eloquent ORM. No raw SQL or improper query builder usage found.
- Clean Architecture: Controllers are thin, business logic is isolated in Services, and no logic exists in views.
- UI Consistency: RetroUI design system is applied uniformly across all pages.
- Auth & Security: Authentication is secure, admin routes are protected, and rate limiting is active.
- REST API: API follows standard conventions, uses Sanctum for auth, and reuses the Service layer.
- Docker (Sail): Project runs fully containerized with a single command.
- CI/CD: GitHub Actions pipeline is robust, running tests, migrations, and security scans.
- Documentation: README is comprehensive, accurate, and includes production security guidelines.