forked from canada-ca/tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsign-up.js
More file actions
146 lines (132 loc) · 4.28 KB
/
sign-up.js
File metadata and controls
146 lines (132 loc) · 4.28 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
const { GraphQLNonNull, GraphQLString } = require('graphql')
const { mutationWithClientMutationId } = require('graphql-relay')
const { t } = require('@lingui/macro')
const { LanguageEnums } = require('../../enums')
const { GraphQLEmailAddress } = require('graphql-scalars')
const { authResultType } = require('../../types')
const signUp = new mutationWithClientMutationId({
name: 'SignUp',
description:
'This mutation allows for new users to sign up for our sites services.',
inputFields: () => ({
displayName: {
type: GraphQLNonNull(GraphQLString),
description: 'The name that will be displayed to other users.',
},
userName: {
type: GraphQLNonNull(GraphQLEmailAddress),
description: 'Email address that the user will use to authenticate with.',
},
password: {
type: GraphQLNonNull(GraphQLString),
description: 'The password the user will authenticate with.',
},
confirmPassword: {
type: GraphQLNonNull(GraphQLString),
description:
'A secondary password field used to confirm the user entered the correct password.',
},
preferredLang: {
type: GraphQLNonNull(LanguageEnums),
description: 'The users preferred language.',
},
signUpToken: {
type: GraphQLString,
description:
'A token sent by email, that will assign a user to an organization with a pre-determined role.',
},
}),
outputFields: () => ({
authResult: {
type: authResultType,
description: 'The authenticated users information, and JWT.',
resolve: async ({ authResult }) => {
return authResult
},
},
}),
mutateAndGetPayload: async (
args,
{
i18n,
query,
auth: { tokenize, bcrypt },
loaders: { userLoaderByUserName },
validators: { cleanseInput },
},
) => {
// Cleanse Inputs
const displayName = cleanseInput(args.displayName)
const userName = cleanseInput(args.userName).toLowerCase()
const password = cleanseInput(args.password)
const confirmPassword = cleanseInput(args.confirmPassword)
const preferredLang = cleanseInput(args.preferredLang)
// Check to make sure password meets length requirement
if (password.length < 12) {
console.warn(
`User: ${userName} tried to sign up but did not meet requirements.`,
)
throw new Error(i18n._(t`Password is too short.`))
}
// Check that password and password confirmation match
if (password !== confirmPassword) {
console.warn(
`User: ${userName} tried to sign up but passwords do not match.`,
)
throw new Error(i18n._(t`Passwords do not match.`))
}
// Check to see if user already exists
const checkUser = await userLoaderByUserName.load(userName)
if (typeof checkUser !== 'undefined') {
console.warn(
`User: ${userName} tried to sign up, however there is already an account in use with that username.`,
)
throw new Error(i18n._(t`Username already in use.`))
}
// Hash Users Password
const hashedPassword = bcrypt.hashSync(password, 10)
// Create User Structure for insert
const user = {
displayName: displayName,
userName: userName,
password: hashedPassword,
preferredLang: preferredLang,
tfaValidated: false,
emailValidated: false,
failedLoginAttempts: 0,
}
let insertedCursor, insertedUser
try {
insertedCursor = await query`
INSERT ${user} INTO users RETURN NEW
`
} catch (err) {
console.error(
`Database error occurred when ${userName} tried to sign up: ${err}`,
)
throw new Error(i18n._(t`Unable to sign up. Please try again.`))
}
try {
insertedUser = await insertedCursor.next()
} catch (err) {
console.error(
`Cursor error occurred when trying to get new user ${userName}: ${err}`,
)
throw new Error(i18n._(t`Unable to sign up. Please try again.`))
}
// Assign global id
insertedUser.id = insertedUser._key
// Generate JWT
const token = tokenize({ parameters: { userId: insertedUser._key } })
console.info(`User: ${userName} successfully created a new account.`)
return {
authResult: {
token,
user: insertedUser,
},
}
},
})
module.exports = {
signUp,
}