bmd-extension 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/launch.json +14 -0
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +9 -0
- package/DEPLOY.md +4 -0
- package/README.md +17 -0
- package/README_PRIVATE.md +1 -0
- package/build.sh +5 -0
- package/logo.png +0 -0
- package/media/dark/add.svg +40 -0
- package/media/dark/block.svg +1 -0
- package/media/dark/checklist-1.svg +1 -0
- package/media/dark/checklist.svg +1 -0
- package/media/dark/control.svg +1 -0
- package/media/dark/create.svg +1 -0
- package/media/dark/delete-1.svg +1 -0
- package/media/dark/delete.svg +1 -0
- package/media/dark/deploy-1.svg +2 -0
- package/media/dark/deploy.svg +2 -0
- package/media/dark/documents.svg +66 -0
- package/media/dark/earth.svg +68 -0
- package/media/dark/exe.svg +15 -0
- package/media/dark/export.svg +1 -0
- package/media/dark/function.svg +1 -0
- package/media/dark/game-controller.svg +77 -0
- package/media/dark/get.svg +1 -0
- package/media/dark/id-card.svg +59 -0
- package/media/dark/identity.svg +81 -0
- package/media/dark/import.svg +1 -0
- package/media/dark/information.svg +1 -0
- package/media/dark/interface.svg +1 -0
- package/media/dark/layout.svg +41 -0
- package/media/dark/leaf.svg +54 -0
- package/media/dark/list.svg +13 -0
- package/media/dark/logo.svg +249 -0
- package/media/dark/mockup.svg +1 -0
- package/media/dark/needle.svg +1 -0
- package/media/dark/pass.svg +46 -0
- package/media/dark/plus.svg +1 -0
- package/media/dark/post.svg +1 -0
- package/media/dark/quit.svg +1 -0
- package/media/dark/rocket.svg +28 -0
- package/media/dark/service.svg +1 -0
- package/media/dark/settings.svg +98 -0
- package/media/dark/social.svg +1 -0
- package/media/dark/spaceship-1.svg +1 -0
- package/media/dark/spaceship-2.svg +1 -0
- package/media/dark/spaceship.svg +1 -0
- package/media/dark/support.svg +88 -0
- package/media/dark/transfer.svg +1 -0
- package/media/dark/transform.svg +92 -0
- package/media/dark/update.svg +45 -0
- package/media/dark/upload-1.svg +1 -0
- package/media/dark/upload.svg +41 -0
- package/media/dark/vaccine.svg +1 -0
- package/media/dark/vr-gaming.svg +1 -0
- package/media/light/add.svg +40 -0
- package/media/light/block.svg +1 -0
- package/media/light/checklist-1.svg +1 -0
- package/media/light/checklist.svg +1 -0
- package/media/light/control.svg +1 -0
- package/media/light/create.svg +1 -0
- package/media/light/delete-1.svg +1 -0
- package/media/light/delete.svg +1 -0
- package/media/light/deploy-1.svg +2 -0
- package/media/light/deploy.svg +2 -0
- package/media/light/documents.svg +66 -0
- package/media/light/earth.svg +68 -0
- package/media/light/exe.svg +15 -0
- package/media/light/export.svg +1 -0
- package/media/light/function.svg +1 -0
- package/media/light/game-controller.svg +77 -0
- package/media/light/get.svg +1 -0
- package/media/light/id-card.svg +59 -0
- package/media/light/identity.svg +81 -0
- package/media/light/import.svg +1 -0
- package/media/light/information.svg +1 -0
- package/media/light/interface.svg +1 -0
- package/media/light/layout.svg +41 -0
- package/media/light/leaf.svg +54 -0
- package/media/light/list.svg +13 -0
- package/media/light/logo.svg +249 -0
- package/media/light/mockup.svg +1 -0
- package/media/light/needle.svg +1 -0
- package/media/light/pass.svg +46 -0
- package/media/light/plus.svg +1 -0
- package/media/light/post.svg +1 -0
- package/media/light/quit.svg +1 -0
- package/media/light/rocket.svg +28 -0
- package/media/light/service.svg +1 -0
- package/media/light/settings.svg +98 -0
- package/media/light/social.svg +1 -0
- package/media/light/spaceship-1.svg +1 -0
- package/media/light/spaceship-2.svg +1 -0
- package/media/light/spaceship.svg +1 -0
- package/media/light/support.svg +88 -0
- package/media/light/transfer.svg +1 -0
- package/media/light/transform.svg +92 -0
- package/media/light/update.svg +45 -0
- package/media/light/upload-1.svg +1 -0
- package/media/light/upload.svg +41 -0
- package/media/light/vaccine.svg +1 -0
- package/media/light/vr-gaming.svg +1 -0
- package/package-lock.json +6430 -0
- package/package.json +540 -0
- package/snippets-tsr.json +512 -0
- package/snippets.json +761 -0
- package/src/API.ts +14 -0
- package/src/FsProvider.ts +105 -0
- package/src/Request.ts +24 -0
- package/src/assets/api/api.txt +27 -0
- package/src/assets/configuration/AdminConfigurationController.ts.txt +72 -0
- package/src/assets/configuration/Configuration.ts.txt +37 -0
- package/src/assets/configuration/ConfigurationService.ts.txt +26 -0
- package/src/assets/contentDefine/AdminContentDefineController.ts.txt +91 -0
- package/src/assets/contentDefine/ContentDefine.ts.txt +45 -0
- package/src/assets/contentDefine/ContentDefineService.ts.txt +19 -0
- package/src/assets/contentDefine/CustomerContentDefineController.ts.txt +34 -0
- package/src/assets/controller/controller.txt +46 -0
- package/src/assets/controller/controllerResource.txt +103 -0
- package/src/assets/entity/entity.txt +22 -0
- package/src/assets/entity-request/entity-request.txt +18 -0
- package/src/assets/init/.env.example.txt +37 -0
- package/src/assets/init/.env.production.txt +37 -0
- package/src/assets/init/.gitignore.txt +8 -0
- package/src/assets/init/config.ts.txt +55 -0
- package/src/assets/init/deploy.sh.txt +46 -0
- package/src/assets/init/package-lock.json.txt +4184 -0
- package/src/assets/init/package.json.txt +79 -0
- package/src/assets/init/src/Server.ts.txt +167 -0
- package/src/assets/init/src/controllers/admin/AuthController.ts.txt +96 -0
- package/src/assets/init/src/controllers/admin/CustomerController.ts.txt +107 -0
- package/src/assets/init/src/controllers/admin/RoleController.ts.txt +143 -0
- package/src/assets/init/src/controllers/admin/StaffController.ts.txt +192 -0
- package/src/assets/init/src/controllers/customer/AuthController.ts.txt +170 -0
- package/src/assets/init/src/controllers/customer/CustomerController.ts.txt +32 -0
- package/src/assets/init/src/core/entity/CoreEntity.ts.txt +70 -0
- package/src/assets/init/src/core/services/CoreService.ts.txt +21 -0
- package/src/assets/init/src/entity/Customer.ts.txt +68 -0
- package/src/assets/init/src/entity/Permission.ts.txt +29 -0
- package/src/assets/init/src/entity/Role.ts.txt +36 -0
- package/src/assets/init/src/entity/Staff.ts.txt +54 -0
- package/src/assets/init/src/entity-request/CustomerInsert.ts.txt +42 -0
- package/src/assets/init/src/entity-request/CustomerUpdate.ts.txt +40 -0
- package/src/assets/init/src/entity-request/PermissionImport.ts.txt +12 -0
- package/src/assets/init/src/entity-request/StaffUpdate.ts.txt +33 -0
- package/src/assets/init/src/index.ts.txt +13 -0
- package/src/assets/init/src/middleware/auth/Verification.ts.txt +16 -0
- package/src/assets/init/src/middleware/auth/VerificationJWT.ts.txt +16 -0
- package/src/assets/init/src/middleware/auth/strategy/AuthStrategy.ts.txt +5 -0
- package/src/assets/init/src/middleware/auth/strategy/JWT.ts.txt +147 -0
- package/src/assets/init/src/middleware/error/handleError.ts.txt +22 -0
- package/src/assets/init/src/middleware/error/handleNotFound.ts.txt +7 -0
- package/src/assets/init/src/middleware/response/CustomSendResponse.ts.txt +35 -0
- package/src/assets/init/src/middleware/response/responseAPI.ts.txt +76 -0
- package/src/assets/init/src/middleware/validator/Validator.ts.txt +103 -0
- package/src/assets/init/src/services/CustomerService.ts.txt +79 -0
- package/src/assets/init/src/services/InitService.ts.txt +11 -0
- package/src/assets/init/src/services/MailService.ts.txt +271 -0
- package/src/assets/init/src/services/RoleService.ts.txt +66 -0
- package/src/assets/init/src/services/StaffService.ts.txt +104 -0
- package/src/assets/init/src/ssl/certificate-ca.crt +0 -0
- package/src/assets/init/src/ssl/certificate.crt +0 -0
- package/src/assets/init/src/ssl/private.key +0 -0
- package/src/assets/init/src/types/express.d.ts.txt +97 -0
- package/src/assets/init/src/util/expo.ts.txt +53 -0
- package/src/assets/init/src/util/helper.ts.txt +321 -0
- package/src/assets/init/src/util/language.ts.txt +8 -0
- package/src/assets/init/src/util/logger.ts.txt +47 -0
- package/src/assets/init/src/util/mailer.ts.txt +32 -0
- package/src/assets/init/src/util/password.ts.txt +13 -0
- package/src/assets/init/tsconfig.json.txt +26 -0
- package/src/assets/service/service.txt +34 -0
- package/src/constant.ts +83 -0
- package/src/extension.ts +459 -0
- package/src/provider/codeAction/controller/addPathParams.ts +65 -0
- package/src/provider/codeAction/controller/addTokenParam.ts +43 -0
- package/src/provider/codeAction/controller/addValidation.ts +47 -0
- package/src/provider/codeAction/controller/codeAction.ts +34 -0
- package/src/provider/codeAction/controller/util.ts +48 -0
- package/src/provider/codeAction/entity/codeAction.ts +48 -0
- package/src/provider/codeAction/entity/handleBuilder.ts +87 -0
- package/src/provider/codeAction/entity/handleFunction.ts +487 -0
- package/src/provider/codeAction/entity/handleProperty.ts +32 -0
- package/src/provider/codeAction/entity/handleRelation.ts +72 -0
- package/src/provider/codeAction/entity/helper.ts +132 -0
- package/src/provider/codeAction/entity-request/codeAction.ts +178 -0
- package/src/provider/codeAction/enum/codeAction.ts +95 -0
- package/src/provider/codeAction/service/codeAction.ts +232 -0
- package/src/provider/completion/CompletionProvider.ts +108 -0
- package/src/provider/errorChecking/checkHeaderToken.ts +60 -0
- package/src/provider/errorChecking/checkPathParam.ts +64 -0
- package/src/provider/errorChecking/checkRequired.ts +56 -0
- package/src/provider/errorChecking/errorChecking.ts +35 -0
- package/src/provider/errorChecking/util.ts +56 -0
- package/src/provider/treeDataProvider/Dependency.ts +26 -0
- package/src/provider/treeDataProvider/TreeProviderCommand.ts +60 -0
- package/src/provider/treeDataProvider/TreeProviderProject.ts +65 -0
- package/src/provider/treeDataProvider/api/createApi.ts +106 -0
- package/src/provider/treeDataProvider/controller/command/createController.ts +99 -0
- package/src/provider/treeDataProvider/controller/command/handleMethod.ts +363 -0
- package/src/provider/treeDataProvider/controller/treeData.ts +81 -0
- package/src/provider/treeDataProvider/deploy/command/handleDeploy.ts +70 -0
- package/src/provider/treeDataProvider/deploy/treeData.ts +21 -0
- package/src/provider/treeDataProvider/entity/command/addProperty.ts +144 -0
- package/src/provider/treeDataProvider/entity/command/addRelation.ts +125 -0
- package/src/provider/treeDataProvider/entity/command/createEntity.ts +53 -0
- package/src/provider/treeDataProvider/entity/command/createEntityRequest.ts +65 -0
- package/src/provider/treeDataProvider/entity/command/exportInterface.ts +130 -0
- package/src/provider/treeDataProvider/entity/treeData.ts +49 -0
- package/src/provider/treeDataProvider/module/command/configuration.ts +34 -0
- package/src/provider/treeDataProvider/module/command/contentDefine.ts +36 -0
- package/src/provider/treeDataProvider/module/command/initProject.ts +155 -0
- package/src/provider/treeDataProvider/module/treeData.ts +28 -0
- package/src/provider/treeDataProvider/project/command/addEnum.ts +0 -0
- package/src/provider/treeDataProvider/project/command/addProjectName.ts +23 -0
- package/src/provider/treeDataProvider/project/command/getProjectDetails.ts +284 -0
- package/src/provider/treeDataProvider/project/treeData.ts +28 -0
- package/src/provider/treeDataProvider/service/command/createService.ts +70 -0
- package/src/provider/treeDataProvider/service/command/handleConstructor.ts +134 -0
- package/src/provider/treeDataProvider/service/treeData.ts +25 -0
- package/src/types/project.d.ts +7 -0
- package/src/util.ts +145 -0
- package/src/utils/Password.ts +19 -0
- package/tsconfig.json +18 -0
- package/tslint.json +15 -0
- package/vsc-extension-quickstart.md +42 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
import { Property } from "@tsed/common";
|
2
|
+
|
3
|
+
import { Customer } from '../entity/Customer';
|
4
|
+
import { Password } from "../util/password";
|
5
|
+
|
6
|
+
export class CustomerInsert {
|
7
|
+
async toCustomer(): Promise<Customer> {
|
8
|
+
const customer = new Customer()
|
9
|
+
customer.phone = this.phone
|
10
|
+
customer.name = this.name
|
11
|
+
customer.email = this.email
|
12
|
+
customer.address = this.address
|
13
|
+
customer.gender = this.gender
|
14
|
+
customer.password = await Password.hash(this.password)
|
15
|
+
|
16
|
+
return customer
|
17
|
+
}
|
18
|
+
|
19
|
+
// PROPERTIES
|
20
|
+
|
21
|
+
@Property()
|
22
|
+
phone: string
|
23
|
+
|
24
|
+
@Property()
|
25
|
+
name: string;
|
26
|
+
|
27
|
+
@Property()
|
28
|
+
phoneRelative: string
|
29
|
+
|
30
|
+
@Property()
|
31
|
+
address: string
|
32
|
+
|
33
|
+
@Property()
|
34
|
+
password: string
|
35
|
+
|
36
|
+
@Property()
|
37
|
+
email: string
|
38
|
+
|
39
|
+
@Property()
|
40
|
+
gender: string
|
41
|
+
|
42
|
+
} // END FILE
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// IMPORT LIBRARY
|
2
|
+
import { Property } from "@tsed/common";
|
3
|
+
|
4
|
+
// IMPORT CUSTOM
|
5
|
+
import { Customer } from "../entity/Customer";
|
6
|
+
|
7
|
+
export class CustomerUpdate {
|
8
|
+
// Transform to draw entity
|
9
|
+
toCustomer(): Customer {
|
10
|
+
const customer = new Customer()
|
11
|
+
customer.name = this.name
|
12
|
+
customer.email = this.email
|
13
|
+
customer.address = this.address
|
14
|
+
customer.password = this.password
|
15
|
+
customer.avatar = this.avatar
|
16
|
+
|
17
|
+
return customer
|
18
|
+
}
|
19
|
+
|
20
|
+
// PROPERTIES
|
21
|
+
|
22
|
+
@Property()
|
23
|
+
name: string;
|
24
|
+
|
25
|
+
@Property()
|
26
|
+
avatar: string;
|
27
|
+
|
28
|
+
@Property()
|
29
|
+
phoneRelative: string
|
30
|
+
|
31
|
+
@Property()
|
32
|
+
address: string
|
33
|
+
|
34
|
+
@Property()
|
35
|
+
password: string
|
36
|
+
|
37
|
+
@Property()
|
38
|
+
email: string
|
39
|
+
|
40
|
+
} // END FILE
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { Property } from "@tsed/common";
|
2
|
+
|
3
|
+
import { Staff } from '../entity/Staff';
|
4
|
+
|
5
|
+
export class StaffUpdate {
|
6
|
+
toStaff(): Staff {
|
7
|
+
const staff = new Staff()
|
8
|
+
staff.name = this.name
|
9
|
+
staff.avatar = this.avatar
|
10
|
+
staff.phone = this.phone
|
11
|
+
staff.email = this.email
|
12
|
+
staff.isBlock = this.isBlock
|
13
|
+
return staff
|
14
|
+
}
|
15
|
+
|
16
|
+
// PROPERTIES
|
17
|
+
|
18
|
+
@Property()
|
19
|
+
name: string;
|
20
|
+
|
21
|
+
@Property()
|
22
|
+
avatar: string;
|
23
|
+
|
24
|
+
@Property()
|
25
|
+
phone: string;
|
26
|
+
|
27
|
+
@Property()
|
28
|
+
email: string;
|
29
|
+
|
30
|
+
@Property()
|
31
|
+
isBlock: boolean;
|
32
|
+
|
33
|
+
} // END FILE
|
@@ -0,0 +1,13 @@
|
|
1
|
+
//============= HANDLE PROCESS ENVIRONMENT VARIABLE =============
|
2
|
+
import dotenv from 'dotenv'
|
3
|
+
dotenv.config()
|
4
|
+
|
5
|
+
//============= START SERVER =============
|
6
|
+
import { Server } from "./Server"
|
7
|
+
|
8
|
+
new Server().start()
|
9
|
+
.then(() => {
|
10
|
+
})
|
11
|
+
.catch((err) => {
|
12
|
+
console.error(err);
|
13
|
+
})
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import AuthStrategy from './strategy/AuthStrategy';
|
2
|
+
import { Request } from 'express';
|
3
|
+
|
4
|
+
class Verification {
|
5
|
+
private authStrategy: AuthStrategy
|
6
|
+
|
7
|
+
constructor(authStrategy: AuthStrategy) {
|
8
|
+
this.authStrategy = authStrategy
|
9
|
+
}
|
10
|
+
|
11
|
+
auth = async (req: Request): Promise<any> => {
|
12
|
+
await this.authStrategy.auth(req)
|
13
|
+
}
|
14
|
+
}
|
15
|
+
|
16
|
+
export default Verification
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { EndpointInfo, IMiddleware, Middleware, Req } from "@tsed/common";
|
2
|
+
import { Request } from 'express';
|
3
|
+
|
4
|
+
import Verification from "./Verification";
|
5
|
+
import JWT from "./strategy/JWT";
|
6
|
+
|
7
|
+
@Middleware()
|
8
|
+
export class VerificationJWT implements IMiddleware {
|
9
|
+
public async use(
|
10
|
+
@Req() request: Request,
|
11
|
+
@EndpointInfo() endpoint: EndpointInfo
|
12
|
+
) {
|
13
|
+
const verification = new Verification(new JWT())
|
14
|
+
await verification.auth(request)
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,147 @@
|
|
1
|
+
import { InternalServerError } from 'ts-httpexceptions';
|
2
|
+
import { Request } from 'express';
|
3
|
+
import jwt from 'jsonwebtoken';
|
4
|
+
import { Unauthorized } from 'ts-httpexceptions';
|
5
|
+
|
6
|
+
import AuthStrategy from './AuthStrategy';
|
7
|
+
import { Staff } from '../../../entity/Staff';
|
8
|
+
import { Customer } from '../../../entity/Customer';
|
9
|
+
import logger from '../../../util/logger';
|
10
|
+
import CONFIG from '../../../../config';
|
11
|
+
// import { Driver } from '../../../entity/Driver';
|
12
|
+
import { getCurrentTimeInt } from '../../../util/helper';
|
13
|
+
|
14
|
+
export enum AuthType {
|
15
|
+
Staff = "ADMIN",
|
16
|
+
Customer = "CUSTOMER",
|
17
|
+
// Driver = 'DRIVER'
|
18
|
+
}
|
19
|
+
|
20
|
+
interface JWTSignedData {
|
21
|
+
id: number,
|
22
|
+
type: AuthType,
|
23
|
+
ia?: number
|
24
|
+
}
|
25
|
+
|
26
|
+
interface RequestHeaders {
|
27
|
+
token?: string,
|
28
|
+
version?: string
|
29
|
+
}
|
30
|
+
|
31
|
+
const VERSION = '1.0.0'
|
32
|
+
|
33
|
+
export default class JWT implements AuthStrategy {
|
34
|
+
|
35
|
+
public async auth(req: Request): Promise<any> {
|
36
|
+
const { baseUrl } = req
|
37
|
+
|
38
|
+
if (this.checkRouter(baseUrl, AuthType.Staff)) {
|
39
|
+
return await this.authenticateStaff(req)
|
40
|
+
}
|
41
|
+
|
42
|
+
// if (this.checkRouter(baseUrl, AuthType.Driver)) {
|
43
|
+
// return await this.authenticateDriver(req)
|
44
|
+
// }
|
45
|
+
|
46
|
+
return await this.authenticateCustomer(req)
|
47
|
+
}
|
48
|
+
|
49
|
+
|
50
|
+
private checkRouter(baseUrl: string, type: AuthType) {
|
51
|
+
return baseUrl.includes(`${CONFIG.PREFIX_URL}/${type.toLowerCase()}`);
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
// private async authenticateDriver(req: Request) {
|
56
|
+
// const { token, version } = <RequestHeaders>req.headers
|
57
|
+
|
58
|
+
// if (version != VERSION) {
|
59
|
+
// throw new InternalServerError(`Phiên bản hiện tại chưa được cập nhật.
|
60
|
+
// Vui lòng thoát hoàn toàn ứng dụng (bao gồm chạy ngầm) rồi mở lại.
|
61
|
+
// Nếu vẫn chưa được hãy lên cửa hàng ứng dụng cập nhật lại phiên bản mới nhất.`)
|
62
|
+
// }
|
63
|
+
|
64
|
+
// const driverId = this.getAuthId(token, AuthType.Driver);
|
65
|
+
// const driver = await Driver.findOneOrThrowId(driverId, null, 'Tài xế');
|
66
|
+
// if (driver.isBlock) {
|
67
|
+
// throw new Unauthorized("Tài khoản đã bị khoá!")
|
68
|
+
// }
|
69
|
+
|
70
|
+
// req.driver = driver;
|
71
|
+
// req.authType = AuthType.Driver
|
72
|
+
// }
|
73
|
+
|
74
|
+
|
75
|
+
private async authenticateCustomer(req: Request) {
|
76
|
+
const { token, version } = <RequestHeaders>req.headers
|
77
|
+
|
78
|
+
if (version != VERSION) {
|
79
|
+
throw new InternalServerError(`Phiên bản hiện tại chưa được cập nhật.
|
80
|
+
Vui lòng thoát hoàn toàn ứng dụng (bao gồm chạy ngầm) rồi mở lại.
|
81
|
+
Nếu vẫn chưa được hãy lên cửa hàng ứng dụng cập nhật lại phiên bản mới nhất.`)
|
82
|
+
}
|
83
|
+
|
84
|
+
const customerId = this.getAuthId(token, AuthType.Customer);
|
85
|
+
const customer = await Customer.findOneOrThrowId(customerId, null, 'Tài khoản');
|
86
|
+
if (customer.isBlock) {
|
87
|
+
throw new Unauthorized("Tài khoản đã bị khoá!")
|
88
|
+
}
|
89
|
+
|
90
|
+
req.customer = customer;
|
91
|
+
req.authType = AuthType.Customer
|
92
|
+
}
|
93
|
+
|
94
|
+
|
95
|
+
private async authenticateStaff(req: Request) {
|
96
|
+
const { token } = req.headers
|
97
|
+
|
98
|
+
const staffId = this.getAuthId(token, AuthType.Staff);
|
99
|
+
const staff = await Staff.findOneOrThrowId(staffId, null, 'Tài khoản');
|
100
|
+
if (staff.isBlock) {
|
101
|
+
throw new Unauthorized("Tài khoản đã bị khoá!")
|
102
|
+
}
|
103
|
+
|
104
|
+
req.staff = staff;
|
105
|
+
req.authType = AuthType.Staff
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
public getAuthId(token: any, type: AuthType): number {
|
110
|
+
if (!token) {
|
111
|
+
throw new Unauthorized("Xác thực không hợp lệ!")
|
112
|
+
}
|
113
|
+
|
114
|
+
try {
|
115
|
+
const decoded = <JWTSignedData>jwt.verify(token, CONFIG.JWT_SECRET)
|
116
|
+
if (decoded.id && decoded.type == type) {
|
117
|
+
return decoded.id
|
118
|
+
} else {
|
119
|
+
throw new Unauthorized("Xác thực không hợp lệ!")
|
120
|
+
}
|
121
|
+
} catch (error) {
|
122
|
+
logger('error').error('Error Get Authenticate ID: ', JSON.stringify(error))
|
123
|
+
throw new Unauthorized("Xác thực không hợp lệ!")
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
static getIa(token: string): number {
|
129
|
+
if (!token) {
|
130
|
+
return 0
|
131
|
+
}
|
132
|
+
|
133
|
+
try {
|
134
|
+
const decoded = <JWTSignedData>jwt.verify(token, CONFIG.JWT_SECRET)
|
135
|
+
return decoded.ia
|
136
|
+
} catch (error) {
|
137
|
+
return 0
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
|
142
|
+
static sign(data: JWTSignedData): string {
|
143
|
+
data = { ...data, ia: getCurrentTimeInt() }
|
144
|
+
return jwt.sign(data, CONFIG.JWT_SECRET, { expiresIn: CONFIG.JWT_EXPIRE })
|
145
|
+
}
|
146
|
+
|
147
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
2
|
+
import logger from '../../util/logger'
|
3
|
+
|
4
|
+
function logRequest(req: Request, err: any) {
|
5
|
+
const statusCode = err.status || 500
|
6
|
+
const messageSummary = `Request: ${req.method} ${req.url} - CODE: ${statusCode}`
|
7
|
+
const messageError = `${err.stack}`
|
8
|
+
const messageHeader = `Headers: ${JSON.stringify(req.headers, null, "\t")}`
|
9
|
+
const messageBody = `Body: ${JSON.stringify(req.body, null, "\t")}`
|
10
|
+
const messageQuery = `Query: ${JSON.stringify(req.query, null, "\t")}`
|
11
|
+
|
12
|
+
console.log('err:', JSON.stringify(err))
|
13
|
+
logger('error').error(`\n${messageSummary}\n${messageHeader}\n${messageBody}\n${messageQuery}\n${messageError}`)
|
14
|
+
}
|
15
|
+
|
16
|
+
export default function handleError(err: any, req: Request, res: Response, next: NextFunction) {
|
17
|
+
const statusCode = err.status || 500
|
18
|
+
const message = err.message || "Server error!"
|
19
|
+
|
20
|
+
logRequest(req, err)
|
21
|
+
return res.status(statusCode).send({ message, data: {}, status: false })
|
22
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
2
|
+
import { NotFound } from 'ts-httpexceptions'
|
3
|
+
|
4
|
+
export default function handleNotFound(req: Request, res: Response, next: NextFunction) {
|
5
|
+
const error = new NotFound(`The request ${req.method}: ${req.url} was not found on this server.`)
|
6
|
+
next(error)
|
7
|
+
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { OverrideProvider, Res, ResponseData, SendResponseMiddleware, ConverterService, Req } from "@tsed/common";
|
2
|
+
import { isStream } from "@tsed/core";
|
3
|
+
|
4
|
+
@OverrideProvider(SendResponseMiddleware)
|
5
|
+
export class CustomDefaultResponse {
|
6
|
+
|
7
|
+
constructor(private converterService: ConverterService) { }
|
8
|
+
|
9
|
+
public use(@Req() request: Req, @Res() response: Res): any {
|
10
|
+
const { ctx: { data, endpoint } } = request;
|
11
|
+
|
12
|
+
let message = ""
|
13
|
+
if (data && data.message) {
|
14
|
+
message = data.message
|
15
|
+
delete data.message
|
16
|
+
}
|
17
|
+
|
18
|
+
if (data === undefined) {
|
19
|
+
return response.send();
|
20
|
+
}
|
21
|
+
|
22
|
+
if (isStream(data)) {
|
23
|
+
data.pipe(response);
|
24
|
+
return response;
|
25
|
+
}
|
26
|
+
|
27
|
+
const payload = {
|
28
|
+
data,
|
29
|
+
message,
|
30
|
+
status: true
|
31
|
+
};
|
32
|
+
|
33
|
+
return response.json(payload);
|
34
|
+
}
|
35
|
+
}
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import { Request, Response, NextFunction } from "express";
|
2
|
+
import { BadRequest, Unauthorized, Forbidden, InternalServerError } from "ts-httpexceptions"
|
3
|
+
|
4
|
+
export default function responseAPI(req: Request, res: Response, next: NextFunction) {
|
5
|
+
res.sendAPI = (
|
6
|
+
data: Array<object> | object = {},
|
7
|
+
message: string = "",
|
8
|
+
status: boolean = true,
|
9
|
+
code: number = 200
|
10
|
+
) => {
|
11
|
+
res.status(code)
|
12
|
+
.send({
|
13
|
+
data,
|
14
|
+
message,
|
15
|
+
status
|
16
|
+
})
|
17
|
+
}
|
18
|
+
|
19
|
+
res.sendOK = (
|
20
|
+
data: Array<object> | object = {},
|
21
|
+
message: string = ""
|
22
|
+
) => {
|
23
|
+
const status = true
|
24
|
+
return res.sendAPI(data, message, status, 200)
|
25
|
+
}
|
26
|
+
|
27
|
+
res.sendCreated = (
|
28
|
+
message: string = "Created successfully!",
|
29
|
+
data: Array<object> | object = {}
|
30
|
+
) => {
|
31
|
+
const status = true
|
32
|
+
return res.sendAPI(data, message, status, 201)
|
33
|
+
}
|
34
|
+
|
35
|
+
res.sendClientError = (
|
36
|
+
message: string = "Bad Request",
|
37
|
+
data: Array<object> | object = {}
|
38
|
+
) => {
|
39
|
+
const err = new BadRequest(message)
|
40
|
+
next(err)
|
41
|
+
}
|
42
|
+
|
43
|
+
res.sendUnauthorized = (
|
44
|
+
message: string = "Unauthorized",
|
45
|
+
data: Array<object> | object = {}
|
46
|
+
) => {
|
47
|
+
const err = new Unauthorized(message)
|
48
|
+
next(err)
|
49
|
+
}
|
50
|
+
|
51
|
+
res.sendForbidden = (
|
52
|
+
message: string = "Forbidden",
|
53
|
+
data: Array<object> | object = {}
|
54
|
+
) => {
|
55
|
+
const err = new Forbidden(message)
|
56
|
+
next(err)
|
57
|
+
}
|
58
|
+
|
59
|
+
res.sendNotFound = (
|
60
|
+
message: string = "Not Found",
|
61
|
+
data: Array<object> | object = {}
|
62
|
+
) => {
|
63
|
+
const status = false
|
64
|
+
return res.sendAPI(data, message, status, 200)
|
65
|
+
}
|
66
|
+
|
67
|
+
res.sendFail = (
|
68
|
+
message: string = "Internal Server Error",
|
69
|
+
data: Array<object> | object = {}
|
70
|
+
) => {
|
71
|
+
const err = new InternalServerError(message)
|
72
|
+
next(err)
|
73
|
+
}
|
74
|
+
|
75
|
+
next()
|
76
|
+
}
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import { applyDecorators } from "@tsed/core";
|
2
|
+
import { IResponseOptions, mapReturnedResponse, UseBefore } from "@tsed/common";
|
3
|
+
import Joi, { ValidationResult, SchemaMap, ValidationErrorItem } from '@hapi/joi';
|
4
|
+
|
5
|
+
import { capitalize, isEmptyObject } from '../../util/helper'
|
6
|
+
import { MESSAGE_VALIDATOR_VI } from '../../util/language'
|
7
|
+
|
8
|
+
export enum Language {
|
9
|
+
Vietnamese = 'VI',
|
10
|
+
English = 'EN'
|
11
|
+
}
|
12
|
+
|
13
|
+
const LANGUAGES = [Language.Vietnamese as string, Language.English as string]
|
14
|
+
|
15
|
+
function validateRequest(req: any, rules: SchemaMap) {
|
16
|
+
const parameters = { ...req.body, ...req.query, ...req.headers, ...req.params }
|
17
|
+
const validateKeys = Object.keys(rules)
|
18
|
+
|
19
|
+
for (const key in parameters) {
|
20
|
+
if (!validateKeys.includes(key)) delete parameters[key]
|
21
|
+
}
|
22
|
+
|
23
|
+
const schema = Joi.object(rules)
|
24
|
+
const result = schema.validate(parameters)
|
25
|
+
return result
|
26
|
+
}
|
27
|
+
|
28
|
+
function handleLanguageRequest(req: any) {
|
29
|
+
const query = req.query
|
30
|
+
const defaultLanguage = 'en'
|
31
|
+
if (!query && !query.lang) return defaultLanguage
|
32
|
+
|
33
|
+
const requestLanguage = query.lang
|
34
|
+
if (!LANGUAGES.includes(requestLanguage)) return defaultLanguage
|
35
|
+
|
36
|
+
return requestLanguage
|
37
|
+
}
|
38
|
+
|
39
|
+
function getMessageEnglish(originMessage: string, originLabel: string): string {
|
40
|
+
const labelCapitalized = capitalize(originLabel)
|
41
|
+
const label = `"${labelCapitalized}"`
|
42
|
+
const message = originMessage.replace(/\"[a-z]*\"/gm, label)
|
43
|
+
return message
|
44
|
+
}
|
45
|
+
|
46
|
+
// function getMessageWithCustomLabels(labels: Object, language: string, error: ValidationErrorItem): any {
|
47
|
+
// const originLabel = error.context.label
|
48
|
+
// const originKey = error.context.key
|
49
|
+
// const originType = error.type
|
50
|
+
|
51
|
+
// const label = labels[originKey] || originLabel
|
52
|
+
|
53
|
+
// if (language == Language.Vietnamese) {
|
54
|
+
// const originLimit = error.context.limit || false
|
55
|
+
// const message = `"${label}"` + MESSAGE_VALIDATOR_VI[originType](originLimit)
|
56
|
+
// return message
|
57
|
+
// }
|
58
|
+
|
59
|
+
// return getMessageEnglish(error.message, label)
|
60
|
+
// }
|
61
|
+
|
62
|
+
function handleMessage(language: string, error: ValidationErrorItem, labels: any): string {
|
63
|
+
const originMessage = error.message
|
64
|
+
const originLabel = error.context.label
|
65
|
+
|
66
|
+
if (!isEmptyObject(labels))
|
67
|
+
return getMessageEnglish(originMessage, originLabel)
|
68
|
+
|
69
|
+
if (language == Language.Vietnamese) {
|
70
|
+
const labelsVietnamese = labels[Language.Vietnamese]
|
71
|
+
if (!labelsVietnamese) return getMessageEnglish(originMessage, originLabel)
|
72
|
+
// else return getMessageWithCustomLabels(labelsVietnamese, Language.Vietnamese, error)
|
73
|
+
}
|
74
|
+
|
75
|
+
const labelsEnglish = labels[Language.English]
|
76
|
+
if (!labelsEnglish) return getMessageEnglish(originMessage, originLabel)
|
77
|
+
// else return getMessageWithCustomLabels(labelsEnglish, Language.English, error)
|
78
|
+
}
|
79
|
+
|
80
|
+
function handleResultValidate(result: any, req: any, labels: any): string {
|
81
|
+
const language = handleLanguageRequest(req)
|
82
|
+
if (!result || !result.error) return
|
83
|
+
|
84
|
+
const errors = result.error.details
|
85
|
+
if (!errors || !errors.length) return
|
86
|
+
|
87
|
+
const error = errors[0]
|
88
|
+
const message = handleMessage(language, error, labels)
|
89
|
+
return message
|
90
|
+
}
|
91
|
+
|
92
|
+
export function Validator(rules: SchemaMap, labels: Object = {}, options: any = {}) {
|
93
|
+
const response = mapReturnedResponse(options);
|
94
|
+
|
95
|
+
return applyDecorators(
|
96
|
+
UseBefore((req: any, res: any, next: any) => {
|
97
|
+
const result = validateRequest(req, rules)
|
98
|
+
const message = handleResultValidate(result, req, labels)
|
99
|
+
if (message) return res.sendClientError(message)
|
100
|
+
else next();
|
101
|
+
})
|
102
|
+
);
|
103
|
+
}
|
@@ -0,0 +1,79 @@
|
|
1
|
+
// IMPORT LIBRARY
|
2
|
+
import { Service } from "@tsed/common";
|
3
|
+
|
4
|
+
// IMPORT CUSTOM
|
5
|
+
import { CoreService } from "../core/services/CoreService";
|
6
|
+
import { BadRequest } from "ts-httpexceptions";
|
7
|
+
import { Customer } from "../entity/Customer";
|
8
|
+
import { Password } from "../util/password";
|
9
|
+
|
10
|
+
interface GetCustomerParams {
|
11
|
+
search: string
|
12
|
+
page: number
|
13
|
+
limit: number
|
14
|
+
}
|
15
|
+
|
16
|
+
@Service()
|
17
|
+
export class CustomerService extends CoreService {
|
18
|
+
|
19
|
+
public async findManyAndCount({ search, page, limit }: GetCustomerParams) {
|
20
|
+
let where = ` CONCAT(customer.name, ' ', customer.phone) LIKE '%${search}%'
|
21
|
+
AND customer.isDeleted = false`
|
22
|
+
|
23
|
+
const [customers, total] = await Customer.createQueryBuilder('customer')
|
24
|
+
.where(where)
|
25
|
+
.skip((page - 1) * limit)
|
26
|
+
.take(limit)
|
27
|
+
.orderBy('customer.id', 'DESC')
|
28
|
+
.getManyAndCount()
|
29
|
+
|
30
|
+
return [customers, total]
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
public async login(phone: string, password: string): Promise<Customer> {
|
35
|
+
const customer = await Customer.findOneOrThrowOption({ where: { phone } }, 'Tài khoản')
|
36
|
+
|
37
|
+
await this.validatePassword(customer, password)
|
38
|
+
|
39
|
+
if (customer.isBlock) {
|
40
|
+
throw new BadRequest('Tài khoản này đã bị khoá!')
|
41
|
+
}
|
42
|
+
|
43
|
+
return customer
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
async validateDuplicate(customer: Customer, userId: number = null) {
|
48
|
+
const { phone, email } = customer
|
49
|
+
|
50
|
+
const oldCustomer = await Customer.findOne({ where: [{ phone }, { email }] })
|
51
|
+
|
52
|
+
if (oldCustomer && oldCustomer.id != userId) {
|
53
|
+
let message = ""
|
54
|
+
|
55
|
+
if (oldCustomer.phone == phone) {
|
56
|
+
message = "Số điện thoại"
|
57
|
+
} else if (oldCustomer.email == email) {
|
58
|
+
message = "Email"
|
59
|
+
}
|
60
|
+
|
61
|
+
throw new BadRequest(`${message} đã tồn tại`)
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
|
66
|
+
async validatePassword(customer: Customer, password: string) {
|
67
|
+
const customerWithPassword = await Customer.findOneOrThrowOption({
|
68
|
+
where: { id: customer.id },
|
69
|
+
select: ['id', 'password']
|
70
|
+
})
|
71
|
+
|
72
|
+
const validate = await Password.validate(password, customerWithPassword.password)
|
73
|
+
if (!validate) {
|
74
|
+
throw new BadRequest('Mật khẩu không chính xác.')
|
75
|
+
}
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
} // END FILE
|