forked from canada-ca/tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreset-password.js
More file actions
124 lines (111 loc) · 3.96 KB
/
reset-password.js
File metadata and controls
124 lines (111 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const { GraphQLNonNull, GraphQLString } = require('graphql')
const { mutationWithClientMutationId } = require('graphql-relay')
const { t } = require('@lingui/macro')
const resetPassword = new mutationWithClientMutationId({
name: 'ResetPassword',
description:
'This mutation allows the user to take the token they received in their email to reset their password.',
inputFields: () => ({
password: {
type: GraphQLNonNull(GraphQLString),
description: 'The users new password.',
},
confirmPassword: {
type: GraphQLNonNull(GraphQLString),
description: 'A confirmation password to confirm the new password.',
},
resetToken: {
type: GraphQLNonNull(GraphQLString),
description:
'The JWT found in the url, redirected from the email they received.',
},
}),
outputFields: () => ({
status: {
type: GraphQLString,
description:
'Informs the user if the password reset was successful, and to redirect to sign in page.',
resolve: async (payload) => {
return payload.status
},
},
}),
mutateAndGetPayload: async (
args,
{
i18n,
query,
auth: { verifyToken, bcrypt },
loaders: { userLoaderByKey },
validators: { cleanseInput },
},
) => {
// Cleanse input
const password = cleanseInput(args.password)
const confirmPassword = cleanseInput(args.confirmPassword)
const resetToken = cleanseInput(args.resetToken)
// Check if reset token is valid
const tokenParameters = verifyToken({ token: resetToken })
// Check to see if user id exists in token params !!!
if (
tokenParameters.userId === 'undefined' ||
typeof tokenParameters.userId === 'undefined'
) {
console.warn(
`When resetting password user attempted to verify account, but userId is not located in the token parameters.`,
)
throw new Error(i18n._(t`Unable to reset password. Please try again.`))
}
// Check if user exists
const user = await userLoaderByKey.load(tokenParameters.userId)
if (typeof user === 'undefined') {
console.warn(
`A user attempted to reset the password for ${tokenParameters.userId}, however there is no associated account.`,
)
throw new Error(i18n._(t`Unable to reset password. Please try again.`))
}
// Check if password in token matches token in db
if (tokenParameters.currentPassword !== user.password) {
console.warn(
`User: ${user._key} attempted to reset password, however the current password does not match the current hashed password in the db.`,
)
throw new Error(i18n._(t`Unable to reset password. Please try again.`))
}
// Check to see if newly submitted passwords match
if (password !== confirmPassword) {
console.warn(
`User: ${user._key} attempted to reset their password, however the submitted passwords do not match.`,
)
throw new Error(i18n._(t`New passwords do not match. Please try again.`))
}
// Check to see if password meets GoC requirements
if (password.length < 12) {
console.warn(
`User: ${user._key} attempted to reset their password, however the submitted password is not long enough.`,
)
throw new Error(
i18n._(t`Password is not strong enough. Please try again.`),
)
}
// Update users password in db
const hashedPassword = bcrypt.hashSync(password, 10)
try {
await query`
FOR user IN users
UPDATE ${user._key} WITH { password: ${hashedPassword} } IN users
`
} catch (err) {
console.error(
`Database error ocurred when user: ${user._key} attempted to reset their password: ${err}`,
)
throw new Error(i18n._(t`Unable to reset password. Please try again.`))
}
console.info(`User: ${user._key} successfully reset their password.`)
return {
status: i18n._(t`Password was successfully reset.`),
}
},
})
module.exports = {
resetPassword,
}