diff --git a/backend/src/graphql/resolvers/emails.ts b/backend/src/graphql/resolvers/emails.ts index 0491c86ad..f5c4eb0ad 100644 --- a/backend/src/graphql/resolvers/emails.ts +++ b/backend/src/graphql/resolvers/emails.ts @@ -15,6 +15,7 @@ import Resolver from './helpers/Resolver' export default { Query: { VerifyNonce: async (_parent, args, context, _resolveInfo) => { + args.email = normalizeEmail(args.email) const session = context.driver.session() const readTxResultPromise = session.readTransaction(async (txc) => { const result = await txc.run( @@ -38,7 +39,6 @@ export default { AddEmailAddress: async (_parent, args, context, _resolveInfo) => { let response args.email = normalizeEmail(args.email) - try { const { neode } = context await new Validator(neode, neode.model('UnverifiedEmailAddress'), args) @@ -86,6 +86,7 @@ export default { const { user: { id: userId }, } = context + args.email = normalizeEmail(args.email) const { nonce, email } = args const session = context.driver.session() const writeTxResultPromise = session.writeTransaction(async (txc) => { diff --git a/backend/src/graphql/resolvers/helpers/existingEmailAddress.ts b/backend/src/graphql/resolvers/helpers/existingEmailAddress.ts index e1e27bda0..03d902881 100644 --- a/backend/src/graphql/resolvers/helpers/existingEmailAddress.ts +++ b/backend/src/graphql/resolvers/helpers/existingEmailAddress.ts @@ -2,7 +2,10 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-return */ +import normalizeEmail from './normalizeEmail' + export default async function alreadyExistingMail({ args, context }) { + args.email = normalizeEmail(args.email) const session = context.driver.session() try { const existingEmailAddressTxPromise = session.writeTransaction(async (transaction) => { diff --git a/backend/src/graphql/resolvers/passwordReset.ts b/backend/src/graphql/resolvers/passwordReset.ts index f806f7249..ac437a555 100644 --- a/backend/src/graphql/resolvers/passwordReset.ts +++ b/backend/src/graphql/resolvers/passwordReset.ts @@ -10,15 +10,18 @@ import { v4 as uuid } from 'uuid' import registrationConstants from '@constants/registrationBranded' import createPasswordReset from './helpers/createPasswordReset' +import normalizeEmail from './helpers/normalizeEmail' export default { Mutation: { requestPasswordReset: async (_parent, { email }, { driver }) => { + email = normalizeEmail(email) // TODO: why this is generated differntly from 'backend/src/schema/resolvers/helpers/generateNonce.js'? const nonce = uuid().substring(0, registrationConstants.NONCE_LENGTH) return createPasswordReset({ driver, nonce, email }) }, resetPassword: async (_parent, { email, nonce, newPassword }, { driver }) => { + email = normalizeEmail(email) const stillValid = new Date() stillValid.setDate(stillValid.getDate() - 1) const encryptedNewPassword = await bcrypt.hash(newPassword, 10) diff --git a/backend/src/graphql/resolvers/users.ts b/backend/src/graphql/resolvers/users.ts index ac1964beb..a2f4b9dcd 100644 --- a/backend/src/graphql/resolvers/users.ts +++ b/backend/src/graphql/resolvers/users.ts @@ -13,6 +13,7 @@ import { getNeode } from '@db/neo4j' import { Context } from '@src/server' import { defaultTrophyBadge, defaultVerificationBadge } from './badges' +import normalizeEmail from './helpers/normalizeEmail' import Resolver from './helpers/Resolver' import { mergeImage, deleteImage } from './images/images' import { createOrUpdateLocations } from './users/location' @@ -66,8 +67,8 @@ export default { } }, User: async (object, args, context, resolveInfo) => { - const { email } = args - if (email) { + if (args.email) { + args.email = normalizeEmail(args.email) let session try { session = context.driver.session() diff --git a/webapp/components/PasswordReset/Request.spec.js b/webapp/components/PasswordReset/Request.spec.js index e2f082242..bd7dc419c 100644 --- a/webapp/components/PasswordReset/Request.spec.js +++ b/webapp/components/PasswordReset/Request.spec.js @@ -89,24 +89,6 @@ describe('Request', () => { }) }) - describe('capital letters in a gmail address', () => { - beforeEach(async () => { - wrapper = Wrapper() - wrapper.find('input#email').setValue('mAiL@gmail.com') - await wrapper.find('form').trigger('submit') - }) - - it('normalizes email to lower case letters', () => { - const expected = expect.objectContaining({ - variables: { - email: 'mail@gmail.com', - locale: 'en', - }, - }) - expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - }) - }) - describe('backend throws an error', () => { beforeEach(() => { mocks.$apollo.mutate = jest.fn().mockRejectedValue({ diff --git a/webapp/components/PasswordReset/Request.vue b/webapp/components/PasswordReset/Request.vue index 3eebeba65..79558a911 100644 --- a/webapp/components/PasswordReset/Request.vue +++ b/webapp/components/PasswordReset/Request.vue @@ -45,7 +45,6 @@