diff --git a/backend/.env.dist b/backend/.env.dist index 62b786456..df08c7a66 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -45,6 +45,8 @@ EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code} EMAIL_LINK_SETPASSWORD=http://localhost/reset-password/{optin} EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password EMAIL_LINK_OVERVIEW=http://localhost/overview +EMAIL_LINK_SUPPORT=https://gradido.net/de/contact/ +EMAIL_EMAIL_SUPPORT=support@gradido.net EMAIL_CODE_VALID_TIME=1440 EMAIL_CODE_REQUEST_TIME=10 diff --git a/backend/.env.template b/backend/.env.template index 140ec67e9..091ddf08c 100644 --- a/backend/.env.template +++ b/backend/.env.template @@ -42,7 +42,10 @@ EMAIL_SMTP_URL=$EMAIL_SMTP_URL EMAIL_SMTP_PORT=587 EMAIL_LINK_VERIFICATION=$EMAIL_LINK_VERIFICATION EMAIL_LINK_SETPASSWORD=$EMAIL_LINK_SETPASSWORD +EMAIL_LINK_FORGOTPASSWORD=$EMAIL_LINK_FORGOTPASSWORD EMAIL_LINK_OVERVIEW=$EMAIL_LINK_OVERVIEW +EMAIL_LINK_SUPPORT=$EMAIL_LINK_SUPPORT +EMAIL_EMAIL_SUPPORT=$EMAIL_EMAIL_SUPPORT EMAIL_CODE_VALID_TIME=$EMAIL_CODE_VALID_TIME EMAIL_CODE_REQUEST_TIME=$EMAIL_CODE_REQUEST_TIME diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index 28318ed6b..7e28d3d08 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -77,6 +77,8 @@ const email = { EMAIL_LINK_FORGOTPASSWORD: process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password', EMAIL_LINK_OVERVIEW: process.env.EMAIL_LINK_OVERVIEW || 'http://localhost/overview', + EMAIL_LINK_SUPPORT: process.env.EMAIL_LINK_SUPPORT || 'https://gradido.net/de/contact/', + EMAIL_EMAIL_SUPPORT: process.env.EMAIL_EMAIL_SUPPORT || 'support@gradido.net', // time in minutes a optin code is valid EMAIL_CODE_VALID_TIME: process.env.EMAIL_CODE_VALID_TIME ? parseInt(process.env.EMAIL_CODE_VALID_TIME) || 1440 diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index 78b630834..a880cf3f9 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -11,6 +11,7 @@ import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' import { User } from '@entity/User' import CONFIG from '@/config' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' +import { sendAccountMultiRegistrationEmail } from '@/mailer/sendAccountMultiRegistrationEmail' import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' import { printTimeDuration, activationLink } from './UserResolver' @@ -25,6 +26,13 @@ jest.mock('@/mailer/sendAccountActivationEmail', () => { } }) +jest.mock('@/mailer/sendAccountMultiRegistrationEmail', () => { + return { + __esModule: true, + sendAccountMultiRegistrationEmail: jest.fn(), + } +}) + jest.mock('@/mailer/sendResetPasswordEmail', () => { return { __esModule: true, @@ -151,14 +159,33 @@ describe('UserResolver', () => { }) describe('email already exists', () => { - it('throws and logs an error', async () => { - const mutation = await mutate({ mutation: createUser, variables }) + let mutation: any + beforeAll(async () => { + mutation = await mutate({ mutation: createUser, variables }) + }) + + it('logs an info', async () => { + expect(logger.info).toBeCalledWith('User already exists with this email=peter@lustig.de') + }) + + it('sends an account multi registration email', () => { + expect(sendAccountMultiRegistrationEmail).toBeCalledWith({ + firstName: 'Peter', + lastName: 'Lustig', + email: 'peter@lustig.de', + }) + }) + + it('results with partly faked user with random "id"', async () => { expect(mutation).toEqual( expect.objectContaining({ - errors: [new GraphQLError('User already exists.')], + data: { + createUser: { + id: expect.any(Number), + }, + }, }), ) - expect(logger.error).toBeCalledWith('User already exists with this email=peter@lustig.de') }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 146abaaa8..95c4316ff 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -338,6 +338,7 @@ export class UserResolver { // Wolle: throw new Error(`User already exists.`) // send mail even CC to support // respond with fake user_id? + dbUser.id = sodium.randombytes_random() % (2048 * 16) dbUser.email = email dbUser.firstName = firstName dbUser.lastName = lastName @@ -349,7 +350,6 @@ export class UserResolver { // eslint-disable-next-line @typescript-eslint/no-unused-vars const emailSent = await sendAccountMultiRegistrationEmail({ - link: CONFIG.EMAIL_LINK_FORGOTPASSWORD, firstName, lastName, email, @@ -361,6 +361,8 @@ export class UserResolver { logger.debug(`Email not send!`) } logger.info('createUser() faked and send multi registration mail...') + // Wolle: + // console.log('dbUser: ', dbUser) } else { // Wolle: const passphrase = PassphraseGenerate() // const keyPair = KeyPairEd25519Create(passphrase) // return pub, priv Key diff --git a/backend/src/mailer/sendAccountMultiRegistrationEmail.test.ts b/backend/src/mailer/sendAccountMultiRegistrationEmail.test.ts new file mode 100644 index 000000000..67749c966 --- /dev/null +++ b/backend/src/mailer/sendAccountMultiRegistrationEmail.test.ts @@ -0,0 +1,31 @@ +import { sendAccountMultiRegistrationEmail } from './sendAccountMultiRegistrationEmail' +import { sendEMail } from './sendEMail' + +jest.mock('./sendEMail', () => { + return { + __esModule: true, + sendEMail: jest.fn(), + } +}) + +describe('sendAccountMultiRegistrationEmail', () => { + beforeEach(async () => { + await sendAccountMultiRegistrationEmail({ + firstName: 'Peter', + lastName: 'Lustig', + email: 'peter@lustig.de', + }) + }) + + it('calls sendEMail', () => { + expect(sendEMail).toBeCalledWith({ + to: `Peter Lustig `, + cc: 'support@gradido.net', + subject: 'Gradido: Erneuter Registrierungsversuch mit deiner E-Mail', + text: + expect.stringContaining('Hallo Peter Lustig') && + expect.stringContaining('http://localhost/forgot-password') && + expect.stringContaining('https://gradido.net/de/contact/'), + }) + }) +}) diff --git a/backend/src/mailer/sendAccountMultiRegistrationEmail.ts b/backend/src/mailer/sendAccountMultiRegistrationEmail.ts index bfbdb391c..f1420a229 100644 --- a/backend/src/mailer/sendAccountMultiRegistrationEmail.ts +++ b/backend/src/mailer/sendAccountMultiRegistrationEmail.ts @@ -3,17 +3,18 @@ import { accountMultiRegistration } from './text/accountMultiRegistration' import CONFIG from '@/config' export const sendAccountMultiRegistrationEmail = (data: { - link: string firstName: string lastName: string email: string }): Promise => { return sendEMail({ to: `${data.firstName} ${data.lastName} <${data.email}>`, + cc: CONFIG.EMAIL_EMAIL_SUPPORT, subject: accountMultiRegistration.de.subject, text: accountMultiRegistration.de.text({ ...data, resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD, + supportLink: CONFIG.EMAIL_LINK_SUPPORT, }), }) } diff --git a/backend/src/mailer/sendEMail.test.ts b/backend/src/mailer/sendEMail.test.ts index 8a13c027d..5746f1ead 100644 --- a/backend/src/mailer/sendEMail.test.ts +++ b/backend/src/mailer/sendEMail.test.ts @@ -31,6 +31,7 @@ describe('sendEMail', () => { beforeEach(async () => { result = await sendEMail({ to: 'receiver@mail.org', + cc: 'support@gradido.net', subject: 'Subject', text: 'Text text text', }) @@ -50,6 +51,7 @@ describe('sendEMail', () => { CONFIG.EMAIL = true result = await sendEMail({ to: 'receiver@mail.org', + cc: 'support@gradido.net', subject: 'Subject', text: 'Text text text', }) @@ -72,6 +74,7 @@ describe('sendEMail', () => { expect((createTransport as jest.Mock).mock.results[0].value.sendMail).toBeCalledWith({ from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`, to: 'receiver@mail.org', + cc: 'support@gradido.net', subject: 'Subject', text: 'Text text text', }) diff --git a/backend/src/mailer/sendEMail.ts b/backend/src/mailer/sendEMail.ts index 640dd7f4c..746daa810 100644 --- a/backend/src/mailer/sendEMail.ts +++ b/backend/src/mailer/sendEMail.ts @@ -5,10 +5,15 @@ import CONFIG from '@/config' export const sendEMail = async (emailDef: { to: string + cc?: string subject: string text: string }): Promise => { - logger.info(`send Email: to=${emailDef.to}, subject=${emailDef.subject}, text=${emailDef.text}`) + logger.info( + `send Email: to=${emailDef.to}` + + (emailDef.cc ? `, cc=${emailDef.cc}` : '') + + `, subject=${emailDef.subject}, text=${emailDef.text}`, + ) if (!CONFIG.EMAIL) { logger.info(`Emails are disabled via config...`) diff --git a/backend/src/mailer/text/accountMultiRegistration.ts b/backend/src/mailer/text/accountMultiRegistration.ts index 58cc53a5f..809ae1419 100644 --- a/backend/src/mailer/text/accountMultiRegistration.ts +++ b/backend/src/mailer/text/accountMultiRegistration.ts @@ -2,11 +2,11 @@ export const accountMultiRegistration = { de: { subject: 'Gradido: Erneuter Registrierungsversuch mit deiner E-Mail', text: (data: { - link: string // Wolle: support link? firstName: string lastName: string email: string resendLink: string + supportLink: string }): string => `Hallo ${data.firstName} ${data.lastName}, @@ -18,7 +18,7 @@ ${data.resendLink} oder kopiere den obigen Link in dein Browserfenster. Wenn du nicht derjenige bist, der sich versucht hat erneut zu registrieren, wende dich bitte an unseren support: -${data.link} +${data.supportLink} Mit freundlichen Grüßen, dein Gradido-Team`, diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index a1751a859..b90ec9ea7 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -47,6 +47,8 @@ EMAIL_LINK_VERIFICATION=https://stage1.gradido.net/checkEmail/{optin}{code} EMAIL_LINK_SETPASSWORD=https://stage1.gradido.net/reset-password/{optin} EMAIL_LINK_FORGOTPASSWORD=https://stage1.gradido.net/forgot-password EMAIL_LINK_OVERVIEW=https://stage1.gradido.net/overview +EMAIL_LINK_SUPPORT=https://gradido.net/de/contact/ +EMAIL_EMAIL_SUPPORT=support@gradido.net EMAIL_CODE_VALID_TIME=1440 EMAIL_CODE_REQUEST_TIME=10