diff --git a/infrastructure/web/routes/error.js b/infrastructure/web/routes/error.js new file mode 100644 index 0000000..2f29a82 --- /dev/null +++ b/infrastructure/web/routes/error.js @@ -0,0 +1,29 @@ +const express = require('express') + +const router = new express.Router() +const config = require('../../../application/config') +const Helper = require('../../../application/helper') +const helper = new(Helper) + +const purgeTime = helper.purgeTimeElemetBuilder() + +router.get('/:address/:errorCode', async(req, res) => { + const mailProcessingService = req.app.get('mailProcessingService') + const count = await mailProcessingService.getCount() + + const errorCode = parseInt(req.params.errorCode) || 404 + const message = req.query.message || (req.session && req.session.errorMessage) || 'An error occurred' + + res.status(errorCode) + res.render('error', { + title: `${config.http.branding[0]} | ${errorCode}`, + purgeTime: purgeTime, + address: req.params.address, + count: count, + message: message, + status: errorCode, + branding: config.http.branding + }) +}) + +module.exports = router diff --git a/infrastructure/web/routes/inbox.js b/infrastructure/web/routes/inbox.js index 5ad0b84..98fad6b 100644 --- a/infrastructure/web/routes/inbox.js +++ b/infrastructure/web/routes/inbox.js @@ -58,16 +58,8 @@ router.get( branding: config.http.branding, }) } else { - res.render( - 'error', { - purgeTime: purgeTime, - address: req.params.address, - count: count, - message: 'This mail could not be found. It either does not exist or has been deleted from our servers!', - branding: config.http.branding - - } - ) + req.session.errorMessage = 'This mail could not be found. It either does not exist or has been deleted from our servers!' + res.redirect(`/error/${req.params.address}/404`) } } catch (error) { console.error('Error while fetching email', error) @@ -76,6 +68,16 @@ router.get( } ) +// Catch-all for invalid UIDs (non-numeric) +router.get( + '^/:address/:uid', + sanitizeAddress, + async(req, res) => { + req.session.errorMessage = 'Invalid/Malformed UID provided.' + res.redirect(`/error/${req.params.address}/400`) + } +) + router.get( '^/:address/delete-all', sanitizeAddress, @@ -121,15 +123,8 @@ router.get( // Validate UID is a valid integer if (isNaN(uid) || uid <= 0) { - return res.render( - 'error', { - purgeTime: purgeTime, - address: req.params.address, - count: count, - message: 'Invalid/Malformed UID provided.', - branding: config.http.branding, - } - ) + req.session.errorMessage = 'Invalid/Malformed UID provided.' + return res.redirect(`/error/${req.params.address}/400`) } const mail = await mailProcessingService.getOneFullMail( @@ -138,15 +133,8 @@ router.get( ) if (!mail || !mail.attachments) { - return res.render( - 'error', { - purgeTime: purgeTime, - address: req.params.address, - count: count, - message: 'This email could not be found. It either does not exist or has been deleted from our servers!', - branding: config.http.branding, - } - ) + req.session.errorMessage = 'This email could not be found. It either does not exist or has been deleted from our servers!' + return res.redirect(`/error/${req.params.address}/404`) } var index = mail.attachments.findIndex(attachment => attachment.checksum === req.params.checksum); @@ -164,15 +152,8 @@ router.get( return; } } else { - return res.render( - 'error', { - purgeTime: purgeTime, - address: req.params.address, - count: count, - message: 'This attachment could not be found. It either does not exist or has been deleted from our servers!', - branding: config.http.branding, - } - ) + req.session.errorMessage = 'This attachment could not be found. It either does not exist or has been deleted from our servers!' + return res.redirect(`/error/${req.params.address}/404`) } } catch (error) { console.error('Error while fetching attachment', error) @@ -194,15 +175,8 @@ router.get( // Validate UID is a valid integer if (isNaN(uid) || uid <= 0) { - return res.render( - 'error', { - purgeTime: purgeTime, - address: req.params.address, - count: count, - message: 'Invalid/Malformed UID provided.', - branding: config.http.branding, - } - ) + req.session.errorMessage = 'Invalid/Malformed UID provided.' + return res.redirect(`/error/${req.params.address}/400`) } mail = await mailProcessingService.getOneFullMail( @@ -219,15 +193,8 @@ router.get( mail }) } else { - res.render( - 'error', { - purgeTime: purgeTime, - address: req.params.address, - count: count, - message: 'This mail could not be found. It either does not exist or has been deleted from our servers!', - branding: config.http.branding, - } - ) + req.session.errorMessage = 'This mail could not be found. It either does not exist or has been deleted from our servers!' + res.redirect(`/error/${req.params.address}/404`) } } catch (error) { console.error('Error while fetching raw email', error) @@ -237,4 +204,4 @@ router.get( ) -module.exports = router \ No newline at end of file +module.exports = router diff --git a/infrastructure/web/web.js b/infrastructure/web/web.js index 789708b..b240544 100644 --- a/infrastructure/web/web.js +++ b/infrastructure/web/web.js @@ -2,6 +2,7 @@ const path = require('path') const http = require('http') const debug = require('debug')('48hr-email:server') const express = require('express') +const session = require('express-session') const logger = require('morgan') const Twig = require('twig') const compression = require('compression') @@ -11,6 +12,7 @@ const socketio = require('socket.io') const config = require('../../application/config') const inboxRouter = require('./routes/inbox') const loginRouter = require('./routes/login') +const errorRouter = require('./routes/error') const { sanitizeHtmlTwigFilter } = require('./views/twig-filters') const Helper = require('../../application/helper') @@ -30,6 +32,14 @@ app.use(logger('dev')) app.use(express.json()) app.use(express.urlencoded({ extended: false })) +// Session middleware +app.use(session({ + secret: '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ', // They will hate me for this + resave: false, + saveUninitialized: true, + cookie: { maxAge: 1000 * 60 * 60 * 24 } // 24 hours +})) + // Remove trailing slash middleware (except for root) app.use((req, res, next) => { if (req.path.length > 1 && req.path.endsWith('/')) { @@ -63,6 +73,7 @@ app.get('/', (req, res, _next) => { app.use('/', loginRouter) app.use('/inbox', inboxRouter) +app.use('/error', errorRouter) // Catch 404 and forward to error handler app.use((req, res, next) => { @@ -105,4 +116,4 @@ server.on('listening', () => { debug('Listening on ' + bind) }) -module.exports = { app, io, server } \ No newline at end of file +module.exports = { app, io, server }