diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 10b777748..ad2787579 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -147,6 +147,7 @@ const permissions = shield( CreateComment: isAuthenticated, DeleteComment: isAuthor, DeleteUser: isDeletingOwnAccount, + requestPasswordReset: allow, }, User: { email: isMyOwn, diff --git a/backend/src/schema/resolvers/passwordReset.js b/backend/src/schema/resolvers/passwordReset.js new file mode 100644 index 000000000..83a1080d0 --- /dev/null +++ b/backend/src/schema/resolvers/passwordReset.js @@ -0,0 +1,10 @@ +export default { + Mutation: { + requestPasswordReset: async (_, { email }, { driver }) => { + throw Error('Not Implemented') + }, + resetPassword: async (_, { email, token, newPassword }, { driver }) => { + throw Error('Not Implemented') + } + } +} diff --git a/backend/src/schema/resolvers/passwordReset.spec.js b/backend/src/schema/resolvers/passwordReset.spec.js new file mode 100644 index 000000000..d07ca4b09 --- /dev/null +++ b/backend/src/schema/resolvers/passwordReset.spec.js @@ -0,0 +1,46 @@ +import { GraphQLClient } from 'graphql-request' +import Factory from '../../seed/factories' +import { host, login } from '../../jest/helpers' +import { getDriver } from '../../bootstrap/neo4j' + +const factory = Factory() +let client +const driver = getDriver() + +const getAllPasswordResets = async () => { + const session = driver.session() + let transactionRes = await session.run('MATCH (r:PasswordReset) RETURN r') + const resets = transactionRes.records.map(record => record.get('r')) + session.close() + return resets +} + +describe('passwordReset', () => { + beforeEach(async () => { + client = new GraphQLClient(host) + await factory.create('User', { + email: 'user@example.org', + role: 'user', + password: '1234', + }) + }) + + afterEach(async () => { + await factory.cleanDatabase() + }) + + describe('requestPasswordReset', () => { + const variables = { email: 'user@example.org' } + const mutation = `mutation($email: String!) { requestPasswordReset(email: $email) }` + + it('resolves', async () => { + await expect(client.request(mutation, variables)).resolves.toEqual(true) + }) + + it('creates node with label `PasswordReset`', async () => { + await client.request(mutation, variables) + const resets = await getAllPasswordResets() + expect(resets).toHaveLength(1) + }) + }) +}) diff --git a/backend/src/schema/resolvers/user_management.js b/backend/src/schema/resolvers/user_management.js index eb07a07b3..e33314f7e 100644 --- a/backend/src/schema/resolvers/user_management.js +++ b/backend/src/schema/resolvers/user_management.js @@ -59,7 +59,7 @@ export default { changePassword: async (_, { oldPassword, newPassword }, { driver, user }) => { const session = driver.session() let result = await session.run( - `MATCH (user:User {email: $userEmail}) + `MATCH (user:User {email: $userEmail}) RETURN user {.id, .email, .password}`, { userEmail: user.email, diff --git a/backend/src/schema/types/schema.gql b/backend/src/schema/types/schema.gql index 2a8be9e09..358797631 100644 --- a/backend/src/schema/types/schema.gql +++ b/backend/src/schema/types/schema.gql @@ -25,6 +25,8 @@ type Mutation { login(email: String!, password: String!): String! signup(email: String!, password: String!): Boolean! changePassword(oldPassword: String!, newPassword: String!): String! + requestPasswordReset(email: String!): Boolean! + resetPassword(email: String!, resetToken: String!, newPassword: String!): String! report(id: ID!, description: String): Report disable(id: ID!): ID enable(id: ID!): ID