172 lines
6.2 KiB
JavaScript
172 lines
6.2 KiB
JavaScript
const logger = require('../utils/logger');
|
|
const nocodbService = require('../services/nocodb');
|
|
|
|
// Helper function to check if a temp user has expired
|
|
const checkTempUserExpiration = async (req, res) => {
|
|
if (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: ${req.session.userEmail}, expired: ${expiration}`);
|
|
|
|
// Destroy the session
|
|
req.session.destroy((err) => {
|
|
if (err) {
|
|
logger.error('Session destroy error:', err);
|
|
}
|
|
});
|
|
|
|
if (req.xhr || req.headers.accept?.indexOf('json') > -1) {
|
|
return res.status(401).json({
|
|
success: false,
|
|
error: 'Account has expired. Please contact an administrator.',
|
|
expired: true
|
|
});
|
|
} else {
|
|
return res.redirect('/login.html?expired=true');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (error) {
|
|
logger.error('Error checking temp user expiration:', error.message);
|
|
// Don't fail the request on database errors, just log it
|
|
}
|
|
}
|
|
return null; // No expiration issue
|
|
};
|
|
|
|
const requireAuth = async (req, res, next) => {
|
|
// Check for both authentication patterns used in your app
|
|
const isAuthenticated = (req.session && req.session.authenticated) ||
|
|
(req.session && req.session.userId && req.session.userEmail);
|
|
|
|
if (isAuthenticated) {
|
|
// Check if temp user has expired
|
|
const expirationResponse = await checkTempUserExpiration(req, res);
|
|
if (expirationResponse) {
|
|
return; // Response already sent by checkTempUserExpiration
|
|
}
|
|
|
|
next();
|
|
} else {
|
|
logger.warn('Unauthorized access attempt', {
|
|
ip: req.ip,
|
|
path: req.path,
|
|
userAgent: req.get('User-Agent')
|
|
});
|
|
|
|
if (req.xhr || req.headers.accept?.indexOf('json') > -1) {
|
|
res.status(401).json({
|
|
success: false,
|
|
error: 'Authentication required'
|
|
});
|
|
} else {
|
|
res.redirect('/login.html');
|
|
}
|
|
}
|
|
};
|
|
|
|
const requireAdmin = async (req, res, next) => {
|
|
// Check for both authentication patterns used in your app
|
|
const isAuthenticated = (req.session && req.session.authenticated) ||
|
|
(req.session && req.session.userId && req.session.userEmail);
|
|
|
|
if (isAuthenticated && req.session.isAdmin) {
|
|
// Check if temp user has expired
|
|
const expirationResponse = await checkTempUserExpiration(req, res);
|
|
if (expirationResponse) {
|
|
return; // Response already sent by checkTempUserExpiration
|
|
}
|
|
|
|
next();
|
|
} else {
|
|
logger.warn('Unauthorized admin access attempt', {
|
|
ip: req.ip,
|
|
path: req.path,
|
|
user: req.session?.userEmail || 'anonymous',
|
|
userAgent: req.get('User-Agent')
|
|
});
|
|
|
|
if (req.xhr || req.headers.accept?.indexOf('json') > -1) {
|
|
res.status(403).json({
|
|
success: false,
|
|
error: 'Admin access required'
|
|
});
|
|
} else {
|
|
res.redirect('/login.html');
|
|
}
|
|
}
|
|
};
|
|
|
|
const requireNonTemp = async (req, res, next) => {
|
|
const isAuthenticated = (req.session && req.session.authenticated) ||
|
|
(req.session && req.session.userId && req.session.userEmail);
|
|
|
|
if (isAuthenticated && req.session.userType !== 'temp') {
|
|
// Check if temp user has expired (shouldn't happen here, but for safety)
|
|
const expirationResponse = await checkTempUserExpiration(req, res);
|
|
if (expirationResponse) {
|
|
return; // Response already sent by checkTempUserExpiration
|
|
}
|
|
|
|
next();
|
|
} else {
|
|
logger.warn('Temp user access denied', {
|
|
ip: req.ip,
|
|
path: req.path,
|
|
user: req.session?.userEmail || 'anonymous',
|
|
userType: req.session?.userType || 'unknown'
|
|
});
|
|
|
|
if (req.xhr || req.headers.accept?.indexOf('json') > -1) {
|
|
res.status(403).json({
|
|
success: false,
|
|
error: 'Access denied for temporary users'
|
|
});
|
|
} else {
|
|
res.redirect('/');
|
|
}
|
|
}
|
|
};
|
|
|
|
const requireDeletePermission = async (req, res, next) => {
|
|
const isAuthenticated = (req.session && req.session.authenticated) ||
|
|
(req.session && req.session.userId && req.session.userEmail);
|
|
|
|
// Only admins and regular users can delete, not temps
|
|
if (isAuthenticated && req.session.userType !== 'temp') {
|
|
// Check if temp user has expired (shouldn't happen here, but for safety)
|
|
const expirationResponse = await checkTempUserExpiration(req, res);
|
|
if (expirationResponse) {
|
|
return; // Response already sent by checkTempUserExpiration
|
|
}
|
|
|
|
next();
|
|
} else {
|
|
logger.warn('Delete permission denied', {
|
|
ip: req.ip,
|
|
path: req.path,
|
|
user: req.session?.userEmail || 'anonymous',
|
|
userType: req.session?.userType || 'unknown'
|
|
});
|
|
|
|
res.status(403).json({
|
|
success: false,
|
|
error: 'Delete permission denied'
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
requireAuth,
|
|
requireAdmin,
|
|
requireNonTemp,
|
|
requireDeletePermission
|
|
}; |