freealberta/map/app/controllers/authController.js

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();