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,271 @@
|
|
1
|
+
import { Service } from "@tsed/common";
|
2
|
+
|
3
|
+
import { Mailer } from "../util/mailer";
|
4
|
+
import config from "../../config";
|
5
|
+
import { Customer } from "../entity/Customer";
|
6
|
+
|
7
|
+
@Service()
|
8
|
+
export class MailService {
|
9
|
+
|
10
|
+
async sendMailLinkReset(forgotCode: string, customer: Customer) {
|
11
|
+
const subject = 'Yêu cầu quên mật khẩu.'
|
12
|
+
const content = this.generateTemplateForgotPassword(forgotCode)
|
13
|
+
Mailer.sendMail(customer.email, subject, content)
|
14
|
+
}
|
15
|
+
|
16
|
+
async sendMailReset(password: string, customer: Customer) {
|
17
|
+
const subject = 'Thay đổi mật khẩu.'
|
18
|
+
const content = this.generateTemplateResetPassword(password, customer)
|
19
|
+
Mailer.sendMail(customer.email, subject, content)
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
generateTemplateResetPassword(password: string, customer: Customer) {
|
24
|
+
let template = this.getFullTemplate()
|
25
|
+
template = template.replace(/{{href}}/g, config.HOST);
|
26
|
+
template = template.replace(/{{title}}/g, 'THAY ĐỔI MẬT KHẨU');
|
27
|
+
const body = this.generateRow(`<h3>Mật khẩu mới để đăng nhập vào số điện thoại ${customer.phone} là: ${password}</h3>`)
|
28
|
+
template = template.replace(/{{body}}/g, body);
|
29
|
+
return template
|
30
|
+
}
|
31
|
+
|
32
|
+
generateTemplateForgotPassword(token: string) {
|
33
|
+
let template = this.getFullTemplate()
|
34
|
+
template = template.replace(/{{href}}/g, config.HOST);
|
35
|
+
template = template.replace(/{{title}}/g, 'YÊU CẦU QUÊN MẬT KHẨU');
|
36
|
+
const body = this.generateRow(`<h3>Vui lòng không chia sẽ mã này với bất kì ai. Đây là mã reset mật khẩu của bạn: ${token}</h3>`)
|
37
|
+
template = template.replace(/{{body}}/g, body);
|
38
|
+
return template
|
39
|
+
}
|
40
|
+
|
41
|
+
generateRow(contentRow: string) {
|
42
|
+
let template = `<tr>
|
43
|
+
<td class="esd-block-text es-p20t"
|
44
|
+
align = "left" >
|
45
|
+
<p style="color: #3f3736;" >{{contentRow}}</p>
|
46
|
+
</td>
|
47
|
+
</tr>
|
48
|
+
<tr>`
|
49
|
+
return template.replace(/{{contentRow}}/g, contentRow);
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
getFullTemplate() {
|
54
|
+
return `
|
55
|
+
<!DOCTYPE html
|
56
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
57
|
+
<html>
|
58
|
+
|
59
|
+
<head>
|
60
|
+
<meta charset="UTF-8">
|
61
|
+
<meta content="width=device-width, initial-scale=1" name="viewport">
|
62
|
+
<meta name="x-apple-disable-message-reformatting">
|
63
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
64
|
+
<meta content="telephone=no" name="format-detection">
|
65
|
+
<title></title>
|
66
|
+
<!--[if (mso 16)]>
|
67
|
+
<style type="text/css">
|
68
|
+
a {text-decoration: none;}
|
69
|
+
</style>
|
70
|
+
<![endif]-->
|
71
|
+
<!--[if gte mso 9]><style>sup { font-size: 100% !important; }</style><![endif]-->
|
72
|
+
</head>
|
73
|
+
|
74
|
+
|
75
|
+
<body>
|
76
|
+
<div class="es-wrapper-color">
|
77
|
+
<!--[if gte mso 9]>
|
78
|
+
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
|
79
|
+
<v:fill type="tile" color="#f6f6f6"></v:fill>
|
80
|
+
</v:background>
|
81
|
+
<![endif]-->
|
82
|
+
<table class="es-wrapper" width="100%" cellspacing="0" cellpadding="0">
|
83
|
+
<tbody>
|
84
|
+
<tr>
|
85
|
+
<td class="esd-email-paddings" valign="top">
|
86
|
+
<table class="esd-header-popover es-content" cellspacing="0" cellpadding="0" align="center">
|
87
|
+
<tbody>
|
88
|
+
<tr>
|
89
|
+
<td class="esd-stripe" align="center">
|
90
|
+
<table class="es-content-body" style="background-color: transparent;"
|
91
|
+
width="600" cellspacing="0" cellpadding="0" align="center">
|
92
|
+
<tbody>
|
93
|
+
<tr>
|
94
|
+
<td class="esd-structure es-p20t es-p20b es-p20r es-p20l"
|
95
|
+
align="left">
|
96
|
+
<!--[if mso]><table width="560" cellpadding="0" cellspacing="0"><tr><td width="356" valign="top"><![endif]-->
|
97
|
+
<table class="es-left" cellspacing="0" cellpadding="0"
|
98
|
+
align="left">
|
99
|
+
<tbody>
|
100
|
+
<tr>
|
101
|
+
<td class="es-m-p0r es-m-p20b esd-container-frame"
|
102
|
+
width="356" valign="top" align="center">
|
103
|
+
<table width="100%" cellspacing="0"
|
104
|
+
cellpadding="0">
|
105
|
+
<tbody>
|
106
|
+
<tr>
|
107
|
+
<td class="esd-block-text es-infoblock es-m-txt-c"
|
108
|
+
align="left">
|
109
|
+
<p></p>
|
110
|
+
</td>
|
111
|
+
</tr>
|
112
|
+
</tbody>
|
113
|
+
</table>
|
114
|
+
</td>
|
115
|
+
</tr>
|
116
|
+
</tbody>
|
117
|
+
</table>
|
118
|
+
<!--[if mso]></td><td width="20"></td><td width="184" valign="top"><![endif]-->
|
119
|
+
<table cellspacing="0" cellpadding="0" align="right">
|
120
|
+
<tbody>
|
121
|
+
<tr>
|
122
|
+
<td class="esd-container-frame" width="184"
|
123
|
+
align="left">
|
124
|
+
<table width="100%" cellspacing="0"
|
125
|
+
cellpadding="0">
|
126
|
+
<tbody>
|
127
|
+
<tr>
|
128
|
+
<td class="esd-block-text es-infoblock es-m-txt-c"
|
129
|
+
align="right">
|
130
|
+
<p><a target="_blank"
|
131
|
+
href="{{href}}"></a></p>
|
132
|
+
</td>
|
133
|
+
</tr>
|
134
|
+
</tbody>
|
135
|
+
</table>
|
136
|
+
</td>
|
137
|
+
</tr>
|
138
|
+
</tbody>
|
139
|
+
</table>
|
140
|
+
<!--[if mso]></td></tr></table><![endif]-->
|
141
|
+
</td>
|
142
|
+
</tr>
|
143
|
+
</tbody>
|
144
|
+
</table>
|
145
|
+
</td>
|
146
|
+
</tr>
|
147
|
+
</tbody>
|
148
|
+
</table>
|
149
|
+
<table class="es-content" cellspacing="0" cellpadding="0" align="center">
|
150
|
+
<tbody>
|
151
|
+
<tr>
|
152
|
+
<td class="esd-stripe" align="center" esd-custom-block-id="77306">
|
153
|
+
<table class="es-content-body" width="600" cellspacing="0" cellpadding="0"
|
154
|
+
bgcolor="#ffffff" align="center">
|
155
|
+
<tbody>
|
156
|
+
<tr>
|
157
|
+
<td class="esd-structure es-p20t es-p20b es-p20r es-p20l"
|
158
|
+
align="left">
|
159
|
+
<table width="100%" cellspacing="0" cellpadding="0">
|
160
|
+
<tbody>
|
161
|
+
<tr>
|
162
|
+
<td class="esd-container-frame" width="560"
|
163
|
+
valign="top" align="center">
|
164
|
+
<table width="100%" cellspacing="0"
|
165
|
+
cellpadding="0">
|
166
|
+
<tbody>
|
167
|
+
<tr>
|
168
|
+
<td class="esd-block-text es-p15b"
|
169
|
+
align="left">
|
170
|
+
<h2>{{title}}</h2>
|
171
|
+
</td>
|
172
|
+
</tr>
|
173
|
+
{{body}}
|
174
|
+
</tbody>
|
175
|
+
</table>
|
176
|
+
</td>
|
177
|
+
</tr>
|
178
|
+
</tbody>
|
179
|
+
</table>
|
180
|
+
</td>
|
181
|
+
</tr>
|
182
|
+
</tbody>
|
183
|
+
</table>
|
184
|
+
</td>
|
185
|
+
</tr>
|
186
|
+
</tbody>
|
187
|
+
</table>
|
188
|
+
<table class="es-footer" cellspacing="0" cellpadding="0" align="center">
|
189
|
+
<tbody>
|
190
|
+
<tr>
|
191
|
+
<td class="esd-stripe" align="center">
|
192
|
+
<table class="es-footer-body" width="600" cellspacing="0" cellpadding="0"
|
193
|
+
align="center">
|
194
|
+
<tbody>
|
195
|
+
<tr>
|
196
|
+
<td class="esd-structure es-p20t es-p20b es-p20r es-p20l"
|
197
|
+
align="left">
|
198
|
+
<table width="100%" cellspacing="0" cellpadding="0">
|
199
|
+
<tbody>
|
200
|
+
<tr>
|
201
|
+
<td class="esd-container-frame" width="560"
|
202
|
+
valign="top" align="center">
|
203
|
+
<table width="100%" cellspacing="0"
|
204
|
+
cellpadding="0">
|
205
|
+
<tbody>
|
206
|
+
<tr>
|
207
|
+
<td align="center"
|
208
|
+
class="esd-empty-container"
|
209
|
+
style="display: none;"></td>
|
210
|
+
</tr>
|
211
|
+
</tbody>
|
212
|
+
</table>
|
213
|
+
</td>
|
214
|
+
</tr>
|
215
|
+
</tbody>
|
216
|
+
</table>
|
217
|
+
</td>
|
218
|
+
</tr>
|
219
|
+
</tbody>
|
220
|
+
</table>
|
221
|
+
</td>
|
222
|
+
</tr>
|
223
|
+
</tbody>
|
224
|
+
</table>
|
225
|
+
<table class="esd-footer-popover es-content" cellspacing="0" cellpadding="0" align="center">
|
226
|
+
<tbody>
|
227
|
+
<tr>
|
228
|
+
<td class="esd-stripe" align="center">
|
229
|
+
<table class="es-content-body" style="background-color: transparent;"
|
230
|
+
width="600" cellspacing="0" cellpadding="0" align="center">
|
231
|
+
<tbody>
|
232
|
+
<tr>
|
233
|
+
<td class="esd-structure es-p30b es-p20r es-p20l" align="left">
|
234
|
+
<table width="100%" cellspacing="0" cellpadding="0">
|
235
|
+
<tbody>
|
236
|
+
<tr>
|
237
|
+
<td class="esd-container-frame" width="560"
|
238
|
+
valign="top" align="center">
|
239
|
+
<table width="100%" cellspacing="0"
|
240
|
+
cellpadding="0">
|
241
|
+
<tbody>
|
242
|
+
<tr>
|
243
|
+
<td align="center"
|
244
|
+
class="esd-empty-container"
|
245
|
+
style="display: none;"></td>
|
246
|
+
</tr>
|
247
|
+
</tbody>
|
248
|
+
</table>
|
249
|
+
</td>
|
250
|
+
</tr>
|
251
|
+
</tbody>
|
252
|
+
</table>
|
253
|
+
</td>
|
254
|
+
</tr>
|
255
|
+
</tbody>
|
256
|
+
</table>
|
257
|
+
</td>
|
258
|
+
</tr>
|
259
|
+
</tbody>
|
260
|
+
</table>
|
261
|
+
</td>
|
262
|
+
</tr>
|
263
|
+
</tbody>
|
264
|
+
</table>
|
265
|
+
</div>
|
266
|
+
</body>
|
267
|
+
|
268
|
+
</html>
|
269
|
+
`
|
270
|
+
}
|
271
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { Service } from "@tsed/common";
|
2
|
+
|
3
|
+
import { CoreService } from "../core/services/CoreService";
|
4
|
+
import { Role } from "../entity/Role";
|
5
|
+
import { Permission } from "../entity/Permission";
|
6
|
+
import { PermissionImport } from "../entity-request/PermissionImport";
|
7
|
+
|
8
|
+
const ROLE_ADMIN = 1
|
9
|
+
|
10
|
+
@Service()
|
11
|
+
export class RoleService extends CoreService {
|
12
|
+
|
13
|
+
async resetRoleForAdmin(permissions: Permission[]) {
|
14
|
+
const adminRole = await Role.findOne(ROLE_ADMIN)
|
15
|
+
adminRole.permissions = permissions
|
16
|
+
adminRole.save()
|
17
|
+
}
|
18
|
+
|
19
|
+
|
20
|
+
private convertPermissionImport(permissionImports: PermissionImport[], path: string = ""): Permission[] {
|
21
|
+
let permissions: Permission[] = []
|
22
|
+
|
23
|
+
for (let i = 0; i < permissionImports.length; i++) {
|
24
|
+
const permissionImport = permissionImports[i];
|
25
|
+
|
26
|
+
if (!permissionImport.path.includes("/")) {
|
27
|
+
permissionImport.path = "/" + permissionImport.path
|
28
|
+
}
|
29
|
+
|
30
|
+
if (!permissionImport.children || permissionImport.children.length <= 0) {
|
31
|
+
const permission = new Permission()
|
32
|
+
permission.path = path + permissionImport.path
|
33
|
+
permissions.push(permission)
|
34
|
+
} else {
|
35
|
+
permissions = permissions.concat(
|
36
|
+
this.convertPermissionImport(permissionImport.children, permissionImport.path)
|
37
|
+
)
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
return permissions
|
42
|
+
}
|
43
|
+
|
44
|
+
async import(permissionImports: PermissionImport[]): Promise<Permission[]> {
|
45
|
+
const permissions = this.convertPermissionImport(permissionImports)
|
46
|
+
|
47
|
+
await Permission.delete({})
|
48
|
+
await Permission.save(permissions)
|
49
|
+
|
50
|
+
return permissions
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
// =====================INIT=====================
|
57
|
+
async initRole(name: string, description: string) {
|
58
|
+
const role = new Role()
|
59
|
+
role.name = name
|
60
|
+
role.description = description
|
61
|
+
await role.save()
|
62
|
+
|
63
|
+
return role
|
64
|
+
}
|
65
|
+
|
66
|
+
} // END FILE
|
@@ -0,0 +1,104 @@
|
|
1
|
+
import { Service } from "@tsed/common";
|
2
|
+
|
3
|
+
import { CoreService } from "../core/services/CoreService";
|
4
|
+
import { Staff } from "../entity/Staff";
|
5
|
+
import { Exception, BadRequest } from "ts-httpexceptions";
|
6
|
+
import { Permission } from "../entity/Permission";
|
7
|
+
import { Password } from "../util/password";
|
8
|
+
import { Role } from "../entity/Role";
|
9
|
+
|
10
|
+
interface ChangePasswordParams {
|
11
|
+
staff: Staff
|
12
|
+
oldPassword: string
|
13
|
+
newPassword: string
|
14
|
+
}
|
15
|
+
|
16
|
+
@Service()
|
17
|
+
export class StaffService extends CoreService {
|
18
|
+
|
19
|
+
// =====================LOGIN=====================
|
20
|
+
public async login(username: string, password: string): Promise<Staff> {
|
21
|
+
const staff = await Staff.findOneOrThrowOption({ where: { username } })
|
22
|
+
|
23
|
+
await this.validatePassword(staff, password)
|
24
|
+
|
25
|
+
if (staff.isBlock) {
|
26
|
+
throw new BadRequest('Tài khoản này đã bị khoá!')
|
27
|
+
}
|
28
|
+
|
29
|
+
return staff
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
// =====================GET PERMISSION=====================
|
34
|
+
public async getPermission(staffId: number): Promise<Permission[]> {
|
35
|
+
return Permission.createQueryBuilder("p")
|
36
|
+
.leftJoin("p.roles", "r")
|
37
|
+
.leftJoin("r.staff", "a")
|
38
|
+
.where("a.id = :staffId", { staffId })
|
39
|
+
.getMany()
|
40
|
+
}
|
41
|
+
|
42
|
+
|
43
|
+
// =====================CHECK DUPLICATE=====================
|
44
|
+
async checkDuplicate(staff: Staff, userId: number = null) {
|
45
|
+
const { username, phone, email } = staff
|
46
|
+
|
47
|
+
const oldStaff = await Staff.findOne({
|
48
|
+
where: [{ username }, { phone }, { email }]
|
49
|
+
})
|
50
|
+
|
51
|
+
if (oldStaff && oldStaff.id != userId) {
|
52
|
+
let message = ""
|
53
|
+
|
54
|
+
if (oldStaff.username == staff.username) {
|
55
|
+
message = "Tài khoản"
|
56
|
+
} else if (oldStaff.phone == staff.phone) {
|
57
|
+
message = "Số điện thoại"
|
58
|
+
} else if (oldStaff.email == staff.email) {
|
59
|
+
message = "Email"
|
60
|
+
}
|
61
|
+
|
62
|
+
throw new BadRequest(`Trùng ${message} với nhân viên khác`)
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
|
67
|
+
// =====================INIT=====================
|
68
|
+
async initStaff(role: Role, name: string, username: string, password: string) {
|
69
|
+
const staff = new Staff()
|
70
|
+
staff.role = role
|
71
|
+
staff.name = name
|
72
|
+
staff.username = username
|
73
|
+
staff.password = await Password.hash(password)
|
74
|
+
await staff.save()
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
// =====================CHANGE PASSWORD=====================
|
79
|
+
async changePassword({ staff, oldPassword, newPassword }: ChangePasswordParams) {
|
80
|
+
await this.validatePassword(staff, oldPassword)
|
81
|
+
|
82
|
+
if (oldPassword == newPassword) {
|
83
|
+
throw new BadRequest('Mật khẩu mới không được trùng mật khẩu cũ');
|
84
|
+
}
|
85
|
+
|
86
|
+
staff.password = await Password.hash(newPassword)
|
87
|
+
await staff.save()
|
88
|
+
}
|
89
|
+
|
90
|
+
|
91
|
+
public async validatePassword(staff: Staff, password: string) {
|
92
|
+
const staffWithPass = await Staff.findOneOrThrowOption({
|
93
|
+
select: ["password", "id"],
|
94
|
+
where: { id: staff.id }
|
95
|
+
})
|
96
|
+
|
97
|
+
const isValid = await Password.validate(password, staffWithPass.password)
|
98
|
+
if (!isValid) {
|
99
|
+
throw new BadRequest('Mật khẩu cũ không đúng')
|
100
|
+
}
|
101
|
+
|
102
|
+
}
|
103
|
+
|
104
|
+
} // END FILE
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
import { ErrorRequestHandler, Response, Request } from 'express';
|
2
|
+
|
3
|
+
import { Customer } from '../entity/Customer';
|
4
|
+
import { Staff } from '../entity/Staff';
|
5
|
+
// import { Driver } from '../entity/Driver';
|
6
|
+
import { AuthType } from '../middleware/auth/strategy/JWT';
|
7
|
+
export { }
|
8
|
+
declare global {
|
9
|
+
|
10
|
+
namespace NodeJS {
|
11
|
+
interface EventEmitter {
|
12
|
+
}
|
13
|
+
}
|
14
|
+
namespace Express {
|
15
|
+
|
16
|
+
interface ErrorRequestHandler {
|
17
|
+
statusCode?: number
|
18
|
+
}
|
19
|
+
|
20
|
+
interface Request {
|
21
|
+
staff: Staff,
|
22
|
+
customer: Customer,
|
23
|
+
// driver: Driver,
|
24
|
+
authType: AuthType
|
25
|
+
}
|
26
|
+
|
27
|
+
interface Response {
|
28
|
+
/**
|
29
|
+
* Gui response voi status code 200
|
30
|
+
* @param {Array<object> | object} data
|
31
|
+
* @param {string} message
|
32
|
+
*/
|
33
|
+
sendOK(data: Array<object> | object,
|
34
|
+
message?: string): void
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Gui response voi status code 201
|
38
|
+
* @param {Array<object> | object} data
|
39
|
+
* @param {string} message
|
40
|
+
*/
|
41
|
+
sendCreated(message: string,
|
42
|
+
data?: Array<object> | object): void
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Gui response voi status code 400
|
46
|
+
* @param {string} message
|
47
|
+
* @param {Array<object> | object} data
|
48
|
+
*/
|
49
|
+
sendClientError(message: string,
|
50
|
+
data?: Array<object> | object): void
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Gui response voi status code 401
|
54
|
+
* @param {string} message
|
55
|
+
* @param {Array<object> | object} data
|
56
|
+
*/
|
57
|
+
sendUnauthorized(message: string,
|
58
|
+
data?: Array<object> | object): void
|
59
|
+
|
60
|
+
/**
|
61
|
+
* Gui response voi status code 403
|
62
|
+
* @param {string} message
|
63
|
+
* @param {Array<object> | object} data
|
64
|
+
*/
|
65
|
+
sendForbidden(message: string,
|
66
|
+
data?: Array<object> | object): void
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Gui response voi status code 200
|
70
|
+
* @param {string} message
|
71
|
+
* @param {Array<object> | object} data
|
72
|
+
*/
|
73
|
+
sendNotFound(message: string,
|
74
|
+
data?: Array<object> | object): void
|
75
|
+
|
76
|
+
/**
|
77
|
+
* Gui response voi status code 500
|
78
|
+
* @param {string} message
|
79
|
+
* @param {Array<object> | object} data
|
80
|
+
*/
|
81
|
+
sendFail(message: string,
|
82
|
+
data?: Array<object> | object): void
|
83
|
+
|
84
|
+
/**
|
85
|
+
* Gui response json
|
86
|
+
* @param {Array<object> | object} data
|
87
|
+
* @param {string} message
|
88
|
+
* @param {boolean} status
|
89
|
+
* @param {number} code
|
90
|
+
*/
|
91
|
+
sendAPI(data: Array<object> | object,
|
92
|
+
message: string,
|
93
|
+
status: boolean,
|
94
|
+
code: number): void
|
95
|
+
}
|
96
|
+
}
|
97
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import Expo, { ExpoPushMessage } from 'expo-server-sdk';
|
2
|
+
const expo = new Expo();
|
3
|
+
|
4
|
+
export class ExpoNotification {
|
5
|
+
|
6
|
+
static getMessages(tokens: string[], body: string, title: string, data: object) {
|
7
|
+
const messages: ExpoPushMessage[] = []
|
8
|
+
for (let pushToken of tokens) {
|
9
|
+
if (!Expo.isExpoPushToken(pushToken)) {
|
10
|
+
console.error(`Push token ${pushToken} is not a valid Expo push token`);
|
11
|
+
continue;
|
12
|
+
}
|
13
|
+
|
14
|
+
messages.push({
|
15
|
+
to: pushToken,
|
16
|
+
sound: {
|
17
|
+
name: "default",
|
18
|
+
critical: true
|
19
|
+
},
|
20
|
+
body: body || "Push notification description",
|
21
|
+
title: title || "Push notification title",
|
22
|
+
data,
|
23
|
+
})
|
24
|
+
}
|
25
|
+
return messages
|
26
|
+
}
|
27
|
+
|
28
|
+
static async sentChunk(chunks: any) {
|
29
|
+
let tickets = []
|
30
|
+
for (let chunk of chunks) {
|
31
|
+
try {
|
32
|
+
let ticketChunk = await expo.sendPushNotificationsAsync(chunk);
|
33
|
+
tickets.push(...ticketChunk);
|
34
|
+
} catch (error) {
|
35
|
+
console.log('error:', error)
|
36
|
+
}
|
37
|
+
}
|
38
|
+
return tickets
|
39
|
+
}
|
40
|
+
|
41
|
+
static async pushNotification(tokens: string[], title: string, body: string, data: object) {
|
42
|
+
data = { ...data }
|
43
|
+
try {
|
44
|
+
let messages = ExpoNotification.getMessages(tokens, body, title, data)
|
45
|
+
let chunks = expo.chunkPushNotifications(messages);
|
46
|
+
const tickets = await ExpoNotification.sentChunk(chunks);
|
47
|
+
console.log('tickets:', tickets)
|
48
|
+
return true
|
49
|
+
} catch (error) {
|
50
|
+
return false
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|