refactor: optimize runtime

This commit is contained in:
Rim
2025-04-16 09:07:54 -04:00
parent 18284f7483
commit 13ea56dc66
3 changed files with 474 additions and 495 deletions

252
app.js
View File

@ -6,6 +6,7 @@ const API = require('./src/js/index.js');
const demoTracker = require('./src/js/demoTracker.js');
const { logger } = require('./src/js/logger.js');
const favicon = require('serve-favicon');
const fs = require('fs');
const app = express();
const port = process.env.PORT || 3512;
require('./src/js/utils.js');
@ -13,7 +14,6 @@ require('./src/js/utils.js');
app.set('trust proxy', true);
// Middleware
// app.use(bodyParser.json({ limit: '10mb' }));
app.use(bodyParser.urlencoded({ extended: true, limit: '10mb' }));
app.use(express.static(__dirname));
app.use(express.static(path.join(__dirname, 'public')));
@ -27,17 +27,8 @@ app.use(
},
})
);
// app.use(express.raw({ type: 'application/json', limit: '10mb' }));
app.use(demoTracker.demoModeMiddleware);
// Set up demo mode cleanup interval
setInterval(
() => demoTracker.demoModeRequestTracker.cleanupExpiredEntries(),
3600000
); // Clean up every hour
const fs = require('fs');
// Initialize key replacements
let keyReplacements = {};
@ -213,6 +204,80 @@ const handleApiError = (error, res) => {
});
};
// Helper function to remove sensitive data from headers
function sanitizeHeaders(headers) {
const safeHeaders = { ...headers };
// Remove potential sensitive information
const sensitiveHeaders = ['authorization', 'cookie', 'set-cookie'];
sensitiveHeaders.forEach((header) => {
if (safeHeaders[header]) {
safeHeaders[header] = '[REDACTED]';
}
});
return safeHeaders;
}
// Set up demo mode cleanup interval
setInterval(
() => demoTracker.demoModeRequestTracker.cleanupExpiredEntries(),
3600000
); // Clean up every hour
app.get('/health', (req, res) => {
const clientIP =
req.headers['cf-connecting-ip'] ||
req.headers['x-forwarded-for']?.split(',')[0] ||
req.ip ||
req.connection.remoteAddress;
const isDemoMode = demoTracker.isDemoModeActive();
res.json({
status: 'ok',
timestamp: global.Utils.toIsoString(new Date()),
demoMode: isDemoMode,
requestsRemaining:
isDemoMode ?
demoTracker.demoModeRequestTracker.maxRequestsPerHour -
(demoTracker.demoModeRequestTracker.requests.get(clientIP)?.count || 0)
: null,
});
});
// Serve the main HTML file
app.get('/', async (req, res) => {
// Check demo mode query parameter
if (req.query.demo === 'true') {
await demoTracker.initializeDemoMode(true);
} else if (req.query.demo === 'false') {
await demoTracker.initializeDemoMode(false);
}
res.sendFile(path.join(__dirname, 'src', 'index.html'));
});
// Demo mode route - enables demo mode when visited
app.get('/demo', async (req, res) => {
const success = await demoTracker.initializeDemoMode(true);
if (success) {
logger.info('Demo mode activated via /demo route');
res.redirect('/?demo=true');
} else {
res
.status(500)
.send('Failed to enable demo mode. Check server logs for details.');
}
});
// Demo mode deactivation route
app.get('/demo/disable', async (req, res) => {
await demoTracker.initializeDemoMode(false);
logger.info('Demo mode deactivated via /demo/disable route');
res.redirect('/?demo=false');
});
// API endpoint to fetch stats
app.post('/api/stats', async (req, res) => {
logger.debug('Received request for /api/stats');
@ -507,16 +572,6 @@ app.post('/api/matches', async (req, res) => {
logger.debug(`Processing Options - Sanitize: ${sanitize}, Replace Keys: ${replaceKeys}`);
logger.debug("========================"); */
if (!username) {
return res.status(400).json({ error: 'Username is required' });
}
if (!username || !ssoToken) {
return res
.status(400)
.json({ error: 'Username and SSO Token are required' });
}
const defaultToken = demoTracker.getDefaultSsoToken();
if (!ssoToken && defaultToken) {
ssoToken = defaultToken;
@ -529,6 +584,16 @@ app.post('/api/matches', async (req, res) => {
});
}
if (!username) {
return res.status(400).json({ error: 'Username is required' });
}
if (!username || !ssoToken) {
return res
.status(400)
.json({ error: 'Username and SSO Token are required' });
}
try {
await ensureLogin(ssoToken);
} catch (loginError) {
@ -670,16 +735,6 @@ app.post('/api/matchInfo', async (req, res) => {
logger.debug(`Processing Options - Sanitize: ${sanitize}, Replace Keys: ${replaceKeys}`);
logger.debug("=========================="); */
if (!matchId) {
return res.status(400).json({ error: 'Match ID is required' });
}
if (!matchId || !ssoToken) {
return res
.status(400)
.json({ error: 'Match ID and SSO Token are required' });
}
const defaultToken = demoTracker.getDefaultSsoToken();
if (!ssoToken && defaultToken) {
ssoToken = defaultToken;
@ -692,6 +747,16 @@ app.post('/api/matchInfo', async (req, res) => {
});
}
if (!matchId) {
return res.status(400).json({ error: 'Match ID is required' });
}
if (!matchId || !ssoToken) {
return res
.status(400)
.json({ error: 'Match ID and SSO Token are required' });
}
try {
await ensureLogin(ssoToken);
} catch (loginError) {
@ -820,10 +885,17 @@ app.post('/api/user', async (req, res) => {
logger.debug(`Processing Options - Sanitize: ${sanitize}, Replace Keys: ${replaceKeys}`);
logger.debug("========================="); */
/*
if (!ssoToken) {
return res.status(400).json({ error: 'SSO Token is required' });
} */
const defaultToken = demoTracker.getDefaultSsoToken();
if (!ssoToken && defaultToken) {
ssoToken = defaultToken;
logger.info('Using default SSO token for demo mode');
} else if (!ssoToken) {
return res.status(200).json({
status: 'error',
message: 'SSO Token is required',
timestamp: global.Utils.toIsoString(new Date()),
});
}
// For eventFeed and identities, username is not required
if (
@ -837,18 +909,6 @@ app.post('/api/user', async (req, res) => {
.json({ error: 'Username is required for this API call' });
}
const defaultToken = demoTracker.getDefaultSsoToken();
if (!ssoToken && defaultToken) {
ssoToken = defaultToken;
logger.info('Using default SSO token for demo mode');
} else if (!ssoToken) {
return res.status(200).json({
status: 'error',
message: 'SSO Token is required',
timestamp: global.Utils.toIsoString(new Date()),
});
}
try {
await ensureLogin(ssoToken);
} catch (loginError) {
@ -966,16 +1026,6 @@ app.post('/api/search', async (req, res) => {
logger.debug(`Processing Options - Sanitize: ${sanitize}, Replace Keys: ${replaceKeys}`);
logger.debug("=========================="); */
if (!username) {
return res.status(400).json({ error: 'Username is required' });
}
if (!username || !ssoToken) {
return res
.status(400)
.json({ error: 'Username and SSO Token are required' });
}
const defaultToken = demoTracker.getDefaultSsoToken();
if (!ssoToken && defaultToken) {
ssoToken = defaultToken;
@ -988,6 +1038,16 @@ app.post('/api/search', async (req, res) => {
});
}
if (!username) {
return res.status(400).json({ error: 'Username is required' });
}
if (!username || !ssoToken) {
return res
.status(400)
.json({ error: 'Username and SSO Token are required' });
}
try {
await ensureLogin(ssoToken);
} catch (loginError) {
@ -1092,21 +1152,6 @@ app.post('/api/log', (req, res) => {
res.status(200).send();
});
// Helper function to remove sensitive data from headers
function sanitizeHeaders(headers) {
const safeHeaders = { ...headers };
// Remove potential sensitive information
const sensitiveHeaders = ['authorization', 'cookie', 'set-cookie'];
sensitiveHeaders.forEach((header) => {
if (safeHeaders[header]) {
safeHeaders[header] = '[REDACTED]';
}
});
return safeHeaders;
}
// Database storage function
/*
function storeLogInDatabase(logData) {
@ -1116,71 +1161,6 @@ function storeLogInDatabase(logData) {
}
*/
app.get('/health', (req, res) => {
const clientIP =
req.headers['cf-connecting-ip'] ||
req.headers['x-forwarded-for']?.split(',')[0] ||
req.ip ||
req.connection.remoteAddress;
const isDemoMode = demoTracker.isDemoModeActive();
res.json({
status: 'ok',
timestamp: global.Utils.toIsoString(new Date()),
demoMode: isDemoMode,
requestsRemaining:
isDemoMode ?
demoTracker.demoModeRequestTracker.maxRequestsPerHour -
(demoTracker.demoModeRequestTracker.requests.get(clientIP)?.count || 0)
: null,
});
});
/*
app.get('/demo', (req, res) => {
// Set a cookie or session variable to enable demo mode
if (!req.session) {
req.session = {};
}
req.session.forceDemoMode = true;
// Redirect to the main app
res.redirect('/');
}); */
// Demo mode route - enables demo mode when visited
app.get('/demo', async (req, res) => {
const success = await demoTracker.initializeDemoMode(true);
if (success) {
logger.info('Demo mode activated via /demo route');
res.redirect('/?demo=true');
} else {
res
.status(500)
.send('Failed to enable demo mode. Check server logs for details.');
}
});
// Demo mode deactivation route
app.get('/demo/disable', async (req, res) => {
await demoTracker.initializeDemoMode(false);
logger.info('Demo mode deactivated via /demo/disable route');
res.redirect('/?demo=false');
});
// Serve the main HTML file
app.get('/', async (req, res) => {
// Check demo mode query parameter
if (req.query.demo === 'true') {
await demoTracker.initializeDemoMode(true);
} else if (req.query.demo === 'false') {
await demoTracker.initializeDemoMode(false);
}
res.sendFile(path.join(__dirname, 'src', 'index.html'));
});
// Start the server
app.listen(port, () => {
logger.info(`Server running on http://localhost:${port}`);