270 lines
6.0 KiB
JavaScript
270 lines
6.0 KiB
JavaScript
const bcrypt = require('bcryptjs');
|
|
const { User, AuditLog } = require('../models');
|
|
const { generateToken } = require('../config/auth');
|
|
const { AUDIT_ACTIONS } = require('../config/constants');
|
|
|
|
// Register new user
|
|
exports.register = async (req, res) => {
|
|
try {
|
|
const { email, password, fullName, role, phone, region, zone } = req.body;
|
|
|
|
// Validate input
|
|
if (!email || !password || !fullName || !role) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Email, password, full name, and role are required'
|
|
});
|
|
}
|
|
|
|
// Check if user already exists
|
|
const existingUser = await User.findOne({ where: { email } });
|
|
if (existingUser) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'User with this email already exists'
|
|
});
|
|
}
|
|
|
|
// Hash password
|
|
const hashedPassword = await bcrypt.hash(password, 10);
|
|
|
|
// Insert user
|
|
const user = await User.create({
|
|
email,
|
|
password: hashedPassword,
|
|
name: fullName,
|
|
role,
|
|
phone,
|
|
region,
|
|
zone
|
|
});
|
|
|
|
// Log audit
|
|
await AuditLog.create({
|
|
userId: user.id,
|
|
action: AUDIT_ACTIONS.CREATED,
|
|
entityType: 'user',
|
|
entityId: user.id
|
|
});
|
|
|
|
res.status(201).json({
|
|
success: true,
|
|
message: 'User registered successfully',
|
|
userId: user.id
|
|
});
|
|
} catch (error) {
|
|
console.error('Register error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Error registering user'
|
|
});
|
|
}
|
|
};
|
|
|
|
// Login
|
|
exports.login = async (req, res) => {
|
|
try {
|
|
const { email, password } = req.body;
|
|
|
|
// Validate input
|
|
if (!email || !password) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Email and password are required'
|
|
});
|
|
}
|
|
|
|
// Get user
|
|
const user = await User.findOne({ where: { email } });
|
|
|
|
if (!user) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: 'Invalid email or password'
|
|
});
|
|
}
|
|
|
|
// Check if account is active
|
|
if (user.status !== 'active') {
|
|
return res.status(403).json({
|
|
success: false,
|
|
message: 'Account is deactivated'
|
|
});
|
|
}
|
|
|
|
// Verify password
|
|
const isValidPassword = await bcrypt.compare(password, user.password);
|
|
if (!isValidPassword) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: 'Invalid email or password'
|
|
});
|
|
}
|
|
|
|
// Update last login
|
|
await user.update({ lastLogin: new Date() });
|
|
|
|
// Generate token
|
|
const token = generateToken(user);
|
|
|
|
// Log audit
|
|
await AuditLog.create({
|
|
userId: user.id,
|
|
action: 'user_login',
|
|
entityType: 'user',
|
|
entityId: user.id
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
token,
|
|
user: {
|
|
id: user.id,
|
|
email: user.email,
|
|
fullName: user.name,
|
|
role: user.role,
|
|
region: user.region,
|
|
zone: user.zone
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Login error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Error during login'
|
|
});
|
|
}
|
|
};
|
|
|
|
// Get profile
|
|
exports.getProfile = async (req, res) => {
|
|
try {
|
|
const user = await User.findByPk(req.user.id, {
|
|
attributes: ['id', 'email', 'name', 'role', 'region', 'zone', 'phone', 'createdAt']
|
|
});
|
|
|
|
if (!user) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'User not found'
|
|
});
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
user: {
|
|
id: user.id,
|
|
email: user.email,
|
|
fullName: user.name,
|
|
role: user.role,
|
|
region: user.region,
|
|
zone: user.zone,
|
|
phone: user.phone,
|
|
createdAt: user.createdAt
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error('Get profile error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Error fetching profile'
|
|
});
|
|
}
|
|
};
|
|
|
|
// Update profile
|
|
exports.updateProfile = async (req, res) => {
|
|
try {
|
|
const { fullName, phone } = req.body;
|
|
|
|
const user = await User.findByPk(req.user.id);
|
|
if (!user) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'User not found'
|
|
});
|
|
}
|
|
|
|
await user.update({
|
|
name: fullName || user.name,
|
|
phone: phone || user.phone
|
|
});
|
|
|
|
// Log audit
|
|
await AuditLog.create({
|
|
userId: req.user.id,
|
|
action: AUDIT_ACTIONS.UPDATED,
|
|
entityType: 'user',
|
|
entityId: req.user.id
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Profile updated successfully'
|
|
});
|
|
} catch (error) {
|
|
console.error('Update profile error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Error updating profile'
|
|
});
|
|
}
|
|
};
|
|
|
|
// Change password
|
|
exports.changePassword = async (req, res) => {
|
|
try {
|
|
const { currentPassword, newPassword } = req.body;
|
|
|
|
if (!currentPassword || !newPassword) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
message: 'Current password and new password are required'
|
|
});
|
|
}
|
|
|
|
// Get current user
|
|
const user = await User.findByPk(req.user.id);
|
|
if (!user) {
|
|
return res.status(404).json({
|
|
success: false,
|
|
message: 'User not found'
|
|
});
|
|
}
|
|
|
|
// Verify current password
|
|
const isValid = await bcrypt.compare(currentPassword, user.password);
|
|
if (!isValid) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
message: 'Current password is incorrect'
|
|
});
|
|
}
|
|
|
|
// Hash new password
|
|
const hashedPassword = await bcrypt.hash(newPassword, 10);
|
|
|
|
// Update password
|
|
await user.update({ password: hashedPassword });
|
|
|
|
// Log audit
|
|
await AuditLog.create({
|
|
userId: req.user.id,
|
|
action: 'password_changed',
|
|
entityType: 'user',
|
|
entityId: req.user.id
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Password changed successfully'
|
|
});
|
|
} catch (error) {
|
|
console.error('Change password error:', error);
|
|
res.status(500).json({
|
|
success: false,
|
|
message: 'Error changing password'
|
|
});
|
|
}
|
|
};
|