diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 49959e3e7..cacee6fc8 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -391,10 +391,11 @@ export class UserResolver { } @Authorized([RIGHTS.SEND_RESET_PASSWORD_EMAIL]) - @Query(() => Boolean) - async sendResetPasswordEmail(@Arg('email') email: string): Promise { + @Mutation(() => Boolean) + async forgotPassword(@Arg('email') email: string): Promise { email = email.trim().toLowerCase() - const user = await DbUser.findOneOrFail({ email }) + const user = await DbUser.findOne({ email }) + if (!user) return true // can be both types: REGISTER and RESET_PASSWORD let optInCode = await LoginEmailOptIn.findOne({ diff --git a/frontend/src/graphql/mutations.js b/frontend/src/graphql/mutations.js index 95c811f8d..3dbd8888e 100644 --- a/frontend/src/graphql/mutations.js +++ b/frontend/src/graphql/mutations.js @@ -18,6 +18,12 @@ export const setPassword = gql` } ` +export const forgotPassword = gql` + mutation($email: String!) { + forgotPassword(email: $email) + } +` + export const updateUserInfos = gql` mutation( $firstName: String diff --git a/frontend/src/graphql/queries.js b/frontend/src/graphql/queries.js index ecd8208b5..b8622ef2d 100644 --- a/frontend/src/graphql/queries.js +++ b/frontend/src/graphql/queries.js @@ -81,12 +81,6 @@ export const transactionsQuery = gql` } ` -export const sendResetPasswordEmail = gql` - query($email: String!) { - sendResetPasswordEmail(email: $email) - } -` - export const listGDTEntriesQuery = gql` query($currentPage: Int!, $pageSize: Int!) { listGDTEntries(currentPage: $currentPage, pageSize: $pageSize) { diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index e8994a2e9..d204688db 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -30,6 +30,7 @@ "delete": "Löschen", "em-dash": "—", "error": { + "email-already-sent": "Wir haben dir bereits eine E-Mail vor weniger als 10 Minuten geschickt.", "empty-transactionlist": "Es gab einen Fehler mit der Übermittlung der Anzahl deiner Transaktionen.", "error": "Fehler!", "no-account": "Leider konnten wir keinen Account mit diesen Daten finden.", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index c586bbe46..dfe1c6d2b 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -30,6 +30,7 @@ "delete": "Delete", "em-dash": "—", "error": { + "email-already-sent": "We already sent you an email less than 10 minutes ago.", "empty-transactionlist": "There was an error with the transmission of the number of your transactions.", "error": "Error!", "no-account": "Unfortunately we could not find an account to the given data!", diff --git a/frontend/src/pages/ForgotPassword.spec.js b/frontend/src/pages/ForgotPassword.spec.js index a547f9cc1..dd703d7fc 100644 --- a/frontend/src/pages/ForgotPassword.spec.js +++ b/frontend/src/pages/ForgotPassword.spec.js @@ -2,6 +2,8 @@ import { mount, RouterLinkStub } from '@vue/test-utils' import flushPromises from 'flush-promises' import ForgotPassword from './ForgotPassword' +import { toastErrorSpy } from '@test/testSetup' + const mockAPIcall = jest.fn() const localVue = global.localVue @@ -21,7 +23,7 @@ const createMockObject = (comingFrom) => { push: mockRouterPush, }, $apollo: { - query: mockAPIcall, + mutate: mockAPIcall, }, $route: { params: { @@ -116,6 +118,10 @@ describe('ForgotPassword', () => { await flushPromises() }) + it('toasts a standard error message', () => { + expect(toastErrorSpy).toBeCalledWith('error.email-already-sent') + }) + it('pushes to "/thx/forgotPassword"', () => { expect(mockAPIcall).toBeCalledWith( expect.objectContaining({ diff --git a/frontend/src/pages/ForgotPassword.vue b/frontend/src/pages/ForgotPassword.vue index 81121fbe7..580a0ed97 100644 --- a/frontend/src/pages/ForgotPassword.vue +++ b/frontend/src/pages/ForgotPassword.vue @@ -39,7 +39,7 @@