264 lines
9.2 KiB
JavaScript

const nocodbService = require('../services/nocodb');
class AuthController {
async login(req, res) {
try {
const { email, password } = req.body;
// Validate input
if (!email || !password) {
return res.status(400).json({
success: false,
error: 'Email and password are required'
});
}
// Validate email format
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(email)) {
return res.status(400).json({
success: false,
error: 'Invalid email format'
});
}
console.log('Login attempt:', {
email,
ip: req.ip,
userAgent: req.headers['user-agent']
});
// Fetch user from NocoDB
const user = await nocodbService.getUserByEmail(email);
if (!user) {
console.warn(`No user found with email: ${email}`);
return res.status(401).json({
success: false,
error: 'Invalid email or password'
});
}
// Check password
if (user.Password !== password && user.password !== password) {
console.warn(`Invalid password for email: ${email}`);
return res.status(401).json({
success: false,
error: 'Invalid email or password'
});
}
// Check if temp user has expired
const userType = user['User Type'] || user.UserType || user.userType || 'user';
if (userType === 'temp') {
const expiration = user.ExpiresAt || user.expiresAt || user.Expiration || user.expiration;
if (expiration) {
const expirationDate = new Date(expiration);
const now = new Date();
if (now > expirationDate) {
console.warn(`Expired temp user attempted login: ${email}, expired: ${expiration}`);
return res.status(401).json({
success: false,
error: 'Account has expired. Please contact an administrator.'
});
}
}
}
// Update last login time
try {
// Debug: Log user object structure
console.log('User object keys:', Object.keys(user));
console.log('User ID candidates:', {
ID: user.ID,
Id: user.Id,
id: user.id
});
const userId = user.ID || user.Id || user.id;
if (userId) {
await nocodbService.updateUser(userId, {
'Last Login': new Date().toISOString()
});
} else {
console.warn('No valid user ID found for updating last login time');
}
} catch (updateError) {
console.warn('Failed to update last login time:', updateError.message);
// Don't fail the login
}
// Set session
req.session.authenticated = true;
req.session.userId = user.ID || user.Id || user.id;
req.session.userEmail = user.Email || user.email;
req.session.userName = user.Name || user.name;
req.session.isAdmin = user.Admin || user.admin || false;
req.session.userType = userType;
console.log('User logged in successfully:', {
email: req.session.userEmail,
isAdmin: req.session.isAdmin
});
// Force session save
req.session.save((err) => {
if (err) {
console.error('Session save error:', err);
return res.status(500).json({
success: false,
error: 'Session error. Please try again.'
});
}
res.json({
success: true,
user: {
id: req.session.userId,
email: req.session.userEmail,
name: req.session.userName,
isAdmin: req.session.isAdmin,
userType: req.session.userType
}
});
});
} catch (error) {
console.error('Login error:', error);
res.status(500).json({
success: false,
error: 'Server error. Please try again later.'
});
}
}
async logout(req, res) {
try {
const userEmail = req.session?.userEmail;
req.session.destroy((err) => {
if (err) {
console.error('Session destroy error:', err);
return res.status(500).json({
success: false,
error: 'Logout failed'
});
}
console.log('User logged out:', userEmail);
res.json({ success: true });
});
} catch (error) {
console.error('Logout error:', error);
res.status(500).json({
success: false,
error: 'Server error during logout'
});
}
}
async checkSession(req, res) {
try {
const isAuthenticated = (req.session && req.session.authenticated) ||
(req.session && req.session.userId && req.session.userEmail);
if (isAuthenticated) {
res.json({
authenticated: true,
user: {
id: req.session.userId,
email: req.session.userEmail,
name: req.session.userName,
isAdmin: req.session.isAdmin,
userType: req.session.userType || 'user'
}
});
} else {
res.json({
authenticated: false
});
}
} catch (error) {
console.error('Session check error:', error);
res.status(500).json({
success: false,
error: 'Session check failed'
});
}
}
async changePassword(req, res) {
try {
const { currentPassword, newPassword } = req.body;
// Validate input
if (!currentPassword || !newPassword) {
return res.status(400).json({
success: false,
error: 'Current password and new password are required'
});
}
// Validate new password strength
if (newPassword.length < 8) {
return res.status(400).json({
success: false,
error: 'New password must be at least 8 characters long'
});
}
// Get user from session
const userId = req.session.userId;
const userEmail = req.session.userEmail;
if (!userId || !userEmail) {
return res.status(401).json({
success: false,
error: 'Session expired. Please login again.'
});
}
// Fetch user from NocoDB to verify current password
const user = await nocodbService.getUserByEmail(userEmail);
if (!user) {
return res.status(404).json({
success: false,
error: 'User not found'
});
}
// Verify current password
const storedPassword = user.Password || user.password;
if (storedPassword !== currentPassword) {
return res.status(401).json({
success: false,
error: 'Current password is incorrect'
});
}
// Update password in NocoDB
await nocodbService.updateUser(userId, {
Password: newPassword
});
console.log('Password changed successfully for user:', userEmail);
res.json({
success: true,
message: 'Password changed successfully'
});
} catch (error) {
console.error('Change password error:', error);
res.status(500).json({
success: false,
error: 'Failed to change password. Please try again later.'
});
}
}
}
module.exports = new AuthController();