Skip to content

Commit

Permalink
update mailer util
Browse files Browse the repository at this point in the history
  • Loading branch information
dbauszus-glx committed Oct 26, 2023
1 parent af0e328 commit a4004e8
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 132 deletions.
11 changes: 1 addition & 10 deletions mod/provider/cloudfront.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
const https = require('https')

const httpsAgent = new https.Agent({
keepAlive: true,
maxSockets: parseInt(process.env.CUSTOM_AGENT) || 1
})

const { readFileSync } = require('fs')

const { join } = require('path')
Expand Down Expand Up @@ -36,9 +29,7 @@ module.exports = async ref => {
return signedURL;
}

const response = await fetch(signedURL, {
agent: process.env.CUSTOM_AGENT && httpsAgent
})
const response = await fetch(signedURL)

logger(`${response.status} - ${url}`,'cloudfront')

Expand Down
19 changes: 5 additions & 14 deletions mod/user/delete.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ const acl = require('./acl')()

const mailer = require('../utils/mailer')

const languageTemplates = require('../utils/languageTemplates')

module.exports = async (req, res) => {

const email = req.params.email.replace(/\s+/g, '')
Expand All @@ -18,21 +16,14 @@ module.exports = async (req, res) => {

const user = rows[0]

const protocol = `${req.headers.host.includes('localhost') && 'http' || 'https'}://`

const host = `${req.headers.host.includes('localhost') && req.headers.host || process.env.ALIAS || req.headers.host}${process.env.DIR}`

// Sent email to inform user that their account has been deleted.
const mail_template = await languageTemplates('deleted_account', user.language)

// Assign user email to mail_template.
Object.assign(mail_template, {
await mailer({
template: 'deleted_account',
language: user.language,
to: user.email,
host,
protocol
host: `${req.headers.host.includes('localhost') && req.headers.host || process.env.ALIAS || req.headers.host}${process.env.DIR}`,
protocol: `${req.headers.host.includes('localhost') && 'http' || 'https'}://`
})

await mailer(mail_template)

res.send('User account deleted.')
}
28 changes: 14 additions & 14 deletions mod/user/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ async function post(req, res) {

// Accounts must be verified and approved for login
if (!user.verified || !user.approved) {

var mail_template = await languageTemplates('failed_login', user.language)

await mailer(Object.assign(mail_template, {
await mailer({
template: 'failed_login',
language: user.language,
to: user.email,
host: host,
protocol: protocol,
remote_address
}))
})

return new Error(await languageTemplates('user_not_verified', user.language))
}
Expand Down Expand Up @@ -218,29 +218,29 @@ async function post(req, res) {
WHERE lower(email) = lower($1);`, [req.body.email])

if (rows instanceof Error) return new Error(await languageTemplates('failed_query', req.params.language))

var mail_template = await languageTemplates('locked_account', user.language)

await mailer(Object.assign(mail_template, {
await mailer({
template: 'locked_account',
language: user.language,
to: user.email,
host: host,
failed_attempts: parseInt(process.env.FAILED_ATTEMPTS) || 3,
protocol: protocol,
verificationtoken: verificationtoken,
remote_address
}))
})

return new Error(await languageTemplates('user_locked', user.language))
}

// Login has failed but account is not locked (yet).
var mail_template = await languageTemplates('login_incorrect', user.language)

await mailer(Object.assign(mail_template, {
await mailer({
template: 'login_incorrect',
language: user.language,
to: user.email,
host: host,
remote_address
}))
})

return new Error(await languageTemplates('auth_failed', req.params.language))
}
19 changes: 9 additions & 10 deletions mod/user/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,15 @@ async function post(req, res) {

if (rows instanceof Error) return res.status(500).send(await languageTemplates('failed_query', req.params.language))

// Sent mail with verification token to the account email address.
var mail_template = await languageTemplates('verify_password_reset', user.language)

await mailer(Object.assign(mail_template, {
// Sent mail with verification token to the account email address.
await mailer({
template: 'verify_password_reset',
language: user.language,
to: user.email,
host: host,
link: `${protocol}${host}/api/user/verify/${verificationtoken}`,
remote_address
}))
})

const password_reset_verification = await languageTemplates('password_reset_verification', user.language)

Expand Down Expand Up @@ -151,15 +151,14 @@ async function post(req, res) {

if (rows instanceof Error) return res.status(500).send(await languageTemplates('failed_query', req.params.language))

// Sent mail with verification token to the account email address.
var mail_template = await languageTemplates('verify_account', language)

await mailer(Object.assign(mail_template, {
await mailer({
template: 'verify_account',
language,
to: req.body.email,
host: host,
link: `${protocol}${host}/api/user/verify/${verificationtoken}`,
remote_address
}))
})

// Return msg. No redirect for password reset.
res.send(await languageTemplates('new_account_registered', language))
Expand Down
11 changes: 4 additions & 7 deletions mod/user/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,14 @@ module.exports = async (req, res) => {

// Send email to the user account if an account has been approved.
if (req.params.field === 'approved' && req.params.value === 'true') {

const mail_template = await languageTemplates('approved_account', req.params.user.language)

// Assign email to mail template
Object.assign(mail_template, {

await mailer({
template: 'approved_account',
language: req.params.user.language,
to: email,
host: host,
protocol: protocol
})

await mailer(mail_template)
}

const update_ok = await languageTemplates('update_ok', req.params.user.language)
Expand Down
25 changes: 11 additions & 14 deletions mod/user/verify.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,27 @@ module.exports = async (req, res) => {
// One or more administrator have been
if (rows.length > 0) {

// Create protocol and host for mail templates.
const protocol = `${req.headers.host.includes('localhost') && 'http' || 'https'}://`
const host = `${req.headers.host.includes('localhost') && req.headers.host || process.env.ALIAS || req.headers.host}${process.env.DIR}`

// Get array of mail promises.
const mail_promises = rows.map(async row => {

const mail_template = await languageTemplates('admin_email', row.language || req.params.language)

// Assign email to mail template.
Object.assign(mail_template, {
await mailer({
template: 'admin_email',
language: row.language,
to: row.email,
email: user.email,
host: host,
protocol: protocol
host: `${req.headers.host.includes('localhost') && req.headers.host || process.env.ALIAS || req.headers.host}${process.env.DIR}`,
protocol: `${req.headers.host.includes('localhost') && 'http' || 'https'}://`
})

return mailer(mail_template)
})

// Continue after all mail promises have been resolved.
Promise
.all(mail_promises)
.then(async arr => res.send(await languageTemplates('account_await_approval', user.language)))
.allSettled(mail_promises)
.then(async arr => {

console.log(arr)
res.send(await languageTemplates('account_await_approval', user.language))
})
.catch(error => console.error(error))

} else {
Expand Down
44 changes: 0 additions & 44 deletions mod/utils/languageTemplates.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,55 +18,11 @@ module.exports = async (key, lang = 'en') => {

let template = Object.hasOwn(allLanguages, lang)? allLanguages[lang]: allLanguages.en;

console.log(template)

if (typeof template === 'string' && Object.hasOwn(getFrom, template.split(':')[0])) {

// Get template from method.
template = await getFrom[template.split(':')[0]](template)

} else if (typeof template === 'object' && (Object.hasOwn(template, 'text') || Object.hasOwn(template, 'html'))) {

if (Object.hasOwn(getFrom, template.text?.split(':')[0])) {

template.text = await getFrom[template.text.split(':')[0]](template.text)
}

if (Object.hasOwn(getFrom, template.html?.split(':')[0])) {

template.html = await getFrom[template.html.split(':')[0]](template.html)
}

}

// // Prevent prototype polluting assignment.
// Object.freeze(Object.getPrototypeOf(template));

// for (key in template) {

// // Prevent prototype polluting assignment.
// if (/__proto__/.test(key)) continue;

// // Template key / value is a string with a valid get method.
// if (typeof template[key] === 'string'
// && Object.hasOwn(template, key)
// && Object.hasOwn(getFrom, template[key].split(':')[0])) {

// // Assign template key value from method.
// template[key] = await getFrom[template[key].split(':')[0]](template[key])
// }

// // Template key value is still string after assignment
// if (typeof template[key] === 'string') {

// // Look for template params to be substituted.
// template[key] = template[key].replace(/\$\{{1}(.*?)\}{1}/g,

// // Replace matched params in string values
// matched => params[matched.replace(/\$\{{1}|\}{1}/g, '')] || '')
// }

// }

return template
}
77 changes: 58 additions & 19 deletions mod/utils/mailer.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,75 @@
const logger = require('./logger')

const languageTemplates = require('./languageTemplates')

const getFrom = require('../provider/getFrom')

const mailer = require('nodemailer')

module.exports = async mail => {
let transport

if (!process.env.TRANSPORT && !process.env.TRANSPORT_HOST) return console.error(new Error('Transport not set.'))
module.exports = async params => {

if (!process.env.TRANSPORT && !process.env.TRANSPORT_HOST) {
console.warn('No transport method set for mail.')
return;
}

const email = process.env.TRANSPORT_EMAIL || process.env.TRANSPORT.split(':')[1]

Object.assign(mail, {
from: email,
sender: email,
})
if (!transport) {

transport = process.env.TRANSPORT ?
mailer.createTransport(process.env.TRANSPORT) :
mailer.createTransport({
host: process.env.TRANSPORT_HOST,
name: email.match(/[^@]*$/)[0],
port: process.env.TRANSPORT_PORT || 587,
secure: false,
requireTLS: process.env.TRANSPORT_TLS && true,
auth: {
user: email,
pass: process.env.TRANSPORT_PASSWORD
}
})
}

mail.text = mail.text && mail.text.replace(/^(?!\s+$)\s+/gm, '')
const template = await languageTemplates(params.template, params.language)

if (!process.env.TRANSPORT_HOST) return mailer.createTransport(process.env.TRANSPORT).sendMail(mail)
if (template.text) {

const transporter = mailer.createTransport( {
host: process.env.TRANSPORT_HOST,
name: email.match(/[^@]*$/)[0],
port: process.env.TRANSPORT_PORT || 587,
secure: false,
requireTLS: process.env.TRANSPORT_TLS && true,
auth: {
user: email,
pass: process.env.TRANSPORT_PASSWORD
if (Object.hasOwn(getFrom, template.text?.split(':')[0])) {

template.text = await getFrom[template.text.split(':')[0]](template.text)
}
})

const result = await transporter.sendMail(mail).catch(err => console.error(err))
template.text = replaceStringParams(template.text, params)

template.text = template.text.replace(/^(?!\s+$)\s+/gm, '')
}

if (Object.hasOwn(getFrom, template.html?.split(':')[0])) {

template.html = await getFrom[template.html.split(':')[0]](template.html)

template.html = replaceStringParams(template.html, params)
}

template.subject = replaceStringParams(template.subject, params)

template.to = params.to
template.from = email
template.sender = email

const result = await transport.sendMail(template).catch(err => console.error(err))

logger(result, 'mailer')
}

function replaceStringParams(string, params) {

return string.replace(/\$\{{1}(.*?)\}{1}/g,

// Replace matched params in string values
matched => params[matched.replace(/\$\{{1}|\}{1}/g, '')] || '')
}

0 comments on commit a4004e8

Please sign in to comment.