diff --git a/backend/.env.dist b/backend/.env.dist index 5e3a89f82..447608533 100644 --- a/backend/.env.dist +++ b/backend/.env.dist @@ -1,4 +1,4 @@ -CONFIG_VERSION=v2.2022-03-24 +CONFIG_VERSION=v3.2022-03-29 # Server PORT=4000 @@ -42,6 +42,7 @@ EMAIL_SMTP_URL=gmail.com EMAIL_SMTP_PORT=587 EMAIL_LINK_VERIFICATION=http://localhost/checkEmail/{optin}{code} EMAIL_LINK_SETPASSWORD=http://localhost/reset/{code} +EMAIL_LINK_FORGOTPASSWORD=http://localhost/forgot-password EMAIL_CODE_VALID_TIME=1440 EMAIL_CODE_REQUEST_TIME=10 diff --git a/backend/src/config/index.ts b/backend/src/config/index.ts index caedac08e..50388d29a 100644 --- a/backend/src/config/index.ts +++ b/backend/src/config/index.ts @@ -14,7 +14,7 @@ const constants = { DECAY_START_TIME: new Date('2021-05-13 17:46:31'), // GMT+0 CONFIG_VERSION: { DEFAULT: 'DEFAULT', - EXPECTED: 'v2.2022-03-24', + EXPECTED: 'v3.2022-03-29', CURRENT: '', }, } @@ -70,6 +70,8 @@ const email = { process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/checkEmail/{optin}{code}', EMAIL_LINK_SETPASSWORD: process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/reset-password/{optin}', + EMAIL_LINK_FORGOTPASSWORD: + process.env.EMAIL_LINK_FORGOTPASSWORD || 'http://localhost/forgot-password', // 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/AdminResolver.ts b/backend/src/graphql/resolver/AdminResolver.ts index 9013a91f4..41d66e94e 100644 --- a/backend/src/graphql/resolver/AdminResolver.ts +++ b/backend/src/graphql/resolver/AdminResolver.ts @@ -39,8 +39,9 @@ import Paginated from '@arg/Paginated' import TransactionLinkFilters from '@arg/TransactionLinkFilters' import { Order } from '@enum/Order' import { communityUser } from '@/util/communityUser' -import { checkOptInCode, activationLink } from './UserResolver' +import { checkOptInCode, activationLink, printTimeDuration } from './UserResolver' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' +import CONFIG from '@/config' // const EMAIL_OPT_IN_REGISTER = 1 // const EMAIL_OPT_UNKNOWN = 3 // elopage? @@ -397,6 +398,7 @@ export class AdminResolver { firstName: user.firstName, lastName: user.lastName, email, + duration: printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME), }) /* uncomment this, when you need the activation link on the console diff --git a/backend/src/graphql/resolver/UserResolver.test.ts b/backend/src/graphql/resolver/UserResolver.test.ts index c01cf2de9..07b8e59e2 100644 --- a/backend/src/graphql/resolver/UserResolver.test.ts +++ b/backend/src/graphql/resolver/UserResolver.test.ts @@ -134,6 +134,7 @@ describe('UserResolver', () => { firstName: 'Peter', lastName: 'Lustig', email: 'peter@lustig.de', + duration: expect.any(String), }) }) }) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 07cd90a23..49959e3e7 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -17,7 +17,7 @@ import { UserSettingRepository } from '@repository/UserSettingRepository' import { Setting } from '@enum/Setting' import { OptInType } from '@enum/OptInType' import { LoginEmailOptIn } from '@entity/LoginEmailOptIn' -import { sendResetPasswordEmail } from '@/mailer/sendResetPasswordEmail' +import { sendResetPasswordEmail as sendResetPasswordEmailMailer } from '@/mailer/sendResetPasswordEmail' import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail' import { klicktippSignIn } from '@/apis/KlicktippController' import { RIGHTS } from '@/auth/RIGHTS' @@ -369,6 +369,7 @@ export class UserResolver { firstName, lastName, email, + duration: printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME), }) /* uncomment this, when you need the activation link on the console @@ -403,11 +404,12 @@ export class UserResolver { optInCode = await checkOptInCode(optInCode, user.id, OptInType.EMAIL_OPT_IN_RESET_PASSWORD) // eslint-disable-next-line @typescript-eslint/no-unused-vars - const emailSent = await sendResetPasswordEmail({ + const emailSent = await sendResetPasswordEmailMailer({ link: activationLink(optInCode), firstName: user.firstName, lastName: user.lastName, email, + duration: printTimeDuration(CONFIG.EMAIL_CODE_VALID_TIME), }) /* uncomment this, when you need the activation link on the console diff --git a/backend/src/mailer/sendAccountActivationEmail.test.ts b/backend/src/mailer/sendAccountActivationEmail.test.ts index c53fc0994..08ddae166 100644 --- a/backend/src/mailer/sendAccountActivationEmail.test.ts +++ b/backend/src/mailer/sendAccountActivationEmail.test.ts @@ -15,6 +15,7 @@ describe('sendAccountActivationEmail', () => { firstName: 'Peter', lastName: 'Lustig', email: 'peter@lustig.de', + duration: '23 hours and 30 minutes', }) }) @@ -23,7 +24,9 @@ describe('sendAccountActivationEmail', () => { to: `Peter Lustig `, subject: 'Gradido: E-Mail Überprüfung', text: - expect.stringContaining('Hallo Peter Lustig') && expect.stringContaining('activationLink'), + expect.stringContaining('Hallo Peter Lustig') && + expect.stringContaining('activationLink') && + expect.stringContaining('23 Stunden und 30 Minuten'), }) }) }) diff --git a/backend/src/mailer/sendAccountActivationEmail.ts b/backend/src/mailer/sendAccountActivationEmail.ts index 05c3104cb..335f80a82 100644 --- a/backend/src/mailer/sendAccountActivationEmail.ts +++ b/backend/src/mailer/sendAccountActivationEmail.ts @@ -1,15 +1,17 @@ import { sendEMail } from './sendEMail' import { accountActivation } from './text/accountActivation' +import CONFIG from '@/config' export const sendAccountActivationEmail = (data: { link: string firstName: string lastName: string email: string + duration: string }): Promise => { return sendEMail({ to: `${data.firstName} ${data.lastName} <${data.email}>`, subject: accountActivation.de.subject, - text: accountActivation.de.text(data), + text: accountActivation.de.text({ ...data, resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD }), }) } diff --git a/backend/src/mailer/sendResetPasswordEmail.test.ts b/backend/src/mailer/sendResetPasswordEmail.test.ts index 4bc8ceba0..94f69cf8b 100644 --- a/backend/src/mailer/sendResetPasswordEmail.test.ts +++ b/backend/src/mailer/sendResetPasswordEmail.test.ts @@ -15,6 +15,7 @@ describe('sendResetPasswordEmail', () => { firstName: 'Peter', lastName: 'Lustig', email: 'peter@lustig.de', + duration: '23 hours and 30 minutes', }) }) @@ -22,7 +23,10 @@ describe('sendResetPasswordEmail', () => { expect(sendEMail).toBeCalledWith({ to: `Peter Lustig `, subject: 'Gradido: Passwort zurücksetzen', - text: expect.stringContaining('Hallo Peter Lustig') && expect.stringContaining('resetLink'), + text: + expect.stringContaining('Hallo Peter Lustig') && + expect.stringContaining('resetLink') && + expect.stringContaining('23 Stunden und 30 Minuten'), }) }) }) diff --git a/backend/src/mailer/sendResetPasswordEmail.ts b/backend/src/mailer/sendResetPasswordEmail.ts index c9f5b23e9..d9770f940 100644 --- a/backend/src/mailer/sendResetPasswordEmail.ts +++ b/backend/src/mailer/sendResetPasswordEmail.ts @@ -1,15 +1,17 @@ import { sendEMail } from './sendEMail' import { resetPassword } from './text/resetPassword' +import CONFIG from '@/config' export const sendResetPasswordEmail = (data: { link: string firstName: string lastName: string email: string + duration: string }): Promise => { return sendEMail({ to: `${data.firstName} ${data.lastName} <${data.email}>`, subject: resetPassword.de.subject, - text: resetPassword.de.text(data), + text: resetPassword.de.text({ ...data, resendLink: CONFIG.EMAIL_LINK_FORGOTPASSWORD }), }) } diff --git a/backend/src/mailer/text/accountActivation.ts b/backend/src/mailer/text/accountActivation.ts index bf5d1a2e9..2755c4c0a 100644 --- a/backend/src/mailer/text/accountActivation.ts +++ b/backend/src/mailer/text/accountActivation.ts @@ -1,7 +1,14 @@ export const accountActivation = { de: { subject: 'Gradido: E-Mail Überprüfung', - text: (data: { link: string; firstName: string; lastName: string; email: string }): string => + text: (data: { + link: string + firstName: string + lastName: string + email: string + duration: string + resendLink: string + }): string => `Hallo ${data.firstName} ${data.lastName}, Deine E-Mail-Adresse wurde soeben bei Gradido registriert. @@ -10,6 +17,15 @@ Klicke bitte auf diesen Link, um die Registrierung abzuschließen und dein Gradi ${data.link} oder kopiere den obigen Link in dein Browserfenster. +Der Link hat eine Gültigkeit von ${data.duration + .replace('hours', 'Stunden') + .replace('minutes', 'Minuten') + .replace( + ' and ', + ' und ', + )}. Sollte die Gültigkeit des Links bereits abgelaufen sein, kannst du dir hier einen neuen Link schicken lassen, in dem du deine E-Mail-Adresse eingibst: +${data.resendLink} + Mit freundlichen Grüßen, dein Gradido-Team`, }, diff --git a/backend/src/mailer/text/resetPassword.ts b/backend/src/mailer/text/resetPassword.ts index 58b13cbcd..ff660f76e 100644 --- a/backend/src/mailer/text/resetPassword.ts +++ b/backend/src/mailer/text/resetPassword.ts @@ -1,13 +1,29 @@ export const resetPassword = { de: { subject: 'Gradido: Passwort zurücksetzen', - text: (data: { link: string; firstName: string; lastName: string; email: string }): string => + text: (data: { + link: string + firstName: string + lastName: string + email: string + duration: string + resendLink: 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. +Der Link hat eine Gültigkeit von ${data.duration + .replace('hours', 'Stunden') + .replace('minutes', 'Minuten') + .replace( + ' and ', + ' und ', + )}. Sollte die Gültigkeit des Links bereits abgelaufen sein, kannst du dir hier einen neuen Link schicken lassen, in dem du deine E-Mail-Adresse eingibst: +${data.resendLink} + Mit freundlichen Grüßen, dein Gradido-Team`, }, diff --git a/deployment/bare_metal/.env.dist b/deployment/bare_metal/.env.dist index 1cb78299a..e46ee1d90 100644 --- a/deployment/bare_metal/.env.dist +++ b/deployment/bare_metal/.env.dist @@ -18,7 +18,7 @@ WEBHOOK_GITHUB_SECRET=secret WEBHOOK_GITHUB_BRANCH=master # backend -BACKEND_CONFIG_VERSION=v2.2022-03-24 +BACKEND_CONFIG_VERSION=v3.2022-03-29 EMAIL=true EMAIL_USERNAME=peter@lustig.de