beech-api 3.8.0 → 3.9.0-beta.9-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 +551 -146
- package/package.json +13 -12
- package/packages/cli/bin/beech-app.js +4 -4
- package/packages/cli/bin/beech-service.js +62 -25
- package/packages/cli/core/auth/Credentials.js +115 -88
- package/packages/cli/core/auth/Passport.js +111 -39
- package/packages/cli/core/configure/passport.config.js +1 -1
- package/packages/cli/core/databases/mysql.js +1 -1
- package/packages/cli/core/databases/sequelize.js +15 -6
- package/packages/cli/core/databases/test.js +125 -39
- package/packages/cli/core/generator/_models +3 -26
- package/packages/cli/core/generator/_models_basic +0 -9
- package/packages/cli/core/generator/_package +6 -7
- package/packages/cli/core/generator/_scheduler +16 -6
- package/packages/cli/core/generator/index.js +277 -23
- package/packages/cli/core/helpers/2fa.js +22 -1
- package/packages/cli/core/helpers/math.js +14 -2
- package/packages/cli/core/helpers/poolEntity.js +70 -26
- package/packages/cli/core/index.js +88 -10
- package/packages/cli/core/middleware/express/duplicateRequest.js +10 -6
- package/packages/cli/core/middleware/express/jwtCheckAllow.js +52 -34
- package/packages/cli/core/middleware/express/rateLimit.js +14 -2
- package/packages/cli/core/middleware/origin/guard/advance.js +5 -4
- package/packages/cli/core/services/http.express.js +49 -9
- package/packages/cli/core/test/check-node.js +21 -0
- package/packages/lib/src/endpoint.js +639 -286
- package/packages/lib/src/schema.js +4 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const walk = require("walk");
|
|
2
2
|
const fs = require("fs");
|
|
3
|
+
const moment = require("moment");
|
|
3
4
|
const { checkRoleMiddlewareWithDefaultProject } = require("../../cli/core/middleware/express/jwtCheckAllow");
|
|
5
|
+
const { Limiter, Duplicater } = require("../../cli/core/middleware/index");
|
|
4
6
|
|
|
5
7
|
function walkModel(cb) {
|
|
6
8
|
try {
|
|
@@ -38,7 +40,38 @@ function walkModel(cb) {
|
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
function filterProject(Projects, reqUrl, req, res, cb) {
|
|
43
|
+
function filterProject(Projects, reqUrl, params = "", method = "", req, res, cb) {
|
|
44
|
+
try {
|
|
45
|
+
let pj = Projects.shift();
|
|
46
|
+
let leaveParamsAlone = params.slice(0);
|
|
47
|
+
let paramsItem = leaveParamsAlone.replace(/^\/|\/$/g, "").split('/');
|
|
48
|
+
let leaveReqUrlAlone = reqUrl.slice(0);
|
|
49
|
+
let newParams = params.split("/").filter((e) => (e !== 'undefined')).join("/");
|
|
50
|
+
let urlWithoutParams = leaveReqUrlAlone.replace(newParams, '').split("?")[0].replace(/\/$/, "");
|
|
51
|
+
// sub-way for PATCH method
|
|
52
|
+
urlWithoutParams = (method == "PATCH" || method == "DELETE") ? urlWithoutParams.substring(0, urlWithoutParams.lastIndexOf('/')) : urlWithoutParams;
|
|
53
|
+
// check match project by url
|
|
54
|
+
if(pj[1] == urlWithoutParams) {
|
|
55
|
+
return checkOffset(Object.values(require(pj[0]))[0], req, res, (thenChecked) => {
|
|
56
|
+
if(thenChecked) {
|
|
57
|
+
return cb(null, Object.values(require(pj[0]))[0], paramsItem);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// Finally recursive filterProject function
|
|
62
|
+
if (Projects.length > 0) {
|
|
63
|
+
filterProject(Projects, reqUrl, params, method, req, res, cb);
|
|
64
|
+
} else {
|
|
65
|
+
// not match
|
|
66
|
+
return notfound(res);
|
|
67
|
+
}
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.log(error);
|
|
70
|
+
cb(error, null, []);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function filterProjectForByPass(Projects, reqUrl, req, res, cb) {
|
|
42
75
|
try {
|
|
43
76
|
let pj = Projects.shift();
|
|
44
77
|
let regx = new RegExp(pj[1] + "?[^\/].?[a-zA-Z0-9].*$", 'g');
|
|
@@ -57,9 +90,9 @@ function filterProject(Projects, reqUrl, req, res, cb) {
|
|
|
57
90
|
}
|
|
58
91
|
});
|
|
59
92
|
}
|
|
60
|
-
// Finally recursive
|
|
93
|
+
// Finally recursive filterProjectForByPass function
|
|
61
94
|
if (Projects.length > 0) {
|
|
62
|
-
|
|
95
|
+
filterProjectForByPass(Projects, reqUrl, req, res, cb);
|
|
63
96
|
} else {
|
|
64
97
|
// not match
|
|
65
98
|
return notfound(res);
|
|
@@ -117,52 +150,350 @@ function errMessage(err, res) {
|
|
|
117
150
|
}
|
|
118
151
|
}
|
|
119
152
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
153
|
+
function whereCond(objectCond, cb) {
|
|
154
|
+
if(typeof objectCond === 'object' && Object.keys(objectCond).length) {
|
|
155
|
+
let keys = Object.keys(objectCond);
|
|
156
|
+
let where = {};
|
|
157
|
+
let orderBy = {};
|
|
158
|
+
let groupBy = {};
|
|
159
|
+
// Start Recursive for Check Where condition OR GroupBy OR OrderBy
|
|
160
|
+
recursiveWhereCond(keys, objectCond, where, groupBy, orderBy, (err, cbWhere, cbGroupBy, cbOrderBy) => {
|
|
161
|
+
cb(err, cbWhere, cbGroupBy, cbOrderBy);
|
|
162
|
+
});
|
|
163
|
+
} else {
|
|
164
|
+
cb(null, {}, { group: { groupby: [] } }, { order: { orderby: [] } });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function getValueType(value) {
|
|
169
|
+
if (typeof value === 'string') {
|
|
170
|
+
// Check for ISO-like date string with optional time part
|
|
171
|
+
const isoDateRegex = /^\d{4}-\d{2}-\d{2}(?:[ T]\d{2}:\d{2}:\d{2})?$/;
|
|
172
|
+
const date = new Date(value);
|
|
173
|
+
if (!isNaN(date.getTime()) && isoDateRegex.test(value)) {
|
|
174
|
+
return 'Date';
|
|
175
|
+
}
|
|
176
|
+
return 'String';
|
|
177
|
+
}
|
|
178
|
+
if (typeof value === 'number' && !isNaN(value)) return 'Number';
|
|
179
|
+
if (typeof value === 'boolean') return 'Boolean';
|
|
180
|
+
if (value instanceof Date && !isNaN(value)) return 'Date';
|
|
181
|
+
if (value === null) return 'Null';
|
|
182
|
+
if (typeof value === 'undefined') return 'Undefined';
|
|
183
|
+
if (Array.isArray(value)) return 'Array';
|
|
184
|
+
if (typeof value === 'function') return 'Function';
|
|
185
|
+
if (typeof value === 'symbol') return 'Symbol';
|
|
186
|
+
if (typeof value === 'bigint') return 'BigInt';
|
|
187
|
+
if (typeof value === 'object') return 'Object';
|
|
188
|
+
return 'Unknown';
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async function recursiveWhereCond(keys, objectCond, where, groupBy, orderBy, cb) {
|
|
192
|
+
if(keys.length > 0) {
|
|
193
|
+
let k = keys.shift();
|
|
194
|
+
// Check param key for Where condition OR GroupBy OR OrderBy
|
|
195
|
+
if(k == 'orderby') {
|
|
196
|
+
let oderByValueItemFromQueryString = objectCond[k].replace(/\w+/g, '"$&"').replace(/\[\s*\]/g, '[]');
|
|
197
|
+
// Check Array syntax from Query String
|
|
198
|
+
isValidArrayFormat(oderByValueItemFromQueryString, (err, isArray, strArr) => {
|
|
199
|
+
if(err) {
|
|
200
|
+
cb(["SyntaxError: Unexpected end of Array or String input", ` (${k})`], null, null, null);
|
|
201
|
+
} else {
|
|
202
|
+
let order = JSON.parse(strArr);
|
|
203
|
+
orderBy[k] = order.length ? order : null;
|
|
204
|
+
// Recursive re-call function
|
|
205
|
+
recursiveWhereCond(keys, objectCond, where, groupBy, orderBy, cb);
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
} else if(k == 'groupby') {
|
|
209
|
+
let groupByValueItemFromQueryString = objectCond[k].replace(/\w+/g, '"$&"').replace(/\[\s*\]/g, '[]');
|
|
210
|
+
// Check Array syntax from Query String
|
|
211
|
+
isValidArrayFormat(groupByValueItemFromQueryString, (err, isArray, strArr) => {
|
|
212
|
+
if(err) {
|
|
213
|
+
cb(["SyntaxError: Unexpected end of Array or String input", ` (${k})`], null, null, null);
|
|
214
|
+
} else {
|
|
215
|
+
let group = JSON.parse(strArr);
|
|
216
|
+
groupBy[k] = group.length ? group : null;
|
|
217
|
+
// Recursive re-call function
|
|
218
|
+
recursiveWhereCond(keys, objectCond, where, groupBy, orderBy, cb);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
} else {
|
|
222
|
+
let fieldValueItemFromQueryString = objectCond[k].replace(/([^[\],]+)/g, '"$1"');
|
|
223
|
+
let valueItem = objectCond[k].replace(/[\[\]']+/g, '').split(','); //replace(/[\[\]']+/g, '')
|
|
224
|
+
let cleanValueItem = valueItem.map((e) => e.trim()).filter((e) => e !== '');
|
|
225
|
+
// Check Array syntax from Query String
|
|
226
|
+
isValidArrayFormat(fieldValueItemFromQueryString, async (err) => {
|
|
227
|
+
if(err || cleanValueItem.length < 1) {
|
|
228
|
+
cb(["SyntaxError: Unexpected end of Array or String input", ` (${k})`], null, null, null);
|
|
229
|
+
} else {
|
|
230
|
+
try {
|
|
231
|
+
where[k] = await (cleanValueItem[1])
|
|
232
|
+
? {
|
|
233
|
+
[Op[cleanValueItem[0]]]: (cleanValueItem[1] == 'null') ? null :
|
|
234
|
+
(cleanValueItem[1] == 'true') ? true :
|
|
235
|
+
(cleanValueItem[1] == 'false') ? false :
|
|
236
|
+
(cleanValueItem[0] == 'between' || cleanValueItem[0] == 'notBetween') ? [
|
|
237
|
+
(getValueType(cleanValueItem[1]) == 'Date')
|
|
238
|
+
? cleanValueItem[1].split(' ').map(e => e.trim()).length > 1
|
|
239
|
+
? moment(new Date(cleanValueItem[1]).toISOString())
|
|
240
|
+
: moment(new Date(cleanValueItem[1] + ' 00:00:00').toISOString())
|
|
241
|
+
: cleanValueItem[1],
|
|
242
|
+
(getValueType(cleanValueItem[2]) == 'Date')
|
|
243
|
+
? cleanValueItem[2].split(' ').map(e => e.trim()).length > 1
|
|
244
|
+
? moment(new Date(cleanValueItem[2]).toISOString())
|
|
245
|
+
: moment(new Date(cleanValueItem[2] + ' 23:59:59').toISOString())
|
|
246
|
+
: cleanValueItem[2],
|
|
247
|
+
] :
|
|
248
|
+
(cleanValueItem[0] == 'or' || cleanValueItem[0] == 'in' || cleanValueItem[0] == 'notIn') ? [...cleanValueItem.slice(1)] :
|
|
249
|
+
(cleanValueItem[0] == 'like') ? [cleanValueItem[1],cleanValueItem[2],cleanValueItem[3]].join("") :
|
|
250
|
+
(cleanValueItem[0] == 'notLike') ? [cleanValueItem[1],cleanValueItem[2],cleanValueItem[3]].join("") :
|
|
251
|
+
(cleanValueItem[0] == 'startsWith') ? cleanValueItem[1] :
|
|
252
|
+
(cleanValueItem[0] == 'endsWith') ? cleanValueItem[1] :
|
|
253
|
+
(cleanValueItem[0] == 'substring') ? cleanValueItem[1] :
|
|
254
|
+
[cleanValueItem[1]]
|
|
255
|
+
}
|
|
256
|
+
: cleanValueItem[0];
|
|
257
|
+
// Recursive re-call function
|
|
258
|
+
recursiveWhereCond(keys, objectCond, where, groupBy, orderBy, cb);
|
|
259
|
+
} catch (error) {
|
|
260
|
+
return cb([`Error with (${k})`, error], null, null, null);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
} else {
|
|
266
|
+
// End of recursive function
|
|
267
|
+
cb(null, where, groupBy, orderBy);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function isValidArrayFormat(str, cb) {
|
|
272
|
+
try {
|
|
273
|
+
const parsed = JSON.parse(str);
|
|
274
|
+
cb(null, Array.isArray(parsed), str);
|
|
275
|
+
} catch (err) {
|
|
276
|
+
cb(err, false, null);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
// function parseRawQuery(search) {
|
|
281
|
+
// const rawParams = {};
|
|
282
|
+
// if (search.startsWith('?')) {
|
|
283
|
+
// const queryString = search.slice(1); // Remove '?'
|
|
284
|
+
// const pairs = queryString.split('&');
|
|
285
|
+
|
|
286
|
+
// for (const pair of pairs) {
|
|
287
|
+
// const [key, value = ''] = pair.split('=');
|
|
288
|
+
// if (key) {
|
|
289
|
+
// rawParams[key] = value;
|
|
290
|
+
// }
|
|
291
|
+
// }
|
|
292
|
+
// }
|
|
293
|
+
// return rawParams;
|
|
294
|
+
// }
|
|
295
|
+
|
|
296
|
+
async function findAll(Project, where, offset, group, order, limitRow, cb) {
|
|
297
|
+
try {
|
|
298
|
+
await Project.findAll({
|
|
299
|
+
where,
|
|
300
|
+
group: (group.groupby) ? group.groupby : [],
|
|
301
|
+
order: (order.orderby) ? [order.orderby] : [],
|
|
302
|
+
offset: offset,
|
|
303
|
+
limit: limitRow,
|
|
304
|
+
}).then((results) => {
|
|
305
|
+
cb(null, results)
|
|
306
|
+
}).catch((error) => {
|
|
307
|
+
cb(error, null);
|
|
308
|
+
});
|
|
309
|
+
} catch (error) {
|
|
310
|
+
cb(error, null);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async function retrieving(authEndpoint, Projects, req, res, next) {
|
|
315
|
+
let params = req.params;
|
|
316
|
+
let hash = "/" + req.params.hash;
|
|
317
|
+
// allow official stetragy
|
|
318
|
+
if(hash == authEndpoint && (params[0] == "/facebook" || params[0] == "/facebook/callback" || params[0] == "/google" || params[0] == "/google/callback")) {
|
|
319
|
+
return next();
|
|
320
|
+
}
|
|
321
|
+
// declare variable for check request with params
|
|
322
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
323
|
+
let mergeDuoVar = [req.params.limit, req.params.offset].map((e) => (e || 'undefined')).join("/");
|
|
324
|
+
let reqUrl = req.originalUrl.replace(_publicPath_, '/');
|
|
325
|
+
let checkConditionIsQueryOrId = Object.keys(req.query).length
|
|
326
|
+
? req.query
|
|
327
|
+
: 'undefined';
|
|
328
|
+
/**
|
|
329
|
+
* Function whereCond with callback property
|
|
330
|
+
*
|
|
331
|
+
* @where Object|String
|
|
332
|
+
*
|
|
333
|
+
*/
|
|
334
|
+
whereCond(checkConditionIsQueryOrId, async (err, where, groupBy, orderBy) => {
|
|
335
|
+
if(err) {
|
|
336
|
+
res.status(400).json({
|
|
337
|
+
code: 400,
|
|
338
|
+
status: "BAD_REQUEST",
|
|
339
|
+
err: String(err),
|
|
340
|
+
});
|
|
341
|
+
} else {
|
|
342
|
+
/**
|
|
343
|
+
* Filter Project with callback property
|
|
344
|
+
*
|
|
345
|
+
* @err String
|
|
346
|
+
* @Project Require
|
|
347
|
+
* @params Object [0=limit, 1=offset]
|
|
348
|
+
*
|
|
349
|
+
*/
|
|
350
|
+
await filterProject(leaveMeAlone, reqUrl, "/".concat(mergeDuoVar), "", req, res, async (err, Project, params) => {
|
|
351
|
+
if (!err) {
|
|
352
|
+
try {
|
|
353
|
+
// declare default limit offset
|
|
354
|
+
let offset = 0;
|
|
355
|
+
let limitRow = await (Project.options.limitRows) ? Project.options.limitRows : 100;
|
|
356
|
+
// check assign limit, offset ?
|
|
357
|
+
if ((params[0] && params[0] != 'undefined') && ((params[1] && params[1] != 'undefined') || parseInt(params[1]) === 0)) {
|
|
358
|
+
// Only case: /limit/offset
|
|
359
|
+
limitRow = parseInt(params[0]);
|
|
360
|
+
offset = parseInt(params[1]);
|
|
361
|
+
}
|
|
362
|
+
// findAll data
|
|
363
|
+
await findAll(Project, where, offset, groupBy, orderBy, limitRow, (err, results) => {
|
|
364
|
+
if(err) {
|
|
365
|
+
res.status(500).json({
|
|
366
|
+
code: 500,
|
|
367
|
+
status: "READ_CATCH",
|
|
368
|
+
err: String(err),
|
|
134
369
|
});
|
|
135
370
|
} else {
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
}
|
|
371
|
+
// @ return findAll
|
|
372
|
+
res.json({
|
|
373
|
+
code: 200,
|
|
374
|
+
status: "SUCCESS",
|
|
375
|
+
results,
|
|
376
|
+
length: results.length,
|
|
377
|
+
limitRow,
|
|
378
|
+
});
|
|
156
379
|
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
380
|
+
});
|
|
381
|
+
} catch (error) {
|
|
382
|
+
// @return
|
|
383
|
+
return errMessage(error, res);
|
|
384
|
+
}
|
|
161
385
|
} else {
|
|
162
|
-
//
|
|
386
|
+
// @return
|
|
387
|
+
return errMessage(err, res);
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Duplicater cache for each config, avoid create new instance with same config
|
|
395
|
+
const duplicaterCache = new Map();
|
|
396
|
+
function getDuplicaterInstance(dupConfig = {}) {
|
|
397
|
+
const key = JSON.stringify(dupConfig || {});
|
|
398
|
+
if (!duplicaterCache.has(key)) {
|
|
399
|
+
duplicaterCache.set(key, Duplicater(dupConfig || {}));
|
|
400
|
+
}
|
|
401
|
+
return duplicaterCache.get(key);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Limiter cache for each config, avoid create new instance with same config
|
|
405
|
+
const limiterCache = new Map();
|
|
406
|
+
function getLimiterInstance(rateConfig = {}) {
|
|
407
|
+
const key = JSON.stringify(rateConfig);
|
|
408
|
+
if (!limiterCache.has(key)) {
|
|
409
|
+
limiterCache.set(key, Limiter(rateConfig));
|
|
410
|
+
}
|
|
411
|
+
return limiterCache.get(key);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const byPassCheckRole = (Projects, method, passport_config) => {
|
|
415
|
+
return async function (req, res, next) {
|
|
416
|
+
try {
|
|
417
|
+
if(passport_config[0] !== undefined) {
|
|
418
|
+
if(req.params.hash == passport_config[0].replace(/^\/|\/$/g, "")) {
|
|
163
419
|
return next();
|
|
420
|
+
} else {
|
|
421
|
+
if(passport_config[1].jwt_allow === true) {
|
|
422
|
+
let leaveMeAlone = await Projects.slice(0);
|
|
423
|
+
await filterProjectForByPass(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
424
|
+
if(!err) {
|
|
425
|
+
// Set Duplicater and Limiter for each project with method
|
|
426
|
+
const dupConfig = (Project.options?.defaultEndpoint?.[method]?.duplicate_request) ? Project.options.defaultEndpoint[method].duplicate_request : {};
|
|
427
|
+
const duplicaterMiddleware = getDuplicaterInstance(dupConfig);
|
|
428
|
+
return duplicaterMiddleware(req, res, (err) => {
|
|
429
|
+
if (!err) {
|
|
430
|
+
const rateConfig = (Project.options?.defaultEndpoint?.[method]?.rate_limit) ? Project.options.defaultEndpoint[method].rate_limit : {};
|
|
431
|
+
const limiterMiddleware = getLimiterInstance(rateConfig);
|
|
432
|
+
limiterMiddleware(req, res, (err) => {
|
|
433
|
+
if (!err) {
|
|
434
|
+
if(Project.options.defaultEndpoint === undefined || Project.options.defaultEndpoint === true) {
|
|
435
|
+
// Project is not use options
|
|
436
|
+
return Credentials(req, res, () => {
|
|
437
|
+
return checkRoleMiddlewareWithDefaultProject(null)(req, res, next);
|
|
438
|
+
});
|
|
439
|
+
} else {
|
|
440
|
+
// Method is set
|
|
441
|
+
if(Project.options.defaultEndpoint[method]) {
|
|
442
|
+
if(Project.options.defaultEndpoint[method]["allow"] === undefined || Project.options.defaultEndpoint[method]["allow"] === true) {
|
|
443
|
+
if(Project.options.defaultEndpoint[method]["jwt"]?.allow === false) {
|
|
444
|
+
// by project jwt_allow is false
|
|
445
|
+
return checkRoleMiddlewareWithDefaultProject(null)(req, res, next);
|
|
446
|
+
} else {
|
|
447
|
+
//return Credentials(req, res, () => {
|
|
448
|
+
// return checkRoleMiddlewareWithDefaultProject(Project.options.defaultEndpoint[method].jwt?.broken_role)(req, res, next);
|
|
449
|
+
//});
|
|
450
|
+
return Credentials(req, res, () => checkRoleMiddlewareWithDefaultProject(Project.options.defaultEndpoint[method].jwt?.broken_role || null)(req, res, next));
|
|
451
|
+
}
|
|
452
|
+
} else {
|
|
453
|
+
// METHOD.allow is false || METHOD.allow is undefined
|
|
454
|
+
return notfound(res);
|
|
455
|
+
}
|
|
456
|
+
} else if(Project.options.defaultEndpoint[method] === true || Project.options.defaultEndpoint[method] === undefined) {
|
|
457
|
+
// Method is not set
|
|
458
|
+
return Credentials(req, res, () => {
|
|
459
|
+
return checkRoleMiddlewareWithDefaultProject(null)(req, res, next);
|
|
460
|
+
});
|
|
461
|
+
} else {
|
|
462
|
+
// METHOD is false || METHOD is not undefined
|
|
463
|
+
return notfound(res);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
} else {
|
|
467
|
+
return res.status(429).json({
|
|
468
|
+
code: 429,
|
|
469
|
+
status: "TOO_MANY_REQUEST",
|
|
470
|
+
message: "Too Many Requests.",
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
} else {
|
|
475
|
+
return res.status(409).json({
|
|
476
|
+
code: 409,
|
|
477
|
+
status: "DUPLICATE_REQUEST",
|
|
478
|
+
message: "Duplicate request detected.",
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
});
|
|
482
|
+
} else {
|
|
483
|
+
return errMessage(err, res);
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
} else {
|
|
487
|
+
// global jwt_allow is false
|
|
488
|
+
return next();
|
|
489
|
+
}
|
|
164
490
|
}
|
|
491
|
+
} else {
|
|
492
|
+
// passport config not found
|
|
493
|
+
return next();
|
|
165
494
|
}
|
|
495
|
+
} catch (error) {
|
|
496
|
+
return errMessage(error, res);
|
|
166
497
|
}
|
|
167
498
|
}
|
|
168
499
|
}
|
|
@@ -182,101 +513,24 @@ function Base() {
|
|
|
182
513
|
resolve([_passport_config_.auth_endpoint || "/authentication", _passport_config_]);
|
|
183
514
|
} else {
|
|
184
515
|
// passport config not found
|
|
185
|
-
resolve([passport_config_auth,
|
|
516
|
+
resolve([passport_config_auth, {}]);
|
|
186
517
|
}
|
|
187
518
|
});
|
|
188
519
|
// passport conifg promise
|
|
189
520
|
checkPassport.then((passport_config) => {
|
|
190
521
|
if(Projects.length) {
|
|
191
|
-
// GET method with
|
|
192
|
-
endpoint.get("/:hash", (req, res, next) => byPassCheckRole(Projects, "GET", passport_config)(req, res, next), async (req, res, next) => {
|
|
193
|
-
|
|
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
|
-
});
|
|
522
|
+
// GET method with /:limit/:offset
|
|
523
|
+
endpoint.get("/:hash([a-zA-Z0-9-]+)*/:limit([0-9]+)/:offset([0-9]+)", (req, res, next) => byPassCheckRole(Projects, "GET", passport_config)(req, res, next), async (req, res, next) => {
|
|
524
|
+
await retrieving(passport_config[0], Projects, req, res, next);
|
|
217
525
|
});
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
});
|
|
526
|
+
|
|
527
|
+
// GET method only hash/*
|
|
528
|
+
endpoint.get("/:hash([a-zA-Z0-9-]+)*", (req, res, next) => byPassCheckRole(Projects, "GET", passport_config)(req, res, next), async (req, res, next) => {
|
|
529
|
+
await retrieving(passport_config[0], Projects, req, res, next);
|
|
277
530
|
});
|
|
531
|
+
|
|
278
532
|
// POST method
|
|
279
|
-
endpoint.post("/:hash", (req, res, next) => byPassCheckRole(Projects, "POST", passport_config)(req, res, next), async (req, res, next) => {
|
|
533
|
+
endpoint.post("/:hash*", (req, res, next) => byPassCheckRole(Projects, "POST", passport_config)(req, res, next), async (req, res, next) => {
|
|
280
534
|
// Check auth request match send next
|
|
281
535
|
if(passport_config[0] !== undefined) {
|
|
282
536
|
if(req.params.hash == passport_config[0].replace(/^\/|\/$/g, "")) {
|
|
@@ -285,58 +539,103 @@ function Base() {
|
|
|
285
539
|
}
|
|
286
540
|
// When lost IF
|
|
287
541
|
let leaveMeAlone = await Projects.slice(0);
|
|
288
|
-
|
|
542
|
+
let reqUrl = req.originalUrl.replace(_publicPath_, '/');
|
|
543
|
+
let bodyIsArray = Array.isArray(req.body);
|
|
544
|
+
await filterProject(leaveMeAlone, reqUrl, "", "", req, res, async (err, Project) => {
|
|
289
545
|
if (!err) {
|
|
290
546
|
try {
|
|
291
547
|
// Leave pool by project for check pool error
|
|
292
548
|
let pool = Project.sequelize;
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
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,
|
|
549
|
+
// Transaction create
|
|
550
|
+
Project.transaction(async t => {
|
|
551
|
+
try {
|
|
552
|
+
if (bodyIsArray) {
|
|
553
|
+
// Store with bulk body
|
|
554
|
+
const bulkCreated = await Project.bulkCreate(req.body, { transaction: t });
|
|
555
|
+
await t.commit();
|
|
556
|
+
// @return
|
|
557
|
+
res.status(201).json({
|
|
558
|
+
code: 201,
|
|
559
|
+
status: "CREATE_SUCCESS",
|
|
560
|
+
mode: {
|
|
561
|
+
type: "BULK",
|
|
562
|
+
affectedRows: bulkCreated.length,
|
|
563
|
+
},
|
|
564
|
+
createdId: [
|
|
565
|
+
...bulkCreated.map(item => (item.id) ? item.id : item[Project.primaryKeyAttributes[0]]),
|
|
566
|
+
],
|
|
332
567
|
});
|
|
333
568
|
} else {
|
|
334
|
-
//
|
|
569
|
+
// Store with single body
|
|
570
|
+
const singleCreated = await Project.create(req.body, { transaction: t });
|
|
571
|
+
await t.commit();
|
|
572
|
+
// @return
|
|
573
|
+
res.status(201).json({
|
|
574
|
+
code: 201,
|
|
575
|
+
status: "CREATE_SUCCESS",
|
|
576
|
+
mode: {
|
|
577
|
+
type: "SINGLE",
|
|
578
|
+
affectedRows: 1,
|
|
579
|
+
},
|
|
580
|
+
createdId: (singleCreated.id) ? singleCreated.id : singleCreated[Project.primaryKeyAttributes[0]],
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
} catch (error) {
|
|
584
|
+
await t.rollback();
|
|
585
|
+
if(pool.options.logging) {
|
|
586
|
+
// @return with all error
|
|
335
587
|
res.status(501).json({
|
|
336
588
|
code: 501,
|
|
337
589
|
status: "CREATE_FAILED",
|
|
338
|
-
|
|
590
|
+
mode: {
|
|
591
|
+
debug: true,
|
|
592
|
+
type: (bodyIsArray) ? "BULK" : "SINGLE",
|
|
593
|
+
affectedRows: 0,
|
|
594
|
+
},
|
|
595
|
+
error: error,
|
|
339
596
|
});
|
|
597
|
+
} else {
|
|
598
|
+
if(error.sql) {
|
|
599
|
+
delete error.sql;
|
|
600
|
+
if(error.errors) {
|
|
601
|
+
delete error.errors;
|
|
602
|
+
}
|
|
603
|
+
if(error.parent) {
|
|
604
|
+
delete error.parent;
|
|
605
|
+
}
|
|
606
|
+
if(error.original) {
|
|
607
|
+
delete error.original.sql;
|
|
608
|
+
if(error.original.parameters) {
|
|
609
|
+
delete error.original.parameters;
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
if(error.parameters) {
|
|
613
|
+
delete error.parameters;
|
|
614
|
+
}
|
|
615
|
+
// @return with some error
|
|
616
|
+
res.status(501).json({
|
|
617
|
+
code: 501,
|
|
618
|
+
status: "CREATE_FAILED",
|
|
619
|
+
mode: {
|
|
620
|
+
debug: false,
|
|
621
|
+
type: (bodyIsArray) ? "BULK" : "SINGLE",
|
|
622
|
+
affectedRows: 0,
|
|
623
|
+
},
|
|
624
|
+
error: error,
|
|
625
|
+
});
|
|
626
|
+
} else {
|
|
627
|
+
// @return with some string error
|
|
628
|
+
res.status(501).json({
|
|
629
|
+
code: 501,
|
|
630
|
+
status: "CREATE_FAILED",
|
|
631
|
+
mode: {
|
|
632
|
+
debug: false,
|
|
633
|
+
type: (bodyIsArray) ? "BULK" : "SINGLE",
|
|
634
|
+
affectedRows: 0,
|
|
635
|
+
},
|
|
636
|
+
error: String(error),
|
|
637
|
+
});
|
|
638
|
+
}
|
|
340
639
|
}
|
|
341
640
|
}
|
|
342
641
|
});
|
|
@@ -350,70 +649,111 @@ function Base() {
|
|
|
350
649
|
}
|
|
351
650
|
});
|
|
352
651
|
});
|
|
652
|
+
|
|
353
653
|
// PATCH method
|
|
354
|
-
endpoint.patch("/:hash
|
|
654
|
+
endpoint.patch("/:hash*/:id([a-zA-Z0-9-]+)", (req, res, next) => byPassCheckRole(Projects, "PATCH", passport_config)(req, res, next), async (req, res, next) => {
|
|
355
655
|
let leaveMeAlone = await Projects.slice(0);
|
|
356
|
-
|
|
656
|
+
let reqUrl = req.originalUrl.replace(_publicPath_, '/');
|
|
657
|
+
await filterProject(leaveMeAlone, reqUrl, "", "PATCH", req, res, async (err, Project) => {
|
|
357
658
|
if (!err) {
|
|
358
659
|
try {
|
|
359
|
-
//
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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],
|
|
660
|
+
// Check body is empty
|
|
661
|
+
if(Object.keys(req.body).length === 0) {
|
|
662
|
+
return res.status(400).json({
|
|
663
|
+
code: 400,
|
|
664
|
+
status: "BAD_REQUEST",
|
|
665
|
+
message: "Bad request.",
|
|
666
|
+
info: {
|
|
667
|
+
status: "BAD_ENTIRY",
|
|
668
|
+
message: "Unprocessable Entity.",
|
|
376
669
|
},
|
|
377
670
|
});
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
// @return with some error
|
|
405
|
-
res.status(501).json({
|
|
406
|
-
code: 501,
|
|
407
|
-
status: "UPDATE_FAILED",
|
|
408
|
-
error: error,
|
|
671
|
+
}
|
|
672
|
+
// Leave pool by project for check pool error
|
|
673
|
+
let pool = Project.sequelize;
|
|
674
|
+
// Transaction update|patch
|
|
675
|
+
Project.transaction(async t => {
|
|
676
|
+
try {
|
|
677
|
+
// Assign update pk
|
|
678
|
+
let updatePk = { [Project.primaryKeyAttributes[0]]: req.params.id };
|
|
679
|
+
// Patch with body
|
|
680
|
+
const updated = await Project.update(req.body, {
|
|
681
|
+
where: updatePk,
|
|
682
|
+
}, { transaction: t });
|
|
683
|
+
if(updated[0]) {
|
|
684
|
+
await t.commit();
|
|
685
|
+
// @return
|
|
686
|
+
res.status(200).json({
|
|
687
|
+
code: 200,
|
|
688
|
+
status: "UPDATE_SUCCESS",
|
|
689
|
+
mode: {
|
|
690
|
+
debug: true,
|
|
691
|
+
},
|
|
692
|
+
result: {
|
|
693
|
+
updateId: req.params.id,
|
|
694
|
+
affectedRows: updated[0],
|
|
695
|
+
},
|
|
409
696
|
});
|
|
410
697
|
} else {
|
|
411
|
-
|
|
698
|
+
await t.rollback();
|
|
699
|
+
res.status(406).json({
|
|
700
|
+
code: 406,
|
|
701
|
+
status: "NOT_ACCEPTABLE",
|
|
702
|
+
result: {
|
|
703
|
+
affectedRows: updated[0],
|
|
704
|
+
},
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
} catch (error) {
|
|
708
|
+
await t.rollback();
|
|
709
|
+
if(pool.options.logging) {
|
|
710
|
+
// @return with all error
|
|
412
711
|
res.status(501).json({
|
|
413
712
|
code: 501,
|
|
414
713
|
status: "UPDATE_FAILED",
|
|
415
|
-
|
|
714
|
+
mode: {
|
|
715
|
+
debug: false,
|
|
716
|
+
},
|
|
717
|
+
error: error,
|
|
416
718
|
});
|
|
719
|
+
} else {
|
|
720
|
+
if(error.sql) {
|
|
721
|
+
delete error.sql;
|
|
722
|
+
if(error.parent) {
|
|
723
|
+
delete error.parent;
|
|
724
|
+
}
|
|
725
|
+
if(error.original) {
|
|
726
|
+
delete error.original.sql;
|
|
727
|
+
if(error.original.parameters) {
|
|
728
|
+
delete error.original.parameters;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
if(error.parameters) {
|
|
732
|
+
delete error.parameters;
|
|
733
|
+
}
|
|
734
|
+
if(error.errors) {
|
|
735
|
+
delete error.errors;
|
|
736
|
+
}
|
|
737
|
+
// @return with some error
|
|
738
|
+
res.status(501).json({
|
|
739
|
+
code: 501,
|
|
740
|
+
status: "UPDATE_FAILED",
|
|
741
|
+
mode: {
|
|
742
|
+
debug: false,
|
|
743
|
+
},
|
|
744
|
+
error: error,
|
|
745
|
+
});
|
|
746
|
+
} else {
|
|
747
|
+
// @return with some string error
|
|
748
|
+
res.status(501).json({
|
|
749
|
+
code: 501,
|
|
750
|
+
status: "UPDATE_FAILED",
|
|
751
|
+
mode: {
|
|
752
|
+
debug: false,
|
|
753
|
+
},
|
|
754
|
+
error: String(error),
|
|
755
|
+
});
|
|
756
|
+
}
|
|
417
757
|
}
|
|
418
758
|
}
|
|
419
759
|
});
|
|
@@ -427,81 +767,94 @@ function Base() {
|
|
|
427
767
|
}
|
|
428
768
|
});
|
|
429
769
|
});
|
|
770
|
+
|
|
430
771
|
// DELETE method
|
|
431
|
-
endpoint.delete("/:hash
|
|
772
|
+
endpoint.delete("/:hash*/:id([a-zA-Z0-9-]+)", (req, res, next) => byPassCheckRole(Projects, "DELETE", passport_config)(req, res, next), async (req, res, next) => {
|
|
432
773
|
let leaveMeAlone = await Projects.slice(0);
|
|
433
|
-
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), req, res, async (err, Project) => {
|
|
774
|
+
await filterProject(leaveMeAlone, req.originalUrl.replace(_publicPath_, '/'), "", "DELETE", req, res, async (err, Project) => {
|
|
434
775
|
if (!err) {
|
|
435
776
|
try {
|
|
436
777
|
// Leave pool by project for check pool error
|
|
437
778
|
let pool = Project.sequelize;
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
status
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
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,
|
|
779
|
+
// Transaction update|patch
|
|
780
|
+
Project.transaction(async t => {
|
|
781
|
+
try {
|
|
782
|
+
// Assign delete pk
|
|
783
|
+
let deletePk = { [Project.primaryKeyAttributes[0]]: req.params.id };
|
|
784
|
+
// Delete with params
|
|
785
|
+
const deleted = await Project.destroy({
|
|
786
|
+
where: deletePk,
|
|
787
|
+
}, { transaction: t });
|
|
788
|
+
if (deleted) {
|
|
789
|
+
await t.commit();
|
|
790
|
+
// @return
|
|
791
|
+
res.status(200).json({
|
|
792
|
+
code: 200,
|
|
793
|
+
status: "DELETE_SUCCESS",
|
|
794
|
+
result: {
|
|
795
|
+
deleteId: req.params.id,
|
|
796
|
+
affectedRows: deleted,
|
|
797
|
+
},
|
|
497
798
|
});
|
|
498
799
|
} else {
|
|
499
|
-
|
|
800
|
+
await t.rollback();
|
|
801
|
+
res.status(406).json({
|
|
802
|
+
code: 406,
|
|
803
|
+
status: "NOT_ACCEPTABLE",
|
|
804
|
+
result: {
|
|
805
|
+
affectedRows: deleted,
|
|
806
|
+
},
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
} catch (error) {
|
|
810
|
+
if(pool.options.logging) {
|
|
811
|
+
// @return with all error
|
|
500
812
|
res.status(501).json({
|
|
501
813
|
code: 501,
|
|
502
814
|
status: "DELETE_FAILED",
|
|
503
|
-
|
|
815
|
+
mode: {
|
|
816
|
+
debug: true,
|
|
817
|
+
},
|
|
818
|
+
error: error,
|
|
504
819
|
});
|
|
820
|
+
} else {
|
|
821
|
+
if(error.sql) {
|
|
822
|
+
delete error.sql;
|
|
823
|
+
if(error.parent) {
|
|
824
|
+
delete error.parent;
|
|
825
|
+
}
|
|
826
|
+
if(error.original) {
|
|
827
|
+
delete error.original.sql;
|
|
828
|
+
if(error.original.parameters) {
|
|
829
|
+
delete error.original.parameters;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if(error.parameters) {
|
|
833
|
+
delete error.parameters;
|
|
834
|
+
}
|
|
835
|
+
if(error.errors) {
|
|
836
|
+
delete error.errors;
|
|
837
|
+
}
|
|
838
|
+
// @return with some error
|
|
839
|
+
res.status(501).json({
|
|
840
|
+
code: 501,
|
|
841
|
+
status: "DELETE_FAILED",
|
|
842
|
+
mode: {
|
|
843
|
+
debug: false,
|
|
844
|
+
},
|
|
845
|
+
error: error,
|
|
846
|
+
});
|
|
847
|
+
} else {
|
|
848
|
+
// @return with some string error
|
|
849
|
+
res.status(501).json({
|
|
850
|
+
code: 501,
|
|
851
|
+
status: "DELETE_FAILED",
|
|
852
|
+
mode: {
|
|
853
|
+
debug: false,
|
|
854
|
+
},
|
|
855
|
+
error: String(error),
|
|
856
|
+
});
|
|
857
|
+
}
|
|
505
858
|
}
|
|
506
859
|
}
|
|
507
860
|
});
|