Some checks are pending
Docker Test / test (push) Waiting to run
This commit implements the role-based access control system as outlined in the project documentation. It includes: - A requireRole middleware for protecting routes - Auth routes for registration, login, profile management - Audit logging for sensitive actions - Role management endpoints - Updated app.js to include audit logging middleware
108 lines
No EOL
3 KiB
JavaScript
108 lines
No EOL
3 KiB
JavaScript
// routes/auth.js
|
|
const express = require('express');
|
|
const router = express.Router();
|
|
const jwt = require('jsonwebtoken');
|
|
const bcrypt = require('bcrypt');
|
|
const requireRole = require('../middleware/requireRole');
|
|
|
|
// Mock user database (in real app, this would be a real DB)
|
|
const users = [];
|
|
|
|
// Register route
|
|
router.post('/register', async (req, res) => {
|
|
try {
|
|
const { email, password } = req.body;
|
|
|
|
// Check if user already exists
|
|
const existingUser = users.find(u => u.email === email);
|
|
if (existingUser) {
|
|
return res.status(400).json({ error: 'User already exists' });
|
|
}
|
|
|
|
// Hash password
|
|
const hashedPassword = await bcrypt.hash(password, 10);
|
|
|
|
// Create user
|
|
const user = {
|
|
id: users.length + 1,
|
|
email,
|
|
password: hashedPassword,
|
|
role: 'user' // Default role
|
|
};
|
|
|
|
users.push(user);
|
|
|
|
// Generate JWT token
|
|
const token = jwt.sign(
|
|
{ id: user.id, email: user.email, role: user.role },
|
|
process.env.JWT_SECRET,
|
|
{ expiresIn: '24h' }
|
|
);
|
|
|
|
res.status(201).json({ token, user: { id: user.id, email: user.email, role: user.role } });
|
|
} catch (error) {
|
|
res.status(500).json({ error: 'Registration failed' });
|
|
}
|
|
});
|
|
|
|
// Login route
|
|
router.post('/login', async (req, res) => {
|
|
try {
|
|
const { email, password } = req.body;
|
|
|
|
// Find user
|
|
const user = users.find(u => u.email === email);
|
|
if (!user) {
|
|
return res.status(400).json({ error: 'Invalid credentials' });
|
|
}
|
|
|
|
// Check password
|
|
const validPassword = await bcrypt.compare(password, user.password);
|
|
if (!validPassword) {
|
|
return res.status(400).json({ error: 'Invalid credentials' });
|
|
}
|
|
|
|
// Generate JWT token
|
|
const token = jwt.sign(
|
|
{ id: user.id, email: user.email, role: user.role },
|
|
process.env.JWT_SECRET,
|
|
{ expiresIn: '24h' }
|
|
);
|
|
|
|
res.json({ token, user: { id: user.id, email: user.email, role: user.role } });
|
|
} catch (error) {
|
|
res.status(500).json({ error: 'Login failed' });
|
|
}
|
|
});
|
|
|
|
// Get user profile (requires authentication)
|
|
router.get('/profile', requireRole(['user', 'moderator', 'admin']), (req, res) => {
|
|
const user = users.find(u => u.id === req.user.id);
|
|
if (!user) {
|
|
return res.status(404).json({ error: 'User not found' });
|
|
}
|
|
res.json({ id: user.id, email: user.email, role: user.role });
|
|
});
|
|
|
|
// Update user profile (requires authentication)
|
|
router.put('/profile', requireRole(['user', 'moderator', 'admin']), async (req, res) => {
|
|
try {
|
|
const { email } = req.body;
|
|
const user = users.find(u => u.id === req.user.id);
|
|
|
|
if (!user) {
|
|
return res.status(404).json({ error: 'User not found' });
|
|
}
|
|
|
|
// Update email if provided
|
|
if (email) {
|
|
user.email = email;
|
|
}
|
|
|
|
res.json({ message: 'Profile updated', user: { id: user.id, email: user.email, role: user.role } });
|
|
} catch (error) {
|
|
res.status(500).json({ error: 'Update failed' });
|
|
}
|
|
});
|
|
|
|
module.exports = router; |