File: /home/ekspardev/ekspar-katalog-backend/src/app/user/controller/user.controller.js
const { User, UserLoginHistory } = require('../model/user.model');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { Op } = require('sequelize');
const useragent = require('useragent');
const geoip = require('geoip-lite');
exports.register = async (req, res) => {
try {
const { username, email, password, fullName } = req.body;
const user = await User.create({ username, email, password, fullName });
res.status(201).json({ message: 'User registered successfully', userId: user.id });
} catch (error) {
res.status(500).json({ message: 'Error registering user', error: error.message });
}
};
exports.login = async (req, res) => {
try {
const { username, password } = req.body;
const user = await User.findOne({ where: { username } });
if (!user || !(await bcrypt.compare(password, user.password))) {
return res.status(401).json({ message: 'Invalid credentials' });
}
// IP adresini doğru şekilde alalım
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
console.log('IP Address:', ip); // IP adresini loglayalım
const agent = useragent.parse(req.headers['user-agent']);
const geo = geoip.lookup(ip);
console.log('Geo Data:', geo); // Geo verisini loglayalım
// Eğer geo null ise veya geçerli değilse, varsayılan değerler kullanalım
const location = geo && geo.city ? `${geo.city}, ${geo.region}, ${geo.country}` : 'Unknown';
const latitude = geo && geo.ll ? geo.ll[0] : null;
const longitude = geo && geo.ll ? geo.ll[1] : null;
const countryCode = geo ? geo.country : null;
await UserLoginHistory.create({
userId: user.id,
loginTime: new Date(),
ipAddress: ip,
location: location,
browser: agent.toAgent(),
operatingSystem: agent.os.toString(),
device: agent.device.toString(),
macAddress: req.body.macAddress || 'Not available',
userAgent: req.headers['user-agent'],
acceptLanguage: req.headers['accept-language'],
screenResolution: req.body.screenResolution || 'Not available',
timeZone: req.body.timeZone || 'Not available',
latitude: latitude,
longitude: longitude,
countryCode: countryCode,
});
res.json({ message: 'Login successful', user: { id: user.id, username: user.username } });
} catch (error) {
console.error('Login error:', error);
res.status(500).json({ message: 'An error occurred during login' });
}
};
exports.getProfile = async (req, res) => {
try {
const user = await User.findByPk(req.user.id, {
attributes: { exclude: ['password'] }
});
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.json(user);
} catch (error) {
console.error('Error fetching profile:', error);
res.status(500).json({ message: 'Error fetching profile', error: error.message });
}
};
exports.updateProfile = async (req, res) => {
try {
const { fullName, email } = req.body;
// req.user.id kullanın, çünkü authMiddleware bunu ayarlıyor
const user = await User.findByPk(req.user.id);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
await user.update({ fullName, email });
// Güncellenmiş kullanıcı bilgilerini döndür
res.json({
message: 'Profile updated successfully',
user: {
id: user.id,
fullName: user.fullName,
email: user.email
}
});
} catch (error) {
console.error('Error updating profile:', error);
res.status(500).json({ message: 'Error updating profile', error: error.message });
}
};
exports.changePassword = async (req, res) => {
try {
const { currentPassword, newPassword } = req.body;
const user = await User.findByPk(req.userId);
if (!user || !(await user.validPassword(currentPassword))) {
return res.status(401).json({ message: 'Invalid current password' });
}
await user.update({ password: newPassword });
res.json({ message: 'Password changed successfully' });
} catch (error) {
res.status(500).json({ message: 'Error changing password', error: error.message });
}
};
exports.requestPasswordReset = async (req, res) => {
try {
const { email } = req.body;
const user = await User.findOne({ where: { email } });
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
const resetToken = crypto.randomBytes(20).toString('hex');
await user.update({
passwordResetToken: resetToken,
passwordResetExpires: Date.now() + 3600000 // 1 hour
});
// Send email with reset token
res.json({ message: 'Password reset email sent' });
} catch (error) {
res.status(500).json({ message: 'Error requesting password reset', error: error.message });
}
};
exports.resetPassword = async (req, res) => {
try {
const { token, newPassword } = req.body;
const user = await User.findOne({
where: {
passwordResetToken: token,
passwordResetExpires: { [Op.gt]: Date.now() }
}
});
if (!user) {
return res.status(400).json({ message: 'Invalid or expired password reset token' });
}
await user.update({
password: newPassword,
passwordResetToken: null,
passwordResetExpires: null
});
res.json({ message: 'Password reset successfully' });
} catch (error) {
res.status(500).json({ message: 'Error resetting password', error: error.message });
}
};
exports.enableTwoFactor = async (req, res) => {
try {
const user = await User.findByPk(req.userId);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
const secret = speakeasy.generateSecret();
await user.update({
twoFactorSecret: secret.base32,
isTwoFactorEnabled: true
});
res.json({ secret: secret.otpauth_url });
} catch (error) {
res.status(500).json({ message: 'Error enabling two-factor authentication', error: error.message });
}
};
exports.disableTwoFactor = async (req, res) => {
try {
const user = await User.findByPk(req.userId);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
await user.update({
twoFactorSecret: null,
isTwoFactorEnabled: false
});
res.json({ message: 'Two-factor authentication disabled' });
} catch (error) {
res.status(500).json({ message: 'Error disabling two-factor authentication', error: error.message });
}
};
exports.deleteAccount = async (req, res) => {
try {
const user = await User.findByPk(req.userId);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
await user.destroy();
res.json({ message: 'Account deleted successfully' });
} catch (error) {
res.status(500).json({ message: 'Error deleting account', error: error.message });
}
};
// Admin functions
exports.getAllUsers = async (req, res) => {
try {
const users = await User.findAll({
attributes: { exclude: ['password'] }
});
res.json(users);
} catch (error) {
res.status(500).json({ message: 'Error fetching users', error: error.message });
}
};
exports.getUserById = async (req, res) => {
try {
const user = await User.findByPk(req.params.id, {
attributes: { exclude: ['password'] }
});
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
res.json(user);
} catch (error) {
res.status(500).json({ message: 'Error fetching user', error: error.message });
}
};
exports.updateUser = async (req, res) => {
try {
const user = await User.findByPk(req.params.id);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
await user.update(req.body);
res.json({ message: 'User updated successfully' });
} catch (error) {
res.status(500).json({ message: 'Error updating user', error: error.message });
}
};
exports.deleteUser = async (req, res) => {
try {
const user = await User.findByPk(req.params.id);
if (!user) {
return res.status(404).json({ message: 'User not found' });
}
await user.destroy();
res.json({ message: 'User deleted successfully' });
} catch (error) {
res.status(500).json({ message: 'Error deleting user', error: error.message });
}
};