198 lines
7.6 KiB
JavaScript
198 lines
7.6 KiB
JavaScript
const nocodbService = require('../services/nocodb');
|
|
const logger = require('../utils/logger');
|
|
const { extractId } = require('../utils/helpers');
|
|
|
|
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'
|
|
});
|
|
}
|
|
|
|
logger.info('Login attempt:', {
|
|
email,
|
|
ip: req.ip,
|
|
cfIp: req.headers['cf-connecting-ip'],
|
|
userAgent: req.headers['user-agent']
|
|
});
|
|
|
|
// Fetch user from NocoDB
|
|
const user = await nocodbService.getUserByEmail(email);
|
|
|
|
if (!user) {
|
|
logger.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) {
|
|
logger.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.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) {
|
|
logger.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 {
|
|
const userId = extractId(user);
|
|
await nocodbService.update(
|
|
require('../config').nocodb.loginSheetId,
|
|
userId,
|
|
{
|
|
'Last Login': new Date().toISOString(),
|
|
last_login: new Date().toISOString()
|
|
}
|
|
);
|
|
} catch (updateError) {
|
|
logger.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;
|
|
req.session.userEmail = user.email || user.Email; // Make sure this is set
|
|
req.session.userName = user.name || user.Name;
|
|
req.session.isAdmin = user.admin || user.Admin || false;
|
|
req.session.userType = user.UserType || user.userType || (req.session.isAdmin ? 'admin' : 'user');
|
|
|
|
logger.info('User logged in:', {
|
|
email: req.session.userEmail,
|
|
admin: req.session.isAdmin
|
|
});
|
|
|
|
// Force session save
|
|
req.session.save((err) => {
|
|
if (err) {
|
|
logger.error('Session save error:', err);
|
|
return res.status(500).json({
|
|
success: false,
|
|
error: 'Session error. Please try again.'
|
|
});
|
|
}
|
|
|
|
logger.info(`User authenticated: ${email}, Admin: ${req.session.isAdmin}`);
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Login successful',
|
|
user: {
|
|
email: email,
|
|
name: req.session.userName,
|
|
isAdmin: req.session.isAdmin,
|
|
userType: req.session.userType
|
|
}
|
|
});
|
|
});
|
|
|
|
} catch (error) {
|
|
logger.error('Login error:', error.message);
|
|
res.status(500).json({
|
|
success: false,
|
|
error: 'Authentication service error. Please try again later.'
|
|
});
|
|
}
|
|
}
|
|
|
|
async logout(req, res) {
|
|
req.session.destroy((err) => {
|
|
if (err) {
|
|
logger.error('Logout error:', err);
|
|
return res.status(500).json({
|
|
success: false,
|
|
error: 'Logout failed'
|
|
});
|
|
}
|
|
res.json({
|
|
success: true,
|
|
message: 'Logged out successfully'
|
|
});
|
|
});
|
|
}
|
|
|
|
async check(req, res) {
|
|
// If user is authenticated, check for temp user expiration
|
|
if (req.session?.authenticated && req.session?.userType === 'temp' && req.session?.userEmail) {
|
|
try {
|
|
const user = await nocodbService.getUserByEmail(req.session.userEmail);
|
|
if (user) {
|
|
const expiration = user.ExpiresAt || user.ExpiresAt || user.Expiration || user.expiration;
|
|
if (expiration) {
|
|
const expirationDate = new Date(expiration);
|
|
const now = new Date();
|
|
|
|
if (now > expirationDate) {
|
|
logger.warn(`Expired temp user session detected in check: ${req.session.userEmail}, expired: ${expiration}`);
|
|
|
|
// Destroy the session
|
|
req.session.destroy((err) => {
|
|
if (err) {
|
|
logger.error('Session destroy error:', err);
|
|
}
|
|
});
|
|
|
|
return res.json({
|
|
authenticated: false,
|
|
user: null,
|
|
expired: true,
|
|
message: 'Account has expired. Please contact an administrator.'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error checking temp user expiration in check:', error.message);
|
|
// Don't fail the check on database errors, just log it
|
|
}
|
|
}
|
|
|
|
res.json({
|
|
authenticated: req.session?.authenticated || false,
|
|
user: req.session?.authenticated ? {
|
|
email: req.session.userEmail,
|
|
name: req.session.userName,
|
|
isAdmin: req.session.isAdmin || false,
|
|
userType: req.session.userType || 'user'
|
|
} : null
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = new AuthController(); |