import type { NotificationAgent, NotificationPayload } from './agent'; import { Notification } from '..'; import path from 'path'; import { getSettings } from '../../settings'; import nodemailer from 'nodemailer'; import Email from 'email-templates'; import logger from '../../../logger'; import { getRepository } from 'typeorm'; import { User } from '../../../entity/User'; import { hasPermission, Permission } from '../../permissions'; class EmailAgent implements NotificationAgent { public shouldSend(type: Notification): boolean { const settings = getSettings(); if (settings.notifications.agents.email.enabled) { return true; } return false; } private getSmtpTransport() { const emailSettings = getSettings().notifications.agents.email.options; return nodemailer.createTransport({ host: emailSettings.smtpHost, port: emailSettings.smtpPort, secure: emailSettings.secure, auth: { user: emailSettings.authUser, pass: emailSettings.authPass, }, }); } private getNewEmail() { const settings = getSettings().notifications.agents.email; return new Email({ message: { from: settings.options.emailFrom, }, send: true, transport: this.getSmtpTransport(), }); } private async sendMediaRequestEmail(payload: NotificationPayload) { const settings = getSettings().main; try { const userRepository = getRepository(User); const users = await userRepository.find(); // Send to all users with the manage requests permission (or admins) users .filter((user) => user.hasPermission(Permission.MANAGE_REQUESTS)) .forEach((user) => { const email = this.getNewEmail(); email.send({ template: path.join( __dirname, '../../../templates/email/media-request' ), message: { to: user.email, }, locals: { body: 'A user has requested new media!', mediaName: payload.subject, imageUrl: payload.image, timestamp: new Date().toTimeString(), requestedBy: payload.notifyUser.username, actionUrl: settings.applicationUrl, requestType: 'New Request', }, }); }); return true; } catch (e) { logger.error('Mail notification failed to send', { label: 'Notifications', message: e.message, }); return false; } } private async sendMediaApprovedEmail(payload: NotificationPayload) { const settings = getSettings().main; try { const email = this.getNewEmail(); email.send({ template: path.join( __dirname, '../../../templates/email/media-request' ), message: { to: payload.notifyUser.email, }, locals: { body: 'Your request for the following media has been approved:', mediaName: payload.subject, imageUrl: payload.image, timestamp: new Date().toTimeString(), requestedBy: payload.notifyUser.username, actionUrl: settings.applicationUrl, requestType: 'Request Approved', }, }); return true; } catch (e) { logger.error('Mail notification failed to send', { label: 'Notifications', message: e.message, }); return false; } } private async sendMediaAvailableEmail(payload: NotificationPayload) { const settings = getSettings().main; try { const email = this.getNewEmail(); email.send({ template: path.join( __dirname, '../../../templates/email/media-request' ), message: { to: payload.notifyUser.email, }, locals: { body: 'Your requsested media is now available!', mediaName: payload.subject, imageUrl: payload.image, timestamp: new Date().toTimeString(), requestedBy: payload.notifyUser.username, actionUrl: settings.applicationUrl, requestType: 'Now Available', }, }); return true; } catch (e) { logger.error('Mail notification failed to send', { label: 'Notifications', message: e.message, }); return false; } } public async send( type: Notification, payload: NotificationPayload ): Promise { logger.debug('Sending email notification', { label: 'Notifications' }); switch (type) { case Notification.MEDIA_PENDING: this.sendMediaRequestEmail(payload); break; case Notification.MEDIA_APPROVED: this.sendMediaApprovedEmail(payload); break; case Notification.MEDIA_AVAILABLE: this.sendMediaAvailableEmail(payload); break; } return true; } } export default EmailAgent;