MFA
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
const express = require('express');
|
||||
const { User, UserAddress } = require('../models'); // Import from models/index.js to get models with associations
|
||||
const { authenticateToken, optionalAuth, requireAdmin } = require('../middleware/auth');
|
||||
const { validateCoordinatesBody, handleValidationErrors } = require('../middleware/validation');
|
||||
const { validateCoordinatesBody, validatePasswordChange, handleValidationErrors, sanitizeInput } = require('../middleware/validation');
|
||||
const { requireStepUpAuth } = require('../middleware/stepUpAuth');
|
||||
const { csrfProtection } = require('../middleware/csrf');
|
||||
const logger = require('../utils/logger');
|
||||
const userService = require('../services/UserService');
|
||||
const emailServices = require('../services/email');
|
||||
const { validateS3Keys } = require('../utils/s3KeyValidator');
|
||||
const { IMAGE_LIMITS } = require('../config/imageLimits');
|
||||
const router = express.Router();
|
||||
@@ -362,6 +365,58 @@ router.post('/admin/:id/ban', authenticateToken, requireAdmin, async (req, res,
|
||||
}
|
||||
});
|
||||
|
||||
// Change password (requires step-up auth if 2FA is enabled)
|
||||
router.put('/password', authenticateToken, csrfProtection, requireStepUpAuth('password_change'), sanitizeInput, validatePasswordChange, async (req, res, next) => {
|
||||
try {
|
||||
const { currentPassword, newPassword } = req.body;
|
||||
const user = await User.findByPk(req.user.id);
|
||||
|
||||
if (!user) {
|
||||
return res.status(404).json({ error: 'User not found' });
|
||||
}
|
||||
|
||||
// Google OAuth users can't change password
|
||||
if (user.authProvider === 'google' && !user.password) {
|
||||
return res.status(400).json({
|
||||
error: 'Cannot change password for accounts linked with Google'
|
||||
});
|
||||
}
|
||||
|
||||
// Verify current password
|
||||
const isValid = await user.comparePassword(currentPassword);
|
||||
if (!isValid) {
|
||||
return res.status(400).json({ error: 'Current password is incorrect' });
|
||||
}
|
||||
|
||||
// Update password (this increments jwtVersion to invalidate other sessions)
|
||||
await user.resetPassword(newPassword);
|
||||
|
||||
// Send password changed notification
|
||||
try {
|
||||
await emailServices.auth.sendPasswordChangedEmail(user);
|
||||
} catch (emailError) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.error('Failed to send password changed email', {
|
||||
error: emailError.message,
|
||||
userId: req.user.id
|
||||
});
|
||||
}
|
||||
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.info('Password changed successfully', { userId: req.user.id });
|
||||
|
||||
res.json({ message: 'Password changed successfully' });
|
||||
} catch (error) {
|
||||
const reqLogger = logger.withRequestId(req.id);
|
||||
reqLogger.error('Password change failed', {
|
||||
error: error.message,
|
||||
stack: error.stack,
|
||||
userId: req.user.id
|
||||
});
|
||||
next(error);
|
||||
}
|
||||
});
|
||||
|
||||
// Admin: Unban a user
|
||||
router.post('/admin/:id/unban', authenticateToken, requireAdmin, async (req, res, next) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user