@@ -24,27 +24,20 @@ module.exports = {
24
24
async function authenticate ( { email, password } ) {
25
25
const account = await Account . findOne ( { email, isVerified : true } ) ;
26
26
if ( account && bcrypt . compareSync ( password , account . passwordHash ) ) {
27
+ // return basic details and auth token
27
28
const token = jwt . sign ( { sub : account . id , id : account . id } , config . secret ) ;
28
- return {
29
- ...account . toJSON ( ) ,
30
- token
31
- } ;
29
+ return { ...basicDetails ( account ) , token } ;
32
30
}
33
31
}
34
32
35
33
async function register ( params , origin ) {
36
34
// validate
37
35
if ( await Account . findOne ( { email : params . email } ) ) {
38
- // send already registered notification in email to prevent account enumeration
39
- return sendEmail ( {
40
- to : params . email ,
41
- subject : 'Sign-up Verification API - Email Already Registered' ,
42
- html : `<h4>Email Already Registered</h4>
43
- <p>Your email <strong>${ params . email } </strong> is already registered.</p>
44
- <p>If you don't know your password please visit the <a href="${ origin } /account/forgot-password">forgot password</a> page.</p>`
45
- } ) ;
36
+ // send already registered error in email to prevent account enumeration
37
+ return sendAlreadyRegisteredEmail ( params . email , origin ) ;
46
38
}
47
39
40
+ // create account object
48
41
const account = new Account ( params ) ;
49
42
50
43
// first registered account is an admin
@@ -61,16 +54,8 @@ async function register(params, origin) {
61
54
// save account
62
55
await account . save ( ) ;
63
56
64
- // send verification email
65
- const verifyUrl = `${ origin } /account/verify-email?token=${ account . verificationToken } ` ;
66
- return sendEmail ( {
67
- to : params . email ,
68
- subject : 'Sign-up Verification API - Verify Email' ,
69
- html : `<h4>Verify Email</h4>
70
- <p>Thanks for registering!</p>
71
- <p>Please click the below link to verify your email address:</p>
72
- <p><a href="${ verifyUrl } ">${ verifyUrl } </a></p>`
73
- } ) ;
57
+ // send email
58
+ sendVerificationEmail ( account , origin ) ;
74
59
}
75
60
76
61
async function verifyEmail ( { token } ) {
@@ -93,15 +78,8 @@ async function forgotPassword({ email }, origin) {
93
78
account . resetTokenExpiry = new Date ( Date . now ( ) + 24 * 60 * 60 * 1000 ) . toISOString ( ) ;
94
79
account . save ( ) ;
95
80
96
- // send password reset email
97
- const resetUrl = `${ origin } /account/reset-password?token=${ account . resetToken } ` ;
98
- sendEmail ( {
99
- to : email ,
100
- subject : 'Sign-up Verification API - Reset Password' ,
101
- html : `<h4>Reset Password Email</h4>
102
- <p>Please click the below link to reset your password, the link will be valid for 1 day:</p>
103
- <p><a href="${ resetUrl } ">${ resetUrl } </a></p>`
104
- } )
81
+ // send email
82
+ sendPasswordResetEmail ( account , origin ) ;
105
83
}
106
84
107
85
async function validateResetToken ( { token } ) {
@@ -130,11 +108,13 @@ async function resetPassword({ token, password }) {
130
108
}
131
109
132
110
async function getAll ( ) {
133
- return await Account . find ( ) ;
111
+ const accounts = await Account . find ( ) ;
112
+ return accounts . map ( x => basicDetails ( x ) ) ;
134
113
}
135
114
136
115
async function getById ( id ) {
137
- return await Account . findById ( id ) ;
116
+ const account = await getAccount ( id ) ;
117
+ return basicDetails ( account ) ;
138
118
}
139
119
140
120
async function create ( params ) {
@@ -153,13 +133,14 @@ async function create(params) {
153
133
154
134
// save account
155
135
await account . save ( ) ;
136
+
137
+ return basicDetails ( account ) ;
156
138
}
157
139
158
140
async function update ( id , params ) {
159
- const account = await Account . findById ( id ) ;
141
+ const account = await getAccount ( id ) ;
160
142
161
143
// validate
162
- if ( ! account ) throw 'Account not found' ;
163
144
if ( account . email !== params . email && await Account . findOne ( { email : params . email } ) ) {
164
145
throw 'Email "' + params . email + '" is already taken' ;
165
146
}
@@ -171,20 +152,91 @@ async function update(id, params) {
171
152
172
153
// copy params to account and save
173
154
Object . assign ( account , params ) ;
155
+ account . dateUpdated = Date . now ( ) ;
174
156
await account . save ( ) ;
175
- return account . toJSON ( ) ;
157
+
158
+ return basicDetails ( account ) ;
176
159
}
177
160
178
161
async function _delete ( id ) {
179
- await Account . findByIdAndRemove ( id ) ;
162
+ const account = await getAccount ( id ) ;
163
+ await account . remove ( ) ;
180
164
}
181
165
182
166
// helper functions
183
167
168
+ async function getAccount ( id ) {
169
+ if ( ! db . isValidId ( id ) ) throw 'Account not found' ;
170
+ const account = await Account . findById ( id ) ;
171
+ if ( ! account ) throw 'Account not found' ;
172
+ return account ;
173
+ }
174
+
184
175
function hash ( password ) {
185
176
return bcrypt . hashSync ( password , 10 ) ;
186
177
}
187
178
188
179
function generateToken ( ) {
189
180
return crypto . randomBytes ( 40 ) . toString ( 'hex' ) ;
181
+ }
182
+
183
+ function basicDetails ( account ) {
184
+ const { id, title, firstName, lastName, email, role, dateCreated, dateUpdated } = account ;
185
+ return { id, title, firstName, lastName, email, role, dateCreated, dateUpdated } ;
186
+ }
187
+
188
+ function sendVerificationEmail ( account , origin ) {
189
+ let message ;
190
+ if ( origin ) {
191
+ const verifyUrl = `${ origin } /account/verify-email?token=${ account . verificationToken } ` ;
192
+ message = `<p>Please click the below link to verify your email address:</p>
193
+ <p><a href="${ verifyUrl } ">${ verifyUrl } </a></p>` ;
194
+ } else {
195
+ message = `<p>Please use the below token to verify your email address with the <code>/account/verify-email</code> api route:</p>
196
+ <p><code>${ account . verificationToken } </code></p>` ;
197
+ }
198
+
199
+ sendEmail ( {
200
+ to : account . email ,
201
+ subject : 'Sign-up Verification API - Verify Email' ,
202
+ html : `<h4>Verify Email</h4>
203
+ <p>Thanks for registering!</p>
204
+ ${ message } `
205
+ } ) ;
206
+ }
207
+
208
+ function sendAlreadyRegisteredEmail ( email , origin ) {
209
+ let message ;
210
+ if ( origin ) {
211
+ message = `<p>If you don't know your password please visit the <a href="${ origin } /account/forgot-password">forgot password</a> page.</p>` ;
212
+ } else {
213
+ message = `<p>If you don't know your password you can reset it via the <code>/account/forgot-password</code> api route.</p>` ;
214
+ }
215
+
216
+ sendEmail ( {
217
+ to : email ,
218
+ subject : 'Sign-up Verification API - Email Already Registered' ,
219
+ html : `<h4>Email Already Registered</h4>
220
+ <p>Your email <strong>${ email } </strong> is already registered.</p>
221
+ ${ message } `
222
+ } ) ;
223
+ }
224
+
225
+ function sendPasswordResetEmail ( account , origin ) {
226
+ let message ;
227
+ if ( origin ) {
228
+ const resetUrl = `${ origin } /account/reset-password?token=${ account . resetToken } ` ;
229
+ message = `<p>Please click the below link to reset your password, the link will be valid for 1 day:</p>
230
+ <p><a href="${ resetUrl } ">${ resetUrl } </a></p>` ;
231
+ } else {
232
+ message = `<p>Please use the below token to reset your password with the <code>/account/reset-password</code> api route:</p>
233
+ <p><code>${ account . resetToken } </code></p>` ;
234
+ }
235
+
236
+ sendEmail ( {
237
+ to : account . email ,
238
+ subject : 'Sign-up Verification API - Reset Password' ,
239
+ html : `<h4>Reset Password Email</h4>
240
+ ${ message } `
241
+ } ) ;
190
242
}
0 commit comments