beech-api 3.7.23 → 3.8.0-beta.1-rc
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/README.md +484 -127
- package/index.js +2 -2
- package/package.json +8 -1
- package/packages/cli/beech +2 -2
- package/packages/cli/bin/beech-app.js +10 -8
- package/packages/cli/bin/beech-service.js +1 -1
- package/packages/cli/core/auth/Credentials.js +139 -89
- package/packages/cli/core/auth/Passport.js +264 -164
- package/packages/cli/core/auth/_Request.js +1 -1
- package/packages/cli/core/configure/app.config-basic.js +2 -2
- package/packages/cli/core/configure/app.config-sequelize.js +2 -2
- package/packages/cli/core/configure/beech.config.js +1 -0
- package/packages/cli/core/configure/passport.config.js +33 -13
- package/packages/cli/core/databases/sequelize.js +3 -0
- package/packages/cli/core/databases/test.js +5 -3
- package/packages/cli/core/generator/_endpoints +5 -9
- package/packages/cli/core/generator/_endpoints_basic +11 -8
- package/packages/cli/core/generator/_help +1 -1
- package/packages/cli/core/generator/_models +5 -4
- package/packages/cli/core/generator/_models_basic +2 -2
- package/packages/cli/core/generator/_package +5 -1
- package/packages/cli/core/generator/{_add-on → _scheduler} +1 -1
- package/packages/cli/core/generator/_spec +15 -10
- package/packages/cli/core/generator/index.js +19 -44
- package/packages/cli/core/helpers/2fa.js +85 -0
- package/packages/cli/core/helpers/math.js +55 -7
- package/packages/cli/core/helpers/poolEntity.js +29 -1
- package/packages/cli/core/index.js +65 -34
- package/packages/cli/core/middleware/express/duplicateRequest.js +12 -0
- package/packages/cli/core/middleware/express/jwtCheckAllow.js +68 -0
- package/packages/cli/core/middleware/express/rateLimit.js +17 -0
- package/packages/cli/core/middleware/express/slowDown.js +2 -0
- package/packages/cli/core/middleware/index.js +6 -0
- package/packages/cli/core/middleware/origin/guard/advance.js +74 -0
- package/packages/cli/core/{origin → middleware/origin}/whitelist/cors.js +15 -12
- package/packages/cli/core/services/http.express.js +116 -72
- package/packages/lib/index.js +3 -1
- package/packages/lib/src/endpoint.js +523 -89
- package/packages/lib/src/guard.js +61 -0
- package/packages/lib/src/schema.js +57 -26
- package/packages/lib/src/specificExpress.js +7 -0
- package/packages/lib/src/user.js +94 -18
- package/packages/cli/core/origin/index.js +0 -2
|
@@ -1,98 +1,532 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
const walk = require("walk");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const { checkRoleMiddlewareWithDefaultProject } = require("../../cli/core/middleware/express/jwtCheckAllow");
|
|
4
|
+
|
|
5
|
+
function walkModel(cb) {
|
|
6
|
+
try {
|
|
7
|
+
let jsfiles = [];
|
|
8
|
+
let walker = walk.walk(appRoot + "/src/models", { followLinks: false });
|
|
9
|
+
// Walk file on push
|
|
10
|
+
walker.on("file", (root, stat, next) => {
|
|
11
|
+
jsfiles.push(root + "/" + stat.name);
|
|
12
|
+
next();
|
|
12
13
|
});
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
14
|
+
// Walking
|
|
15
|
+
walker.on("end", () => {
|
|
16
|
+
let preProject = [];
|
|
17
|
+
if(jsfiles.length) {
|
|
18
|
+
jsfiles.forEach((file, k) => {
|
|
19
|
+
let schemaPath = "@/models" + file.split("models")[1].replace(/\\/g, "/");
|
|
20
|
+
let endpoint = file
|
|
21
|
+
.split("models")[1]
|
|
22
|
+
.replace(/\\/g, "/")
|
|
23
|
+
.replace(/_/g, "-")
|
|
24
|
+
.toLowerCase()
|
|
25
|
+
.slice(0, -3);
|
|
26
|
+
preProject.push([schemaPath, endpoint]);
|
|
27
|
+
if (jsfiles.length == k + 1) {
|
|
28
|
+
cb(null, preProject);
|
|
29
|
+
}
|
|
30
30
|
});
|
|
31
|
+
} else {
|
|
32
|
+
// model not found.
|
|
33
|
+
cb(null, preProject);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
cb(error, null);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function filterProject(Projects, reqUrl, req, res, cb) {
|
|
42
|
+
try {
|
|
43
|
+
let pj = Projects.shift();
|
|
44
|
+
let regx = new RegExp(pj[1] + "?[^\/].?[a-zA-Z0-9].*$", 'g');
|
|
45
|
+
let regxMatch = reqUrl.match(regx);
|
|
46
|
+
let regxMatchLength = (regxMatch) ? regxMatch.length: 0;
|
|
47
|
+
if (pj[1] == reqUrl) {
|
|
48
|
+
return checkOffset(Object.values(require(pj[0]))[0], req, res, (thenChecked) => {
|
|
49
|
+
if(thenChecked) {
|
|
50
|
+
return cb(null, Object.values(require(pj[0]))[0]);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
} else if(regxMatchLength) {
|
|
54
|
+
return checkOffset(Object.values(require(pj[0]))[0], req, res, (thenChecked) => {
|
|
55
|
+
if(thenChecked) {
|
|
56
|
+
return cb(null, Object.values(require(pj[0]))[0]);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// Finally recursive filterProject function
|
|
61
|
+
if (Projects.length > 0) {
|
|
62
|
+
filterProject(Projects, reqUrl, req, res, cb);
|
|
63
|
+
} else {
|
|
64
|
+
// not match
|
|
65
|
+
return notfound(res);
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
cb(error, null);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function checkOffset(Project, req, res, cb) {
|
|
73
|
+
if (!Project) {
|
|
74
|
+
return notfound(res);
|
|
75
|
+
}
|
|
76
|
+
// check offset is Ingeter as well as Zero number
|
|
77
|
+
let offset = req.params.offset || undefined;
|
|
78
|
+
let limit = req.params.limit || undefined;
|
|
79
|
+
let offsetRegxMatch = (offset !== undefined) ? offset.match(/^[0-9]+$/) : undefined;
|
|
80
|
+
let limitRegxMatch = (limit !== undefined) ? limit.match(/^[0-9]+$/) : undefined;
|
|
81
|
+
if (offsetRegxMatch && limitRegxMatch) {
|
|
82
|
+
cb(true);
|
|
83
|
+
} else {
|
|
84
|
+
if(offset === undefined) {
|
|
85
|
+
cb(true);
|
|
86
|
+
} else {
|
|
87
|
+
return notfound(res);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function notfound(res) {
|
|
93
|
+
return res.status(404).json({
|
|
94
|
+
code: 404,
|
|
95
|
+
status: "404_NOT_FOUND",
|
|
96
|
+
message: "The Endpoint not found!.",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function errMessage(err, res) {
|
|
101
|
+
let errTurnOffDbDefine = JSON.stringify(err.toString()).match(/'define'/);
|
|
102
|
+
let errTurnOffDbOption = JSON.stringify(err.toString()).match(/'options'/);
|
|
103
|
+
if(errTurnOffDbDefine || errTurnOffDbOption) {
|
|
104
|
+
// @return
|
|
105
|
+
return res.status(500).json({
|
|
106
|
+
code: 500,
|
|
107
|
+
status: "ERR_INTERNAL_SERVER",
|
|
108
|
+
message: "Database connection name is CLOSED.",
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
// @return
|
|
112
|
+
return res.status(500).json({
|
|
113
|
+
code: 500,
|
|
114
|
+
status: "ERR_INTERNAL_SERVER",
|
|
115
|
+
message: err.toString(),
|
|
31
116
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const byPassCheckRole = (Projects, method, passport_config) => {
|
|
121
|
+
return async function (req, res, next) {
|
|
122
|
+
if(passport_config[0] !== undefined) {
|
|
123
|
+
if(req.params.hash == passport_config[0].replace(/^\/|\/$/g, "")) {
|
|
124
|
+
return next();
|
|
125
|
+
} else {
|
|
126
|
+
if(passport_config[1].jwt_allow === true) {
|
|
127
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
128
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
129
|
+
if(!err) {
|
|
130
|
+
if(Project.options.defaultEndpoint === undefined || Project.options.defaultEndpoint === true) {
|
|
131
|
+
// Project is not use options
|
|
132
|
+
return Credentials(req, res, () => {
|
|
133
|
+
return checkRoleMiddlewareWithDefaultProject(null)(req, res, next);
|
|
134
|
+
});
|
|
135
|
+
} else {
|
|
136
|
+
// Method is set
|
|
137
|
+
if(Project.options.defaultEndpoint[method]) {
|
|
138
|
+
if(Project.options.defaultEndpoint[method]["allow"] === undefined || Project.options.defaultEndpoint[method]["allow"] === true) {
|
|
139
|
+
if(Project.options.defaultEndpoint[method]["jwt"]?.allow === false) {
|
|
140
|
+
// by project jwt_allow is false
|
|
141
|
+
return checkRoleMiddlewareWithDefaultProject(null)(req, res, next);
|
|
142
|
+
} else {
|
|
143
|
+
return Credentials(req, res, () => {
|
|
144
|
+
return checkRoleMiddlewareWithDefaultProject(Project.options.defaultEndpoint[method].jwt?.broken_role)(req, res, next);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
return notfound(res);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
// Method is not set
|
|
152
|
+
return Credentials(req, res, () => {
|
|
153
|
+
return checkRoleMiddlewareWithDefaultProject(null)(req, res, next);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
return errMessage(err, res);
|
|
159
|
+
}
|
|
47
160
|
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
161
|
+
} else {
|
|
162
|
+
// global jwt_allow is false
|
|
163
|
+
return next();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function Base() {
|
|
171
|
+
return new Promise((resolve, reject) => {
|
|
172
|
+
try {
|
|
173
|
+
walkModel((err, Projects) => {
|
|
174
|
+
if (err) {
|
|
175
|
+
reject(err);
|
|
176
|
+
} else {
|
|
177
|
+
const checkPassport = new Promise((resolve) => {
|
|
178
|
+
const passport_config_file = appRoot + "/passport.config.js";
|
|
179
|
+
let passport_config_auth = undefined;
|
|
180
|
+
if (fs.existsSync(passport_config_file)) {
|
|
181
|
+
const _passport_config_ = require(passport_config_file);
|
|
182
|
+
resolve([_passport_config_.auth_endpoint || "/authentication", _passport_config_]);
|
|
183
|
+
} else {
|
|
184
|
+
// passport config not found
|
|
185
|
+
resolve([passport_config_auth, _passport_config_]);
|
|
186
|
+
}
|
|
55
187
|
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
188
|
+
// passport conifg promise
|
|
189
|
+
checkPassport.then((passport_config) => {
|
|
190
|
+
if(Projects.length) {
|
|
191
|
+
// GET method with ALL data, default: limit rows 100
|
|
192
|
+
endpoint.get("/:hash", (req, res, next) => byPassCheckRole(Projects, "GET", passport_config)(req, res, next), async (req, res, next) => {
|
|
193
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
194
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
195
|
+
if (!err) {
|
|
196
|
+
try {
|
|
197
|
+
const results = await Project.findAll({
|
|
198
|
+
offset: 0,
|
|
199
|
+
limit: (Project.options.limitRows) ? Project.options.limitRows : 100,
|
|
200
|
+
});
|
|
201
|
+
// @ return
|
|
202
|
+
await res.json({
|
|
203
|
+
code: 200,
|
|
204
|
+
status: "SUCCESS",
|
|
205
|
+
results,
|
|
206
|
+
length: results.length,
|
|
207
|
+
});
|
|
208
|
+
} catch (error) {
|
|
209
|
+
// @return
|
|
210
|
+
return errMessage(error, res);
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
// @return
|
|
214
|
+
return errMessage(err, res);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
// GET method with id
|
|
219
|
+
endpoint.get("/:hash/:id", (req, res, next) => byPassCheckRole(Projects, "GET", passport_config)(req, res, next), async (req, res, next) => {
|
|
220
|
+
// allow official stetragy
|
|
221
|
+
if(req.params.id == "google" || req.params.id == "facebook") {
|
|
222
|
+
return next();
|
|
223
|
+
}
|
|
224
|
+
// filter GET project
|
|
225
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
226
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
227
|
+
if (!err) {
|
|
228
|
+
try {
|
|
229
|
+
const results = await Project.findByPk(req.params.id);
|
|
230
|
+
// @ return
|
|
231
|
+
await res.json({
|
|
232
|
+
code: 200,
|
|
233
|
+
status: "SUCCESS",
|
|
234
|
+
results,
|
|
235
|
+
});
|
|
236
|
+
} catch (error) {
|
|
237
|
+
// @return
|
|
238
|
+
return errMessage(error, res);
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
// @return
|
|
242
|
+
return errMessage(err, res);
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
// GET method with :limit and :offset
|
|
247
|
+
endpoint.get("/:hash/:limit/:offset", (req, res, next) => byPassCheckRole(Projects, "GET", passport_config)(req, res, next), async (req, res, next) => {
|
|
248
|
+
// allow official stetragy
|
|
249
|
+
if(req.params.limit == "google" || req.params.limit == "facebook" || req.params.offset == "callback") {
|
|
250
|
+
return next();
|
|
251
|
+
}
|
|
252
|
+
// filter GET limit,offset project
|
|
253
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
254
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
255
|
+
if (!err) {
|
|
256
|
+
try {
|
|
257
|
+
const results = await Project.findAll({
|
|
258
|
+
offset: parseInt(req.params.offset) || 0,
|
|
259
|
+
limit: (parseInt(req.params.limit) === 0) ? 0 : parseInt(req.params.limit),
|
|
260
|
+
});
|
|
261
|
+
// @ return
|
|
262
|
+
await res.json({
|
|
263
|
+
code: 200,
|
|
264
|
+
status: "SUCCESS",
|
|
265
|
+
results,
|
|
266
|
+
length: results.length,
|
|
267
|
+
});
|
|
268
|
+
} catch (error) {
|
|
269
|
+
// @return
|
|
270
|
+
return errMessage(error, res);
|
|
271
|
+
}
|
|
272
|
+
} else {
|
|
273
|
+
// @return
|
|
274
|
+
return errMessage(err, res);
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
// POST method
|
|
279
|
+
endpoint.post("/:hash", (req, res, next) => byPassCheckRole(Projects, "POST", passport_config)(req, res, next), async (req, res, next) => {
|
|
280
|
+
// Check auth request match send next
|
|
281
|
+
if(passport_config[0] !== undefined) {
|
|
282
|
+
if(req.params.hash == passport_config[0].replace(/^\/|\/$/g, "")) {
|
|
283
|
+
return next();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// When lost IF
|
|
287
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
288
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
289
|
+
if (!err) {
|
|
290
|
+
try {
|
|
291
|
+
// Leave pool by project for check pool error
|
|
292
|
+
let pool = Project.sequelize;
|
|
293
|
+
// Store with body
|
|
294
|
+
await Project.create(req.body).then((created) => {
|
|
295
|
+
// @return
|
|
296
|
+
res.status(201).json({
|
|
297
|
+
code: 201,
|
|
298
|
+
status: "CREATE_SUCCESS",
|
|
299
|
+
createdId: (created.id) ? created.id : created[Project.primaryKeyAttributes[0]],
|
|
300
|
+
});
|
|
301
|
+
}).catch((error) => {
|
|
302
|
+
if(pool.options.logging) {
|
|
303
|
+
// @return with all error
|
|
304
|
+
res.status(501).json({
|
|
305
|
+
code: 501,
|
|
306
|
+
status: "CREATE_FAILED",
|
|
307
|
+
error: error,
|
|
308
|
+
});
|
|
309
|
+
} else {
|
|
310
|
+
if(error.sql) {
|
|
311
|
+
delete error.sql;
|
|
312
|
+
if(error.errors) {
|
|
313
|
+
delete error.errors;
|
|
314
|
+
}
|
|
315
|
+
if(error.parent) {
|
|
316
|
+
delete error.parent;
|
|
317
|
+
}
|
|
318
|
+
if(error.original) {
|
|
319
|
+
delete error.original.sql;
|
|
320
|
+
if(error.original.parameters) {
|
|
321
|
+
delete error.original.parameters;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if(error.parameters) {
|
|
325
|
+
delete error.parameters;
|
|
326
|
+
}
|
|
327
|
+
// @return with some error
|
|
328
|
+
res.status(501).json({
|
|
329
|
+
code: 501,
|
|
330
|
+
status: "CREATE_FAILED",
|
|
331
|
+
error: error,
|
|
332
|
+
});
|
|
333
|
+
} else {
|
|
334
|
+
// @return with some string error
|
|
335
|
+
res.status(501).json({
|
|
336
|
+
code: 501,
|
|
337
|
+
status: "CREATE_FAILED",
|
|
338
|
+
error: String(error),
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
} catch (error) {
|
|
344
|
+
// @return
|
|
345
|
+
return errMessage(error, res);
|
|
346
|
+
}
|
|
347
|
+
} else {
|
|
348
|
+
// @return
|
|
349
|
+
return errMessage(err, res);
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
// PATCH method
|
|
354
|
+
endpoint.patch("/:hash/:id", (req, res, next) => byPassCheckRole(Projects, "PATCH", passport_config)(req, res, next), async (req, res, next) => {
|
|
355
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
356
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
357
|
+
if (!err) {
|
|
358
|
+
try {
|
|
359
|
+
// Leave pool by project for check pool error
|
|
360
|
+
let pool = Project.sequelize;
|
|
361
|
+
// Assign update pk
|
|
362
|
+
let updatePk = {
|
|
363
|
+
[Project.primaryKeyAttributes[0]]: req.params.id
|
|
364
|
+
};
|
|
365
|
+
// Patch with body
|
|
366
|
+
await Project.update(req.body, {
|
|
367
|
+
where: updatePk,
|
|
368
|
+
}).then((updated) => {
|
|
369
|
+
// @return
|
|
370
|
+
res.status(200).json({
|
|
371
|
+
code: 200,
|
|
372
|
+
status: "UPDATE_SUCCESS",
|
|
373
|
+
result: {
|
|
374
|
+
updateId: req.params.id,
|
|
375
|
+
affectedRows: updated[0],
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
}).catch((error) => {
|
|
379
|
+
if(pool.options.logging) {
|
|
380
|
+
// @return with all error
|
|
381
|
+
res.status(501).json({
|
|
382
|
+
code: 501,
|
|
383
|
+
status: "UPDATE_FAILED",
|
|
384
|
+
error: error,
|
|
385
|
+
});
|
|
386
|
+
} else {
|
|
387
|
+
if(error.sql) {
|
|
388
|
+
delete error.sql;
|
|
389
|
+
if(error.parent) {
|
|
390
|
+
delete error.parent;
|
|
391
|
+
}
|
|
392
|
+
if(error.original) {
|
|
393
|
+
delete error.original.sql;
|
|
394
|
+
if(error.original.parameters) {
|
|
395
|
+
delete error.original.parameters;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
if(error.parameters) {
|
|
399
|
+
delete error.parameters;
|
|
400
|
+
}
|
|
401
|
+
if(error.errors) {
|
|
402
|
+
delete error.errors;
|
|
403
|
+
}
|
|
404
|
+
// @return with some error
|
|
405
|
+
res.status(501).json({
|
|
406
|
+
code: 501,
|
|
407
|
+
status: "UPDATE_FAILED",
|
|
408
|
+
error: error,
|
|
409
|
+
});
|
|
410
|
+
} else {
|
|
411
|
+
// @return with some string error
|
|
412
|
+
res.status(501).json({
|
|
413
|
+
code: 501,
|
|
414
|
+
status: "UPDATE_FAILED",
|
|
415
|
+
error: String(error),
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
} catch (error) {
|
|
421
|
+
// @return
|
|
422
|
+
return errMessage(error, res);
|
|
423
|
+
}
|
|
424
|
+
} else {
|
|
425
|
+
// @return
|
|
426
|
+
return errMessage(err, res);
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
// DELETE method
|
|
431
|
+
endpoint.delete("/:hash/:id", (req, res, next) => byPassCheckRole(Projects, "DELETE", passport_config)(req, res, next), async (req, res, next) => {
|
|
432
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
433
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
434
|
+
if (!err) {
|
|
435
|
+
try {
|
|
436
|
+
// Leave pool by project for check pool error
|
|
437
|
+
let pool = Project.sequelize;
|
|
438
|
+
// Assign delete pk
|
|
439
|
+
let deletePk = {
|
|
440
|
+
[Project.primaryKeyAttributes[0]]: req.params.id
|
|
441
|
+
};
|
|
442
|
+
// Delete with params
|
|
443
|
+
await Project.destroy({
|
|
444
|
+
where: deletePk,
|
|
445
|
+
}).then((deleted) => {
|
|
446
|
+
if (deleted) {
|
|
447
|
+
// @return
|
|
448
|
+
res.status(200).json({
|
|
449
|
+
code: 200,
|
|
450
|
+
status: "DELETE_SUCCESS",
|
|
451
|
+
result: {
|
|
452
|
+
deleteId: req.params.id,
|
|
453
|
+
affectedRows: deleted,
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
} else {
|
|
457
|
+
res.status(406).json({
|
|
458
|
+
code: 406,
|
|
459
|
+
status: "NOT_ACCEPTABLE",
|
|
460
|
+
result: {
|
|
461
|
+
deleteId: req.params.id,
|
|
462
|
+
affectedRows: deleted,
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
}).catch((error) => {
|
|
467
|
+
if(pool.options.logging) {
|
|
468
|
+
// @return with all error
|
|
469
|
+
res.status(501).json({
|
|
470
|
+
code: 501,
|
|
471
|
+
status: "DELETE_FAILED",
|
|
472
|
+
error: error,
|
|
473
|
+
});
|
|
474
|
+
} else {
|
|
475
|
+
if(error.sql) {
|
|
476
|
+
delete error.sql;
|
|
477
|
+
if(error.parent) {
|
|
478
|
+
delete error.parent;
|
|
479
|
+
}
|
|
480
|
+
if(error.original) {
|
|
481
|
+
delete error.original.sql;
|
|
482
|
+
if(error.original.parameters) {
|
|
483
|
+
delete error.original.parameters;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if(error.parameters) {
|
|
487
|
+
delete error.parameters;
|
|
488
|
+
}
|
|
489
|
+
if(error.errors) {
|
|
490
|
+
delete error.errors;
|
|
491
|
+
}
|
|
492
|
+
// @return with some error
|
|
493
|
+
res.status(501).json({
|
|
494
|
+
code: 501,
|
|
495
|
+
status: "DELETE_FAILED",
|
|
496
|
+
error: error,
|
|
497
|
+
});
|
|
498
|
+
} else {
|
|
499
|
+
// @return with some string error
|
|
500
|
+
res.status(501).json({
|
|
501
|
+
code: 501,
|
|
502
|
+
status: "DELETE_FAILED",
|
|
503
|
+
error: String(error),
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
} catch (error) {
|
|
509
|
+
// @return
|
|
510
|
+
return errMessage(error, res);
|
|
511
|
+
}
|
|
512
|
+
} else {
|
|
513
|
+
// @return
|
|
514
|
+
return errMessage(err, res);
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
// resolve it.
|
|
520
|
+
resolve(true);
|
|
521
|
+
}).catch((err) => {
|
|
522
|
+
reject(err);
|
|
92
523
|
});
|
|
93
|
-
}
|
|
94
|
-
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
} catch (error) {
|
|
527
|
+
reject(error);
|
|
528
|
+
}
|
|
95
529
|
});
|
|
96
|
-
}
|
|
530
|
+
}
|
|
97
531
|
|
|
98
532
|
module.exports = { Base };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const md5 = require("md5");
|
|
2
|
+
const secret = require("./salt").salt;
|
|
3
|
+
const { findPassportPk } = require("../../cli/core/helpers/poolEntity");
|
|
4
|
+
|
|
5
|
+
async function Guard(usr, pws, fields = [], fieldCondArr = {}, cb) {
|
|
6
|
+
try {
|
|
7
|
+
const passport_config = require(appRoot + "/passport.config.js");
|
|
8
|
+
let stm = '';
|
|
9
|
+
let cond = '1=1';
|
|
10
|
+
let passportTable = await [passport_config.model.table || "users"];
|
|
11
|
+
let passportUsernameField = passport_config.model.username_field || "username";
|
|
12
|
+
let passportPasswordField = passport_config.model.password_field || "password";
|
|
13
|
+
const pool = await eval("sql." + passport_config.model.name);
|
|
14
|
+
let expectFields = await (fields) ? fields : (passport_config.model.fields.length) ? passport_config.model.fields : [];
|
|
15
|
+
await findPassportPk(pool_base, pool, passportTable, expectFields, async (err, passportFields) => {
|
|
16
|
+
if(err) {
|
|
17
|
+
cb(err, null);
|
|
18
|
+
} else {
|
|
19
|
+
cond += ` AND ${passportUsernameField} = ? AND ${passportPasswordField} = ?`
|
|
20
|
+
let dynReplacement = [];
|
|
21
|
+
// Check for generate more condition
|
|
22
|
+
if(fieldCondArr) {
|
|
23
|
+
Object.keys(fieldCondArr).forEach(key => {
|
|
24
|
+
cond += ` AND ${key} = ?`;
|
|
25
|
+
dynReplacement.push(fieldCondArr[key]);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// check base pool
|
|
29
|
+
if (pool_base == "basic") {
|
|
30
|
+
// pool base is MySQL
|
|
31
|
+
stm += 'SELECT ?? FROM ?? WHERE ' + cond + ' LIMIT 1;';
|
|
32
|
+
await pool.query(stm, [passportFields, passportTable, usr, md5(pws + secret), ...dynReplacement], (err, row) => {
|
|
33
|
+
if(err) {
|
|
34
|
+
cb(err, null);
|
|
35
|
+
} else {
|
|
36
|
+
cb(null, row);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
} else if (pool_base == "sequelize") {
|
|
40
|
+
// pool base is Sequelize
|
|
41
|
+
try {
|
|
42
|
+
stm += `SELECT ${passportFields} FROM ${passportTable} WHERE ` + cond;
|
|
43
|
+
let result = await pool.query(stm, {
|
|
44
|
+
replacements: [usr, md5(pws + secret), ...dynReplacement],
|
|
45
|
+
type: QueryTypes.SELECT
|
|
46
|
+
});
|
|
47
|
+
return cb(null, result);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return cb((error.errors) ? error.errors[0] : error, null);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
return cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
} catch (error) {
|
|
57
|
+
cb(error, null);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { Guard };
|