const EventEmitter = require('events') const debug = require('debug')('48hr-email:imap-manager') const mem = require('mem') const moment = require('moment') const ImapService = require('./imap-service') class MailProcessingService extends EventEmitter { constructor(mailRepository, imapService, clientNotification, config) { super() this.mailRepository = mailRepository this.clientNotification = clientNotification this.imapService = imapService this.config = config // Cached methods: this.cachedFetchFullMail = mem( this.imapService.fetchOneFullMail.bind(this.imapService), {maxAge: 10 * 60 * 1000} ) this.initialLoadDone = false // Delete old messages now and every few hours this.imapService.once(ImapService.EVENT_INITIAL_LOAD_DONE, () => this._deleteOldMails() ) setInterval(() => this._deleteOldMails(), 10 * 60 * 1000) } getMailSummaries(address) { return this.mailRepository.getForRecipient(address) } deleteSpecificEmail(adress, uid) { if (this.mailRepository.removeUid(uid, adress) == true) { this.imapService.deleteSpecificEmail(uid) } } getOneFullMail(address, uid, raw = false) { return this.cachedFetchFullMail(address, uid, raw) } getAllMailSummaries() { return this.mailRepository.getAll() } onInitialLoadDone() { this.initialLoadDone = true console.log( `initial load done, got ${this.mailRepository.mailCount()} mails` ) } onNewMail(mail) { if (this.initialLoadDone) { // For now, only log messages if they arrive after the initial load debug('new mail for', mail.to[0]) } mail.to.forEach(to => { this.mailRepository.add(to, mail) return this.clientNotification.emit(to) }) } onMailDeleted(uid) { debug('mail deleted with uid', uid) this.mailRepository.removeUid(uid) } async _deleteOldMails() { try { await this.imapService.deleteOldMails( moment() // Because of how we have to handle the times (IMAP isnt time-aware), we need to subtract one day // to get all mails in their last few hours before technical purge // // This is a bit of a hack, but it works. See imap-service.js#deleteOldMails (L211-227) for more info .subtract(this.config.email.deleteMailsOlderThanDays - 1, 'days') .toDate() ) } catch (error) { console.log('can not delete old messages', error) } } _saveToFile(mails, filename) { const fs = require('fs') fs.writeFile(filename, JSON.stringify(mails), err => { if (err) { console.error('can not save mails to file', err) } }) } } module.exports = MailProcessingService