Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4f7deaf

Browse files
fix: update service
1 parent 7e01fa7 commit 4f7deaf

File tree

8 files changed

+183
-137
lines changed

8 files changed

+183
-137
lines changed

‎src/app/service/auth.ts‎

Lines changed: 77 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import _ from 'lodash'
2-
import { Repository} from 'typeorm'
2+
import { Model,ModelStatic} from 'sequelize'
33
import { v4 as uuidv4 } from 'uuid'
44
import { env } from '~/config/env'
5+
import { logger } from '~/config/logger'
56
import { ConstRole } from '~/lib/constant/seed/role'
67
import ErrorResponse from '~/lib/http/errors'
78
import JwtToken from '~/lib/token/jwt'
89
import { validate } from '~/lib/validate'
9-
import { AppDataSource } from '../database/connection'
10+
import { db } from '../database/connection'
1011
import { Role } from '../database/entity/role'
1112
import { Session } from '../database/entity/session'
1213
import { User } from '../database/entity/user'
1314
import { LoginSchema, loginSchema, UserLoginState, userSchema } from '../database/schema/user'
1415
import 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

1721
type VerifySessionParams = {
1822
user_id: string
@@ -25,10 +29,18 @@ const jwt = new JwtToken({ secret: env.JWT_SECRET, expires: env.JWT_EXPIRES })
2529
const sessionService = new SessionService()
2630

2731
export 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')

‎src/app/service/base.ts‎

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import _ from 'lodash'
2-
import { FindOneOptions,In,ObjectLiteral,Repository} from 'typeorm'
2+
import { Attributes,Model,ModelStatic,NonNullFindOptions,Op} from 'sequelize'
33
import { z } from 'zod'
44
import ErrorResponse from '~/lib/http/errors'
55
import { useQuery } from '~/lib/query-builder'
66
import { validate } from '~/lib/validate'
77
import { BaseServiceParams, DtoFindAll, FindParams } from './types'
88

9-
export default class BaseService<T extends ObjectLiteral> {
10-
public repository: Repository<T>
9+
export default class BaseService<T extends Model> {
10+
public repository: ModelStatic<T>
1111
private _schema: z.ZodType<any>
1212
protected _model: string
1313

@@ -21,23 +21,29 @@ export default class BaseService<T extends ObjectLiteral> {
2121
* Find all
2222
*/
2323
async find({ page, pageSize, filtered = [], sorted = [] }: FindParams): Promise<DtoFindAll<T>> {
24-
const query = this.repository.createQueryBuilder(this._model)
25-
const newQuery = useQuery({
26-
query,
27-
model: this._model,
24+
const query = useQuery({
25+
model: this.repository,
2826
reqQuery: { page, pageSize, filtered, sorted },
27+
includeRule: [],
2928
})
3029

31-
const data = await newQuery.getMany()
32-
const total = await newQuery.getCount()
30+
const data = await this.repository.findAll({
31+
...query,
32+
order: query.order ? query.order : [['created_at', 'desc']],
33+
})
34+
35+
const total = await this.repository.count({
36+
include: query.includeCount,
37+
where: query.where,
38+
})
3339

3440
return { data, total }
3541
}
3642

3743
/**
3844
* Find one
3945
*/
40-
protected async _findOne(options: FindOneOptions<T>): Promise<T> {
46+
protected async _findOne(options: NonNullFindOptions<Attributes<T>>): Promise<T> {
4147
const record = await this.repository.findOne(options)
4248

4349
if (!record) {
@@ -50,7 +56,7 @@ export default class BaseService<T extends ObjectLiteral> {
5056
/**
5157
* Find by id
5258
*/
53-
async findById(id: string, options?: FindOneOptions<T>): Promise<T> {
59+
async findById(id: string, options?: NonNullFindOptions<Attributes<T>>): Promise<T> {
5460
const newId = validate.uuid(id)
5561

5662
// @ts-expect-error
@@ -62,7 +68,7 @@ export default class BaseService<T extends ObjectLiteral> {
6268
*/
6369
async create(data: T): Promise<T> {
6470
const values = this._schema.parse(data)
65-
return this.repository.save(values)
71+
return this.repository.create(values)
6672
}
6773

6874
/**
@@ -72,31 +78,37 @@ export default class BaseService<T extends ObjectLiteral> {
7278
const record = await this.findById(id)
7379

7480
const values = this._schema.parse({ ...record, ...data })
75-
return this.repository.save({ ...record, ...values })
81+
return record.update({ ...record, ...values })
7682
}
7783

7884
/**
7985
* Restore
8086
*/
8187
async restore(id: string) {
82-
const record = await this.findById(id, { withDeleted: true })
83-
await this.repository.restore(record.id)
88+
const record = await this.findById(id, { rejectOnEmpty: true, paranoid: true })
89+
90+
// @ts-expect-error
91+
await this.repository.restore({ where: { id: record.id } })
8492
}
8593

8694
/**
8795
* Soft delete
8896
*/
8997
async softDelete(id: string) {
90-
const record = await this.findById(id)
91-
await this.repository.softDelete(record.id)
98+
const record = await this.findById(id, { rejectOnEmpty: true, paranoid: true })
99+
100+
// @ts-expect-error
101+
await this.repository.destroy({ where: { id: record.id }, force: false })
92102
}
93103

94104
/**
95105
* Force delete
96106
*/
97107
async forceDelete(id: string) {
98-
const record = await this.findById(id)
99-
await this.repository.delete(record.id)
108+
const record = await this.findById(id, { rejectOnEmpty: true, paranoid: true })
109+
110+
// @ts-expect-error
111+
await this.repository.destroy({ where: { id: record.id }, force: true })
100112
}
101113

102114
/**
@@ -117,7 +129,7 @@ export default class BaseService<T extends ObjectLiteral> {
117129
const newIds = this._validateIds(ids)
118130

119131
// @ts-expect-error
120-
await this.repository.restore({ where: { id: In(newIds)},withDeleted: true })
132+
await this.repository.restore({ where: { id: {[Op.in]: newIds}},paranoid: true })
121133
}
122134

123135
/**
@@ -127,7 +139,7 @@ export default class BaseService<T extends ObjectLiteral> {
127139
const newIds = this._validateIds(ids)
128140

129141
// @ts-expect-error
130-
await this.repository.softDelete({ where: { id: In(newIds)} })
142+
await this.repository.destroy({ where: { id: {[Op.in]: newIds}},force: false })
131143
}
132144

133145
/**
@@ -137,6 +149,6 @@ export default class BaseService<T extends ObjectLiteral> {
137149
const newIds = this._validateIds(ids)
138150

139151
// @ts-expect-error
140-
await this.repository.delete({ where: { id: In(newIds)} })
152+
await this.repository.destroy({ where: { id: {[Op.in]: newIds}},force: true })
141153
}
142154
}

‎src/app/service/role.ts‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
import { AppDataSource} from '../database/connection'
1+
import { Model,ModelStatic} from 'sequelize'
22
import { Role } from '../database/entity/role'
33
import { roleSchema } from '../database/schema/role'
44
import BaseService from './base'
55

6-
export default class RoleService extends BaseService<Role> {
6+
// Define a type that ensures Role is recognized as a Sequelize Model
7+
type RoleModel = Role & Model
8+
9+
export default class RoleService extends BaseService<RoleModel> {
710
constructor() {
811
super({
9-
repository: AppDataSource.getRepository(Role),
12+
repository: RoleasunknownasModelStatic<RoleModel>,
1013
schema: roleSchema,
1114
model: 'role',
1215
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /