updates to saving settings

This commit is contained in:
2025-07-10 10:56:52 -06:00
parent 9f12538248
commit 728a0bb6a9
21 changed files with 4008 additions and 1969 deletions

View File

@@ -0,0 +1,34 @@
const requireAuth = (req, res, next) => {
if (req.session && req.session.authenticated) {
next();
} else {
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 = (req, res, next) => {
if (req.session && req.session.authenticated && req.session.isAdmin) {
next();
} else {
if (req.xhr || req.headers.accept?.indexOf('json') > -1) {
res.status(403).json({
success: false,
error: 'Admin access required'
});
} else {
res.redirect('/login.html');
}
}
};
module.exports = {
requireAuth,
requireAdmin
};

View File

@@ -0,0 +1,44 @@
const rateLimit = require('express-rate-limit');
const config = require('../config');
// Helper to extract real IP with Cloudflare support
const keyGenerator = (req) => {
return req.headers['cf-connecting-ip'] ||
req.headers['x-forwarded-for']?.split(',')[0] ||
req.ip;
};
// General API rate limiter
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100,
keyGenerator,
standardHeaders: true,
legacyHeaders: false,
message: 'Too many requests, please try again later.'
});
// Strict limiter for write operations
const strictLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 20,
keyGenerator,
message: 'Too many write operations, please try again later.'
});
// Auth-specific limiter
const authLimiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: config.isProduction ? 10 : 50,
keyGenerator,
standardHeaders: true,
legacyHeaders: false,
message: 'Too many login attempts, please try again later.',
skipSuccessfulRequests: true
});
module.exports = {
apiLimiter,
strictLimiter,
authLimiter
};