mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2025-12-14 05:46:33 +01:00
log updates
This commit is contained in:
parent
075940b0d8
commit
0ad3e40fcc
6 changed files with 221 additions and 226 deletions
67
app.js
67
app.js
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
/* eslint unicorn/no-process-exit: 0 */
|
/* eslint unicorn/no-process-exit: 0 */
|
||||||
|
|
||||||
const config = require('./application/config')
|
const config = require('./application/config')
|
||||||
|
|
@ -6,7 +7,7 @@ const config = require('./application/config')
|
||||||
// Until node 11 adds flatmap, we use this:
|
// Until node 11 adds flatmap, we use this:
|
||||||
require('array.prototype.flatmap').shim()
|
require('array.prototype.flatmap').shim()
|
||||||
|
|
||||||
const {app, io, server} = require('./infrastructure/web/web')
|
const { app, io, server } = require('./infrastructure/web/web')
|
||||||
const ClientNotification = require('./infrastructure/web/client-notification')
|
const ClientNotification = require('./infrastructure/web/client-notification')
|
||||||
const ImapService = require('./application/imap-service')
|
const ImapService = require('./application/imap-service')
|
||||||
const MailProcessingService = require('./application/mail-processing-service')
|
const MailProcessingService = require('./application/mail-processing-service')
|
||||||
|
|
@ -17,58 +18,58 @@ clientNotification.use(io)
|
||||||
|
|
||||||
const imapService = new ImapService(config)
|
const imapService = new ImapService(config)
|
||||||
const mailProcessingService = new MailProcessingService(
|
const mailProcessingService = new MailProcessingService(
|
||||||
new MailRepository(),
|
new MailRepository(),
|
||||||
imapService,
|
imapService,
|
||||||
clientNotification,
|
clientNotification,
|
||||||
config
|
config
|
||||||
)
|
)
|
||||||
|
|
||||||
// Put everything together:
|
// Put everything together:
|
||||||
imapService.on(ImapService.EVENT_NEW_MAIL, mail =>
|
imapService.on(ImapService.EVENT_NEW_MAIL, mail =>
|
||||||
mailProcessingService.onNewMail(mail)
|
mailProcessingService.onNewMail(mail)
|
||||||
)
|
)
|
||||||
imapService.on(ImapService.EVENT_INITIAL_LOAD_DONE, () =>
|
imapService.on(ImapService.EVENT_INITIAL_LOAD_DONE, () =>
|
||||||
mailProcessingService.onInitialLoadDone()
|
mailProcessingService.onInitialLoadDone()
|
||||||
)
|
)
|
||||||
imapService.on(ImapService.EVENT_DELETED_MAIL, mail =>
|
imapService.on(ImapService.EVENT_DELETED_MAIL, mail =>
|
||||||
mailProcessingService.onMailDeleted(mail)
|
mailProcessingService.onMailDeleted(mail)
|
||||||
)
|
)
|
||||||
|
|
||||||
mailProcessingService.on('error', err => {
|
mailProcessingService.on('error', err => {
|
||||||
console.error('error from mailProcessingService, stopping.', err)
|
console.error('Error from mailProcessingService, stopping.', err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
imapService.on(ImapService.EVENT_ERROR, error => {
|
imapService.on(ImapService.EVENT_ERROR, error => {
|
||||||
console.error('fatal error from imap service', error)
|
console.error('Fatal error from IMAP service', error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
app.set('mailProcessingService', mailProcessingService)
|
app.set('mailProcessingService', mailProcessingService)
|
||||||
|
|
||||||
imapService.connectAndLoadMessages().catch(error => {
|
imapService.connectAndLoadMessages().catch(error => {
|
||||||
console.error('fatal error from imap service', error)
|
console.error('Fatal error from IMAP service', error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
server.on('error', error => {
|
server.on('error', error => {
|
||||||
if (error.syscall !== 'listen') {
|
if (error.syscall !== 'listen') {
|
||||||
console.error('fatal web server error', error)
|
console.error('Fatal web server error', error)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle specific listen errors with friendly messages
|
// Handle specific listen errors with friendly messages
|
||||||
switch (error.code) {
|
switch (error.code) {
|
||||||
case 'EACCES':
|
case 'EACCES':
|
||||||
console.error(
|
console.error(
|
||||||
'Port ' + config.http.port + ' requires elevated privileges'
|
'Port ' + config.http.port + ' requires elevated privileges'
|
||||||
)
|
)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
case 'EADDRINUSE':
|
case 'EADDRINUSE':
|
||||||
console.error('Port ' + config.http.port + ' is already in use')
|
console.error('Port ' + config.http.port + ' is already in use')
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
default:
|
default:
|
||||||
console.error('fatal web server error', error)
|
console.error('Fatal web server error', error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -127,21 +127,18 @@ class ImapService extends EventEmitter {
|
||||||
|
|
||||||
this.connection.on('error', err => {
|
this.connection.on('error', err => {
|
||||||
// We assume that the app will be restarted after a crash.
|
// We assume that the app will be restarted after a crash.
|
||||||
console.error(
|
console.error('got fatal error during imap operation, stop app.', err)
|
||||||
'got fatal error during imap operation, stop app.',
|
|
||||||
err
|
|
||||||
)
|
|
||||||
this.emit('error', err)
|
this.emit('error', err)
|
||||||
})
|
})
|
||||||
|
|
||||||
await this.connection.openBox('INBOX')
|
await this.connection.openBox('INBOX')
|
||||||
debug('connected to imap')
|
debug('Connected to imap')
|
||||||
}, {
|
}, {
|
||||||
retries: 5
|
retries: 5
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('can not connect, even with retry, stop app', error)
|
console.error('Cant connect, even after retrying, stopping app', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -226,7 +223,7 @@ class ImapService extends EventEmitter {
|
||||||
})
|
})
|
||||||
|
|
||||||
if (uids.length === 0) {
|
if (uids.length === 0) {
|
||||||
debug('no mails to delete.')
|
debug('No mails to delete.')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -235,7 +232,7 @@ class ImapService extends EventEmitter {
|
||||||
uids.forEach(uid => {
|
uids.forEach(uid => {
|
||||||
this.emit(ImapService.EVENT_DELETED_MAIL, uid)
|
this.emit(ImapService.EVENT_DELETED_MAIL, uid)
|
||||||
})
|
})
|
||||||
console.log(`deleted ${uids.length} old messages.`)
|
console.log(`Deleted ${uids.length} old messages.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -243,10 +240,10 @@ class ImapService extends EventEmitter {
|
||||||
* @param uid delete specific mail per UID
|
* @param uid delete specific mail per UID
|
||||||
*/
|
*/
|
||||||
async deleteSpecificEmail(uid) {
|
async deleteSpecificEmail(uid) {
|
||||||
debug(`deleting mails ${uid}`)
|
debug(`Deleting mails ${uid}`)
|
||||||
if (!this.config.email.examples.uids.includes(parseInt(uid))) {
|
if (!this.config.email.examples.uids.includes(parseInt(uid))) {
|
||||||
await this.connection.deleteMessage(uid)
|
await this.connection.deleteMessage(uid)
|
||||||
debug(`deleted mail with UID: ${uid}.`)
|
debug(`Deleted mail with UID: ${uid}.`)
|
||||||
this.emit(ImapService.EVENT_DELETED_MAIL, uid)
|
this.emit(ImapService.EVENT_DELETED_MAIL, uid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,10 +294,10 @@ class ImapService extends EventEmitter {
|
||||||
async fetchOneFullMail(to, uid, raw = false) {
|
async fetchOneFullMail(to, uid, raw = false) {
|
||||||
if (!this.connection) {
|
if (!this.connection) {
|
||||||
// Here we 'fail fast' instead of waiting for the connection.
|
// Here we 'fail fast' instead of waiting for the connection.
|
||||||
throw new Error('imap connection not ready')
|
throw new Error('IMAP connection not ready')
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(`fetching full message ${uid}`)
|
debug(`Fetching full message ${uid}`)
|
||||||
|
|
||||||
// For security we also filter TO, so it is harder to just enumerate all messages.
|
// For security we also filter TO, so it is harder to just enumerate all messages.
|
||||||
const searchCriteria = [
|
const searchCriteria = [
|
||||||
|
|
@ -344,7 +341,7 @@ class ImapService extends EventEmitter {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
debug('can not fetch', error)
|
debug('Cant fetch', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,13 +54,13 @@ class MailProcessingService extends EventEmitter {
|
||||||
|
|
||||||
onInitialLoadDone() {
|
onInitialLoadDone() {
|
||||||
this.initialLoadDone = true
|
this.initialLoadDone = true
|
||||||
console.log(`initial load done, got ${this.mailRepository.mailCount()} mails`)
|
console.log(`Initial load done, got ${this.mailRepository.mailCount()} mails`)
|
||||||
}
|
}
|
||||||
|
|
||||||
onNewMail(mail) {
|
onNewMail(mail) {
|
||||||
if (this.initialLoadDone) {
|
if (this.initialLoadDone) {
|
||||||
// For now, only log messages if they arrive after the initial load
|
// For now, only log messages if they arrive after the initial load
|
||||||
debug('new mail for', mail.to[0])
|
debug('New mail for', mail.to[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
mail.to.forEach(to => {
|
mail.to.forEach(to => {
|
||||||
|
|
@ -70,7 +70,7 @@ class MailProcessingService extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMailDeleted(uid) {
|
onMailDeleted(uid) {
|
||||||
debug('mail deleted with uid', uid)
|
debug('Mail deleted with uid', uid)
|
||||||
this.mailRepository.removeUid(uid)
|
this.mailRepository.removeUid(uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ class MailProcessingService extends EventEmitter {
|
||||||
try {
|
try {
|
||||||
await this.imapService.deleteOldMails(helper.purgeTimeStamp())
|
await this.imapService.deleteOldMails(helper.purgeTimeStamp())
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log('can not delete old messages', error)
|
console.log('Cant delete old messages', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ class MailProcessingService extends EventEmitter {
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
fs.writeFile(filename, JSON.stringify(mails), err => {
|
fs.writeFile(filename, JSON.stringify(mails), err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('can not save mails to file', err)
|
console.error('Cant save mails to file', err)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class MailRepository {
|
||||||
mails.forEach(mail => {
|
mails.forEach(mail => {
|
||||||
if (mail.to == this.config.email.examples.account && !this.config.email.examples.uids.includes(parseInt(mail.uid))) {
|
if (mail.to == this.config.email.examples.account && !this.config.email.examples.uids.includes(parseInt(mail.uid))) {
|
||||||
mails = mails.filter(m => m.uid != mail.uid)
|
mails = mails.filter(m => m.uid != mail.uid)
|
||||||
debug('prevented non-example email from being shown in example inbox', mail.uid)
|
debug('Prevented non-example email from being shown in example inbox', mail.uid)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return _.orderBy(mails, mail => Date.parse(mail.date), ['desc'])
|
return _.orderBy(mails, mail => Date.parse(mail.date), ['desc'])
|
||||||
|
|
@ -43,7 +43,7 @@ class MailRepository {
|
||||||
.filter(mail => mail.uid === parseInt(uid) && (address ? to == address : true))
|
.filter(mail => mail.uid === parseInt(uid) && (address ? to == address : true))
|
||||||
.forEach(mail => {
|
.forEach(mail => {
|
||||||
this.mailSummaries.remove(to, mail)
|
this.mailSummaries.remove(to, mail)
|
||||||
debug('removed ', mail.date, to, mail.subject)
|
debug('Removed ', mail.date, to, mail.subject)
|
||||||
deleted = true
|
deleted = true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const router = new express.Router()
|
const router = new express.Router()
|
||||||
const {param} = require('express-validator')
|
const { param } = require('express-validator')
|
||||||
|
|
||||||
const config = require('../../../application/config')
|
const config = require('../../../application/config')
|
||||||
const Helper = require('../../../application/helper')
|
const Helper = require('../../../application/helper')
|
||||||
|
|
@ -9,182 +9,179 @@ const helper = new(Helper)
|
||||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
const purgeTime = helper.purgeTimeElemetBuilder()
|
||||||
|
|
||||||
const sanitizeAddress = param('address').customSanitizer(
|
const sanitizeAddress = param('address').customSanitizer(
|
||||||
(value, {req}) => {
|
(value, { req }) => {
|
||||||
return req.params.address
|
return req.params.address
|
||||||
.replace(/[^A-Za-z0-9_.+@-]/g, '') // Remove special characters
|
.replace(/[^A-Za-z0-9_.+@-]/g, '') // Remove special characters
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
router.get('^/:address([^@/]+@[^@/]+)', sanitizeAddress, (req, res, _next) => {
|
router.get('^/:address([^@/]+@[^@/]+)', sanitizeAddress, (req, res, _next) => {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
res.render('inbox', {
|
res.render('inbox', {
|
||||||
title: `${config.http.branding[0]} | ` + req.params.address,
|
title: `${config.http.branding[0]} | ` + req.params.address,
|
||||||
purgeTime: purgeTime,
|
purgeTime: purgeTime,
|
||||||
address: req.params.address,
|
address: req.params.address,
|
||||||
mailSummaries: mailProcessingService.getMailSummaries(req.params.address),
|
mailSummaries: mailProcessingService.getMailSummaries(req.params.address),
|
||||||
branding: config.http.branding,
|
branding: config.http.branding,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'^/:address/:uid([0-9]+)',
|
'^/:address/:uid([0-9]+)',
|
||||||
sanitizeAddress,
|
sanitizeAddress,
|
||||||
async (req, res, next) => {
|
async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
const mail = await mailProcessingService.getOneFullMail(
|
const mail = await mailProcessingService.getOneFullMail(
|
||||||
req.params.address,
|
req.params.address,
|
||||||
req.params.uid
|
req.params.uid
|
||||||
)
|
)
|
||||||
if (mail) {
|
if (mail) {
|
||||||
// Set a default subject if none is present
|
// Set a default subject if none is present
|
||||||
if (!mail.subject) {
|
if (!mail.subject) {
|
||||||
mail.subject = 'No Subject'
|
mail.subject = 'No Subject'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emails are immutable, cache if found
|
// Emails are immutable, cache if found
|
||||||
res.set('Cache-Control', 'private, max-age=600')
|
res.set('Cache-Control', 'private, max-age=600')
|
||||||
res.render('mail', {
|
res.render('mail', {
|
||||||
title: mail.subject + " | " + req.params.address,
|
title: mail.subject + " | " + req.params.address,
|
||||||
purgeTime: purgeTime,
|
purgeTime: purgeTime,
|
||||||
address: req.params.address,
|
address: req.params.address,
|
||||||
mail,
|
mail,
|
||||||
uid: req.params.uid,
|
uid: req.params.uid,
|
||||||
branding: config.http.branding,
|
branding: config.http.branding,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
res.render(
|
res.render(
|
||||||
'error',
|
'error', {
|
||||||
{
|
purgeTime: purgeTime,
|
||||||
purgeTime: purgeTime,
|
address: req.params.address,
|
||||||
address: req.params.address,
|
message: 'This mail could not be found. It either does not exist or has been deleted from our servers!',
|
||||||
message: 'This mail could not be found. It either does not exist or has been deleted from our servers!',
|
branding: config.http.branding
|
||||||
branding: config.http.branding
|
|
||||||
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('error while fetching one email', error)
|
console.error('Error while fetching email', error)
|
||||||
next(error)
|
next(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'^/:address/delete-all',
|
'^/:address/delete-all',
|
||||||
sanitizeAddress,
|
sanitizeAddress,
|
||||||
async (req, res, next) => {
|
async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
const mailSummaries = await mailProcessingService.getMailSummaries(req.params.address)
|
const mailSummaries = await mailProcessingService.getMailSummaries(req.params.address)
|
||||||
for (mail in mailSummaries) {
|
for (mail in mailSummaries) {
|
||||||
await mailProcessingService.deleteSpecificEmail(req.params.address, mailSummaries[mail].uid)
|
await mailProcessingService.deleteSpecificEmail(req.params.address, mailSummaries[mail].uid)
|
||||||
}
|
}
|
||||||
res.redirect(`/inbox/${req.params.address}`)
|
res.redirect(`/inbox/${req.params.address}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('error while deleting email', error)
|
console.error('Error while deleting email', error)
|
||||||
next(error)
|
next(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'^/:address/:uid/delete',
|
'^/:address/:uid/delete',
|
||||||
sanitizeAddress,
|
sanitizeAddress,
|
||||||
async (req, res, next) => {
|
async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
await mailProcessingService.deleteSpecificEmail(req.params.address, req.params.uid)
|
await mailProcessingService.deleteSpecificEmail(req.params.address, req.params.uid)
|
||||||
res.redirect(`/inbox/${req.params.address}`)
|
res.redirect(`/inbox/${req.params.address}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('error while deleting email', error)
|
console.error('Error while deleting email', error)
|
||||||
next(error)
|
next(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'^/:address/:uid/:checksum([a-f0-9]+)',
|
'^/:address/:uid/:checksum([a-f0-9]+)',
|
||||||
sanitizeAddress,
|
sanitizeAddress,
|
||||||
async (req, res, next) => {
|
async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
const mail = await mailProcessingService.getOneFullMail(
|
const mail = await mailProcessingService.getOneFullMail(
|
||||||
req.params.address,
|
req.params.address,
|
||||||
req.params.uid
|
req.params.uid
|
||||||
)
|
)
|
||||||
var index = mail.attachments.findIndex(attachment => attachment.checksum === req.params.checksum);
|
var index = mail.attachments.findIndex(attachment => attachment.checksum === req.params.checksum);
|
||||||
const attachment = mail.attachments[index];
|
const attachment = mail.attachments[index];
|
||||||
if (attachment) {
|
if (attachment) {
|
||||||
try {
|
try {
|
||||||
res.set('Content-Disposition', `attachment; filename=${attachment.filename}`);
|
res.set('Content-Disposition', `attachment; filename=${attachment.filename}`);
|
||||||
res.set('Content-Type', attachment.contentType);
|
res.set('Content-Type', attachment.contentType);
|
||||||
res.send(attachment.content);
|
res.send(attachment.content);
|
||||||
return;
|
return;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('error while fetching attachment', error);
|
console.error('Error while fetching attachment', error);
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.render(
|
res.render(
|
||||||
'error',
|
'error', {
|
||||||
{
|
purgeTime: purgeTime,
|
||||||
purgeTime: purgeTime,
|
address: req.params.address,
|
||||||
address: req.params.address,
|
message: 'This attachment could not be found. It either does not exist or has been deleted from our servers!',
|
||||||
message: 'This attachment could not be found. It either does not exist or has been deleted from our servers!',
|
branding: config.http.branding,
|
||||||
branding: config.http.branding,
|
}
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
}
|
res.redirect(`/inbox/${req.params.address}`)
|
||||||
res.redirect(`/inbox/${req.params.address}`)
|
} catch (error) {
|
||||||
} catch (error) {
|
console.error('Error while deleting email', error)
|
||||||
console.error('error while deleting email', error)
|
next(error)
|
||||||
next(error)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
'^/:address/:uid/raw',
|
'^/:address/:uid/raw',
|
||||||
sanitizeAddress,
|
sanitizeAddress,
|
||||||
async (req, res, next) => {
|
async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
mail = await mailProcessingService.getOneFullMail(
|
mail = await mailProcessingService.getOneFullMail(
|
||||||
req.params.address,
|
req.params.address,
|
||||||
req.params.uid,
|
req.params.uid,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
if (mail) {
|
if (mail) {
|
||||||
mail = mail.replace(/(?:\r\n|\r|\n)/g, '<br>')
|
mail = mail.replace(/(?:\r\n|\r|\n)/g, '<br>')
|
||||||
// Emails are immutable, cache if found
|
// Emails are immutable, cache if found
|
||||||
res.set('Cache-Control', 'private, max-age=600')
|
res.set('Cache-Control', 'private, max-age=600')
|
||||||
res.render('raw', {
|
res.render('raw', {
|
||||||
title: req.params.uid + " | raw | " + req.params.address,
|
title: req.params.uid + " | raw | " + req.params.address,
|
||||||
mail
|
mail
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
res.render(
|
res.render(
|
||||||
'error',
|
'error', {
|
||||||
{
|
purgeTime: purgeTime,
|
||||||
purgeTime: purgeTime,
|
address: req.params.address,
|
||||||
address: req.params.address,
|
message: 'This mail could not be found. It either does not exist or has been deleted from our servers!',
|
||||||
message: 'This mail could not be found. It either does not exist or has been deleted from our servers!',
|
branding: config.http.branding,
|
||||||
branding: config.http.branding,
|
}
|
||||||
}
|
)
|
||||||
)
|
}
|
||||||
}
|
} catch (error) {
|
||||||
} catch (error) {
|
console.error('Error while fetching raw email', error)
|
||||||
console.error('error while fetching one email', error)
|
next(error)
|
||||||
next(error)
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router
|
||||||
|
|
@ -11,7 +11,7 @@ const socketio = require('socket.io')
|
||||||
const config = require('../../application/config')
|
const config = require('../../application/config')
|
||||||
const inboxRouter = require('./routes/inbox')
|
const inboxRouter = require('./routes/inbox')
|
||||||
const loginRouter = require('./routes/login')
|
const loginRouter = require('./routes/login')
|
||||||
const {sanitizeHtmlTwigFilter} = require('./views/twig-filters')
|
const { sanitizeHtmlTwigFilter } = require('./views/twig-filters')
|
||||||
|
|
||||||
// Init express middleware
|
// Init express middleware
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
@ -24,20 +24,20 @@ const io = socketio(server)
|
||||||
app.set('socketio', io)
|
app.set('socketio', io)
|
||||||
app.use(logger('dev'))
|
app.use(logger('dev'))
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
app.use(express.urlencoded({extended: false}))
|
app.use(express.urlencoded({ extended: false }))
|
||||||
// View engine setup
|
// View engine setup
|
||||||
app.set('views', path.join(__dirname, 'views'))
|
app.set('views', path.join(__dirname, 'views'))
|
||||||
app.set('view engine', 'twig')
|
app.set('view engine', 'twig')
|
||||||
app.set('twig options', {
|
app.set('twig options', {
|
||||||
autoescape: true
|
autoescape: true
|
||||||
})
|
})
|
||||||
|
|
||||||
// Application code:
|
// Application code:
|
||||||
app.use(
|
app.use(
|
||||||
express.static(path.join(__dirname, 'public'), {
|
express.static(path.join(__dirname, 'public'), {
|
||||||
immutable: true,
|
immutable: true,
|
||||||
maxAge: '1h'
|
maxAge: '1h'
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
Twig.extendFilter('sanitizeHtml', sanitizeHtmlTwigFilter)
|
Twig.extendFilter('sanitizeHtml', sanitizeHtmlTwigFilter)
|
||||||
|
|
||||||
|
|
@ -52,18 +52,18 @@ app.use('/inbox', inboxRouter)
|
||||||
|
|
||||||
// Catch 404 and forward to error handler
|
// Catch 404 and forward to error handler
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
next({message: 'page not found', status: 404})
|
next({ message: 'Page not found', status: 404 })
|
||||||
})
|
})
|
||||||
|
|
||||||
// Error handler
|
// Error handler
|
||||||
app.use((err, req, res, _next) => {
|
app.use((err, req, res, _next) => {
|
||||||
// Set locals, only providing error in development
|
// Set locals, only providing error in development
|
||||||
res.locals.message = err.message
|
res.locals.message = err.message
|
||||||
res.locals.error = req.app.get('env') === 'development' ? err : {}
|
res.locals.error = req.app.get('env') === 'development' ? err : {}
|
||||||
|
|
||||||
// Render the error page
|
// Render the error page
|
||||||
res.status(err.status || 500)
|
res.status(err.status || 500)
|
||||||
res.render('error')
|
res.render('error')
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -77,9 +77,9 @@ app.set('port', config.http.port)
|
||||||
*/
|
*/
|
||||||
server.listen(config.http.port)
|
server.listen(config.http.port)
|
||||||
server.on('listening', () => {
|
server.on('listening', () => {
|
||||||
const addr = server.address()
|
const addr = server.address()
|
||||||
const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port
|
const bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port
|
||||||
debug('Listening on ' + bind)
|
debug('Listening on ' + bind)
|
||||||
})
|
})
|
||||||
|
|
||||||
module.exports = {app, io, server}
|
module.exports = { app, io, server }
|
||||||
Loading…
Add table
Reference in a new issue