'use strict' /* * NOTE: This test ACTUALLY will send an email * (see commented out email variable below) */ // Change email here to your actual email // const email = 'myalias@myactualemail.com' const test = require('ava') const { stub } = require('sinon') const Hapi = require('@hapi/hapi') const UserService = require('../lib/services/user.js') const plugin = require('../lib/plugins/user.js') // Necessary Dependencies/Configurations for Brevo Transac Email const crypto = require('crypto') const SibApiV3Sdk = require('sib-api-v3-sdk') const defaultClient = SibApiV3Sdk.ApiClient.instance const apiKey = defaultClient.authentications['api-key'] apiKey.apiKey = process.env.BREVO_KEY const apiInstance = new SibApiV3Sdk.TransactionalEmailsApi() // Existing activeSession to test against (should not match) const activeSessions = { 'a;lsdkfja;ldfjka;ldfja;lskjdfa;dfjk': { email: 'test@testemail.com', name: 'john_doe', seeking: 'position', sessionToken: 'efasdf;laksdfja;lkdjfa;lkdjf', expiration: Date.now() + 600000, emailWasRespondedTo: false, accessToken: null, }, } let hashedSessionToken = '' const payload = { email: email, name: 'fk', seeking: 'seeker', sessionToken: 'a;slkdjfa;lskdf;asjkdfl;asdf;klj', } const userCredentials = payload const pathToTest = { method: 'POST', url: '/send-email/', payload: JSON.stringify(payload), } test('path /send-email should send test transac email', async t => { /** * Create a new server and register services, * models and routes for testing */ const server = Hapi.server() server.registrations = { 'main-app-plugin': { options: {}, }, } /** * Register Services */ await plugin.register(server) server.services()['userService'] = new UserService(server) server.services()['userService']['activeSessions'] = activeSessions const hashToken = token => { const salt = process.env.APP_SESSION_SALT try { return crypto.createHmac('sha256', salt).update(token).digest('hex') } catch (err) { throw new Error(err.message) } } /** * Sends a Transactional Email via Brevo * @ returns {Object} */ const emailSent = async userCredentials => { hashedSessionToken = hashToken(userCredentials.sessionToken) if (Object.keys(activeSessions).includes(hashedSessionToken)) { return new Error('session already in cache!!') } // Set expiration time for ten minutes from now const duration = 600000 activeSessions[hashedSessionToken] = { email: userCredentials.email, name: userCredentials.name, seeking: userCredentials.seeking, sessionToken: userCredentials.sessionToken, expiration: Date.now() + duration, emailWasRespondedTo: false, accessToken: null, } const sendSmtpEmail = { to: [ { email: userCredentials.email, }, ], templateId: 1, params: { // TODO: Change this in production... link: `localhost:3000/verify/${hashedSessionToken}`, }, } return await apiInstance.sendTransacEmail(sendSmtpEmail).then( data => { return { wasSuccessfull: true, data: data } }, error => { return { wasSuccessfull: false, error: error } }, ) } hashedSessionToken = Object.keys(activeSessions).find(hashedToken => { return activeSessions[`${hashedToken}`].email === userCredentials.email }) stub(server.services()['userService'], 'emailSent').returns( await emailSent(userCredentials), ) const mockReturn = { emailSentSuccessfully: true, hashedSessionToken, } /** * Test the server with registered models and services */ const { payload } = await server.inject(pathToTest) const res = JSON.parse(payload) t.deepEqual(res.ok, true) t.deepEqual(res.data, mockReturn) server.stop() })