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.
Files changed (226) hide show
  1. package/.vscode/launch.json +14 -0
  2. package/.vscode/settings.json +1 -0
  3. package/CHANGELOG.md +9 -0
  4. package/DEPLOY.md +4 -0
  5. package/README.md +17 -0
  6. package/README_PRIVATE.md +1 -0
  7. package/build.sh +5 -0
  8. package/logo.png +0 -0
  9. package/media/dark/add.svg +40 -0
  10. package/media/dark/block.svg +1 -0
  11. package/media/dark/checklist-1.svg +1 -0
  12. package/media/dark/checklist.svg +1 -0
  13. package/media/dark/control.svg +1 -0
  14. package/media/dark/create.svg +1 -0
  15. package/media/dark/delete-1.svg +1 -0
  16. package/media/dark/delete.svg +1 -0
  17. package/media/dark/deploy-1.svg +2 -0
  18. package/media/dark/deploy.svg +2 -0
  19. package/media/dark/documents.svg +66 -0
  20. package/media/dark/earth.svg +68 -0
  21. package/media/dark/exe.svg +15 -0
  22. package/media/dark/export.svg +1 -0
  23. package/media/dark/function.svg +1 -0
  24. package/media/dark/game-controller.svg +77 -0
  25. package/media/dark/get.svg +1 -0
  26. package/media/dark/id-card.svg +59 -0
  27. package/media/dark/identity.svg +81 -0
  28. package/media/dark/import.svg +1 -0
  29. package/media/dark/information.svg +1 -0
  30. package/media/dark/interface.svg +1 -0
  31. package/media/dark/layout.svg +41 -0
  32. package/media/dark/leaf.svg +54 -0
  33. package/media/dark/list.svg +13 -0
  34. package/media/dark/logo.svg +249 -0
  35. package/media/dark/mockup.svg +1 -0
  36. package/media/dark/needle.svg +1 -0
  37. package/media/dark/pass.svg +46 -0
  38. package/media/dark/plus.svg +1 -0
  39. package/media/dark/post.svg +1 -0
  40. package/media/dark/quit.svg +1 -0
  41. package/media/dark/rocket.svg +28 -0
  42. package/media/dark/service.svg +1 -0
  43. package/media/dark/settings.svg +98 -0
  44. package/media/dark/social.svg +1 -0
  45. package/media/dark/spaceship-1.svg +1 -0
  46. package/media/dark/spaceship-2.svg +1 -0
  47. package/media/dark/spaceship.svg +1 -0
  48. package/media/dark/support.svg +88 -0
  49. package/media/dark/transfer.svg +1 -0
  50. package/media/dark/transform.svg +92 -0
  51. package/media/dark/update.svg +45 -0
  52. package/media/dark/upload-1.svg +1 -0
  53. package/media/dark/upload.svg +41 -0
  54. package/media/dark/vaccine.svg +1 -0
  55. package/media/dark/vr-gaming.svg +1 -0
  56. package/media/light/add.svg +40 -0
  57. package/media/light/block.svg +1 -0
  58. package/media/light/checklist-1.svg +1 -0
  59. package/media/light/checklist.svg +1 -0
  60. package/media/light/control.svg +1 -0
  61. package/media/light/create.svg +1 -0
  62. package/media/light/delete-1.svg +1 -0
  63. package/media/light/delete.svg +1 -0
  64. package/media/light/deploy-1.svg +2 -0
  65. package/media/light/deploy.svg +2 -0
  66. package/media/light/documents.svg +66 -0
  67. package/media/light/earth.svg +68 -0
  68. package/media/light/exe.svg +15 -0
  69. package/media/light/export.svg +1 -0
  70. package/media/light/function.svg +1 -0
  71. package/media/light/game-controller.svg +77 -0
  72. package/media/light/get.svg +1 -0
  73. package/media/light/id-card.svg +59 -0
  74. package/media/light/identity.svg +81 -0
  75. package/media/light/import.svg +1 -0
  76. package/media/light/information.svg +1 -0
  77. package/media/light/interface.svg +1 -0
  78. package/media/light/layout.svg +41 -0
  79. package/media/light/leaf.svg +54 -0
  80. package/media/light/list.svg +13 -0
  81. package/media/light/logo.svg +249 -0
  82. package/media/light/mockup.svg +1 -0
  83. package/media/light/needle.svg +1 -0
  84. package/media/light/pass.svg +46 -0
  85. package/media/light/plus.svg +1 -0
  86. package/media/light/post.svg +1 -0
  87. package/media/light/quit.svg +1 -0
  88. package/media/light/rocket.svg +28 -0
  89. package/media/light/service.svg +1 -0
  90. package/media/light/settings.svg +98 -0
  91. package/media/light/social.svg +1 -0
  92. package/media/light/spaceship-1.svg +1 -0
  93. package/media/light/spaceship-2.svg +1 -0
  94. package/media/light/spaceship.svg +1 -0
  95. package/media/light/support.svg +88 -0
  96. package/media/light/transfer.svg +1 -0
  97. package/media/light/transform.svg +92 -0
  98. package/media/light/update.svg +45 -0
  99. package/media/light/upload-1.svg +1 -0
  100. package/media/light/upload.svg +41 -0
  101. package/media/light/vaccine.svg +1 -0
  102. package/media/light/vr-gaming.svg +1 -0
  103. package/package-lock.json +6430 -0
  104. package/package.json +540 -0
  105. package/snippets-tsr.json +512 -0
  106. package/snippets.json +761 -0
  107. package/src/API.ts +14 -0
  108. package/src/FsProvider.ts +105 -0
  109. package/src/Request.ts +24 -0
  110. package/src/assets/api/api.txt +27 -0
  111. package/src/assets/configuration/AdminConfigurationController.ts.txt +72 -0
  112. package/src/assets/configuration/Configuration.ts.txt +37 -0
  113. package/src/assets/configuration/ConfigurationService.ts.txt +26 -0
  114. package/src/assets/contentDefine/AdminContentDefineController.ts.txt +91 -0
  115. package/src/assets/contentDefine/ContentDefine.ts.txt +45 -0
  116. package/src/assets/contentDefine/ContentDefineService.ts.txt +19 -0
  117. package/src/assets/contentDefine/CustomerContentDefineController.ts.txt +34 -0
  118. package/src/assets/controller/controller.txt +46 -0
  119. package/src/assets/controller/controllerResource.txt +103 -0
  120. package/src/assets/entity/entity.txt +22 -0
  121. package/src/assets/entity-request/entity-request.txt +18 -0
  122. package/src/assets/init/.env.example.txt +37 -0
  123. package/src/assets/init/.env.production.txt +37 -0
  124. package/src/assets/init/.gitignore.txt +8 -0
  125. package/src/assets/init/config.ts.txt +55 -0
  126. package/src/assets/init/deploy.sh.txt +46 -0
  127. package/src/assets/init/package-lock.json.txt +4184 -0
  128. package/src/assets/init/package.json.txt +79 -0
  129. package/src/assets/init/src/Server.ts.txt +167 -0
  130. package/src/assets/init/src/controllers/admin/AuthController.ts.txt +96 -0
  131. package/src/assets/init/src/controllers/admin/CustomerController.ts.txt +107 -0
  132. package/src/assets/init/src/controllers/admin/RoleController.ts.txt +143 -0
  133. package/src/assets/init/src/controllers/admin/StaffController.ts.txt +192 -0
  134. package/src/assets/init/src/controllers/customer/AuthController.ts.txt +170 -0
  135. package/src/assets/init/src/controllers/customer/CustomerController.ts.txt +32 -0
  136. package/src/assets/init/src/core/entity/CoreEntity.ts.txt +70 -0
  137. package/src/assets/init/src/core/services/CoreService.ts.txt +21 -0
  138. package/src/assets/init/src/entity/Customer.ts.txt +68 -0
  139. package/src/assets/init/src/entity/Permission.ts.txt +29 -0
  140. package/src/assets/init/src/entity/Role.ts.txt +36 -0
  141. package/src/assets/init/src/entity/Staff.ts.txt +54 -0
  142. package/src/assets/init/src/entity-request/CustomerInsert.ts.txt +42 -0
  143. package/src/assets/init/src/entity-request/CustomerUpdate.ts.txt +40 -0
  144. package/src/assets/init/src/entity-request/PermissionImport.ts.txt +12 -0
  145. package/src/assets/init/src/entity-request/StaffUpdate.ts.txt +33 -0
  146. package/src/assets/init/src/index.ts.txt +13 -0
  147. package/src/assets/init/src/middleware/auth/Verification.ts.txt +16 -0
  148. package/src/assets/init/src/middleware/auth/VerificationJWT.ts.txt +16 -0
  149. package/src/assets/init/src/middleware/auth/strategy/AuthStrategy.ts.txt +5 -0
  150. package/src/assets/init/src/middleware/auth/strategy/JWT.ts.txt +147 -0
  151. package/src/assets/init/src/middleware/error/handleError.ts.txt +22 -0
  152. package/src/assets/init/src/middleware/error/handleNotFound.ts.txt +7 -0
  153. package/src/assets/init/src/middleware/response/CustomSendResponse.ts.txt +35 -0
  154. package/src/assets/init/src/middleware/response/responseAPI.ts.txt +76 -0
  155. package/src/assets/init/src/middleware/validator/Validator.ts.txt +103 -0
  156. package/src/assets/init/src/services/CustomerService.ts.txt +79 -0
  157. package/src/assets/init/src/services/InitService.ts.txt +11 -0
  158. package/src/assets/init/src/services/MailService.ts.txt +271 -0
  159. package/src/assets/init/src/services/RoleService.ts.txt +66 -0
  160. package/src/assets/init/src/services/StaffService.ts.txt +104 -0
  161. package/src/assets/init/src/ssl/certificate-ca.crt +0 -0
  162. package/src/assets/init/src/ssl/certificate.crt +0 -0
  163. package/src/assets/init/src/ssl/private.key +0 -0
  164. package/src/assets/init/src/types/express.d.ts.txt +97 -0
  165. package/src/assets/init/src/util/expo.ts.txt +53 -0
  166. package/src/assets/init/src/util/helper.ts.txt +321 -0
  167. package/src/assets/init/src/util/language.ts.txt +8 -0
  168. package/src/assets/init/src/util/logger.ts.txt +47 -0
  169. package/src/assets/init/src/util/mailer.ts.txt +32 -0
  170. package/src/assets/init/src/util/password.ts.txt +13 -0
  171. package/src/assets/init/tsconfig.json.txt +26 -0
  172. package/src/assets/service/service.txt +34 -0
  173. package/src/constant.ts +83 -0
  174. package/src/extension.ts +459 -0
  175. package/src/provider/codeAction/controller/addPathParams.ts +65 -0
  176. package/src/provider/codeAction/controller/addTokenParam.ts +43 -0
  177. package/src/provider/codeAction/controller/addValidation.ts +47 -0
  178. package/src/provider/codeAction/controller/codeAction.ts +34 -0
  179. package/src/provider/codeAction/controller/util.ts +48 -0
  180. package/src/provider/codeAction/entity/codeAction.ts +48 -0
  181. package/src/provider/codeAction/entity/handleBuilder.ts +87 -0
  182. package/src/provider/codeAction/entity/handleFunction.ts +487 -0
  183. package/src/provider/codeAction/entity/handleProperty.ts +32 -0
  184. package/src/provider/codeAction/entity/handleRelation.ts +72 -0
  185. package/src/provider/codeAction/entity/helper.ts +132 -0
  186. package/src/provider/codeAction/entity-request/codeAction.ts +178 -0
  187. package/src/provider/codeAction/enum/codeAction.ts +95 -0
  188. package/src/provider/codeAction/service/codeAction.ts +232 -0
  189. package/src/provider/completion/CompletionProvider.ts +108 -0
  190. package/src/provider/errorChecking/checkHeaderToken.ts +60 -0
  191. package/src/provider/errorChecking/checkPathParam.ts +64 -0
  192. package/src/provider/errorChecking/checkRequired.ts +56 -0
  193. package/src/provider/errorChecking/errorChecking.ts +35 -0
  194. package/src/provider/errorChecking/util.ts +56 -0
  195. package/src/provider/treeDataProvider/Dependency.ts +26 -0
  196. package/src/provider/treeDataProvider/TreeProviderCommand.ts +60 -0
  197. package/src/provider/treeDataProvider/TreeProviderProject.ts +65 -0
  198. package/src/provider/treeDataProvider/api/createApi.ts +106 -0
  199. package/src/provider/treeDataProvider/controller/command/createController.ts +99 -0
  200. package/src/provider/treeDataProvider/controller/command/handleMethod.ts +363 -0
  201. package/src/provider/treeDataProvider/controller/treeData.ts +81 -0
  202. package/src/provider/treeDataProvider/deploy/command/handleDeploy.ts +70 -0
  203. package/src/provider/treeDataProvider/deploy/treeData.ts +21 -0
  204. package/src/provider/treeDataProvider/entity/command/addProperty.ts +144 -0
  205. package/src/provider/treeDataProvider/entity/command/addRelation.ts +125 -0
  206. package/src/provider/treeDataProvider/entity/command/createEntity.ts +53 -0
  207. package/src/provider/treeDataProvider/entity/command/createEntityRequest.ts +65 -0
  208. package/src/provider/treeDataProvider/entity/command/exportInterface.ts +130 -0
  209. package/src/provider/treeDataProvider/entity/treeData.ts +49 -0
  210. package/src/provider/treeDataProvider/module/command/configuration.ts +34 -0
  211. package/src/provider/treeDataProvider/module/command/contentDefine.ts +36 -0
  212. package/src/provider/treeDataProvider/module/command/initProject.ts +155 -0
  213. package/src/provider/treeDataProvider/module/treeData.ts +28 -0
  214. package/src/provider/treeDataProvider/project/command/addEnum.ts +0 -0
  215. package/src/provider/treeDataProvider/project/command/addProjectName.ts +23 -0
  216. package/src/provider/treeDataProvider/project/command/getProjectDetails.ts +284 -0
  217. package/src/provider/treeDataProvider/project/treeData.ts +28 -0
  218. package/src/provider/treeDataProvider/service/command/createService.ts +70 -0
  219. package/src/provider/treeDataProvider/service/command/handleConstructor.ts +134 -0
  220. package/src/provider/treeDataProvider/service/treeData.ts +25 -0
  221. package/src/types/project.d.ts +7 -0
  222. package/src/util.ts +145 -0
  223. package/src/utils/Password.ts +19 -0
  224. package/tsconfig.json +18 -0
  225. package/tslint.json +15 -0
  226. 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,12 @@
1
+ import { Property } from "@tsed/common";
2
+
3
+ export class PermissionImport {
4
+ // PROPERTIES
5
+
6
+ @Property()
7
+ path: string;
8
+
9
+ @Property()
10
+ children: PermissionImport[];
11
+
12
+ }
@@ -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,5 @@
1
+ import { Request, Response, NextFunction } from "express";
2
+
3
+ export default interface AuthStrategy {
4
+ auth(req: Request): Promise<any>;
5
+ }
@@ -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
@@ -0,0 +1,11 @@
1
+ // IMPORT LIBRARY
2
+ import { Service } from "@tsed/common";
3
+
4
+
5
+ // IMPORT CUSTOM
6
+ import { CoreService } from "../core/services/CoreService";
7
+
8
+ @Service()
9
+ export class InitService extends CoreService {
10
+
11
+ } //END FILE