From cb7e49b0e12024adf10993b3ef425e922fed2401 Mon Sep 17 00:00:00 2001 From: greirson Date: Mon, 5 May 2025 17:19:40 -0700 Subject: [PATCH] refactor(app): Improve error handling and HTML response processing in root route - Enhanced error logging to include specific context for index.html processing errors. - Added checks to ensure headers are sent only when appropriate, preventing potential issues with multiple responses. - Improved comments for clarity on the purpose of code sections, particularly around HTML processing and error handling. feat(config): Log raw FOOTER_LINKS from environment variables - Introduced logging for the raw FOOTER_LINKS value to aid in debugging and configuration verification. - Maintained existing functionality while enhancing visibility into configuration values. --- src/app.js | 36 +++++++++++++++++++----------------- src/config/index.js | 5 +++++ 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/app.js b/src/app.js index 29d59f0..de22aeb 100644 --- a/src/app.js +++ b/src/app.js @@ -46,28 +46,19 @@ app.use('/api/files', requirePin(config.pin), downloadLimiter, fileRoutes); // Root route app.get('/', (req, res) => { - // Check if the PIN is configured and the cookie exists - if (config.pin && (!req.cookies?.DUMBDROP_PIN || !safeCompare(req.cookies.DUMBDROP_PIN, config.pin))) { - return res.redirect('/login.html'); - } - - let html = fs.readFileSync(path.join(__dirname, '../public', 'index.html'), 'utf8'); - html = html.replace(/{{SITE_TITLE}}/g, config.siteTitle); - html = html.replace('{{AUTO_UPLOAD}}', config.autoUpload.toString()); - html = html.replace('{{MAX_RETRIES}}', config.clientMaxRetries.toString()); - // Ensure baseUrl has a trailing slash for correct asset linking - const baseUrlWithSlash = config.baseUrl.endsWith('/') ? config.baseUrl : config.baseUrl + '/'; - html = html.replace(/{{BASE_URL}}/g, baseUrlWithSlash); - html = injectDemoBanner(html); - res.send(html); try { + // Check if the PIN is configured and the cookie exists + if (config.pin && (!req.cookies?.DUMBDROP_PIN || !safeCompare(req.cookies.DUMBDROP_PIN, config.pin))) { + return res.redirect('/login.html'); + } + let html = fs.readFileSync(path.join(__dirname, '../public', 'index.html'), 'utf8'); // Standard replacements html = html.replace(/{{SITE_TITLE}}/g, config.siteTitle); html = html.replace('{{AUTO_UPLOAD}}', config.autoUpload.toString()); html = html.replace('{{MAX_RETRIES}}', config.clientMaxRetries.toString()); - // Ensure baseUrl has a trailing slash + // Ensure baseUrl has a trailing slash for correct asset linking const baseUrlWithSlash = config.baseUrl.endsWith('/') ? config.baseUrl : config.baseUrl + '/'; html = html.replace(/{{BASE_URL}}/g, baseUrlWithSlash); @@ -84,11 +75,18 @@ app.get('/', (req, res) => { } html = html.replace('{{FOOTER_CONTENT}}', footerHtml); + // Inject demo banner if applicable html = injectDemoBanner(html); + + // Send the final processed HTML res.send(html); + } catch (err) { - logger.error(`Error processing index.html: ${err.message}`); - res.status(500).send('Error loading page'); + logger.error(`Error processing index.html for / route: ${err.message}`); + // Check if headers have already been sent before trying to send an error response + if (!res.headersSent) { + res.status(500).send('Error loading page'); + } } }); @@ -138,6 +136,10 @@ app.use(express.static('public')); // Error handling middleware app.use((err, req, res, next) => { // eslint-disable-line no-unused-vars logger.error(`Unhandled error: ${err.message}`); + // Check if headers have already been sent before trying to send an error response + if (res.headersSent) { + return next(err); // Pass error to default handler if headers sent + } res.status(500).json({ message: 'Internal server error', error: process.env.NODE_ENV === 'development' ? err.message : undefined diff --git a/src/config/index.js b/src/config/index.js index fe7a5be..2e9369b 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -210,6 +210,11 @@ const config = { * Parsed custom footer links * Set via FOOTER_LINKS in .env (e.g., "Link 1 @ URL1, Link 2 @ URL2") */ + _footerLinksRaw: (() => { + const rawValue = process.env.FOOTER_LINKS; + console.log(`[CONFIG] Raw FOOTER_LINKS from process.env: '${rawValue}'`); + return rawValue; // Keep the original flow, just log + })(), footerLinks: parseFooterLinks(process.env.FOOTER_LINKS), // =====================