appointment_system/backend/ADMIN_AUTH.md
2025-12-11 22:50:18 +08:00

287 lines
6.6 KiB
Markdown

# Admin Authentication and Authorization System
## Overview
This document describes the admin authentication and role-based access control (RBAC) system implemented for the overseas appointment backend.
## Features
1. **Admin Login** - Secure authentication with JWT tokens
2. **Role-Based Access Control (RBAC)** - Three-tier permission system
3. **Operation Logging** - Audit trail for all admin actions
4. **Login History** - Track admin login attempts and device information
## Admin Roles
The system supports three admin roles with hierarchical permissions:
| Role | Level | Description |
|------|-------|-------------|
| `super_admin` | 3 | Full system access, can manage all resources |
| `admin` | 2 | Can manage users, orders, and services |
| `operator` | 1 | Basic read access and limited operations |
**Role Hierarchy**: Higher roles inherit permissions from lower roles.
- `super_admin` can access all `admin` and `operator` endpoints
- `admin` can access all `operator` endpoints
- `operator` has limited access
## API Endpoints
### Admin Login
```
POST /api/v1/admin/login
```
**Request Body:**
```json
{
"username": "admin",
"password": "password123"
}
```
**Response:**
```json
{
"success": true,
"data": {
"admin": {
"id": "uuid",
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"status": "active",
"lastLoginAt": "2025-12-01T12:00:00.000Z"
},
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
```
### Get Admin Profile
```
GET /api/v1/admin/profile
Authorization: Bearer <token>
```
**Response:**
```json
{
"success": true,
"data": {
"admin": {
"id": "uuid",
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"status": "active"
}
}
}
```
## Using Authentication Middleware
### Authenticate Admin Requests
```javascript
const { authenticateAdmin } = require('../middleware/auth');
router.get('/admin/users', authenticateAdmin, (req, res) => {
// req.admin contains the authenticated admin
// req.adminId contains the admin's ID
});
```
### Apply Role-Based Access Control
```javascript
const { authenticateAdmin } = require('../middleware/auth');
const { requireSuperAdmin, requireAdmin, requireOperator } = require('../middleware/rbac');
// Only super_admin can access
router.delete('/admin/users/:id',
authenticateAdmin,
requireSuperAdmin,
deleteUserController
);
// admin or super_admin can access
router.put('/admin/services/:id',
authenticateAdmin,
requireAdmin,
updateServiceController
);
// Any authenticated admin can access
router.get('/admin/statistics',
authenticateAdmin,
requireOperator,
getStatisticsController
);
```
### Custom Role Requirements
```javascript
const { requireRole } = require('../middleware/rbac');
// Only specific roles can access
router.post('/admin/reports',
authenticateAdmin,
requireRole(['admin', 'super_admin']),
generateReportController
);
```
## Operation Logging
All admin operations are automatically logged for audit purposes. To enable logging on a route:
```javascript
const { logAdminOperation } = require('../middleware/adminLogger');
router.put('/admin/users/:id',
authenticateAdmin,
requireAdmin,
logAdminOperation, // Add this middleware
updateUserController
);
```
**Logged Information:**
- Timestamp
- Admin ID and username
- Admin role
- HTTP method and path
- IP address
- User agent
- Status code
- Request body (with sensitive data redacted)
## Login History
Every successful admin login creates a record in the `login_history` table with:
- User ID
- User type (`admin`)
- IP address
- User agent
- Device information
- Login timestamp
## Security Features
1. **Password Hashing**: Passwords are hashed using bcrypt with 10 salt rounds
2. **JWT Tokens**: Tokens expire after 7 days (configurable)
3. **Token Type Validation**: Admin tokens cannot be used for user endpoints and vice versa
4. **Account Status Check**: Inactive admin accounts cannot login
5. **Sensitive Data Redaction**: Passwords and secrets are redacted from logs
## Error Codes
| Code | Status | Description |
|------|--------|-------------|
| `MISSING_CREDENTIALS` | 400 | Username or password not provided |
| `INVALID_CREDENTIALS` | 401 | Wrong username or password |
| `ACCOUNT_INACTIVE` | 403 | Admin account is inactive |
| `MISSING_TOKEN` | 401 | No authentication token provided |
| `INVALID_TOKEN` | 401 | Token is invalid or expired |
| `INVALID_TOKEN_TYPE` | 401 | Wrong token type (user token for admin endpoint) |
| `UNAUTHORIZED` | 401 | Authentication required |
| `FORBIDDEN` | 403 | Insufficient permissions for this action |
## Example Usage
### Complete Admin Route Setup
```javascript
const express = require('express');
const router = express.Router();
const { authenticateAdmin } = require('../middleware/auth');
const { requireAdmin } = require('../middleware/rbac');
const { logAdminOperation } = require('../middleware/adminLogger');
const userController = require('../controllers/admin/userController');
// Get all users (any admin)
router.get('/users',
authenticateAdmin,
logAdminOperation,
userController.getUsers
);
// Update user status (admin or super_admin only)
router.put('/users/:id/status',
authenticateAdmin,
requireAdmin,
logAdminOperation,
userController.updateUserStatus
);
module.exports = router;
```
### Frontend Integration
```javascript
// Login
const response = await fetch('/api/v1/admin/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
});
const { data } = await response.json();
const { token } = data;
// Store token
localStorage.setItem('adminToken', token);
// Use token for authenticated requests
const usersResponse = await fetch('/api/v1/admin/users', {
headers: {
'Authorization': `Bearer ${token}`
}
});
```
## Testing
### Unit Tests
```bash
npm test -- rbac.unit.test.js
```
### Integration Tests (requires database)
```bash
npm test -- admin.integration.test.js
npm test -- rbac.test.js
```
## Default Admin Account
A default super admin account is created during database seeding:
- **Username**: `admin`
- **Password**: `admin123`
- **Role**: `super_admin`
**⚠️ Important**: Change the default password in production!
## Configuration
Environment variables for admin authentication:
```env
JWT_SECRET=your-secret-key
JWT_EXPIRES_IN=7d
```
## Future Enhancements
- [ ] Two-factor authentication (2FA)
- [ ] Password reset functionality
- [ ] Session management and revocation
- [ ] IP whitelisting for admin access
- [ ] More granular permissions system