mirror of
https://github.com/Permissionless-Software-Foundation/x402-base-facilitator.git
synced 2026-09-21 16:52:01 -07:00
Merge branch 'master' of https://github.com/christroutner/koa-api-boilerplate into koa-api-boilerplate
This commit is contained in:
Generated
+1052
-20376
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -68,7 +68,7 @@
|
||||
"husky": "^4.3.8",
|
||||
"mocha": "^8.2.1",
|
||||
"nyc": "^15.1.0",
|
||||
"semantic-release": "^17.3.7",
|
||||
"semantic-release": "^17.4.2",
|
||||
"sinon": "^9.2.4",
|
||||
"standard": "^16.0.3"
|
||||
},
|
||||
|
||||
+66
-83
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
A library for controlling the sending email.
|
||||
A library for controlling the sending of email.
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
@@ -34,15 +34,6 @@ class NodeMailer {
|
||||
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.
|
||||
async sendEmail (data) {
|
||||
try {
|
||||
@@ -50,10 +41,6 @@ class NodeMailer {
|
||||
if (!data.email || typeof data.email !== '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)) {
|
||||
throw new Error("Property 'to' must be a array!")
|
||||
@@ -62,66 +49,28 @@ class NodeMailer {
|
||||
await _this.validateEmailArray(data.to)
|
||||
|
||||
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') {
|
||||
throw new Error("Property 'subject' must be a string!")
|
||||
}
|
||||
|
||||
if (!data.payloadTitle || typeof data.payloadTitle !== 'string') {
|
||||
throw new Error("Property 'payloadTitle' must be a string!")
|
||||
// Use the provided html or use a default html generated from the input data
|
||||
|
||||
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
|
||||
const info = await _this.transporter.sendMail({
|
||||
// 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
|
||||
})
|
||||
const info = await _this.transporter.sendMail(sendObj)
|
||||
console.log('Message sent: %s', info.messageId)
|
||||
return info
|
||||
} catch (err) {
|
||||
@@ -140,30 +89,64 @@ class NodeMailer {
|
||||
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
|
||||
} catch (err) {
|
||||
wlogger.error('Error in lib/nodemailer.js/validateEmailArray()')
|
||||
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
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
Unit tests for the nodemailer.js library.
|
||||
*/
|
||||
|
||||
// Public npm libraries
|
||||
const assert = require('chai').assert
|
||||
const sinon = require('sinon')
|
||||
|
||||
const NodeMailer = require('../../../src/lib/nodemailer')
|
||||
|
||||
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