mirror of
https://github.com/Crazyco-xyz/48hr.email.git
synced 2026-01-09 19:29:34 +01:00
[Chore]: Various tiny fixes and updates
This commit is contained in:
parent
ed2cc90852
commit
2f7194e6bd
4 changed files with 48 additions and 49 deletions
37
app.js
37
app.js
|
|
@ -19,7 +19,24 @@ const clientNotification = new ClientNotification()
|
||||||
debug('Client notification service initialized')
|
debug('Client notification service initialized')
|
||||||
clientNotification.use(io)
|
clientNotification.use(io)
|
||||||
|
|
||||||
const imapService = new ImapService(config)
|
let inboxLock = null
|
||||||
|
// Initialize inbox locking if enabled
|
||||||
|
if (config.lock.enabled) {
|
||||||
|
inboxLock = new InboxLock(config.lock.dbPath)
|
||||||
|
app.set('inboxLock', inboxLock)
|
||||||
|
console.log(`Inbox locking enabled (auto-release after ${config.lock.releaseHours} hours)`)
|
||||||
|
|
||||||
|
// Check for inactive locked inboxes
|
||||||
|
setInterval(() => {
|
||||||
|
const inactive = inboxLock.getInactive(config.lock.releaseHours)
|
||||||
|
if (inactive.length > 0) {
|
||||||
|
console.log(`Releasing ${inactive.length} inactive locked inbox(es)`)
|
||||||
|
inactive.forEach(address => inboxLock.release(address))
|
||||||
|
}
|
||||||
|
}, config.imap.refreshIntervalSeconds * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const imapService = new ImapService(config, inboxLock)
|
||||||
debug('IMAP service initialized')
|
debug('IMAP service initialized')
|
||||||
const mailProcessingService = new MailProcessingService(
|
const mailProcessingService = new MailProcessingService(
|
||||||
new MailRepository(),
|
new MailRepository(),
|
||||||
|
|
@ -58,22 +75,6 @@ imapService.on(ImapService.EVENT_ERROR, error => {
|
||||||
app.set('mailProcessingService', mailProcessingService)
|
app.set('mailProcessingService', mailProcessingService)
|
||||||
app.set('config', config)
|
app.set('config', config)
|
||||||
|
|
||||||
// Initialize inbox locking if enabled
|
|
||||||
if (config.lock.enabled) {
|
|
||||||
const inboxLock = new InboxLock(config.lock.dbPath)
|
|
||||||
app.set('inboxLock', inboxLock)
|
|
||||||
console.log(`Inbox locking enabled (auto-release after ${config.lock.releaseHours} hours)`)
|
|
||||||
|
|
||||||
// Check for inactive locked inboxes
|
|
||||||
setInterval(() => {
|
|
||||||
const inactive = inboxLock.getInactive(config.lock.releaseHours)
|
|
||||||
if (inactive.length > 0) {
|
|
||||||
console.log(`Releasing ${inactive.length} inactive locked inbox(es)`)
|
|
||||||
inactive.forEach(address => inboxLock.release(address))
|
|
||||||
}
|
|
||||||
}, config.imap.refreshIntervalSeconds * 1000)
|
|
||||||
}
|
|
||||||
|
|
||||||
app.locals.imapService = imapService
|
app.locals.imapService = imapService
|
||||||
app.locals.mailProcessingService = mailProcessingService
|
app.locals.mailProcessingService = mailProcessingService
|
||||||
|
|
||||||
|
|
@ -104,4 +105,4 @@ server.on('error', error => {
|
||||||
console.error('Fatal web server error', error)
|
console.error('Fatal web server error', error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -89,13 +89,13 @@ imaps.ImapSimple.prototype.closeBox = function(autoExpunge = true, callback) {
|
||||||
* With this abstraction it would be easy to replace this with any inbound mail service like mailgun.com.
|
* With this abstraction it would be easy to replace this with any inbound mail service like mailgun.com.
|
||||||
*/
|
*/
|
||||||
class ImapService extends EventEmitter {
|
class ImapService extends EventEmitter {
|
||||||
constructor(config) {
|
constructor(config, inboxLock = null) {
|
||||||
super()
|
super()
|
||||||
if (!config || !config.imap) {
|
if (!config || !config.imap) {
|
||||||
throw new Error("ImapService requires a valid config with 'imap' object");
|
throw new Error("ImapService requires a valid config with 'imap' object");
|
||||||
}
|
}
|
||||||
this.config = config
|
this.config = config
|
||||||
|
this.inboxLock = inboxLock
|
||||||
this.loadedUids = new Set()
|
this.loadedUids = new Set()
|
||||||
this.connection = null
|
this.connection = null
|
||||||
this.initialLoadDone = false
|
this.initialLoadDone = false
|
||||||
|
|
@ -255,15 +255,10 @@ class ImapService extends EventEmitter {
|
||||||
|
|
||||||
// Get locked inboxes if available
|
// Get locked inboxes if available
|
||||||
let lockedAddresses = [];
|
let lockedAddresses = [];
|
||||||
if (typeof this.config.lock !== 'undefined' && this.config.lock.enabled && this.config.lock.dbPath) {
|
if (this.inboxLock && typeof this.inboxLock.getAllLocked === 'function') {
|
||||||
try {
|
try {
|
||||||
// Try to get the app instance and inboxLock
|
lockedAddresses = this.inboxLock.getAllLocked().map(addr => addr.toLowerCase());
|
||||||
const app = require('../app');
|
debug(`Locked inboxes (excluded from purge): ${lockedAddresses.length > 0 ? lockedAddresses.join(', ') : '0'}`);
|
||||||
const inboxLock = app.get('inboxLock');
|
|
||||||
if (inboxLock && typeof inboxLock.getAllLocked === 'function') {
|
|
||||||
lockedAddresses = inboxLock.getAllLocked().map(addr => addr.toLowerCase());
|
|
||||||
debug(`Locked inboxes (excluded from purge): ${lockedAddresses.join(', ')}`);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
debug('Could not get locked inboxes for purge:', err.message);
|
debug('Could not get locked inboxes for purge:', err.message);
|
||||||
}
|
}
|
||||||
|
|
@ -275,8 +270,7 @@ class ImapService extends EventEmitter {
|
||||||
const date = mail.attributes.date;
|
const date = mail.attributes.date;
|
||||||
const uid = parseInt(mail.attributes.uid);
|
const uid = parseInt(mail.attributes.uid);
|
||||||
const toAddresses = Array.isArray(mail.parts[0].body.to) ?
|
const toAddresses = Array.isArray(mail.parts[0].body.to) ?
|
||||||
mail.parts[0].body.to.map(a => a.toLowerCase()) :
|
mail.parts[0].body.to.map(a => a.toLowerCase()) : [String(mail.parts[0].body.to).toLowerCase()];
|
||||||
[String(mail.parts[0].body.to).toLowerCase()];
|
|
||||||
|
|
||||||
if (exampleUids.includes(uid)) return false;
|
if (exampleUids.includes(uid)) return false;
|
||||||
if (toAddresses.some(addr => lockedAddresses.includes(addr))) return false;
|
if (toAddresses.some(addr => lockedAddresses.includes(addr))) return false;
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,7 @@ class MailProcessingService extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
onNewMail(mail) {
|
onNewMail(mail) {
|
||||||
|
debug('onNewMail called for:', mail.to)
|
||||||
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])
|
||||||
|
|
@ -79,7 +80,9 @@ class MailProcessingService extends EventEmitter {
|
||||||
debug('Adding mail to repository for recipient:', to)
|
debug('Adding mail to repository for recipient:', to)
|
||||||
this.mailRepository.add(to, mail)
|
this.mailRepository.add(to, mail)
|
||||||
debug('Emitting notification for:', to)
|
debug('Emitting notification for:', to)
|
||||||
return this.clientNotification.emit(to)
|
const emitResult = this.clientNotification.emit(to)
|
||||||
|
debug('clientNotification.emit result:', emitResult)
|
||||||
|
return emitResult
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,27 +6,28 @@ require('events').defaultMaxListeners = 50;
|
||||||
* Receives sign-ins from users and notifies them when new mails are available.
|
* Receives sign-ins from users and notifies them when new mails are available.
|
||||||
*/
|
*/
|
||||||
class ClientNotification extends EventEmitter {
|
class ClientNotification extends EventEmitter {
|
||||||
use(io) {
|
use(io) {
|
||||||
io.on('connection', socket => {
|
io.on('connection', socket => {
|
||||||
socket.on('sign in', address => this._signIn(socket, address))
|
socket.on('sign in', address => this._signIn(socket, address))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
_signIn(socket, address) {
|
_signIn(socket, address) {
|
||||||
debug(`socketio signed in: ${address}`)
|
debug(`socketio signed in: ${address}`)
|
||||||
|
|
||||||
const newMailListener = () => {
|
const newMailListener = () => {
|
||||||
debug(`${address} has new messages, sending notification`)
|
debug(`${address} has new messages, sending notification`)
|
||||||
socket.emit('new emails')
|
socket.emit('new emails')
|
||||||
}
|
debug(`socket.emit('new emails') sent to ${address}`)
|
||||||
|
}
|
||||||
|
|
||||||
this.on(address, newMailListener)
|
this.on(address, newMailListener)
|
||||||
|
|
||||||
socket.on('disconnect', reason => {
|
socket.on('disconnect', reason => {
|
||||||
debug(`client disconnect: ${address} (${reason})`)
|
debug(`client disconnect: ${address} (${reason})`)
|
||||||
this.removeListener(address, newMailListener)
|
this.removeListener(address, newMailListener)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = ClientNotification
|
module.exports = ClientNotification
|
||||||
Loading…
Add table
Reference in a new issue