diff --git a/backend/src/schema/resolvers/passwordReset.js b/backend/src/schema/resolvers/passwordReset.js index 415eb6f21..88d82846a 100644 --- a/backend/src/schema/resolvers/passwordReset.js +++ b/backend/src/schema/resolvers/passwordReset.js @@ -5,7 +5,7 @@ export async function createPasswordReset(options) { const { driver, code, email, issuedAt = new Date() } = options const session = driver.session() const cypher = ` - MATCH (u:User) WHERE u.email = $email + MATCH (u:User)-[:PRIMARY_EMAIL]->(e:EmailAddress {email:$email}) CREATE(pr:PasswordReset {code: $code, issuedAt: datetime($issuedAt), usedAt: NULL}) MERGE (u)-[:REQUESTED]->(pr) RETURN u @@ -35,7 +35,7 @@ export default { const encryptedNewPassword = await bcrypt.hashSync(newPassword, 10) const cypher = ` MATCH (pr:PasswordReset {code: $code}) - MATCH (u:User {email: $email})-[:REQUESTED]->(pr) + MATCH (e:EmailAddress {email: $email})<-[:PRIMARY_EMAIL]-(u:User)-[:REQUESTED]->(pr) WHERE duration.between(pr.issuedAt, datetime()).days <= 0 AND pr.usedAt IS NULL SET pr.usedAt = datetime() SET u.encryptedPassword = $encryptedNewPassword diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.js index 3c8243d8a..20c54a49b 100644 --- a/backend/src/schema/resolvers/registration.js +++ b/backend/src/schema/resolvers/registration.js @@ -12,8 +12,8 @@ const instance = neode() */ const checkEmailDoesNotExist = async ({ email }) => { email = email.toLowerCase() - const users = await instance.all('User', { email }) - if (users.length > 0) throw new UserInputError('User account with this email already exists.') + const emails = await instance.all('EmailAddress', { email }) + if (emails.length > 0) throw new UserInputError('User account with this email already exists.') } export default { diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.js index 2cbce9a36..1cf3a13bb 100644 --- a/backend/src/schema/resolvers/registration.spec.js +++ b/backend/src/schema/resolvers/registration.spec.js @@ -166,11 +166,12 @@ describe('SignupByInvitation', () => { await expect(action()).rejects.toThrow('"email" must be a valid email') }) - it('creates no EmailAddress node', async done => { + it('creates no additional EmailAddress node', async done => { try { await action() } catch (e) { - const emailAddresses = await instance.all('EmailAddress') + let emailAddresses = await instance.all('EmailAddress') + emailAddresses = await emailAddresses.toJson expect(emailAddresses).toHaveLength(0) done() } diff --git a/backend/src/schema/resolvers/user_management.js b/backend/src/schema/resolvers/user_management.js index fba5fe3bd..ab7438a17 100644 --- a/backend/src/schema/resolvers/user_management.js +++ b/backend/src/schema/resolvers/user_management.js @@ -47,17 +47,9 @@ export default { }, changePassword: async (_, { oldPassword, newPassword }, { driver, user }) => { const session = driver.session() - let result = await session.run( - `MATCH (user:User)-[:PRIMARY_EMAIL]->(e:EmailAddress {email: $userEmail}) - RETURN user {.id, .email, .encryptedPassword}`, - { - userEmail: user.email, - }, - ) + let result = await session.run('MATCH (user:User {id:$id}) RETURN user', { id: user.id }) - const [currentUser] = result.records.map(function(record) { - return record.get('user') - }) + const [currentUser] = result.records.map(record => record.get('user').properties) if (!(await bcrypt.compareSync(oldPassword, currentUser.encryptedPassword))) { throw new AuthenticationError('Old password is not correct') diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index aa9532e2d..db5342881 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -109,7 +109,7 @@ export default { const { id } = parent const statement = `MATCH(u:User {id: {id}})-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e` const result = await instance.cypher(statement, { id }) - let [{email}]= result.records.map(r => r.get('e').properties) + let [{ email }] = result.records.map(r => r.get('e').properties) return email }, ...undefinedToNull([ diff --git a/backend/src/seed/factories/users.js b/backend/src/seed/factories/users.js index c34a9b3de..3c5131a77 100644 --- a/backend/src/seed/factories/users.js +++ b/backend/src/seed/factories/users.js @@ -25,10 +25,7 @@ export default function create() { neodeInstance.create('User', args), neodeInstance.create('EmailAddress', { email: args.email }), ]) - await Promise.all([ - user.relateTo(email, 'primaryEmail'), - email.relateTo(user, 'belongsTo') - ]) + await Promise.all([user.relateTo(email, 'primaryEmail'), email.relateTo(user, 'belongsTo')]) return user }, } diff --git a/neo4j/db_setup.sh b/neo4j/db_setup.sh index 21ed54571..d4c7b9af8 100755 --- a/neo4j/db_setup.sh +++ b/neo4j/db_setup.sh @@ -34,6 +34,8 @@ CREATE CONSTRAINT ON (p:Post) ASSERT p.slug IS UNIQUE; CREATE CONSTRAINT ON (c:Category) ASSERT c.slug IS UNIQUE; CREATE CONSTRAINT ON (u:User) ASSERT u.slug IS UNIQUE; CREATE CONSTRAINT ON (o:Organization) ASSERT o.slug IS UNIQUE; + +CREATE CONSTRAINT ON (e:EmailAddress) ASSERT e.email IS UNIQUE; ' | cypher-shell echo '