1
1
import bcrypt from "bcrypt" ;
2
- import jwt from "jsonwebtoken" ;
3
2
import { jwtConfig , REFRESH_TOKEN_COOKIE_KEY , refreshTokenCookieOptions } from "../config/authConfig.js" ;
4
3
import { isValidObjectId } from "mongoose" ;
5
4
import {
@@ -12,10 +11,15 @@ import {
12
11
findUserByUsernameOrEmail as _findUserByUsernameOrEmail ,
13
12
updateUserById as _updateUserById ,
14
13
updateUserPrivilegeById as _updateUserPrivilegeById ,
14
+ findUserByEmail ,
15
15
} from "../model/repository.js" ;
16
- import { BadRequestError , ConflictError , NotFoundError } from "../utils/httpErrors.js" ;
16
+ import { BadRequestError , ConflictError , NotFoundError , UnauthorisedError } from "../utils/httpErrors.js" ;
17
17
import TokenService from "../services/tokenService.js" ;
18
+ import { sendEmail } from "../services/emailService.js" ;
19
+ import dotenv from "dotenv" ;
18
20
21
+ dotenv . config ( ) ;
22
+ const PASSWORD_SALT = 10 ;
19
23
export async function createUser ( req , res , next ) {
20
24
try {
21
25
const { username, email, password } = req . body ;
@@ -28,7 +32,7 @@ export async function createUser(req, res, next) {
28
32
throw new ConflictError ( "Username or email already exists" ) ;
29
33
}
30
34
31
- const salt = bcrypt . genSaltSync ( 10 ) ;
35
+ const salt = bcrypt . genSaltSync ( PASSWORD_SALT ) ;
32
36
const hashedPassword = bcrypt . hashSync ( password , salt ) ;
33
37
const createdUser = await _createUser ( username , email , hashedPassword ) ;
34
38
@@ -42,12 +46,11 @@ export async function createUser(req, res, next) {
42
46
data : { accessToken, user : { ...formatUserResponse ( createdUser ) } } ,
43
47
} ) ;
44
48
} catch ( err ) {
45
- console . error ( ' Error creating user:' , err ) ;
49
+ console . error ( " Error creating user:" , err ) ;
46
50
next ( err ) ;
47
51
}
48
52
}
49
53
50
-
51
54
export async function getUser ( req , res , next ) {
52
55
try {
53
56
const userId = req . params . id ;
@@ -101,7 +104,7 @@ export async function updateUser(req, res, next) {
101
104
102
105
let hashedPassword ;
103
106
if ( password ) {
104
- const salt = bcrypt . genSaltSync ( 10 ) ;
107
+ const salt = bcrypt . genSaltSync ( PASSWORD_SALT ) ;
105
108
hashedPassword = bcrypt . hashSync ( password , salt ) ;
106
109
}
107
110
const updatedUser = await _updateUserById ( userId , username , email , hashedPassword ) ;
@@ -162,6 +165,56 @@ export async function deleteUser(req, res, next) {
162
165
}
163
166
}
164
167
168
+ export async function forgetPassword ( req , res , next ) {
169
+ try {
170
+ const { email } = req . body ;
171
+ const resetToken = await TokenService . generateResetToken ( email ) ;
172
+ const passwordResetLink = `${ process . env . APP_URL } /reset-password?token=${ resetToken } ` ;
173
+
174
+ await sendEmail ( {
175
+ to : email ,
176
+ subject : "Reset password" ,
177
+ htmlTemplateData : { passwordResetLink } ,
178
+ } ) ;
179
+
180
+ res . sendStatus ( 204 ) ;
181
+ } catch ( err ) {
182
+ console . error ( err ) ;
183
+ next ( err ) ;
184
+ }
185
+ }
186
+
187
+ export async function resetPassword ( req , res , next ) {
188
+ try {
189
+ const { password, token } = req . body ;
190
+ if ( password ) {
191
+ const decoded = await TokenService . verifyResetToken ( token , jwtConfig . resetTokenSecret ) ;
192
+
193
+ if ( await TokenService . isResetTokenBlacklisted ( decoded ) ) {
194
+ throw new UnauthorisedError ( "Reset token is invalid" ) ;
195
+ }
196
+
197
+ const email = decoded . email ;
198
+ const user = await findUserByEmail ( email ) ;
199
+ if ( ! user ) {
200
+ throw new NotFoundError ( `No user with the email ${ email } is found` ) ;
201
+ }
202
+ const salt = bcrypt . genSaltSync ( PASSWORD_SALT ) ;
203
+ const hashedPassword = bcrypt . hashSync ( password , salt ) ;
204
+ const updatedUser = await _updateUserById ( user . id , user . username , user . email , hashedPassword ) ;
205
+ await TokenService . blacklistResetToken ( decoded ) ;
206
+
207
+ return res . status ( 200 ) . json ( {
208
+ message : "Password has been resetted" ,
209
+ data : formatUserResponse ( updatedUser ) ,
210
+ } ) ;
211
+ }
212
+ } catch ( err ) {
213
+ console . error ( err ) ;
214
+ next ( err ) ;
215
+ }
216
+ }
217
+
165
218
export function formatUserResponse ( user ) {
166
219
return {
167
220
_id : user . id ,
0 commit comments