mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-consumer.git
synced 2026-09-21 16:52:03 -07:00
refactor(nodemailer): Refactored koa nodemailer
This commit is contained in:
Generated
+59
-17870
File diff suppressed because it is too large
Load Diff
+65
-82
@@ -34,15 +34,6 @@ class NodeMailer {
|
|||||||
return transporter
|
return transporter
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate email
|
|
||||||
async validateEmail (email) {
|
|
||||||
// eslint-disable-next-line no-useless-escape
|
|
||||||
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles the sending of data via email.
|
// Handles the sending of data via email.
|
||||||
async sendEmail (data) {
|
async sendEmail (data) {
|
||||||
try {
|
try {
|
||||||
@@ -50,10 +41,6 @@ class NodeMailer {
|
|||||||
if (!data.email || typeof data.email !== 'string') {
|
if (!data.email || typeof data.email !== 'string') {
|
||||||
throw new Error("Property 'email' must be a string!")
|
throw new Error("Property 'email' must be a string!")
|
||||||
}
|
}
|
||||||
const isEmail = await _this.validateEmail(data.email)
|
|
||||||
if (!isEmail) {
|
|
||||||
throw new Error("Property 'email' must be email format!")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.to || !Array.isArray(data.to)) {
|
if (!data.to || !Array.isArray(data.to)) {
|
||||||
throw new Error("Property 'to' must be a array!")
|
throw new Error("Property 'to' must be a array!")
|
||||||
@@ -62,66 +49,28 @@ class NodeMailer {
|
|||||||
await _this.validateEmailArray(data.to)
|
await _this.validateEmailArray(data.to)
|
||||||
|
|
||||||
if (!data.formMessage || typeof data.formMessage !== 'string') {
|
if (!data.formMessage || typeof data.formMessage !== 'string') {
|
||||||
throw new Error("Property 'message' must be a string!")
|
throw new Error("Property 'formMessage' must be a string!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.subject || typeof data.subject !== 'string') {
|
if (!data.subject || typeof data.subject !== 'string') {
|
||||||
throw new Error("Property 'subject' must be a string!")
|
throw new Error("Property 'subject' must be a string!")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!data.payloadTitle || typeof data.payloadTitle !== 'string') {
|
// Use the provided html or use a default html generated from the input data
|
||||||
throw new Error("Property 'payloadTitle' must be a string!")
|
|
||||||
|
const html = data.htmlData || _this.getHtmlFromObject(data)
|
||||||
|
const sendObj = {
|
||||||
|
// from: `${data.email}`, // sender address
|
||||||
|
from: data.email,
|
||||||
|
to: data.to, // list of receivers
|
||||||
|
// subject: `Pearson ${subject}`, // Subject line
|
||||||
|
subject: data.subject,
|
||||||
|
// html: '<b>This is a test email</b>' // html body
|
||||||
|
html
|
||||||
}
|
}
|
||||||
|
|
||||||
const msg = data.formMessage.replace(/(\r\n|\n|\r)/g, '<br />')
|
|
||||||
|
|
||||||
const now = new Date()
|
|
||||||
|
|
||||||
const subject = data.subject
|
|
||||||
const to = data.to
|
|
||||||
// const emailUser = data.email // email from the user who initiated the sharing email
|
|
||||||
const payload = data.payloadTitle
|
|
||||||
|
|
||||||
const bodyJson = data
|
|
||||||
delete bodyJson.to
|
|
||||||
delete bodyJson.subject
|
|
||||||
delete bodyJson.formMessage
|
|
||||||
|
|
||||||
// Prototyping email output.
|
|
||||||
bodyJson.email = 'noreply@launchpadip.net'
|
|
||||||
delete bodyJson.email
|
|
||||||
delete bodyJson.emailList
|
|
||||||
delete bodyJson.payloadTitle
|
|
||||||
|
|
||||||
bodyJson.message = msg
|
|
||||||
|
|
||||||
// Html body
|
|
||||||
let htmlData = ''
|
|
||||||
|
|
||||||
// maps the object and converts it into html format
|
|
||||||
Object.keys(bodyJson).forEach(function (key) {
|
|
||||||
htmlData += `${key}: ${bodyJson[key]}<br/>`
|
|
||||||
})
|
|
||||||
// This paragraph just be added to the message for
|
|
||||||
// emails that are not password reset ones
|
|
||||||
const paragraphTag = 'This is a test email'
|
|
||||||
|
|
||||||
const htmlMsg = `<h3>${subject}:</h3>
|
|
||||||
${payload === 'Email reset' ? '' : paragraphTag}
|
|
||||||
<p>
|
|
||||||
time: ${now.toLocaleString()}<br/>
|
|
||||||
${htmlData}
|
|
||||||
</p>`
|
|
||||||
// send mail with defined transport object
|
// send mail with defined transport object
|
||||||
const info = await _this.transporter.sendMail({
|
const info = await _this.transporter.sendMail(sendObj)
|
||||||
// from: `${data.email}`, // sender address
|
|
||||||
from: 'noreply@launchpadip.net',
|
|
||||||
to: `${to}`, // list of receivers
|
|
||||||
// subject: `Pearson ${subject}`, // Subject line
|
|
||||||
subject: subject,
|
|
||||||
// html: '<b>This is a test email</b>' // html body
|
|
||||||
html: htmlMsg
|
|
||||||
})
|
|
||||||
console.log('Message sent: %s', info.messageId)
|
console.log('Message sent: %s', info.messageId)
|
||||||
return info
|
return info
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -140,30 +89,64 @@ class NodeMailer {
|
|||||||
throw new Error("Property 'emailList' cant be empty!")
|
throw new Error("Property 'emailList' cant be empty!")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterates the array and validates each email format
|
|
||||||
const isValid = await new Promise(resolve => {
|
|
||||||
emailList.map(async (value, i) => {
|
|
||||||
const isEmail = await _this.validateEmail(value)
|
|
||||||
|
|
||||||
if (!isEmail) {
|
|
||||||
resolve(false)
|
|
||||||
}
|
|
||||||
if (i >= emailList.length - 1) {
|
|
||||||
resolve(true)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!isValid) {
|
|
||||||
throw new Error('Array must contain emails format!')
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
wlogger.error('Error in lib/nodemailer.js/validateEmailArray()')
|
wlogger.error('Error in lib/nodemailer.js/validateEmailArray()')
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the email html from object
|
||||||
|
getHtmlFromObject (objectData) {
|
||||||
|
try {
|
||||||
|
if (!objectData || typeof objectData !== 'object') {
|
||||||
|
throw new Error("Property 'objectData' must be a object!")
|
||||||
|
}
|
||||||
|
if (!objectData.subject) {
|
||||||
|
throw new Error("Property 'subject' must be a string!")
|
||||||
|
}
|
||||||
|
if (!objectData.formMessage) {
|
||||||
|
throw new Error("Property 'formMessage' must be a string!")
|
||||||
|
}
|
||||||
|
|
||||||
|
const obj = {}
|
||||||
|
Object.assign(obj, objectData)
|
||||||
|
|
||||||
|
// neccesary data
|
||||||
|
const msg = obj.formMessage.replace(/(\r\n|\n|\r)/g, '<br />')
|
||||||
|
const now = new Date()
|
||||||
|
const subject = obj.subject
|
||||||
|
|
||||||
|
// Delete unneccesary data if it exist
|
||||||
|
delete obj.to
|
||||||
|
delete obj.subject
|
||||||
|
delete obj.from
|
||||||
|
delete obj.emailList
|
||||||
|
delete obj.formMessage
|
||||||
|
|
||||||
|
const bodyJson = obj
|
||||||
|
bodyJson.message = msg
|
||||||
|
|
||||||
|
// Html body
|
||||||
|
let htmlBody = ''
|
||||||
|
|
||||||
|
// maps the object and converts it into html format
|
||||||
|
Object.keys(bodyJson).forEach(function (key) {
|
||||||
|
htmlBody += `${key}: ${bodyJson[key]}<br/>`
|
||||||
|
})
|
||||||
|
|
||||||
|
const defaultHtmlData = `<h3>${subject}:</h3>
|
||||||
|
<p>
|
||||||
|
time: ${now.toLocaleString()}<br/>
|
||||||
|
${htmlBody}
|
||||||
|
</p>`
|
||||||
|
|
||||||
|
return defaultHtmlData
|
||||||
|
} catch (error) {
|
||||||
|
wlogger.error('Error in lib/nodemailer.js/getHtmlFromObject()')
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = NodeMailer
|
module.exports = NodeMailer
|
||||||
|
|||||||
@@ -0,0 +1,214 @@
|
|||||||
|
const assert = require('chai').assert
|
||||||
|
|
||||||
|
const NodeMailer = require('../../../src/lib/nodemailer')
|
||||||
|
|
||||||
|
const sinon = require('sinon')
|
||||||
|
|
||||||
|
const util = require('util')
|
||||||
|
util.inspect.defaultOptions = { depth: 1 }
|
||||||
|
|
||||||
|
let sandbox
|
||||||
|
let uut
|
||||||
|
describe('NodeMailer', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
uut = new NodeMailer()
|
||||||
|
|
||||||
|
sandbox = sinon.createSandbox()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => sandbox.restore())
|
||||||
|
|
||||||
|
describe('sendEmail()', () => {
|
||||||
|
it('should throw error if email property is not provided', async () => {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
formMessage: 'test msg',
|
||||||
|
name: 'test name',
|
||||||
|
subject: 'test subject',
|
||||||
|
to: ['test2@email.com']
|
||||||
|
}
|
||||||
|
await uut.sendEmail(data)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'email\' must be a string!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if formMessage property is not provided', async () => {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
email: 'test@email.com',
|
||||||
|
name: 'test name',
|
||||||
|
subject: 'test subject',
|
||||||
|
to: ['test2@email.com']
|
||||||
|
}
|
||||||
|
await uut.sendEmail(data)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'formMessage\' must be a string!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('should throw error if <to> property is not provided', async () => {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
email: 'test@email.com',
|
||||||
|
name: 'test name',
|
||||||
|
subject: 'test subject'
|
||||||
|
}
|
||||||
|
await uut.sendEmail(data)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'to\' must be a array!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if <to> is wrong type', async () => {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
email: 'test@email.com',
|
||||||
|
formMessage: 'test msg',
|
||||||
|
name: 'test name',
|
||||||
|
subject: 'test subject',
|
||||||
|
to: 'test'
|
||||||
|
}
|
||||||
|
await uut.sendEmail(data)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, "Property 'to' must be a array!")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should throw error if subject Property is not provided', async () => {
|
||||||
|
try {
|
||||||
|
const data = {
|
||||||
|
email: 'test@email.com',
|
||||||
|
formMessage: 'test msg',
|
||||||
|
name: 'test name',
|
||||||
|
to: ['test2@email.com']
|
||||||
|
}
|
||||||
|
await uut.sendEmail(data)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'subject\' must be a string!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should send email with default html data', async () => {
|
||||||
|
try {
|
||||||
|
sandbox.stub(uut.transporter, 'sendMail').resolves({ messageId: 'messageId' })
|
||||||
|
const data = {
|
||||||
|
email: 'test@email.com',
|
||||||
|
formMessage: 'test msg',
|
||||||
|
to: ['test2@email.com'],
|
||||||
|
subject: 'test subject'
|
||||||
|
}
|
||||||
|
const info = await uut.sendEmail(data)
|
||||||
|
assert.isObject(info)
|
||||||
|
assert.isString(info.messageId)
|
||||||
|
} catch (err) {
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('should send email if htmlData is provided', async () => {
|
||||||
|
try {
|
||||||
|
sandbox.stub(uut.transporter, 'sendMail').resolves({ messageId: 'messageId' })
|
||||||
|
const data = {
|
||||||
|
email: 'test@email.com',
|
||||||
|
formMessage: 'test msg',
|
||||||
|
name: 'test name',
|
||||||
|
to: ['test2@email.com'],
|
||||||
|
subject: 'test subject',
|
||||||
|
htmlData: '<p> Unit test </p>'
|
||||||
|
}
|
||||||
|
const info = await uut.sendEmail(data)
|
||||||
|
assert.isObject(info)
|
||||||
|
assert.isString(info.messageId)
|
||||||
|
} catch (err) {
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('validateEmailArray()', () => {
|
||||||
|
it('should throw error if email list is not provided ', async () => {
|
||||||
|
try {
|
||||||
|
await uut.validateEmailArray()
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'emailList\' must be a array!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('should throw error if email list is empty', async () => {
|
||||||
|
try {
|
||||||
|
const emailList = []
|
||||||
|
await uut.validateEmailArray(emailList)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'emailList\' cant be empty!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return true ', async () => {
|
||||||
|
try {
|
||||||
|
const emailList = [
|
||||||
|
'test@email.com',
|
||||||
|
'simple@email.com'
|
||||||
|
]
|
||||||
|
const result = await uut.validateEmailArray(emailList)
|
||||||
|
assert.isTrue(result)
|
||||||
|
} catch (err) {
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('getHtmlFromObject()', () => {
|
||||||
|
it('should throw error if the input is not provided ', async () => {
|
||||||
|
try {
|
||||||
|
await uut.getHtmlFromObject()
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'objectData\' must be a object!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('should throw error if the object is empty', async () => {
|
||||||
|
try {
|
||||||
|
await uut.getHtmlFromObject({})
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'subject\' must be a string!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
it('should throw error if "formMessage" property is not provided', async () => {
|
||||||
|
try {
|
||||||
|
const obj = {
|
||||||
|
subject: 'unit'
|
||||||
|
}
|
||||||
|
await uut.getHtmlFromObject(obj)
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
} catch (err) {
|
||||||
|
assert.include(err.message, 'Property \'formMessage\' must be a string!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should return the html', async () => {
|
||||||
|
try {
|
||||||
|
const obj = {
|
||||||
|
subject: 'unit ',
|
||||||
|
formMessage: 'test',
|
||||||
|
value1: 'value1',
|
||||||
|
value2: 'value2',
|
||||||
|
value3: 'value3'
|
||||||
|
|
||||||
|
}
|
||||||
|
const result = await uut.getHtmlFromObject(obj)
|
||||||
|
assert.isString(result)
|
||||||
|
assert.include(result, '<p>', 'expect html tag')
|
||||||
|
assert.include(result, '</p>', 'expect html tag')
|
||||||
|
assert.include(result, 'value1', 'Expect value 1 is included in the html')
|
||||||
|
assert.include(result, 'value2', 'expect is included in the html')
|
||||||
|
assert.include(result, 'value3', 'expect is included in the html')
|
||||||
|
} catch (err) {
|
||||||
|
assert(false, 'Unexpected result')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user