diff --git a/backend/src/schema/resolvers/emails.js b/backend/src/schema/resolvers/emails.js index ce93a28e9..06c0dbd1a 100644 --- a/backend/src/schema/resolvers/emails.js +++ b/backend/src/schema/resolvers/emails.js @@ -3,11 +3,14 @@ import Resolver from './helpers/Resolver' import existingEmailAddress from './helpers/existingEmailAddress' import { UserInputError } from 'apollo-server' import Validator from 'neode/build/Services/Validator.js' +import { normalizeEmail } from 'validator' export default { Mutation: { 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) @@ -16,13 +19,13 @@ export default { } // check email does not belong to anybody - await existingEmailAddress(_parent, args, context) + await existingEmailAddress({ args, context }) const nonce = generateNonce() const { user: { id: userId }, } = context - const { email } = args + const session = context.driver.session() const writeTxResultPromise = session.writeTransaction(async txc => { const result = await txc.run( @@ -32,7 +35,7 @@ export default { SET email.createdAt = toString(datetime()) RETURN email, user `, - { userId, email, nonce }, + { userId, email: args.email, nonce }, ) return result.records.map(record => ({ name: record.get('user').properties.name, diff --git a/backend/src/schema/resolvers/passwordReset/createPasswordReset.js b/backend/src/schema/resolvers/helpers/createPasswordReset.js similarity index 100% rename from backend/src/schema/resolvers/passwordReset/createPasswordReset.js rename to backend/src/schema/resolvers/helpers/createPasswordReset.js diff --git a/backend/src/schema/resolvers/passwordReset/createPasswordReset.spec.js b/backend/src/schema/resolvers/helpers/createPasswordReset.spec.js similarity index 68% rename from backend/src/schema/resolvers/passwordReset/createPasswordReset.spec.js rename to backend/src/schema/resolvers/helpers/createPasswordReset.spec.js index a5c4d75a5..a566e225a 100644 --- a/backend/src/schema/resolvers/passwordReset/createPasswordReset.spec.js +++ b/backend/src/schema/resolvers/helpers/createPasswordReset.spec.js @@ -12,9 +12,9 @@ describe('createPasswordReset', () => { close() {}, run: jest.fn().mockReturnValue({ records: { - map: jest.fn(() => []) - } - }) + map: jest.fn(() => []), + }, + }), } driver = { session: () => mockSession } }) @@ -22,10 +22,14 @@ describe('createPasswordReset', () => { it('lowercases email address', async () => { const email = 'stRaNGeCaSiNG@ExAmplE.ORG' await createPasswordReset({ driver, email, issuedAt, nonce }) - expect(mockSession.run.mock.calls) - .toEqual([[expect.any(String), expect.objectContaining({ - email: 'strangecasing@example.org' - })]]) + expect(mockSession.run.mock.calls).toEqual([ + [ + expect.any(String), + expect.objectContaining({ + email: 'strangecasing@example.org', + }), + ], + ]) }) }) }) diff --git a/backend/src/schema/resolvers/helpers/existingEmailAddress.js b/backend/src/schema/resolvers/helpers/existingEmailAddress.js index 007d2de6b..ee1a6af82 100644 --- a/backend/src/schema/resolvers/helpers/existingEmailAddress.js +++ b/backend/src/schema/resolvers/helpers/existingEmailAddress.js @@ -1,7 +1,6 @@ import { UserInputError } from 'apollo-server' -export default async function alreadyExistingMail(_parent, args, context) { - let { email } = args - email = email.toLowerCase() + +export default async function alreadyExistingMail({ args, context }) { const cypher = ` MATCH (email:EmailAddress {email: $email}) OPTIONAL MATCH (email)-[:BELONGS_TO]-(user) @@ -10,7 +9,7 @@ export default async function alreadyExistingMail(_parent, args, context) { let transactionRes const session = context.driver.session() try { - transactionRes = await session.run(cypher, { email }) + transactionRes = await session.run(cypher, { email: args.email }) } finally { session.close() } diff --git a/backend/src/schema/resolvers/passwordReset.js b/backend/src/schema/resolvers/passwordReset.js index e03378ec1..7c0d9e747 100644 --- a/backend/src/schema/resolvers/passwordReset.js +++ b/backend/src/schema/resolvers/passwordReset.js @@ -1,7 +1,6 @@ import uuid from 'uuid/v4' import bcrypt from 'bcryptjs' -import createPasswordReset from './passwordReset/createPasswordReset' - +import createPasswordReset from './helpers/createPasswordReset' export default { Mutation: { diff --git a/backend/src/schema/resolvers/passwordReset.spec.js b/backend/src/schema/resolvers/passwordReset.spec.js index 03de77493..e9f986acd 100644 --- a/backend/src/schema/resolvers/passwordReset.spec.js +++ b/backend/src/schema/resolvers/passwordReset.spec.js @@ -1,7 +1,7 @@ import Factory from '../../seed/factories' import { gql } from '../../jest/helpers' import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' -import { createPasswordReset } from './passwordReset/createPasswordReset' +import { createPasswordReset } from './helpers/createPasswordReset' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.js index bd62b32c3..bdcb6f04f 100644 --- a/backend/src/schema/resolvers/registration.js +++ b/backend/src/schema/resolvers/registration.js @@ -4,6 +4,7 @@ import fileUpload from './fileUpload' import encryptPassword from '../../helpers/encryptPassword' import generateNonce from './helpers/generateNonce' import existingEmailAddress from './helpers/existingEmailAddress' +import { normalizeEmail } from 'validator' const instance = neode() @@ -29,9 +30,9 @@ export default { return response }, Signup: async (_parent, args, context) => { - const nonce = generateNonce() - args.nonce = nonce - let emailAddress = await existingEmailAddress(_parent, args, context) + args.nonce = generateNonce() + args.email = normalizeEmail(args.email) + let emailAddress = await existingEmailAddress({ args, context }) if (emailAddress) return emailAddress try { emailAddress = await instance.create('EmailAddress', args) @@ -42,8 +43,8 @@ export default { }, SignupByInvitation: async (_parent, args, context) => { const { token } = args - const nonce = generateNonce() - args.nonce = nonce + args.nonce = generateNonce() + args.email = normalizeEmail(args.email) let emailAddress = await existingEmailAddress(_parent, args, context) if (emailAddress) return emailAddress try { @@ -78,7 +79,7 @@ export default { args.termsAndConditionsAgreedAt = new Date().toISOString() let { nonce, email } = args - email = email.toLowerCase() + email = normalizeEmail(email) const result = await instance.cypher( ` MATCH(email:EmailAddress {nonce: {nonce}, email: {email}})