// newsletter.js // Copyright (C) 2022 DTP Technologies, LLC // License: Apache-2.0 'use strict'; const striptags = require('striptags'); const { SiteService } = require('../../lib/site-lib'); const mongoose = require('mongoose'); const Newsletter = mongoose.model('Newsletter'); const NewsletterRecipient = mongoose.model('NewsletterRecipient'); class NewsletterService extends SiteService { constructor (dtp) { super(dtp, module.exports); this.populateNewsletter = [ { path: 'author', select: '_id username username_lc displayName picture', }, ]; } async create (author, newsletterDefinition) { const NOW = new Date(); const newsletter = new Newsletter(); newsletter.created = NOW; newsletter.author = author._id; newsletter.title = striptags(newsletterDefinition.title.trim()); newsletter.summary = striptags(newsletterDefinition.summary.trim()); newsletter.content.html = newsletterDefinition['content.html'].trim(); newsletter.content.text = striptags(newsletterDefinition['content.text'].trim()); newsletter.status = 'draft'; await newsletter.save(); return newsletter.toObject(); } async update (newsletter, newsletterDefinition) { const updateOp = { $set: { } }; if (newsletterDefinition.title) { updateOp.$set.title = striptags(newsletterDefinition.title.trim()); } if (newsletterDefinition.summary) { updateOp.$set.summary = striptags(newsletterDefinition.summary.trim()); } if (newsletterDefinition['content.html']) { updateOp.$set['content.html'] = newsletterDefinition['content.html'].trim(); } if (newsletterDefinition['content.text']) { updateOp.$set['content.text'] = striptags(newsletterDefinition['content.text'].trim()); } if (newsletterDefinition.status) { updateOp.$set.status = striptags(newsletterDefinition.status.trim()); } if (Object.keys(updateOp.$set).length === 0) { return; // no update to perform } await Newsletter.updateOne( { _id: newsletter._id }, updateOp, { upsert: true }, ); } async getNewsletters (pagination, status = ['published']) { if (!Array.isArray(status)) { status = [status]; } const newsletters = await Newsletter .find({ status: { $in: status } }) .sort({ created: -1 }) .skip(pagination.skip) .limit(pagination.cpp) .lean(); return newsletters; } async getById (newsletterId) { const newsletter = await Newsletter .findById(newsletterId) .select('+content.html +content.text') .populate(this.populateNewsletter) .lean(); return newsletter; } async addRecipient (emailAddress) { const { email: emailService } = this.dtp.services; const NOW = new Date(); await emailService.checkEmailAddress(emailAddress); const recipient = new NewsletterRecipient(); recipient.created = NOW; recipient.address = striptags(emailAddress.trim()); recipient.address_lc = recipient.address.toLowerCase(); await recipient.save(); return recipient.toObject(); } async deleteNewsletter (newsletter) { this.log.info('deleting newsletter', { newsletterId: newsletter._id }); await Newsletter.deleteOne({ _id: newsletter._id }); } } module.exports = { logId: 'svc:newsletter', index: 'newsletter', className: 'NewsletterService', create: (dtp) => { return new NewsletterService(dtp); }, };