@@ -2,8 +2,9 @@ import jwt, { SignOptions } from 'jsonwebtoken'
22import { env } from '../../../constant/env.constant'
33import { IUser } from './user.type'
44import User from './user.model'
5+ import bcrypt from 'bcrypt'
56import * as argon2 from 'argon2'
6- import UserConstant from './user.constant'
7+ import UserConstant , { PasswordConfig } from './user.constant'
78
89export interface JwtPayload {
910 userId : string
@@ -21,7 +22,7 @@ class UserUtils {
2122 } as SignOptions )
2223 }
2324
24- public static verifyToken ( token : string ) : IUser | null {
25+ public static verifyToken ( token : string ) : Partial < IUser > | null {
2526 try {
2627 const decoded = jwt . verify ( token , this . JWT_SECRET )
2728
@@ -61,11 +62,11 @@ class UserUtils {
6162 if ( ! PassMatch ) {
6263 throw new Error ( UserConstant . INVALID_PASSWORD )
6364 }
64- const userObj : IUser = user . toObject ( )
65- delete ( userObj as { password ?: string } ) . password
66- delete ( userObj as { createdAt ?: Date } ) . createdAt
67- delete ( userObj as { updatedAt ?: Date } ) . updatedAt
68- delete ( userObj as { __v ?: number } ) . __v
65+ const userObj = this . sanitizeUser ( user )
66+
67+ if ( ! userObj ) {
68+ throw new Error ( UserConstant . USER_NOT_FOUND )
69+ }
6970
7071 const token = this . generateToken ( {
7172 userId : String ( user . _id ) ,
@@ -84,22 +85,16 @@ class UserUtils {
8485
8586 public static async findById ( userId : string ) : Promise < IUser | null > {
8687 const user = await User . findById ( userId )
87- return user
88+ return this . sanitizeUser ( user ) as IUser | null
8889 }
8990
9091 public static async passwordHash ( password : string ) : Promise < string > {
91- return await argon2 . hash ( password )
92+ return bcrypt . hash ( password , PasswordConfig . saltRounds )
9293 }
9394
9495 public static async findUserByEmail ( email : string ) : Promise < Partial < IUser > | null > {
9596 const user = await User . findOne ( { email } )
96- if ( ! user ) return null
97- const userObj = user . toObject ( ) as IUser
98- delete ( userObj as { password ?: string } ) . password
99- delete ( userObj as { createdAt ?: Date } ) . createdAt
100- delete ( userObj as { updatedAt ?: Date } ) . updatedAt
101- delete ( userObj as { __v ?: number } ) . __v
102- return userObj
97+ return this . sanitizeUser ( user )
10398 }
10499
105100 private static async passwordMatching ( {
@@ -109,7 +104,24 @@ class UserUtils {
109104 dbPass : string
110105 userPass : string
111106 } ) : Promise < boolean > {
112- return await argon2 . verify ( dbPass , userPass )
107+ const isBcryptMatch = await bcrypt . compare ( userPass , dbPass )
108+ if ( isBcryptMatch ) return true
109+
110+ try {
111+ return await argon2 . verify ( dbPass , userPass )
112+ } catch {
113+ return false
114+ }
115+ }
116+ public static sanitizeUser ( user : IUser | null ) : Partial < IUser > | null {
117+ if ( ! user ) return null
118+ const userObj = typeof ( user as any ) . toObject === 'function' ? ( user as any ) . toObject ( ) : { ...user }
119+
120+ delete ( userObj as { password ?: string } ) . password
121+ delete ( userObj as { __v ?: number } ) . __v
122+ delete ( userObj as { apikey ?: string | null } ) . apikey
123+ delete ( userObj as { modelApiKey ?: string | null } ) . modelApiKey
124+ return userObj as Partial < IUser >
113125 }
114126 public static maskApiKey ( apiKey : string ) : string {
115127 if ( ! apiKey || apiKey . length < 8 ) return '*'
0 commit comments