refactor: optimize runtime
This commit is contained in:
252
app.js
252
app.js
@ -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}`);
|
||||
|
Reference in New Issue
Block a user