tududi/backend/middleware/auth.js
Chris 542be2c1e9
Fix bug 366 (#764)
* Optimize DB

* Clean up names

* fixup! Clean up names

* fixup! fixup! Clean up names
2026-01-07 18:18:07 +02:00

70 lines
2.4 KiB
JavaScript

const { User } = require('../models');
const { findValidTokenByValue } = require('../modules/users/apiTokenService');
const getBearerToken = (req) => {
const authHeader = req.headers?.authorization || '';
const [scheme, token] = authHeader.split(' ');
if (scheme && token && scheme.toLowerCase() === 'bearer') {
return token.trim();
}
return null;
};
const requireAuth = async (req, res, next) => {
try {
// Skip authentication for health check, login routes, and current_user
const skipPaths = ['/api/health', '/api/login', '/api/current_user'];
if (skipPaths.includes(req.path) || req.originalUrl === '/api/health') {
return next();
}
if (req.session && req.session.userId) {
const user = await User.findByPk(req.session.userId);
if (!user) {
req.session.destroy();
return res.status(401).json({ error: 'User not found' });
}
req.currentUser = user;
return next();
}
const bearerToken = getBearerToken(req);
if (!bearerToken) {
return res.status(401).json({ error: 'Authentication required' });
}
const apiToken = await findValidTokenByValue(bearerToken);
if (!apiToken) {
return res
.status(401)
.json({ error: 'Invalid or expired API token' });
}
const user = await User.findByPk(apiToken.user_id);
if (!user) {
return res.status(401).json({ error: 'User not found' });
}
req.currentUser = user;
req.authToken = apiToken;
// Update last_used_at asynchronously (non-blocking) to avoid slowing down the request
// Only update if it hasn't been updated in the last 5 minutes to reduce database writes
const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
if (!apiToken.last_used_at || apiToken.last_used_at < fiveMinutesAgo) {
// Fire and forget - don't await this update
apiToken.update({ last_used_at: new Date() }).catch((err) => {
console.error('Failed to update token last_used_at:', err);
});
}
next();
} catch (error) {
console.error('Authentication error:', error);
res.status(500).json({ error: 'Authentication error' });
}
};
module.exports = {
requireAuth,
};