mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2026-01-09 11:19:36 +01:00
[Fix]: Update old config mentions and plug missing ones
This commit is contained in:
parent
0c8db0b597
commit
8151587036
10 changed files with 103 additions and 184 deletions
|
|
@ -1,3 +1,5 @@
|
||||||
|
const templateContext = require('../template-context')
|
||||||
|
|
||||||
function checkLockAccess(req, res, next) {
|
function checkLockAccess(req, res, next) {
|
||||||
const inboxLock = req.app.get('inboxLock')
|
const inboxLock = req.app.get('inboxLock')
|
||||||
const address = req.params.address
|
const address = req.params.address
|
||||||
|
|
@ -21,14 +23,10 @@ function checkLockAccess(req, res, next) {
|
||||||
const unlockError = req.session ? req.session.unlockError : undefined
|
const unlockError = req.session ? req.session.unlockError : undefined
|
||||||
if (req.session) delete req.session.unlockError
|
if (req.session) delete req.session.unlockError
|
||||||
|
|
||||||
return res.render('error', {
|
return res.render('error', templateContext.build(req, {
|
||||||
purgeTime: require('../../../application/helper').prototype.purgeTimeElemetBuilder(),
|
title: 'Access Denied',
|
||||||
address: address,
|
message: 'This inbox is locked by another user. Only the owner can access it.'
|
||||||
message: 'This inbox is locked by another user. Only the owner can access it.',
|
}))
|
||||||
branding: req.app.get('config').http.branding,
|
|
||||||
currentUser: req.session && req.session.username,
|
|
||||||
authEnabled: req.app.get('config').user.authEnabled
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update last access if they have access and are authenticated
|
// Update last access if they have access and are authenticated
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ const express = require('express')
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
const { requireAuth } = require('../middleware/auth')
|
const { requireAuth } = require('../middleware/auth')
|
||||||
const { body, validationResult } = require('express-validator')
|
const { body, validationResult } = require('express-validator')
|
||||||
|
const templateContext = require('../template-context')
|
||||||
|
|
||||||
// GET /account - Account dashboard
|
// GET /account - Account dashboard
|
||||||
router.get('/account', requireAuth, async(req, res) => {
|
router.get('/account', requireAuth, async(req, res) => {
|
||||||
|
|
@ -26,25 +27,20 @@ router.get('/account', requireAuth, async(req, res) => {
|
||||||
const config = req.app.get('config')
|
const config = req.app.get('config')
|
||||||
const stats = userRepository.getUserStats(req.session.userId, config.user)
|
const stats = userRepository.getUserStats(req.session.userId, config.user)
|
||||||
|
|
||||||
// Get purge time for footer
|
const successMessage = req.session.accountSuccess
|
||||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
const errorMessage = req.session.accountError
|
||||||
|
delete req.session.accountSuccess
|
||||||
|
delete req.session.accountError
|
||||||
|
|
||||||
res.render('account', {
|
res.render('account', templateContext.build(req, {
|
||||||
title: 'Account Dashboard',
|
title: 'Account Dashboard',
|
||||||
username: req.session.username,
|
username: req.session.username,
|
||||||
forwardEmails,
|
forwardEmails,
|
||||||
lockedInboxes,
|
lockedInboxes,
|
||||||
stats,
|
stats,
|
||||||
branding: config.http.features.branding || ['48hr.email', 'Service', 'https://example.com'],
|
successMessage,
|
||||||
purgeTime: purgeTime,
|
errorMessage
|
||||||
smtpEnabled: config.email.features.smtp,
|
}))
|
||||||
successMessage: req.session.accountSuccess,
|
|
||||||
errorMessage: req.session.accountError
|
|
||||||
})
|
|
||||||
|
|
||||||
// Clear flash messages
|
|
||||||
delete req.session.accountSuccess
|
|
||||||
delete req.session.accountError
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Account page error:', error)
|
console.error('Account page error:', error)
|
||||||
res.status(500).render('error', {
|
res.status(500).render('error', {
|
||||||
|
|
|
||||||
|
|
@ -4,10 +4,7 @@ const { body, validationResult } = require('express-validator')
|
||||||
const debug = require('debug')('48hr-email:auth-routes')
|
const debug = require('debug')('48hr-email:auth-routes')
|
||||||
const { redirectIfAuthenticated } = require('../middleware/auth')
|
const { redirectIfAuthenticated } = require('../middleware/auth')
|
||||||
const config = require('../../../application/config')
|
const config = require('../../../application/config')
|
||||||
const Helper = require('../../../application/helper')
|
const templateContext = require('../template-context')
|
||||||
const helper = new Helper()
|
|
||||||
|
|
||||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
|
||||||
|
|
||||||
// Simple in-memory rate limiters for registration and login
|
// Simple in-memory rate limiters for registration and login
|
||||||
const registrationRateLimitStore = new Map()
|
const registrationRateLimitStore = new Map()
|
||||||
|
|
@ -96,21 +93,13 @@ router.use((req, res, next) => {
|
||||||
// GET /auth - Show unified auth page (login or register)
|
// GET /auth - Show unified auth page (login or register)
|
||||||
router.get('/auth', redirectIfAuthenticated, (req, res) => {
|
router.get('/auth', redirectIfAuthenticated, (req, res) => {
|
||||||
const config = req.app.get('config')
|
const config = req.app.get('config')
|
||||||
const errorMessage = req.session.errorMessage
|
|
||||||
const successMessage = req.session.successMessage
|
const successMessage = req.session.successMessage
|
||||||
|
|
||||||
// Clear messages after reading
|
|
||||||
delete req.session.errorMessage
|
|
||||||
delete req.session.successMessage
|
delete req.session.successMessage
|
||||||
|
|
||||||
res.render('auth', {
|
res.render('auth', templateContext.build(req, {
|
||||||
title: `Login or Register | ${(config.http.features.branding || ['48hr.email'])[0]}`,
|
title: `Login or Register | ${(config.http.features.branding || ['48hr.email'])[0]}`,
|
||||||
branding: config.http.features.branding || ['48hr.email', 'Service', 'https://example.com'],
|
|
||||||
purgeTime: purgeTime,
|
|
||||||
smtpEnabled: config.email.features.smtp,
|
|
||||||
errorMessage,
|
|
||||||
successMessage
|
successMessage
|
||||||
})
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
// POST /register - Process registration
|
// POST /register - Process registration
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,9 @@
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
|
|
||||||
const router = new express.Router()
|
const router = new express.Router()
|
||||||
const config = require('../../../application/config')
|
const config = require('../../../application/config')
|
||||||
const Helper = require('../../../application/helper')
|
const templateContext = require('../template-context')
|
||||||
const helper = new(Helper)
|
|
||||||
const debug = require('debug')('48hr-email:routes')
|
const debug = require('debug')('48hr-email:routes')
|
||||||
|
|
||||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
|
||||||
|
|
||||||
router.get('/:address/:errorCode', async(req, res, next) => {
|
router.get('/:address/:errorCode', async(req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const mailProcessingService = req.app.get('mailProcessingService')
|
const mailProcessingService = req.app.get('mailProcessingService')
|
||||||
|
|
@ -21,14 +17,11 @@ router.get('/:address/:errorCode', async(req, res, next) => {
|
||||||
debug(`Rendering error page ${errorCode} with message: ${message}`)
|
debug(`Rendering error page ${errorCode} with message: ${message}`)
|
||||||
const branding = config.http.features.branding || ['48hr.email', 'Service', 'https://example.com']
|
const branding = config.http.features.branding || ['48hr.email', 'Service', 'https://example.com']
|
||||||
res.status(errorCode)
|
res.status(errorCode)
|
||||||
res.render('error', {
|
res.render('error', templateContext.build(req, {
|
||||||
title: `${branding[0]} | ${errorCode}`,
|
title: `${branding[0]} | ${errorCode}`,
|
||||||
purgeTime: purgeTime,
|
|
||||||
address: req.params.address,
|
|
||||||
message: message,
|
message: message,
|
||||||
status: errorCode,
|
status: errorCode
|
||||||
branding: branding
|
}))
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
debug('Error loading error page:', error.message)
|
debug('Error loading error page:', error.message)
|
||||||
console.error('Error while loading error page', error)
|
console.error('Error while loading error page', error)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ const debug = require('debug')('48hr-email:routes')
|
||||||
const config = require('../../../application/config')
|
const config = require('../../../application/config')
|
||||||
const Helper = require('../../../application/helper')
|
const Helper = require('../../../application/helper')
|
||||||
const CryptoDetector = require('../../../application/crypto-detector')
|
const CryptoDetector = require('../../../application/crypto-detector')
|
||||||
|
const templateContext = require('../template-context')
|
||||||
const helper = new(Helper)
|
const helper = new(Helper)
|
||||||
const cryptoDetector = new CryptoDetector()
|
const cryptoDetector = new CryptoDetector()
|
||||||
const { checkLockAccess } = require('../middleware/lock')
|
const { checkLockAccess } = require('../middleware/lock')
|
||||||
|
|
@ -105,68 +106,11 @@ router.get('^/:address([^@/]+@[^@/]+)', sanitizeAddress, validateDomain, optiona
|
||||||
throw new Error('Mail processing service not available')
|
throw new Error('Mail processing service not available')
|
||||||
}
|
}
|
||||||
debug(`Inbox request for ${req.params.address}`)
|
debug(`Inbox request for ${req.params.address}`)
|
||||||
const inboxLock = req.app.get('inboxLock')
|
|
||||||
|
|
||||||
// Check lock status
|
res.render('inbox', templateContext.build(req, {
|
||||||
const isLocked = inboxLock && inboxLock.isLocked(req.params.address)
|
|
||||||
const userId = req.session && req.session.userId
|
|
||||||
const isAuthenticated = req.session && req.session.isAuthenticated
|
|
||||||
|
|
||||||
// Check if user has access (either owns the lock or has session access)
|
|
||||||
const hasAccess = isAuthenticated && userId && inboxLock ?
|
|
||||||
(inboxLock.isLockedByUser(req.params.address, userId) || req.session.lockedInbox === req.params.address) :
|
|
||||||
(req.session && req.session.lockedInbox === req.params.address)
|
|
||||||
|
|
||||||
// Get user's verified emails if logged in
|
|
||||||
let userForwardEmails = []
|
|
||||||
if (req.session && req.session.userId) {
|
|
||||||
const userRepository = req.app.get('userRepository')
|
|
||||||
if (userRepository) {
|
|
||||||
userForwardEmails = userRepository.getForwardEmails(req.session.userId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pull any lock error from session and clear it after reading
|
|
||||||
const lockError = req.session ? req.session.lockError : undefined
|
|
||||||
const unlockErrorSession = req.session ? req.session.unlockError : undefined
|
|
||||||
const errorMessage = req.session ? req.session.errorMessage : undefined
|
|
||||||
if (req.session) {
|
|
||||||
delete req.session.lockError
|
|
||||||
delete req.session.unlockError
|
|
||||||
delete req.session.errorMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for forward all success flag
|
|
||||||
const forwardAllSuccess = req.query.forwardedAll ? parseInt(req.query.forwardedAll) : null
|
|
||||||
|
|
||||||
// Check for verification sent flag
|
|
||||||
const verificationSent = req.query.verificationSent === 'true'
|
|
||||||
const verificationEmail = req.query.email || ''
|
|
||||||
|
|
||||||
res.render('inbox', {
|
|
||||||
title: `${(config.http.features.branding || ['48hr.email'])[0]} | ` + req.params.address,
|
title: `${(config.http.features.branding || ['48hr.email'])[0]} | ` + req.params.address,
|
||||||
purgeTime: purgeTime,
|
mailSummaries: mailProcessingService.getMailSummaries(req.params.address)
|
||||||
address: req.params.address,
|
}))
|
||||||
mailSummaries: mailProcessingService.getMailSummaries(req.params.address),
|
|
||||||
branding: config.http.branding,
|
|
||||||
authEnabled: config.user.authEnabled,
|
|
||||||
smtpEnabled: config.email.features.smtp,
|
|
||||||
isAuthenticated: req.session && req.session.userId ? true : false,
|
|
||||||
userForwardEmails: userForwardEmails,
|
|
||||||
isLocked: isLocked,
|
|
||||||
hasAccess: hasAccess,
|
|
||||||
unlockError: unlockErrorSession,
|
|
||||||
locktimer: config.user.lockReleaseHours,
|
|
||||||
error: lockError,
|
|
||||||
redirectTo: req.originalUrl,
|
|
||||||
expiryTime: config.email.purgeTime.time,
|
|
||||||
expiryUnit: config.email.purgeTime.unit,
|
|
||||||
refreshInterval: config.imap.refreshIntervalSeconds,
|
|
||||||
errorMessage: errorMessage,
|
|
||||||
forwardAllSuccess: forwardAllSuccess,
|
|
||||||
verificationSent: verificationSent,
|
|
||||||
verificationEmail: verificationEmail
|
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
debug(`Error loading inbox for ${req.params.address}:`, error.message)
|
debug(`Error loading inbox for ${req.params.address}:`, error.message)
|
||||||
console.error('Error while loading inbox', error)
|
console.error('Error while loading inbox', error)
|
||||||
|
|
@ -201,58 +145,13 @@ router.get(
|
||||||
const cryptoAttachments = cryptoDetector.detectCryptoAttachments(mail.attachments)
|
const cryptoAttachments = cryptoDetector.detectCryptoAttachments(mail.attachments)
|
||||||
debug(`Found ${cryptoAttachments.length} cryptographic attachments`)
|
debug(`Found ${cryptoAttachments.length} cryptographic attachments`)
|
||||||
|
|
||||||
const inboxLock = req.app.get('inboxLock')
|
|
||||||
const isLocked = inboxLock && inboxLock.isLocked(req.params.address)
|
|
||||||
const userId = req.session && req.session.userId
|
|
||||||
const isAuthenticated = req.session && req.session.isAuthenticated
|
|
||||||
|
|
||||||
// Check if user has access (either owns the lock or has session access)
|
|
||||||
const hasAccess = isAuthenticated && userId && inboxLock ?
|
|
||||||
(inboxLock.isLockedByUser(req.params.address, userId) || req.session.lockedInbox === req.params.address) :
|
|
||||||
(req.session && req.session.lockedInbox === req.params.address)
|
|
||||||
|
|
||||||
// Get user's verified emails if logged in
|
|
||||||
let userForwardEmails = []
|
|
||||||
if (req.session && req.session.userId) {
|
|
||||||
const userRepository = req.app.get('userRepository')
|
|
||||||
if (userRepository) {
|
|
||||||
userForwardEmails = userRepository.getForwardEmails(req.session.userId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pull error message from session and clear it
|
|
||||||
const errorMessage = req.session ? req.session.errorMessage : undefined
|
|
||||||
if (req.session) {
|
|
||||||
delete req.session.errorMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for forward success flag
|
|
||||||
const forwardSuccess = req.query.forwarded === 'true'
|
|
||||||
|
|
||||||
// Check for verification sent flag
|
|
||||||
const verificationSent = req.query.verificationSent === 'true'
|
|
||||||
const verificationEmail = req.query.email || ''
|
|
||||||
|
|
||||||
debug(`Rendering email view for UID ${req.params.uid}`)
|
debug(`Rendering email view for UID ${req.params.uid}`)
|
||||||
res.render('mail', {
|
res.render('mail', templateContext.build(req, {
|
||||||
title: mail.subject + " | " + req.params.address,
|
title: mail.subject + " | " + req.params.address,
|
||||||
purgeTime: purgeTime,
|
|
||||||
address: req.params.address,
|
|
||||||
mail,
|
mail,
|
||||||
cryptoAttachments: cryptoAttachments,
|
cryptoAttachments: cryptoAttachments,
|
||||||
uid: req.params.uid,
|
uid: req.params.uid
|
||||||
branding: config.http.features.branding || ['48hr.email', 'Service', 'https://example.com'],
|
}))
|
||||||
authEnabled: config.user.authEnabled,
|
|
||||||
smtpEnabled: config.email.features.smtp,
|
|
||||||
isAuthenticated: req.session && req.session.userId ? true : false,
|
|
||||||
userForwardEmails: userForwardEmails,
|
|
||||||
isLocked: isLocked,
|
|
||||||
hasAccess: hasAccess,
|
|
||||||
errorMessage: errorMessage,
|
|
||||||
forwardSuccess: forwardSuccess,
|
|
||||||
verificationSent: verificationSent,
|
|
||||||
verificationEmail: verificationEmail
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
debug(`Email ${req.params.uid} not found for ${req.params.address}`)
|
debug(`Email ${req.params.uid} not found for ${req.params.address}`)
|
||||||
req.session.errorMessage = 'This mail could not be found. It either does not exist or has been deleted from our servers!'
|
req.session.errorMessage = 'This mail could not be found. It either does not exist or has been deleted from our servers!'
|
||||||
|
|
@ -424,11 +323,11 @@ router.get(
|
||||||
// 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')
|
||||||
debug(`Rendering raw email view for UID ${req.params.uid}`)
|
debug(`Rendering raw email view for UID ${req.params.uid}`)
|
||||||
res.render('raw', {
|
res.render('raw', templateContext.build(req, {
|
||||||
title: req.params.uid + " | raw | " + req.params.address,
|
title: req.params.uid + " | raw | " + req.params.address,
|
||||||
mail: rawMail,
|
mail: rawMail,
|
||||||
decoded: decodedMail
|
decoded: decodedMail
|
||||||
})
|
}))
|
||||||
} else {
|
} else {
|
||||||
debug(`Raw email ${uid} not found for ${req.params.address}`)
|
debug(`Raw email ${uid} not found for ${req.params.address}`)
|
||||||
req.session.errorMessage = 'This mail could not be found. It either does not exist or has been deleted from our servers!'
|
req.session.errorMessage = 'This mail could not be found. It either does not exist or has been deleted from our servers!'
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
const express = require('express')
|
const express = require('express')
|
||||||
const router = new express.Router()
|
const router = new express.Router()
|
||||||
const debug = require('debug')('48hr-email:stats-routes')
|
const debug = require('debug')('48hr-email:stats-routes')
|
||||||
|
const templateContext = require('../template-context')
|
||||||
|
|
||||||
// GET /stats - Statistics page with lazy loading
|
// GET /stats - Statistics page with lazy loading
|
||||||
router.get('/', async(req, res) => {
|
router.get('/', async(req, res) => {
|
||||||
|
|
@ -16,10 +17,7 @@ router.get('/', async(req, res) => {
|
||||||
return res.redirect(redirectUrl)
|
return res.redirect(redirectUrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Helper = require('../../../application/helper')
|
|
||||||
const helper = new Helper()
|
|
||||||
const branding = config.http.features.branding || ['48hr.email', 'Service', 'https://example.com']
|
const branding = config.http.features.branding || ['48hr.email', 'Service', 'https://example.com']
|
||||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
|
||||||
|
|
||||||
// Return page with placeholder data immediately - real data loads via JS
|
// Return page with placeholder data immediately - real data loads via JS
|
||||||
const placeholderStats = {
|
const placeholderStats = {
|
||||||
|
|
@ -48,15 +46,11 @@ router.get('/', async(req, res) => {
|
||||||
|
|
||||||
debug(`Stats page requested - returning with lazy loading`)
|
debug(`Stats page requested - returning with lazy loading`)
|
||||||
|
|
||||||
res.render('stats', {
|
res.render('stats', templateContext.build(req, {
|
||||||
title: `Statistics | ${branding[0]}`,
|
title: `Statistics | ${branding[0]}`,
|
||||||
branding: branding,
|
|
||||||
purgeTime: purgeTime,
|
|
||||||
stats: placeholderStats,
|
stats: placeholderStats,
|
||||||
authEnabled: config.user.authEnabled,
|
|
||||||
currentUser: req.session && req.session.username,
|
|
||||||
lazyLoad: true
|
lazyLoad: true
|
||||||
})
|
}))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
debug(`Error loading stats page: ${error.message}`)
|
debug(`Error loading stats page: ${error.message}`)
|
||||||
console.error('Error while loading stats page', error)
|
console.error('Error while loading stats page', error)
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,36 @@ class TemplateContext {
|
||||||
* @returns {Object} Base template context
|
* @returns {Object} Base template context
|
||||||
*/
|
*/
|
||||||
getBaseContext(req) {
|
getBaseContext(req) {
|
||||||
|
const inboxLock = req.app.get('inboxLock')
|
||||||
|
const address = req.params && req.params.address
|
||||||
|
const userId = req.session && req.session.userId
|
||||||
|
const isAuthenticated = !!(req.session && req.session.userId)
|
||||||
|
|
||||||
|
// Calculate lock status for current address
|
||||||
|
const isLocked = address && inboxLock ? inboxLock.isLocked(address) : false
|
||||||
|
const hasAccess = address && isAuthenticated && userId && inboxLock ?
|
||||||
|
(inboxLock.isLockedByUser(address, userId) || req.session.lockedInbox === address) :
|
||||||
|
(address && req.session && req.session.lockedInbox === address)
|
||||||
|
|
||||||
|
// Get user's verified forward emails if logged in
|
||||||
|
let userForwardEmails = []
|
||||||
|
if (isAuthenticated && userId) {
|
||||||
|
const userRepository = req.app.get('userRepository')
|
||||||
|
if (userRepository) {
|
||||||
|
userForwardEmails = userRepository.getForwardEmails(userId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// Config values
|
// Config values
|
||||||
config: config,
|
config: config,
|
||||||
branding: config.http.features.branding || ['48hr.email', 'Service', 'https://example.com'],
|
branding: config.http.features.branding || ['48hr.email', 'Service', 'https://example.com'],
|
||||||
purgeTime: this.purgeTime,
|
purgeTime: this.purgeTime,
|
||||||
purgeTimeRaw: config.email.purgeTime,
|
purgeTimeRaw: config.email.purgeTime,
|
||||||
|
expiryTime: config.email.purgeTime.time,
|
||||||
|
expiryUnit: config.email.purgeTime.unit,
|
||||||
|
refreshInterval: config.imap.refreshIntervalSeconds,
|
||||||
|
locktimer: config.user.lockReleaseHours,
|
||||||
|
|
||||||
// Feature flags
|
// Feature flags
|
||||||
authEnabled: config.user.authEnabled,
|
authEnabled: config.user.authEnabled,
|
||||||
|
|
@ -32,8 +56,29 @@ class TemplateContext {
|
||||||
smtpEnabled: config.email.features.smtp,
|
smtpEnabled: config.email.features.smtp,
|
||||||
showInfoSection: config.http.features.infoSection,
|
showInfoSection: config.http.features.infoSection,
|
||||||
|
|
||||||
// User session
|
// User session & authentication
|
||||||
currentUser: req.session && req.session.username ? req.session.username : null,
|
currentUser: req.session && req.session.username ? req.session.username : null,
|
||||||
|
isAuthenticated: isAuthenticated,
|
||||||
|
userForwardEmails: userForwardEmails,
|
||||||
|
|
||||||
|
// Lock status
|
||||||
|
isLocked: isLocked,
|
||||||
|
hasAccess: hasAccess,
|
||||||
|
|
||||||
|
// Session messages/errors (auto-clear after reading)
|
||||||
|
error: this._getAndClearSession(req, 'lockError'),
|
||||||
|
unlockError: this._getAndClearSession(req, 'unlockError'),
|
||||||
|
errorMessage: this._getAndClearSession(req, 'errorMessage'),
|
||||||
|
|
||||||
|
// Query parameters
|
||||||
|
verificationSent: req.query && req.query.verificationSent === 'true',
|
||||||
|
verificationEmail: req.query && req.query.email || '',
|
||||||
|
forwardSuccess: req.query && req.query.forwarded === 'true',
|
||||||
|
forwardAllSuccess: req.query && req.query.forwardedAll ? parseInt(req.query.forwardedAll) : null,
|
||||||
|
|
||||||
|
// Request info
|
||||||
|
redirectTo: req.originalUrl,
|
||||||
|
address: address,
|
||||||
|
|
||||||
// Common data
|
// Common data
|
||||||
domains: this.cachedDomains,
|
domains: this.cachedDomains,
|
||||||
|
|
@ -41,6 +86,17 @@ class TemplateContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to get and clear session value
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_getAndClearSession(req, key) {
|
||||||
|
if (!req.session) return undefined
|
||||||
|
const value = req.session[key]
|
||||||
|
delete req.session[key]
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge base context with page-specific data
|
* Merge base context with page-specific data
|
||||||
* @param {Object} req - Express request object
|
* @param {Object} req - Express request object
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{% block metaTags %}
|
{% block metaTags %}
|
||||||
<!-- SEO Meta Tags -->
|
<!-- SEO Meta Tags -->
|
||||||
<meta name="description" content="Your temporary Inbox. Create instant throwaway email addresses to protect your privacy. No registration required. Emails auto-delete after 48 hours.">
|
<meta name="description" content="Your temporary Inbox. Create instant throwaway email addresses to protect your privacy. No registration required. Emails auto-delete after {{ purgeTime | raw }}.">
|
||||||
<meta name="keywords" content="temporary email, disposable email, throwaway email, fake email, temp mail, anonymous email, 48hr email, privacy protection, burner email">
|
<meta name="keywords" content="temporary email, disposable email, throwaway email, fake email, temp mail, anonymous email, 48hr email, privacy protection, burner email">
|
||||||
<meta name="author" content="CrazyCo">
|
<meta name="author" content="CrazyCo">
|
||||||
<meta name="robots" content="index, follow">
|
<meta name="robots" content="index, follow">
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
<meta property="og:type" content="website">
|
<meta property="og:type" content="website">
|
||||||
<meta property="og:url" content="https://48hr.email/">
|
<meta property="og:url" content="https://48hr.email/">
|
||||||
<meta property="og:title" content="48hr.email - Your temporary Inbox">
|
<meta property="og:title" content="48hr.email - Your temporary Inbox">
|
||||||
<meta property="og:description" content="Protect your privacy with free temporary email addresses. No registration required. Emails auto-delete after 48 hours.">
|
<meta property="og:description" content="Protect your privacy with free temporary email addresses. No registration required. Emails auto-delete after {{ purgeTime | raw }}.">
|
||||||
<meta property="og:image" content="https://48hr.email/images/logo.png">
|
<meta property="og:image" content="https://48hr.email/images/logo.png">
|
||||||
<meta property="og:site_name" content="48hr.email">
|
<meta property="og:site_name" content="48hr.email">
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,12 +71,7 @@ function convertAndRound(time, unit) {
|
||||||
*/
|
*/
|
||||||
exports.readablePurgeTime = function(purgeTime) {
|
exports.readablePurgeTime = function(purgeTime) {
|
||||||
if (!purgeTime || !purgeTime.time || !purgeTime.unit) {
|
if (!purgeTime || !purgeTime.time || !purgeTime.unit) {
|
||||||
// Fallback to config if not provided
|
purgeTime = config.email.purgeTime
|
||||||
if (config.email.purgeTime) {
|
|
||||||
purgeTime = config.email.purgeTime
|
|
||||||
} else {
|
|
||||||
return '48 hours'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = `${purgeTime.time} ${purgeTime.unit}`
|
let result = `${purgeTime.time} ${purgeTime.unit}`
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,9 @@ const lockRouter = require('./routes/lock')
|
||||||
const authRouter = require('./routes/auth')
|
const authRouter = require('./routes/auth')
|
||||||
const accountRouter = require('./routes/account')
|
const accountRouter = require('./routes/account')
|
||||||
const statsRouter = require('./routes/stats')
|
const statsRouter = require('./routes/stats')
|
||||||
|
const templateContext = require('./template-context')
|
||||||
const { sanitizeHtmlTwigFilter, readablePurgeTime } = require('./views/twig-filters')
|
const { sanitizeHtmlTwigFilter, readablePurgeTime } = require('./views/twig-filters')
|
||||||
|
|
||||||
const Helper = require('../../application/helper')
|
|
||||||
const helper = new(Helper)
|
|
||||||
const purgeTime = helper.purgeTimeElemetBuilder()
|
|
||||||
|
|
||||||
// Utility function for consistent error handling in routes
|
// Utility function for consistent error handling in routes
|
||||||
const handleRouteError = (error, req, res, next, context = 'route') => {
|
const handleRouteError = (error, req, res, next, context = 'route') => {
|
||||||
debug(`Error in ${context}:`, error.message)
|
debug(`Error in ${context}:`, error.message)
|
||||||
|
|
@ -143,7 +140,9 @@ app.use(async(req, res, next) => {
|
||||||
app.use((req, res, next) => {
|
app.use((req, res, next) => {
|
||||||
const isImapReady = req.app.get('isImapReady')
|
const isImapReady = req.app.get('isImapReady')
|
||||||
if (!isImapReady && !req.path.startsWith('/images') && !req.path.startsWith('/javascripts') && !req.path.startsWith('/stylesheets') && !req.path.startsWith('/dependencies')) {
|
if (!isImapReady && !req.path.startsWith('/images') && !req.path.startsWith('/javascripts') && !req.path.startsWith('/stylesheets') && !req.path.startsWith('/dependencies')) {
|
||||||
return res.render('loading')
|
return res.render('loading', templateContext.build(req, {
|
||||||
|
title: 'Loading...'
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
})
|
})
|
||||||
|
|
@ -174,11 +173,11 @@ app.use(async(err, req, res, _next) => {
|
||||||
|
|
||||||
// Render the error page
|
// Render the error page
|
||||||
res.status(err.status || 500)
|
res.status(err.status || 500)
|
||||||
res.render('error', {
|
res.render('error', templateContext.build(req, {
|
||||||
purgeTime: purgeTime,
|
title: 'Error',
|
||||||
address: req.params && req.params.address,
|
message: err.message,
|
||||||
branding: config.http.features.branding || ['48hr.email', 'Service', 'https://example.com']
|
status: err.status || 500
|
||||||
})
|
}))
|
||||||
} catch (renderError) {
|
} catch (renderError) {
|
||||||
debug('Error in error handler:', renderError.message)
|
debug('Error in error handler:', renderError.message)
|
||||||
console.error('Critical error in error handler', renderError)
|
console.error('Critical error in error handler', renderError)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue