11import _ from 'lodash'
2- import { Repository } from 'typeorm '
2+ import { Model , ModelStatic } from 'sequelize '
33import { v4 as uuidv4 } from 'uuid'
44import { env } from '~/config/env'
5+ import { logger } from '~/config/logger'
56import { ConstRole } from '~/lib/constant/seed/role'
67import ErrorResponse from '~/lib/http/errors'
78import JwtToken from '~/lib/token/jwt'
89import { validate } from '~/lib/validate'
9- import { AppDataSource } from '../database/connection'
10+ import { db } from '../database/connection'
1011import { Role } from '../database/entity/role'
1112import { Session } from '../database/entity/session'
1213import { User } from '../database/entity/user'
1314import { LoginSchema , loginSchema , UserLoginState , userSchema } from '../database/schema/user'
1415import SessionService from './session'
15- import { fromUnixTime } from 'date-fns'
16+ 17+ type UserModel = User & Model
18+ type RoleModel = Role & Model
19+ type SessionModel = Session & Model
1620
1721type VerifySessionParams = {
1822 user_id : string
@@ -25,10 +29,18 @@ const jwt = new JwtToken({ secret: env.JWT_SECRET, expires: env.JWT_EXPIRES })
2529const sessionService = new SessionService ( )
2630
2731export default class AuthService {
28- private _repository : Repository < User >
32+ private _repository : {
33+ user : ModelStatic < UserModel >
34+ role : ModelStatic < RoleModel >
35+ session : ModelStatic < SessionModel >
36+ }
2937
3038 constructor ( ) {
31- this . _repository = AppDataSource . getRepository ( User )
39+ this . _repository = {
40+ user : User as unknown as ModelStatic < UserModel > ,
41+ role : Role as unknown as ModelStatic < RoleModel > ,
42+ session : Session as unknown as ModelStatic < SessionModel > ,
43+ }
3244 }
3345
3446 /**
@@ -51,8 +63,7 @@ export default class AuthService {
5163 } )
5264
5365 const formRegister : any = { ...values , password : validate . empty ( formData . new_password ) }
54- const userEntity = new User ( )
55- const data = await this . _repository . save ( { ...userEntity , ...formRegister } )
66+ const data = await this . _repository . user . create ( { ...formRegister } )
5667
5768 return data
5869 }
@@ -62,67 +73,72 @@ export default class AuthService {
6273 */
6374 async login ( formData : LoginSchema ) {
6475 const values = loginSchema . parse ( formData )
65- let data : any
66- 67- await AppDataSource . transaction ( async ( entityManager ) => {
68- const repo = {
69- user : entityManager . getRepository ( User ) ,
70- role : entityManager . getRepository ( Role ) ,
71- session : entityManager . getRepository ( Session ) ,
72- }
73- 74- const getUser = await repo . user . findOne ( {
75- select : [ 'id' , 'fullname' , 'email' , 'password' , 'is_active' , 'role_id' ] ,
76- where : { email : values . email } ,
77- } )
7876
79- if ( ! getUser ) {
80- throw new ErrorResponse . NotFound ( 'user not found' )
81- }
82- 83- if ( ! getUser . is_active ) {
84- throw new ErrorResponse . BadRequest ( 'user is not active, please verify your email' )
85- }
86- 87- const isPasswordMatch = await getUser . comparePassword ( values . password )
88- if ( ! isPasswordMatch ) {
89- throw new ErrorResponse . BadRequest ( 'current password is incorrect' )
90- }
91- 92- const getRole = await repo . role . findOne ( { where : { id : getUser . role_id } } )
93- if ( ! getRole ) {
94- throw new ErrorResponse . NotFound ( 'role not found' )
95- }
96- 97- const payload = JSON . parse ( JSON . stringify ( { uid : getUser . id } ) )
98- const { token, expiresIn } = jwt . generate ( payload )
99- 100- const sessionEntity = new Session ( )
101- const formSession = { ...formData , user_id : getUser . id , token }
102- 103- // @ts -expect-error
104- await repo . session . save ( { ...sessionEntity , ...formSession } )
105- const is_admin = [ ConstRole . ID_ADMIN , ConstRole . ID_SUPER_ADMIN ] . includes ( getRole . id )
106- 107- data = {
108- fullname : getUser . fullname ,
109- email : getUser . email ,
110- uid : getUser . id ,
111- access_token : token ,
112- expires_at : new Date ( Date . now ( ) + expiresIn * 1000 ) ,
113- expires_in : expiresIn ,
114- is_admin,
115- }
116- } )
77+ try {
78+ let data : any
79+ 80+ await db . sequelize ! . transaction ( async ( transaction ) => {
81+ const repo = {
82+ user : this . _repository . user ,
83+ role : this . _repository . role ,
84+ session : this . _repository . session ,
85+ }
86+ 87+ const getUser = await repo . user . findOne ( {
88+ attributes : [ 'id' , 'fullname' , 'email' , 'password' , 'is_active' , 'role_id' ] ,
89+ where : { email : values . email } ,
90+ transaction,
91+ } )
92+ 93+ if ( ! getUser ) {
94+ throw new ErrorResponse . NotFound ( 'user not found' )
95+ }
96+ 97+ if ( ! getUser . is_active ) {
98+ throw new ErrorResponse . BadRequest ( 'user is not active, please verify your email' )
99+ }
100+ 101+ const isPasswordMatch = await getUser . comparePassword ( values . password )
102+ if ( ! isPasswordMatch ) {
103+ throw new ErrorResponse . BadRequest ( 'current password is incorrect' )
104+ }
105+ 106+ const getRole = await repo . role . findOne ( { where : { id : getUser . role_id } , transaction } )
107+ if ( ! getRole ) {
108+ throw new ErrorResponse . NotFound ( 'role not found' )
109+ }
110+ 111+ const payload = JSON . parse ( JSON . stringify ( { uid : getUser . id } ) )
112+ const { token, expiresIn } = jwt . generate ( payload )
113+ 114+ const formSession = { ...formData , user_id : getUser . id , token }
115+ await repo . session . create ( { ...formSession } , { transaction } )
116+ 117+ const is_admin = [ ConstRole . ID_ADMIN , ConstRole . ID_SUPER_ADMIN ] . includes ( getRole . id )
118+ 119+ data = {
120+ fullname : getUser . fullname ,
121+ email : getUser . email ,
122+ uid : getUser . id ,
123+ access_token : token ,
124+ expires_at : new Date ( Date . now ( ) + expiresIn * 1000 ) ,
125+ expires_in : expiresIn ,
126+ is_admin,
127+ }
128+ } )
117129
118- return data
130+ return data
131+ } catch ( error ) {
132+ logger . error ( error )
133+ throw new ErrorResponse . InternalServer ( 'failed to login' )
134+ }
119135 }
120136
121137 /**
122138 * Verify user session
123139 */
124140 async verifySession ( { user_id, token } : VerifySessionParams ) {
125- const user = await this . _repository . findOne ( { where : { id : user_id } } )
141+ const user = await this . _repository . user . findOne ( { where : { id : user_id } } )
126142
127143 if ( ! user ) {
128144 throw new ErrorResponse . NotFound ( 'user not found' )
@@ -143,7 +159,7 @@ export default class AuthService {
143159 * Logout user
144160 */
145161 async logout ( { user_id, token } : LogoutParams ) {
146- const user = await this . _repository . findOne ( { where : { id : user_id } } )
162+ const user = await this . _repository . user . findOne ( { where : { id : user_id } } )
147163
148164 if ( ! user ) {
149165 throw new ErrorResponse . NotFound ( 'user not found' )
0 commit comments