From 3ef4d94aaeedc086cd2db3e6bdd192fdc8386ff9 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 4 Jan 2022 18:04:06 +0100 Subject: [PATCH 01/11] feat: Test Send Email --- backend/src/util/sendEMail.test.ts | 85 ++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 backend/src/util/sendEMail.test.ts diff --git a/backend/src/util/sendEMail.test.ts b/backend/src/util/sendEMail.test.ts new file mode 100644 index 000000000..60b338974 --- /dev/null +++ b/backend/src/util/sendEMail.test.ts @@ -0,0 +1,85 @@ +import { sendEMail } from './sendEMail' +import { createTransport } from 'nodemailer' +import CONFIG from '../config' + +CONFIG.EMAIL = false +CONFIG.EMAIL_SMTP_URL = 'EMAIL_SMTP_URL' +CONFIG.EMAIL_SMTP_PORT = '1234' +CONFIG.EMAIL_USERNAME = 'user' +CONFIG.EMAIL_PASSWORD = 'pwd' + +jest.mock('nodemailer', () => { + return { + __esModule: true, + createTransport: jest.fn(() => { + return { + sendMail: jest.fn(() => { + return { + messageId: 'message', + } + }), + } + }), + } +}) + +describe('sendEMail', () => { + let result: boolean + describe('config email is false', () => { + // eslint-disable-next-line no-console + const consoleLog = console.log + const consoleLogMock = jest.fn() + // eslint-disable-next-line no-console + console.log = consoleLogMock + beforeEach(async () => { + result = await sendEMail({ + from: 'sender@mail.org', + to: 'receiver@mail.org', + subject: 'Subject', + text: 'Text text text', + }) + }) + + afterAll(() => { + // eslint-disable-next-line no-console + console.log = consoleLog + }) + + it('logs warining to console', () => { + expect(consoleLogMock).toBeCalledWith('Emails are disabled via config') + }) + + it('returns false', () => { + expect(result).toBeFalsy() + }) + }) + + describe('config email is true', () => { + beforeEach(async () => { + CONFIG.EMAIL = true + result = await sendEMail({ + from: 'sender@mail.org', + to: 'receiver@mail.org', + subject: 'Subject', + text: 'Text text text', + }) + }) + + it('calls the transporter', () => { + expect(createTransport).toBeCalledWith({ + host: 'EMAIL_SMTP_URL', + port: 1234, + secure: false, + requireTLS: true, + auth: { + user: 'user', + pass: 'pwd', + }, + }) + }) + + it('returns true', () => { + expect(result).toBeTruthy() + }) + }) +}) From b7186209f1669bc431668761a9cc341ba2c80607 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 4 Jan 2022 18:37:59 +0100 Subject: [PATCH 02/11] sendAccountActivationEmail as imprted function --- .../src/graphql/resolver/UserResolver.test.ts | 20 +++++------ backend/src/graphql/resolver/UserResolver.ts | 34 ++----------------- backend/src/util/sendEMail.ts | 27 ++++++++++++++- 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index d0c144e22..6944215d9 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -12,12 +12,12 @@ import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' import CONFIG from '../../config' -import { sendEMail } from '../../util/sendEMail' +import { sendAccountActivationEmail } from '../../util/sendEMail' jest.mock('../../util/sendEMail', () => { return { __esModule: true, - sendEMail: jest.fn(), + sendAccountActivationEmail: jest.fn(), } }) @@ -62,7 +62,6 @@ describe('UserResolver', () => { let result: any let emailOptIn: string - let newUser: User beforeAll(async () => { result = await mutate({ mutation, variables }) @@ -90,7 +89,6 @@ describe('UserResolver', () => { loginEmailOptIn = await getRepository(LoginEmailOptIn) .createQueryBuilder('login_email_optin') .getMany() - newUser = user[0] emailOptIn = loginEmailOptIn[0].verificationCode.toString() }) @@ -165,14 +163,12 @@ describe('UserResolver', () => { describe('account activation email', () => { it('sends an account activation email', () => { const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(/\$1/g, emailOptIn) - expect(sendEMail).toBeCalledWith({ - from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, - to: `${newUser.firstName} ${newUser.lastName} <${newUser.email}>`, - subject: 'Gradido: E-Mail Überprüfung', - text: - expect.stringContaining(`Hallo ${newUser.firstName} ${newUser.lastName},`) && - expect.stringContaining(activationLink), - }) + expect(sendAccountActivationEmail).toBeCalledWith( + activationLink, + 'Peter', + 'Lustig', + 'peter@lustig.de', + ) }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 2f98a2f6f..0d3a48ddf 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -20,7 +20,7 @@ import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' -import { sendEMail } from '../../util/sendEMail' +import { sendAccountActivationEmail, sendEMail } from '../../util/sendEMail' import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys' import { signIn } from '../../apis/KlicktippController' import { RIGHTS } from '../../auth/RIGHTS' @@ -450,12 +450,7 @@ export class UserResolver { /\$1/g, emailOptIn.verificationCode.toString(), ) - const emailSent = await this.sendAccountActivationEmail( - activationLink, - firstName, - lastName, - email, - ) + const emailSent = await sendAccountActivationEmail(activationLink, firstName, lastName, email) // In case EMails are disabled log the activation link for the user if (!emailSent) { @@ -472,29 +467,6 @@ export class UserResolver { return 'success' } - private sendAccountActivationEmail( - activationLink: string, - firstName: string, - lastName: string, - email: string, - ): Promise { - return sendEMail({ - from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, - to: `${firstName} ${lastName} <${email}>`, - subject: 'Gradido: E-Mail Überprüfung', - text: `Hallo ${firstName} ${lastName}, - - Deine EMail wurde soeben bei Gradido registriert. - - Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: - ${activationLink} - oder kopiere den obigen Link in dein Browserfenster. - - Mit freundlichen Grüßen, - dein Gradido-Team`, - }) - } - @Mutation(() => Boolean) async sendActivationEmail(@Arg('email') email: string): Promise { const loginUserRepository = getCustomRepository(LoginUserRepository) @@ -512,7 +484,7 @@ export class UserResolver { emailOptIn.verificationCode.toString(), ) - const emailSent = await this.sendAccountActivationEmail( + const emailSent = await sendAccountActivationEmail( activationLink, loginUser.firstName, loginUser.lastName, diff --git a/backend/src/util/sendEMail.ts b/backend/src/util/sendEMail.ts index 4c239980d..0221c001c 100644 --- a/backend/src/util/sendEMail.ts +++ b/backend/src/util/sendEMail.ts @@ -2,7 +2,7 @@ import { createTransport } from 'nodemailer' import CONFIG from '../config' -export const sendEMail = async (emailDef: { +const sendEMail = async (emailDef: { from: string to: string subject: string @@ -29,3 +29,28 @@ export const sendEMail = async (emailDef: { } return true } + +const sendAccountActivationEmail = ( + activationLink: string, + firstName: string, + lastName: string, + email: string, +): Promise => { + return sendEMail({ + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + to: `${firstName} ${lastName} <${email}>`, + subject: 'Gradido: E-Mail Überprüfung', + text: `Hallo ${firstName} ${lastName}, + + Deine EMail wurde soeben bei Gradido registriert. + + Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: + ${activationLink} + oder kopiere den obigen Link in dein Browserfenster. + + Mit freundlichen Grüßen, + dein Gradido-Team`, + }) +} + +export { sendAccountActivationEmail, sendEMail } From 055a9c9d80a8a7e7c9e239fd930879820065128d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Tue, 4 Jan 2022 19:18:05 +0100 Subject: [PATCH 03/11] try to test send verification email --- backend/src/util/sendEMail.test.ts | 32 +++++++++++++++++++++++++++--- backend/src/util/sendEMail.ts | 6 +++--- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/backend/src/util/sendEMail.test.ts b/backend/src/util/sendEMail.test.ts index 60b338974..76f7ad016 100644 --- a/backend/src/util/sendEMail.test.ts +++ b/backend/src/util/sendEMail.test.ts @@ -1,4 +1,4 @@ -import { sendEMail } from './sendEMail' +import sendEmail from './sendEMail' import { createTransport } from 'nodemailer' import CONFIG from '../config' @@ -32,7 +32,7 @@ describe('sendEMail', () => { // eslint-disable-next-line no-console console.log = consoleLogMock beforeEach(async () => { - result = await sendEMail({ + result = await sendEmail.sendEMail({ from: 'sender@mail.org', to: 'receiver@mail.org', subject: 'Subject', @@ -57,7 +57,7 @@ describe('sendEMail', () => { describe('config email is true', () => { beforeEach(async () => { CONFIG.EMAIL = true - result = await sendEMail({ + result = await sendEmail.sendEMail({ from: 'sender@mail.org', to: 'receiver@mail.org', subject: 'Subject', @@ -83,3 +83,29 @@ describe('sendEMail', () => { }) }) }) + +describe('sendAccountActivationEmail', () => { + const spy = jest.spyOn(sendEmail, 'sendEMail') + beforeEach(async () => { + jest.clearAllMocks() + await sendEmail.sendAccountActivationEmail( + 'activationLink', + 'Petet', + 'Lustig', + 'peter@lustig.de', + ) + }) + + it.skip('calls sendEMail', () => { + expect(spy).toBeCalledWith( + expect.objectContaining({ + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + to: `Peter Lustig `, + subject: 'Gradido: E-Mail Überprüfung', + text: + expect.stringContaining('Hallo Peter Lustig') && + expect.stringContaining('activationLink'), + }), + ) + }) +}) diff --git a/backend/src/util/sendEMail.ts b/backend/src/util/sendEMail.ts index 0221c001c..5ef2117b7 100644 --- a/backend/src/util/sendEMail.ts +++ b/backend/src/util/sendEMail.ts @@ -2,7 +2,7 @@ import { createTransport } from 'nodemailer' import CONFIG from '../config' -const sendEMail = async (emailDef: { +export const sendEMail = async (emailDef: { from: string to: string subject: string @@ -30,7 +30,7 @@ const sendEMail = async (emailDef: { return true } -const sendAccountActivationEmail = ( +export const sendAccountActivationEmail = ( activationLink: string, firstName: string, lastName: string, @@ -53,4 +53,4 @@ const sendAccountActivationEmail = ( }) } -export { sendAccountActivationEmail, sendEMail } +export default { sendAccountActivationEmail, sendEMail } From b95eb902e95b7286e73032c998936f7a959ef0bb Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 09:54:34 +0100 Subject: [PATCH 04/11] move mailer functions into own folder --- backend/src/graphql/resolver/TransactionResolver.ts | 2 +- backend/src/graphql/resolver/UserResolver.ts | 2 +- backend/src/{util => mailer}/sendEMail.test.ts | 0 backend/src/{util => mailer}/sendEMail.ts | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename backend/src/{util => mailer}/sendEMail.test.ts (100%) rename backend/src/{util => mailer}/sendEMail.ts (100%) diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 88c1424b3..0782417be 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -6,7 +6,7 @@ import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql' import { getCustomRepository, getConnection, QueryRunner } from 'typeorm' import CONFIG from '../../config' -import { sendEMail } from '../../util/sendEMail' +import { sendEMail } from '../../mailer/sendEMail' import { Transaction } from '../model/Transaction' import { TransactionList } from '../model/TransactionList' diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 58d043538..de0ad7143 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -20,7 +20,7 @@ import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' -import { sendAccountActivationEmail, sendEMail } from '../../util/sendEMail' +import { sendAccountActivationEmail, sendEMail } from '../../mailer/sendEMail' import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys' import { signIn } from '../../apis/KlicktippController' import { RIGHTS } from '../../auth/RIGHTS' diff --git a/backend/src/util/sendEMail.test.ts b/backend/src/mailer/sendEMail.test.ts similarity index 100% rename from backend/src/util/sendEMail.test.ts rename to backend/src/mailer/sendEMail.test.ts diff --git a/backend/src/util/sendEMail.ts b/backend/src/mailer/sendEMail.ts similarity index 100% rename from backend/src/util/sendEMail.ts rename to backend/src/mailer/sendEMail.ts From c6863d6e64642c59fb9794aab9657393545d7ecb Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 11:02:49 +0100 Subject: [PATCH 05/11] sendAccountActivationEmail in separate file --- .../graphql/resolver/TransactionResolver.ts | 1 - .../src/graphql/resolver/UserResolver.test.ts | 4 +-- backend/src/graphql/resolver/UserResolver.ts | 4 +-- .../mailer/sendAccountActivationEmail.test.ts | 24 +++++++++++++ .../src/mailer/sendAccountActivationEmail.ts | 23 +++++++++++++ backend/src/mailer/sendEMail.test.ts | 34 ++----------------- backend/src/mailer/sendEMail.ts | 31 +++-------------- 7 files changed, 58 insertions(+), 63 deletions(-) create mode 100644 backend/src/mailer/sendAccountActivationEmail.test.ts create mode 100644 backend/src/mailer/sendAccountActivationEmail.ts diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 0782417be..40c836b1b 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -652,7 +652,6 @@ export class TransactionResolver { // send notification email // TODO: translate await sendEMail({ - from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, to: `${recipiantUser.firstName} ${recipiantUser.lastName} <${recipiantUser.email}>`, subject: 'Gradido Überweisung', text: `Hallo ${recipiantUser.firstName} ${recipiantUser.lastName} diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 6944215d9..0348a4c4e 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -12,9 +12,9 @@ import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' import CONFIG from '../../config' -import { sendAccountActivationEmail } from '../../util/sendEMail' +import { sendAccountActivationEmail } from '../../mailer/sendAccountActivationEmail' -jest.mock('../../util/sendEMail', () => { +jest.mock('../../mailer/sendAccountActivationEmail', () => { return { __esModule: true, sendAccountActivationEmail: jest.fn(), diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index de0ad7143..5857a15ed 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -20,7 +20,8 @@ import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' -import { sendAccountActivationEmail, sendEMail } from '../../mailer/sendEMail' +import { sendEMail } from '../../mailer/sendEMail' +import { sendAccountActivationEmail } from '../../mailer/sendAccountActivationEmail' import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys' import { signIn } from '../../apis/KlicktippController' import { RIGHTS } from '../../auth/RIGHTS' @@ -522,7 +523,6 @@ export class UserResolver { ) const emailSent = await sendEMail({ - from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, to: `${loginUser.firstName} ${loginUser.lastName} <${email}>`, subject: 'Gradido: Reset Password', text: `Hallo ${loginUser.firstName} ${loginUser.lastName}, diff --git a/backend/src/mailer/sendAccountActivationEmail.test.ts b/backend/src/mailer/sendAccountActivationEmail.test.ts new file mode 100644 index 000000000..e1c41b088 --- /dev/null +++ b/backend/src/mailer/sendAccountActivationEmail.test.ts @@ -0,0 +1,24 @@ +import { sendAccountActivationEmail } from './sendAccountActivationEmail' +import { sendEMail } from './sendEMail' + +jest.mock('./sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) + +describe('sendAccountActivationEmail', () => { + beforeEach(async () => { + await sendAccountActivationEmail('activationLink', 'Peter', 'Lustig', 'peter@lustig.de') + }) + + it('calls sendEMail', () => { + expect(sendEMail).toBeCalledWith({ + to: `Peter Lustig `, + subject: 'Gradido: E-Mail Überprüfung', + text: + expect.stringContaining('Hallo Peter Lustig') && expect.stringContaining('activationLink'), + }) + }) +}) diff --git a/backend/src/mailer/sendAccountActivationEmail.ts b/backend/src/mailer/sendAccountActivationEmail.ts new file mode 100644 index 000000000..4252eac46 --- /dev/null +++ b/backend/src/mailer/sendAccountActivationEmail.ts @@ -0,0 +1,23 @@ +import { sendEMail } from './sendEMail' + +export const sendAccountActivationEmail = ( + activationLink: string, + firstName: string, + lastName: string, + email: string, +): Promise => { + return sendEMail({ + to: `${firstName} ${lastName} <${email}>`, + subject: 'Gradido: E-Mail Überprüfung', + text: `Hallo ${firstName} ${lastName}, + +Deine EMail wurde soeben bei Gradido registriert. + +Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: +${activationLink} +oder kopiere den obigen Link in dein Browserfenster. + +Mit freundlichen Grüßen, +dein Gradido-Team`, + }) +} diff --git a/backend/src/mailer/sendEMail.test.ts b/backend/src/mailer/sendEMail.test.ts index 76f7ad016..f933dd9b3 100644 --- a/backend/src/mailer/sendEMail.test.ts +++ b/backend/src/mailer/sendEMail.test.ts @@ -1,4 +1,4 @@ -import sendEmail from './sendEMail' +import { sendEMail } from './sendEMail' import { createTransport } from 'nodemailer' import CONFIG from '../config' @@ -32,8 +32,7 @@ describe('sendEMail', () => { // eslint-disable-next-line no-console console.log = consoleLogMock beforeEach(async () => { - result = await sendEmail.sendEMail({ - from: 'sender@mail.org', + result = await sendEMail({ to: 'receiver@mail.org', subject: 'Subject', text: 'Text text text', @@ -57,8 +56,7 @@ describe('sendEMail', () => { describe('config email is true', () => { beforeEach(async () => { CONFIG.EMAIL = true - result = await sendEmail.sendEMail({ - from: 'sender@mail.org', + result = await sendEMail({ to: 'receiver@mail.org', subject: 'Subject', text: 'Text text text', @@ -83,29 +81,3 @@ describe('sendEMail', () => { }) }) }) - -describe('sendAccountActivationEmail', () => { - const spy = jest.spyOn(sendEmail, 'sendEMail') - beforeEach(async () => { - jest.clearAllMocks() - await sendEmail.sendAccountActivationEmail( - 'activationLink', - 'Petet', - 'Lustig', - 'peter@lustig.de', - ) - }) - - it.skip('calls sendEMail', () => { - expect(spy).toBeCalledWith( - expect.objectContaining({ - from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, - to: `Peter Lustig `, - subject: 'Gradido: E-Mail Überprüfung', - text: - expect.stringContaining('Hallo Peter Lustig') && - expect.stringContaining('activationLink'), - }), - ) - }) -}) diff --git a/backend/src/mailer/sendEMail.ts b/backend/src/mailer/sendEMail.ts index 5ef2117b7..e26589347 100644 --- a/backend/src/mailer/sendEMail.ts +++ b/backend/src/mailer/sendEMail.ts @@ -3,7 +3,6 @@ import { createTransport } from 'nodemailer' import CONFIG from '../config' export const sendEMail = async (emailDef: { - from: string to: string subject: string text: string @@ -23,34 +22,12 @@ export const sendEMail = async (emailDef: { pass: CONFIG.EMAIL_PASSWORD, }, }) - const info = await transporter.sendMail(emailDef) + const info = await transporter.sendMail({ + ...emailDef, + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + }) if (!info.messageId) { throw new Error('error sending notification email, but transaction succeed') } return true } - -export const sendAccountActivationEmail = ( - activationLink: string, - firstName: string, - lastName: string, - email: string, -): Promise => { - return sendEMail({ - from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, - to: `${firstName} ${lastName} <${email}>`, - subject: 'Gradido: E-Mail Überprüfung', - text: `Hallo ${firstName} ${lastName}, - - Deine EMail wurde soeben bei Gradido registriert. - - Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: - ${activationLink} - oder kopiere den obigen Link in dein Browserfenster. - - Mit freundlichen Grüßen, - dein Gradido-Team`, - }) -} - -export default { sendAccountActivationEmail, sendEMail } From fb53a0bcb042694ba52c48c20c62d9000371f122 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 11:36:17 +0100 Subject: [PATCH 06/11] extract reset password email --- backend/src/graphql/resolver/UserResolver.ts | 20 ++++++---------- .../src/mailer/sendResetPasswordEmail.test.ts | 23 +++++++++++++++++++ backend/src/mailer/sendResetPasswordEmail.ts | 21 +++++++++++++++++ 3 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 backend/src/mailer/sendResetPasswordEmail.test.ts create mode 100644 backend/src/mailer/sendResetPasswordEmail.ts diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 5857a15ed..bf2274c7e 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -20,7 +20,7 @@ import { UserRepository } from '../../typeorm/repository/User' import { LoginUser } from '@entity/LoginUser' import { LoginUserBackup } from '@entity/LoginUserBackup' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' -import { sendEMail } from '../../mailer/sendEMail' +import { sendResetPasswordEmail } from '../../mailer/sendResetPasswordEmail' import { sendAccountActivationEmail } from '../../mailer/sendAccountActivationEmail' import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys' import { signIn } from '../../apis/KlicktippController' @@ -522,18 +522,12 @@ export class UserResolver { optInCode.verificationCode.toString(), ) - const emailSent = await sendEMail({ - to: `${loginUser.firstName} ${loginUser.lastName} <${email}>`, - subject: 'Gradido: Reset Password', - text: `Hallo ${loginUser.firstName} ${loginUser.lastName}, - - Du oder jemand anderes hat für dieses Konto ein Zurücksetzen des Passworts angefordert. - Wenn du es warst, klicke bitte auf den Link: ${link} - oder kopiere den obigen Link in Dein Browserfenster. - - Mit freundlichen Grüßen, - dein Gradido-Team`, - }) + const emailSent = await sendResetPasswordEmail( + link, + loginUser.firstName, + loginUser.lastName, + email, + ) // In case EMails are disabled log the activation link for the user if (!emailSent) { diff --git a/backend/src/mailer/sendResetPasswordEmail.test.ts b/backend/src/mailer/sendResetPasswordEmail.test.ts new file mode 100644 index 000000000..18eaaf179 --- /dev/null +++ b/backend/src/mailer/sendResetPasswordEmail.test.ts @@ -0,0 +1,23 @@ +import { sendResetPasswordEmail } from './sendResetPasswordEmail' +import { sendEMail } from './sendEMail' + +jest.mock('./sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) + +describe('sendResetPasswordEmail', () => { + beforeEach(async () => { + await sendResetPasswordEmail('resetLink', 'Peter', 'Lustig', 'peter@lustig.de') + }) + + it('calls sendEMail', () => { + expect(sendEMail).toBeCalledWith({ + to: `Peter Lustig `, + subject: 'Gradido: Reset Password', + text: expect.stringContaining('Hallo Peter Lustig') && expect.stringContaining('resetLink'), + }) + }) +}) diff --git a/backend/src/mailer/sendResetPasswordEmail.ts b/backend/src/mailer/sendResetPasswordEmail.ts new file mode 100644 index 000000000..7cf9e7f23 --- /dev/null +++ b/backend/src/mailer/sendResetPasswordEmail.ts @@ -0,0 +1,21 @@ +import { sendEMail } from './sendEMail' + +export const sendResetPasswordEmail = ( + resetLink: string, + firstName: string, + lastName: string, + email: string, +): Promise => { + return sendEMail({ + to: `${firstName} ${lastName} <${email}>`, + subject: 'Gradido: Reset Password', + text: `Hallo ${firstName} ${lastName}, + +Du oder jemand anderes hat für dieses Konto ein Zurücksetzen des Passworts angefordert. +Wenn du es warst, klicke bitte auf den Link: ${resetLink} +oder kopiere den obigen Link in Dein Browserfenster. + +Mit freundlichen Grüßen, +dein Gradido-Team`, + }) +} From ce9d4b2ca8a02ef8f6819cb96b5112cae1ed3878 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 12:05:44 +0100 Subject: [PATCH 07/11] extract sendTransactionReceivedEmail --- .../graphql/resolver/TransactionResolver.ts | 24 +++++-------- .../sendTransactionReceivedEmail.test.ts | 35 +++++++++++++++++++ .../mailer/sendTransactionReceivedEmail.ts | 29 +++++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 backend/src/mailer/sendTransactionReceivedEmail.test.ts create mode 100644 backend/src/mailer/sendTransactionReceivedEmail.ts diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 40c836b1b..871e1b9d6 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -6,7 +6,7 @@ import { Resolver, Query, Args, Authorized, Ctx, Mutation } from 'type-graphql' import { getCustomRepository, getConnection, QueryRunner } from 'typeorm' import CONFIG from '../../config' -import { sendEMail } from '../../mailer/sendEMail' +import { sendTransactionReceivedEmail } from '../../mailer/sendTransactionReceivedEmail' import { Transaction } from '../model/Transaction' import { TransactionList } from '../model/TransactionList' @@ -651,20 +651,14 @@ export class TransactionResolver { } // send notification email // TODO: translate - await sendEMail({ - to: `${recipiantUser.firstName} ${recipiantUser.lastName} <${recipiantUser.email}>`, - subject: 'Gradido Überweisung', - text: `Hallo ${recipiantUser.firstName} ${recipiantUser.lastName} - - Du hast soeben ${amount} GDD von ${senderUser.firstName} ${senderUser.lastName} erhalten. - ${senderUser.firstName} ${senderUser.lastName} schreibt: - - ${memo} - - Bitte antworte nicht auf diese E-Mail! - - Mit freundlichen Grüßen, - dein Gradido-Team`, + await sendTransactionReceivedEmail({ + senderFirstName: senderUser.firstName, + senderLastName: senderUser.lastName, + recipientFirstName: recipiantUser.firstName, + recipientLastName: recipiantUser.lastName, + email: recipiantUser.email, + amount, + memo, }) return 'success' diff --git a/backend/src/mailer/sendTransactionReceivedEmail.test.ts b/backend/src/mailer/sendTransactionReceivedEmail.test.ts new file mode 100644 index 000000000..7b4080622 --- /dev/null +++ b/backend/src/mailer/sendTransactionReceivedEmail.test.ts @@ -0,0 +1,35 @@ +import { sendTransactionReceivedEmail } from './sendTransactionReceivedEmail' +import { sendEMail } from './sendEMail' + +jest.mock('./sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) + +describe('sendTransactionReceivedEmail', () => { + beforeEach(async () => { + await sendTransactionReceivedEmail({ + senderFirstName: 'Bibi', + senderLastName: 'Bloxberg', + recipientFirstName: 'Peter', + recipientLastName: 'Lustig', + email: 'peter@lustig.de', + amount: 42.0, + memo: 'Vielen herzlichen Dank für den neuen Hexenbesen!', + }) + }) + + it('calls sendEMail', () => { + expect(sendEMail).toBeCalledWith({ + to: `Peter Lustig `, + subject: 'Gradido Überweisung', + text: + expect.stringContaining('Hallo Peter Lustig') && + expect.stringContaining('42,00') && + expect.stringContaining('Bibi Bloxberg') && + expect.stringContaining('Vielen herzlichen Dank für den neuen Hexenbesen!'), + }) + }) +}) diff --git a/backend/src/mailer/sendTransactionReceivedEmail.ts b/backend/src/mailer/sendTransactionReceivedEmail.ts new file mode 100644 index 000000000..51f8ef45c --- /dev/null +++ b/backend/src/mailer/sendTransactionReceivedEmail.ts @@ -0,0 +1,29 @@ +import { sendEMail } from './sendEMail' + +export const sendTransactionReceivedEmail = (data: { + senderFirstName: string + senderLastName: string + recipientFirstName: string + recipientLastName: string + email: string + amount: number + memo: string +}): Promise => { + return sendEMail({ + to: `${data.recipientFirstName} ${data.recipientLastName} <${data.email}>`, + subject: 'Gradido Überweisung', + text: `Hallo ${data.recipientFirstName} ${data.recipientLastName} + +Du hast soeben ${data.amount.toFixed(2).replace('.', ',')} GDD von ${data.senderFirstName} ${ + data.senderLastName + } erhalten. +${data.senderFirstName} ${data.senderLastName} schreibt: + +${data.memo} + +Bitte antworte nicht auf diese E-Mail! + +Mit freundlichen Grüßen, +dein Gradido-Team`, + }) +} From b1520182a2435783690321d6f070d598f470768d Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 12:13:42 +0100 Subject: [PATCH 08/11] sendResetPasswordEmail with object as arg --- backend/src/graphql/resolver/UserResolver.ts | 8 ++++---- .../src/mailer/sendResetPasswordEmail.test.ts | 7 ++++++- backend/src/mailer/sendResetPasswordEmail.ts | 18 +++++++++--------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index bf2274c7e..b37c69f87 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -522,12 +522,12 @@ export class UserResolver { optInCode.verificationCode.toString(), ) - const emailSent = await sendResetPasswordEmail( + const emailSent = await sendResetPasswordEmail({ link, - loginUser.firstName, - loginUser.lastName, + firstName: loginUser.firstName, + lastName: loginUser.lastName, email, - ) + }) // In case EMails are disabled log the activation link for the user if (!emailSent) { diff --git a/backend/src/mailer/sendResetPasswordEmail.test.ts b/backend/src/mailer/sendResetPasswordEmail.test.ts index 18eaaf179..a384d979a 100644 --- a/backend/src/mailer/sendResetPasswordEmail.test.ts +++ b/backend/src/mailer/sendResetPasswordEmail.test.ts @@ -10,7 +10,12 @@ jest.mock('./sendEMail', () => { describe('sendResetPasswordEmail', () => { beforeEach(async () => { - await sendResetPasswordEmail('resetLink', 'Peter', 'Lustig', 'peter@lustig.de') + await sendResetPasswordEmail({ + link: 'resetLink', + firstName: 'Peter', + lastName: 'Lustig', + email: 'peter@lustig.de', + }) }) it('calls sendEMail', () => { diff --git a/backend/src/mailer/sendResetPasswordEmail.ts b/backend/src/mailer/sendResetPasswordEmail.ts index 7cf9e7f23..ffdc84f41 100644 --- a/backend/src/mailer/sendResetPasswordEmail.ts +++ b/backend/src/mailer/sendResetPasswordEmail.ts @@ -1,18 +1,18 @@ import { sendEMail } from './sendEMail' -export const sendResetPasswordEmail = ( - resetLink: string, - firstName: string, - lastName: string, - email: string, -): Promise => { +export const sendResetPasswordEmail = (data: { + link: string + firstName: string + lastName: string + email: string +}): Promise => { return sendEMail({ - to: `${firstName} ${lastName} <${email}>`, + to: `${data.firstName} ${data.lastName} <${data.email}>`, subject: 'Gradido: Reset Password', - text: `Hallo ${firstName} ${lastName}, + text: `Hallo ${data.firstName} ${data.lastName}, Du oder jemand anderes hat für dieses Konto ein Zurücksetzen des Passworts angefordert. -Wenn du es warst, klicke bitte auf den Link: ${resetLink} +Wenn du es warst, klicke bitte auf den Link: ${data.link} oder kopiere den obigen Link in Dein Browserfenster. Mit freundlichen Grüßen, From c05f32cf5f0bce8d9727d94026b757740227c3c0 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 12:19:45 +0100 Subject: [PATCH 09/11] sendAccountActivationEmail with object as arg --- .../src/graphql/resolver/UserResolver.test.ts | 12 ++++++------ backend/src/graphql/resolver/UserResolver.ts | 17 +++++++++++------ .../mailer/sendAccountActivationEmail.test.ts | 7 ++++++- .../src/mailer/sendAccountActivationEmail.ts | 18 +++++++++--------- 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 0348a4c4e..1f0bce30f 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -163,12 +163,12 @@ describe('UserResolver', () => { describe('account activation email', () => { it('sends an account activation email', () => { const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(/\$1/g, emailOptIn) - expect(sendAccountActivationEmail).toBeCalledWith( - activationLink, - 'Peter', - 'Lustig', - 'peter@lustig.de', - ) + expect(sendAccountActivationEmail).toBeCalledWith({ + link: activationLink, + firstName: 'Peter', + lastName: 'Lustig', + email: 'peter@lustig.de', + }) }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index b37c69f87..b751eb633 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -451,7 +451,12 @@ export class UserResolver { /\$1/g, emailOptIn.verificationCode.toString(), ) - const emailSent = await sendAccountActivationEmail(activationLink, firstName, lastName, email) + const emailSent = await sendAccountActivationEmail({ + link: activationLink, + firstName, + lastName, + email, + }) // In case EMails are disabled log the activation link for the user if (!emailSent) { @@ -485,12 +490,12 @@ export class UserResolver { emailOptIn.verificationCode.toString(), ) - const emailSent = await sendAccountActivationEmail( - activationLink, - loginUser.firstName, - loginUser.lastName, + const emailSent = await sendAccountActivationEmail({ + link: activationLink, + firstName: loginUser.firstName, + lastName: loginUser.lastName, email, - ) + }) // In case EMails are disabled log the activation link for the user if (!emailSent) { diff --git a/backend/src/mailer/sendAccountActivationEmail.test.ts b/backend/src/mailer/sendAccountActivationEmail.test.ts index e1c41b088..c53fc0994 100644 --- a/backend/src/mailer/sendAccountActivationEmail.test.ts +++ b/backend/src/mailer/sendAccountActivationEmail.test.ts @@ -10,7 +10,12 @@ jest.mock('./sendEMail', () => { describe('sendAccountActivationEmail', () => { beforeEach(async () => { - await sendAccountActivationEmail('activationLink', 'Peter', 'Lustig', 'peter@lustig.de') + await sendAccountActivationEmail({ + link: 'activationLink', + firstName: 'Peter', + lastName: 'Lustig', + email: 'peter@lustig.de', + }) }) it('calls sendEMail', () => { diff --git a/backend/src/mailer/sendAccountActivationEmail.ts b/backend/src/mailer/sendAccountActivationEmail.ts index 4252eac46..42d7c54f9 100644 --- a/backend/src/mailer/sendAccountActivationEmail.ts +++ b/backend/src/mailer/sendAccountActivationEmail.ts @@ -1,20 +1,20 @@ import { sendEMail } from './sendEMail' -export const sendAccountActivationEmail = ( - activationLink: string, - firstName: string, - lastName: string, - email: string, -): Promise => { +export const sendAccountActivationEmail = (data: { + link: string + firstName: string + lastName: string + email: string +}): Promise => { return sendEMail({ - to: `${firstName} ${lastName} <${email}>`, + to: `${data.firstName} ${data.lastName} <${data.email}>`, subject: 'Gradido: E-Mail Überprüfung', - text: `Hallo ${firstName} ${lastName}, + text: `Hallo ${data.firstName} ${data.lastName}, Deine EMail wurde soeben bei Gradido registriert. Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: -${activationLink} +${data.link} oder kopiere den obigen Link in dein Browserfenster. Mit freundlichen Grüßen, From 899994c128cd29ddd1919107d2fedb5770b1b0e2 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 12:51:16 +0100 Subject: [PATCH 10/11] improve tests --- .github/workflows/test.yml | 2 +- backend/src/mailer/sendEMail.test.ts | 9 +++++++++ backend/src/mailer/sendTransactionReceivedEmail.test.ts | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 51f8e49b0..e243c9184 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -520,7 +520,7 @@ jobs: report_name: Coverage Backend type: lcov result_path: ./backend/coverage/lcov.info - min_coverage: 40 + min_coverage: 41 token: ${{ github.token }} ############################################################################## diff --git a/backend/src/mailer/sendEMail.test.ts b/backend/src/mailer/sendEMail.test.ts index f933dd9b3..5baae00ab 100644 --- a/backend/src/mailer/sendEMail.test.ts +++ b/backend/src/mailer/sendEMail.test.ts @@ -76,6 +76,15 @@ describe('sendEMail', () => { }) }) + it('calls sendMail of transporter', () => { + expect((createTransport as jest.Mock).mock.results[0].value.sendMail).toBeCalledWith({ + from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, + to: 'receiver@mail.org', + subject: 'Subject', + text: 'Text text text', + }) + }) + it('returns true', () => { expect(result).toBeTruthy() }) diff --git a/backend/src/mailer/sendTransactionReceivedEmail.test.ts b/backend/src/mailer/sendTransactionReceivedEmail.test.ts index 7b4080622..29f227185 100644 --- a/backend/src/mailer/sendTransactionReceivedEmail.test.ts +++ b/backend/src/mailer/sendTransactionReceivedEmail.test.ts @@ -27,7 +27,7 @@ describe('sendTransactionReceivedEmail', () => { subject: 'Gradido Überweisung', text: expect.stringContaining('Hallo Peter Lustig') && - expect.stringContaining('42,00') && + expect.stringContaining('42,00 GDD') && expect.stringContaining('Bibi Bloxberg') && expect.stringContaining('Vielen herzlichen Dank für den neuen Hexenbesen!'), }) From 0135d59dd5d7aabc0cbdd5345023d642e7b5eca2 Mon Sep 17 00:00:00 2001 From: Moriz Wahl Date: Wed, 12 Jan 2022 13:23:19 +0100 Subject: [PATCH 11/11] localize subject and body --- .../src/mailer/sendAccountActivationEmail.ts | 14 +++------- .../src/mailer/sendResetPasswordEmail.test.ts | 2 +- backend/src/mailer/sendResetPasswordEmail.ts | 12 +++------ .../mailer/sendTransactionReceivedEmail.ts | 17 +++--------- backend/src/mailer/text/accountActivation.ts | 16 +++++++++++ backend/src/mailer/text/resetPassword.ts | 14 ++++++++++ .../src/mailer/text/transactionReceived.ts | 27 +++++++++++++++++++ 7 files changed, 67 insertions(+), 35 deletions(-) create mode 100644 backend/src/mailer/text/accountActivation.ts create mode 100644 backend/src/mailer/text/resetPassword.ts create mode 100644 backend/src/mailer/text/transactionReceived.ts diff --git a/backend/src/mailer/sendAccountActivationEmail.ts b/backend/src/mailer/sendAccountActivationEmail.ts index 42d7c54f9..05c3104cb 100644 --- a/backend/src/mailer/sendAccountActivationEmail.ts +++ b/backend/src/mailer/sendAccountActivationEmail.ts @@ -1,4 +1,5 @@ import { sendEMail } from './sendEMail' +import { accountActivation } from './text/accountActivation' export const sendAccountActivationEmail = (data: { link: string @@ -8,16 +9,7 @@ export const sendAccountActivationEmail = (data: { }): Promise => { return sendEMail({ to: `${data.firstName} ${data.lastName} <${data.email}>`, - subject: 'Gradido: E-Mail Überprüfung', - text: `Hallo ${data.firstName} ${data.lastName}, - -Deine EMail wurde soeben bei Gradido registriert. - -Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: -${data.link} -oder kopiere den obigen Link in dein Browserfenster. - -Mit freundlichen Grüßen, -dein Gradido-Team`, + subject: accountActivation.de.subject, + text: accountActivation.de.text(data), }) } diff --git a/backend/src/mailer/sendResetPasswordEmail.test.ts b/backend/src/mailer/sendResetPasswordEmail.test.ts index a384d979a..4bc8ceba0 100644 --- a/backend/src/mailer/sendResetPasswordEmail.test.ts +++ b/backend/src/mailer/sendResetPasswordEmail.test.ts @@ -21,7 +21,7 @@ describe('sendResetPasswordEmail', () => { it('calls sendEMail', () => { expect(sendEMail).toBeCalledWith({ to: `Peter Lustig `, - subject: 'Gradido: Reset Password', + subject: 'Gradido: Passwort zurücksetzen', text: expect.stringContaining('Hallo Peter Lustig') && expect.stringContaining('resetLink'), }) }) diff --git a/backend/src/mailer/sendResetPasswordEmail.ts b/backend/src/mailer/sendResetPasswordEmail.ts index ffdc84f41..c9f5b23e9 100644 --- a/backend/src/mailer/sendResetPasswordEmail.ts +++ b/backend/src/mailer/sendResetPasswordEmail.ts @@ -1,4 +1,5 @@ import { sendEMail } from './sendEMail' +import { resetPassword } from './text/resetPassword' export const sendResetPasswordEmail = (data: { link: string @@ -8,14 +9,7 @@ export const sendResetPasswordEmail = (data: { }): Promise => { return sendEMail({ to: `${data.firstName} ${data.lastName} <${data.email}>`, - subject: 'Gradido: Reset Password', - text: `Hallo ${data.firstName} ${data.lastName}, - -Du oder jemand anderes hat für dieses Konto ein Zurücksetzen des Passworts angefordert. -Wenn du es warst, klicke bitte auf den Link: ${data.link} -oder kopiere den obigen Link in Dein Browserfenster. - -Mit freundlichen Grüßen, -dein Gradido-Team`, + subject: resetPassword.de.subject, + text: resetPassword.de.text(data), }) } diff --git a/backend/src/mailer/sendTransactionReceivedEmail.ts b/backend/src/mailer/sendTransactionReceivedEmail.ts index 51f8ef45c..3560f6548 100644 --- a/backend/src/mailer/sendTransactionReceivedEmail.ts +++ b/backend/src/mailer/sendTransactionReceivedEmail.ts @@ -1,4 +1,5 @@ import { sendEMail } from './sendEMail' +import { transactionReceived } from './text/transactionReceived' export const sendTransactionReceivedEmail = (data: { senderFirstName: string @@ -11,19 +12,7 @@ export const sendTransactionReceivedEmail = (data: { }): Promise => { return sendEMail({ to: `${data.recipientFirstName} ${data.recipientLastName} <${data.email}>`, - subject: 'Gradido Überweisung', - text: `Hallo ${data.recipientFirstName} ${data.recipientLastName} - -Du hast soeben ${data.amount.toFixed(2).replace('.', ',')} GDD von ${data.senderFirstName} ${ - data.senderLastName - } erhalten. -${data.senderFirstName} ${data.senderLastName} schreibt: - -${data.memo} - -Bitte antworte nicht auf diese E-Mail! - -Mit freundlichen Grüßen, -dein Gradido-Team`, + subject: transactionReceived.de.subject, + text: transactionReceived.de.text(data), }) } diff --git a/backend/src/mailer/text/accountActivation.ts b/backend/src/mailer/text/accountActivation.ts new file mode 100644 index 000000000..c4f70ff0f --- /dev/null +++ b/backend/src/mailer/text/accountActivation.ts @@ -0,0 +1,16 @@ +export const accountActivation = { + de: { + subject: 'Gradido: E-Mail Überprüfung', + text: (data: { link: string; firstName: string; lastName: string; email: string }): string => + `Hallo ${data.firstName} ${data.lastName}, + +Deine EMail wurde soeben bei Gradido registriert. + +Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradido-Konto zu aktivieren: +${data.link} +oder kopiere den obigen Link in dein Browserfenster. + +Mit freundlichen Grüßen, +dein Gradido-Team`, + }, +} diff --git a/backend/src/mailer/text/resetPassword.ts b/backend/src/mailer/text/resetPassword.ts new file mode 100644 index 000000000..58b13cbcd --- /dev/null +++ b/backend/src/mailer/text/resetPassword.ts @@ -0,0 +1,14 @@ +export const resetPassword = { + de: { + subject: 'Gradido: Passwort zurücksetzen', + text: (data: { link: string; firstName: string; lastName: string; email: string }): string => + `Hallo ${data.firstName} ${data.lastName}, + +Du oder jemand anderes hat für dieses Konto ein Zurücksetzen des Passworts angefordert. +Wenn du es warst, klicke bitte auf den Link: ${data.link} +oder kopiere den obigen Link in Dein Browserfenster. + +Mit freundlichen Grüßen, +dein Gradido-Team`, + }, +} diff --git a/backend/src/mailer/text/transactionReceived.ts b/backend/src/mailer/text/transactionReceived.ts new file mode 100644 index 000000000..3df2b718a --- /dev/null +++ b/backend/src/mailer/text/transactionReceived.ts @@ -0,0 +1,27 @@ +export const transactionReceived = { + de: { + subject: 'Gradido Überweisung', + text: (data: { + senderFirstName: string + senderLastName: string + recipientFirstName: string + recipientLastName: string + email: string + amount: number + memo: string + }): string => + `Hallo ${data.recipientFirstName} ${data.recipientLastName} + +Du hast soeben ${data.amount.toFixed(2).replace('.', ',')} GDD von ${data.senderFirstName} ${ + data.senderLastName + } erhalten. +${data.senderFirstName} ${data.senderLastName} schreibt: + +${data.memo} + +Bitte antworte nicht auf diese E-Mail! + +Mit freundlichen Grüßen, +dein Gradido-Team`, + }, +}