From 9f6d2d9d3af4718eaf7f198df93f09c5a927572f Mon Sep 17 00:00:00 2001 From: Kristaps Fabians Geikins Date: Tue, 10 Sep 2024 14:26:06 +0300 Subject: [PATCH] chore(server): emails IoC 6 - sendVerificationEmailFactory --- .../core/graph/resolvers/userEmails.ts | 6 ++- .../server/modules/core/services/users.js | 6 ++- .../integration/userEmails.graph.spec.ts | 6 ++- .../core/tests/integration/userEmails.spec.ts | 6 ++- .../modules/core/tests/usersGraphql.spec.ts | 6 ++- .../modules/emails/graph/resolvers/index.ts | 6 ++- .../emails/services/verification/request.ts | 49 ++++++++++++------- .../emails/tests/verifications.spec.ts | 6 ++- .../graph/resolvers/serverInvites.ts | 6 ++- .../workspaces/graph/resolvers/workspaces.ts | 6 ++- 10 files changed, 75 insertions(+), 28 deletions(-) diff --git a/packages/server/modules/core/graph/resolvers/userEmails.ts b/packages/server/modules/core/graph/resolvers/userEmails.ts index 613204d40..bac38f0f2 100644 --- a/packages/server/modules/core/graph/resolvers/userEmails.ts +++ b/packages/server/modules/core/graph/resolvers/userEmails.ts @@ -18,12 +18,16 @@ import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userE import { getUser } from '@/modules/core/repositories/users' import { getServerInfo } from '@/modules/core/services/generic' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) export = { diff --git a/packages/server/modules/core/services/users.js b/packages/server/modules/core/services/users.js index 6ab66be8a..8d269d0ca 100644 --- a/packages/server/modules/core/services/users.js +++ b/packages/server/modules/core/services/users.js @@ -56,6 +56,8 @@ const { const { deleteOldAndInsertNewVerificationFactory } = require('@/modules/emails/repositories') +const { renderEmail } = require('@/modules/emails/services/emailRendering') +const { sendEmail } = require('@/modules/emails/services/sending') const _changeUserRole = async ({ userId, role }) => await Acl().where({ userId }).update({ role }) @@ -77,7 +79,9 @@ const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) module.exports = { diff --git a/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts b/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts index 4b06e5ebb..92a62abed 100644 --- a/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts +++ b/packages/server/modules/core/tests/integration/userEmails.graph.spec.ts @@ -28,12 +28,16 @@ import { import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' import { getServerInfo } from '@/modules/core/services/generic' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) const createUserEmail = validateAndCreateUserEmailFactory({ diff --git a/packages/server/modules/core/tests/integration/userEmails.spec.ts b/packages/server/modules/core/tests/integration/userEmails.spec.ts index cfb2186c2..8681684a7 100644 --- a/packages/server/modules/core/tests/integration/userEmails.spec.ts +++ b/packages/server/modules/core/tests/integration/userEmails.spec.ts @@ -39,12 +39,16 @@ import { import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' import { getServerInfo } from '@/modules/core/services/generic' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) const createUserEmail = validateAndCreateUserEmailFactory({ diff --git a/packages/server/modules/core/tests/usersGraphql.spec.ts b/packages/server/modules/core/tests/usersGraphql.spec.ts index 69cd63a59..5024d79c3 100644 --- a/packages/server/modules/core/tests/usersGraphql.spec.ts +++ b/packages/server/modules/core/tests/usersGraphql.spec.ts @@ -33,12 +33,16 @@ import { requestNewEmailVerificationFactory } from '@/modules/emails/services/ve import { getUser } from '@/modules/core/repositories/users' import { getServerInfo } from '@/modules/core/services/generic' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) const createUserEmail = validateAndCreateUserEmailFactory({ diff --git a/packages/server/modules/emails/graph/resolvers/index.ts b/packages/server/modules/emails/graph/resolvers/index.ts index 77e13f0b9..4c4cdd858 100644 --- a/packages/server/modules/emails/graph/resolvers/index.ts +++ b/packages/server/modules/emails/graph/resolvers/index.ts @@ -7,13 +7,17 @@ import { deleteOldAndInsertNewVerificationFactory, getPendingTokenFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' import { requestEmailVerificationFactory } from '@/modules/emails/services/verification/request' const requestEmailVerification = requestEmailVerificationFactory({ getUser, getServerInfo, deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), - findPrimaryEmailForUser: findPrimaryEmailForUserFactory({ db }) + findPrimaryEmailForUser: findPrimaryEmailForUserFactory({ db }), + sendEmail, + renderEmail }) export = { diff --git a/packages/server/modules/emails/services/verification/request.ts b/packages/server/modules/emails/services/verification/request.ts index 79ef53e13..d82aa362e 100644 --- a/packages/server/modules/emails/services/verification/request.ts +++ b/packages/server/modules/emails/services/verification/request.ts @@ -152,29 +152,36 @@ function buildEmailTemplateParams(verificationId: string): EmailTemplateParams { } } -async function sendVerificationEmail(state: VerificationRequestContext) { - const emailTemplateParams = buildEmailTemplateParams(state.verificationId) - const { html, text } = await renderEmail( - emailTemplateParams, - state.serverInfo, - // im deliberately setting this to null, so that the email will not show the unsubscribe bit - null - ) - await sendEmail({ - to: state.email.email, - subject: EMAIL_SUBJECT, - text, - html - }) +type SendVerificationEmailDeps = { + sendEmail: typeof sendEmail + renderEmail: typeof renderEmail } +const sendVerificationEmailFactory = + (deps: SendVerificationEmailDeps) => async (state: VerificationRequestContext) => { + const emailTemplateParams = buildEmailTemplateParams(state.verificationId) + const { html, text } = await deps.renderEmail( + emailTemplateParams, + state.serverInfo, + // im deliberately setting this to null, so that the email will not show the unsubscribe bit + null + ) + await deps.sendEmail({ + to: state.email.email, + subject: EMAIL_SUBJECT, + text, + html + }) + } + /** * Request email verification (send out verification message) for user with specified ID */ export const requestEmailVerificationFactory = - (deps: CreateNewVerificationDeps) => async (userId: string) => { + (deps: CreateNewVerificationDeps & SendVerificationEmailDeps) => + async (userId: string) => { const newVerificationState = await createNewVerificationFactory(deps)(userId) - await sendVerificationEmail(newVerificationState) + await sendVerificationEmailFactory(deps)(newVerificationState) } /** @@ -191,7 +198,9 @@ export function initializeVerificationOnRegistration() { deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), - findPrimaryEmailForUser: findPrimaryEmailForUserFactory({ db }) + findPrimaryEmailForUser: findPrimaryEmailForUserFactory({ db }), + sendEmail, + renderEmail }) await requestEmailVerification(user.id) @@ -201,10 +210,12 @@ export function initializeVerificationOnRegistration() { type RequestNewEmailVerificationDeps = CreateNewEmailVerificationFactoryDeps export const requestNewEmailVerificationFactory = - (deps: RequestNewEmailVerificationDeps): RequestNewEmailVerification => + ( + deps: RequestNewEmailVerificationDeps & SendVerificationEmailDeps + ): RequestNewEmailVerification => async (emailId) => { const createNewEmailVerification = createNewEmailVerificationFactory(deps) const newVerificationState = await createNewEmailVerification(emailId) - await sendVerificationEmail(newVerificationState) + await sendVerificationEmailFactory(deps)(newVerificationState) } diff --git a/packages/server/modules/emails/tests/verifications.spec.ts b/packages/server/modules/emails/tests/verifications.spec.ts index 605141f75..d2bbfba13 100644 --- a/packages/server/modules/emails/tests/verifications.spec.ts +++ b/packages/server/modules/emails/tests/verifications.spec.ts @@ -27,6 +27,8 @@ import { db } from '@/db/knex' import { requestEmailVerificationFactory } from '@/modules/emails/services/verification/request' import { getServerInfo } from '@/modules/core/services/generic' import { findPrimaryEmailForUserFactory } from '@/modules/core/repositories/userEmails' +import { sendEmail } from '@/modules/emails/services/sending' +import { renderEmail } from '@/modules/emails/services/emailRendering' const mailerMock = EmailSendingServiceMock const getPendingToken = getPendingTokenFactory({ db }) @@ -37,7 +39,9 @@ const requestEmailVerification = requestEmailVerificationFactory({ deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), - findPrimaryEmailForUser: findPrimaryEmailForUserFactory({ db }) + findPrimaryEmailForUser: findPrimaryEmailForUserFactory({ db }), + sendEmail, + renderEmail }) const cleanup = async () => { diff --git a/packages/server/modules/serverinvites/graph/resolvers/serverInvites.ts b/packages/server/modules/serverinvites/graph/resolvers/serverInvites.ts index b37f27a0e..8a26b66f6 100644 --- a/packages/server/modules/serverinvites/graph/resolvers/serverInvites.ts +++ b/packages/server/modules/serverinvites/graph/resolvers/serverInvites.ts @@ -69,12 +69,16 @@ import { validateAndCreateUserEmailFactory } from '@/modules/core/services/userE import { getServerInfo } from '@/modules/core/services/generic' import { requestNewEmailVerificationFactory } from '@/modules/emails/services/verification/request' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) const buildCollectAndValidateResourceTargets = () => diff --git a/packages/server/modules/workspaces/graph/resolvers/workspaces.ts b/packages/server/modules/workspaces/graph/resolvers/workspaces.ts index dfe9273be..c4741c20e 100644 --- a/packages/server/modules/workspaces/graph/resolvers/workspaces.ts +++ b/packages/server/modules/workspaces/graph/resolvers/workspaces.ts @@ -125,12 +125,16 @@ import { getServerInfo } from '@/modules/core/services/generic' import { mapWorkspaceRoleToInitialProjectRole } from '@/modules/workspaces/domain/logic' import { updateStreamRoleAndNotify } from '@/modules/core/services/streams/management' import { deleteOldAndInsertNewVerificationFactory } from '@/modules/emails/repositories' +import { renderEmail } from '@/modules/emails/services/emailRendering' +import { sendEmail } from '@/modules/emails/services/sending' const requestNewEmailVerification = requestNewEmailVerificationFactory({ findEmail: findEmailFactory({ db }), getUser, getServerInfo, - deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }) + deleteOldAndInsertNewVerification: deleteOldAndInsertNewVerificationFactory({ db }), + renderEmail, + sendEmail }) const buildCollectAndValidateResourceTargets = () =>