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.
Files changed (43) hide show
  1. package/README.md +484 -127
  2. package/index.js +2 -2
  3. package/package.json +8 -1
  4. package/packages/cli/beech +2 -2
  5. package/packages/cli/bin/beech-app.js +10 -8
  6. package/packages/cli/bin/beech-service.js +1 -1
  7. package/packages/cli/core/auth/Credentials.js +139 -89
  8. package/packages/cli/core/auth/Passport.js +264 -164
  9. package/packages/cli/core/auth/_Request.js +1 -1
  10. package/packages/cli/core/configure/app.config-basic.js +2 -2
  11. package/packages/cli/core/configure/app.config-sequelize.js +2 -2
  12. package/packages/cli/core/configure/beech.config.js +1 -0
  13. package/packages/cli/core/configure/passport.config.js +33 -13
  14. package/packages/cli/core/databases/sequelize.js +3 -0
  15. package/packages/cli/core/databases/test.js +5 -3
  16. package/packages/cli/core/generator/_endpoints +5 -9
  17. package/packages/cli/core/generator/_endpoints_basic +11 -8
  18. package/packages/cli/core/generator/_help +1 -1
  19. package/packages/cli/core/generator/_models +5 -4
  20. package/packages/cli/core/generator/_models_basic +2 -2
  21. package/packages/cli/core/generator/_package +5 -1
  22. package/packages/cli/core/generator/{_add-on → _scheduler} +1 -1
  23. package/packages/cli/core/generator/_spec +15 -10
  24. package/packages/cli/core/generator/index.js +19 -44
  25. package/packages/cli/core/helpers/2fa.js +85 -0
  26. package/packages/cli/core/helpers/math.js +55 -7
  27. package/packages/cli/core/helpers/poolEntity.js +29 -1
  28. package/packages/cli/core/index.js +65 -34
  29. package/packages/cli/core/middleware/express/duplicateRequest.js +12 -0
  30. package/packages/cli/core/middleware/express/jwtCheckAllow.js +68 -0
  31. package/packages/cli/core/middleware/express/rateLimit.js +17 -0
  32. package/packages/cli/core/middleware/express/slowDown.js +2 -0
  33. package/packages/cli/core/middleware/index.js +6 -0
  34. package/packages/cli/core/middleware/origin/guard/advance.js +74 -0
  35. package/packages/cli/core/{origin → middleware/origin}/whitelist/cors.js +15 -12
  36. package/packages/cli/core/services/http.express.js +116 -72
  37. package/packages/lib/index.js +3 -1
  38. package/packages/lib/src/endpoint.js +523 -89
  39. package/packages/lib/src/guard.js +61 -0
  40. package/packages/lib/src/schema.js +57 -26
  41. package/packages/lib/src/specificExpress.js +7 -0
  42. package/packages/lib/src/user.js +94 -18
  43. package/packages/cli/core/origin/index.js +0 -2
@@ -1,98 +1,532 @@
1
- const Base = (Pj = []) => {
2
- Pj.map((Project) => {
3
- let endpointName = Object.values(Project)[4];
4
- endpoint.get(`/${endpointName}/:limit?/:offset?`, Credentials, async (req, res) => {
5
- const results = await Project.findAll({ offset: (parseInt(req.params.offset) || 0), limit: (parseInt(req.params.limit) || 100) });
6
- await res.json({
7
- code: 200,
8
- status: "SUCCESS",
9
- results,
10
- length: results.length,
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
- endpoint.post(`/${endpointName}`, Credentials, (req, res) => {
14
- Project.create(req.body)
15
- .then((created) => {
16
- // @return
17
- res.status(201).json({
18
- code: 201,
19
- status: "CREATE_SUCCESS",
20
- createdId: created.id,
21
- });
22
- })
23
- .catch((err) => {
24
- // @return
25
- res.status(501).json({
26
- code: 501,
27
- status: "CREATE_FAILED",
28
- error: err,
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
- endpoint.patch(`/${endpointName}/:id`, Credentials, (req, res) => {
33
- Project.update(req.body, {
34
- where: {
35
- id: req.params.id,
36
- },
37
- })
38
- .then((updated) => {
39
- // @return
40
- res.status(200).json({
41
- code: 200,
42
- status: "UPDATE_SUCCESS",
43
- result: {
44
- updateId: req.params.id,
45
- affectedRows: updated[0],
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
- .catch((err) => {
50
- // @return
51
- res.status(501).json({
52
- code: 501,
53
- status: "UPDATE_FAILED",
54
- error: err,
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
- endpoint.delete(`/${endpointName}/:id`, Credentials, (req, res) => {
59
- Project.destroy({
60
- where: {
61
- id: req.params.id,
62
- },
63
- })
64
- .then((deleted) => {
65
- if(deleted) {
66
- // @return
67
- res.status(200).json({
68
- code: 200,
69
- status: "DELETE_SUCCESS",
70
- result: {
71
- deleteId: req.params.id,
72
- affectedRows: deleted,
73
- },
74
- });
75
- } else {
76
- res.status(406).json({
77
- code: 406,
78
- status: "NOT_ACCEPTABLE",
79
- result: {
80
- deleteId: req.params.id,
81
- affectedRows: deleted,
82
- },
83
- });
84
- }
85
- })
86
- .catch((err) => {
87
- // @return
88
- res.status(501).json({
89
- code: 501,
90
- status: "DELETE_FAILED",
91
- error: err,
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 };