89 lines
2.3 KiB
JavaScript
89 lines
2.3 KiB
JavaScript
import express from 'express';
|
|
import crypto from 'crypto';
|
|
import { query } from '../db/index.js';
|
|
import { asyncHandler, AppError } from '../middleware/errorHandler.js';
|
|
import { verifyToken } from '../middleware/auth.js';
|
|
|
|
const router = express.Router();
|
|
|
|
// Middleware to check if user is admin
|
|
const requireAdmin = asyncHandler(async (req, res, next) => {
|
|
if (!req.user || !req.user.is_admin) {
|
|
throw new AppError('Admin access required', 403);
|
|
}
|
|
next();
|
|
});
|
|
|
|
// Get all users (admin only)
|
|
router.get('/users', verifyToken, requireAdmin, asyncHandler(async (req, res) => {
|
|
const users = await query(
|
|
'SELECT id, email, username, is_admin, created_at FROM users ORDER BY created_at DESC'
|
|
);
|
|
res.json({ users });
|
|
}));
|
|
|
|
// Generate password reset token (admin only)
|
|
router.post('/generate-reset-token', verifyToken, requireAdmin, asyncHandler(async (req, res) => {
|
|
const { userId } = req.body;
|
|
|
|
if (!userId) {
|
|
throw new AppError('User ID required', 400);
|
|
}
|
|
|
|
// Verify user exists
|
|
const users = await query('SELECT id, username, email FROM users WHERE id = ?', [userId]);
|
|
if (users.length === 0) {
|
|
throw new AppError('User not found', 404);
|
|
}
|
|
|
|
const user = users[0];
|
|
|
|
// Generate secure token
|
|
const token = crypto.randomBytes(32).toString('hex');
|
|
|
|
// Token expires in 1 hour
|
|
const expiresAt = new Date(Date.now() + 60 * 60 * 1000);
|
|
|
|
// Store token
|
|
await query(
|
|
'INSERT INTO password_reset_tokens (user_id, token, created_by, expires_at) VALUES (?, ?, ?, ?)',
|
|
[userId, token, req.user.userId, expiresAt]
|
|
);
|
|
|
|
res.json({
|
|
success: true,
|
|
token,
|
|
user: {
|
|
id: user.id,
|
|
username: user.username,
|
|
email: user.email
|
|
},
|
|
expiresAt
|
|
});
|
|
}));
|
|
|
|
// Get reset token history (admin only)
|
|
router.get('/reset-tokens', verifyToken, requireAdmin, asyncHandler(async (req, res) => {
|
|
const tokens = await query(`
|
|
SELECT
|
|
prt.id,
|
|
prt.token,
|
|
prt.created_at,
|
|
prt.expires_at,
|
|
prt.used_at,
|
|
u.id as user_id,
|
|
u.username,
|
|
u.email,
|
|
admin.username as created_by_username
|
|
FROM password_reset_tokens prt
|
|
JOIN users u ON prt.user_id = u.id
|
|
JOIN users admin ON prt.created_by = admin.id
|
|
ORDER BY prt.created_at DESC
|
|
LIMIT 100
|
|
`);
|
|
|
|
res.json({ tokens });
|
|
}));
|
|
|
|
export default router;
|