beech-api 3.7.23 → 3.8.0

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 +490 -168
  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,33 +1,64 @@
1
+ const { Transaction } = require("sequelize");
2
+ let isolationLevel = { isolationLevel: Transaction.ISOLATION_LEVELS.SERIALIZABLE };
1
3
  function Schema(Sequelize) {
2
4
  return {
3
- define: (table, schemaProps = {}) => {
4
- let Project = Sequelize.define(table, schemaProps);
5
- return Object.assign(Project, {
6
- query: (
7
- rawSql,
8
- props = {
9
- model: Project,
10
- mapToModel: false,
11
- }
12
- ) => {
13
- return new Promise((resolve) => {
14
- if (props.mapToModel) {
15
- let data = Sequelize.query(rawSql, props);
16
- let results = [];
17
- mapDataToModel(data, props.model, results, (err, r) => {
18
- if (err) {
19
- resolve([]);
20
- } else {
21
- resolve(r);
22
- }
23
- });
5
+ define: (table, schemaProps = {}, elementProps = {}) => {
6
+ try {
7
+ let Project = Sequelize.define(table, schemaProps, elementProps);
8
+ return Object.assign(Project, {
9
+ query: (
10
+ rawSql,
11
+ props = {
12
+ model: Project,
13
+ mapToModel: false,
14
+ }
15
+ ) => {
16
+ return new Promise((resolve) => {
17
+ if (props.mapToModel) {
18
+ let data = Sequelize.query(rawSql, props);
19
+ let results = [];
20
+ mapDataToModel(data, props.model, results, (err, r) => {
21
+ if (err) {
22
+ resolve([]);
23
+ } else {
24
+ resolve(r);
25
+ }
26
+ });
27
+ } else {
28
+ resolve(Sequelize.query(rawSql, props));
29
+ }
30
+ });
31
+ },
32
+ Sequelize,
33
+ /**
34
+ * Transaction
35
+ *
36
+ * @param object DEFAULT isolationLevel SERIALIZABLE
37
+ * @param cb Object
38
+ *
39
+ * @returns Object
40
+ */
41
+ transaction: async (object, cb = null) => {
42
+ if(typeof object == "function") {
43
+ const t = await Sequelize.transaction(isolationLevel);
44
+ object(t);
45
+ } else if(cb) {
46
+ const t = await Sequelize.transaction(object = isolationLevel);
47
+ cb(t);
24
48
  } else {
25
- resolve(Sequelize.query(rawSql, props));
49
+ return await Sequelize.transaction(object = isolationLevel);
26
50
  }
27
- });
28
- },
29
- Sequelize,
30
- });
51
+ },
52
+ });
53
+ } catch (error) {
54
+ let errTurnOffDbDefine = JSON.stringify(error.toString()).match(/'define'/);
55
+ let errTurnOffDbOption = JSON.stringify(error.toString()).match(/'options'/);
56
+ if(errTurnOffDbDefine || errTurnOffDbOption) {
57
+ console.log(`\n Failed  Database connection name is CLOSED.\n`, error);
58
+ } else {
59
+ console.log("\n Failed ", error);
60
+ }
61
+ }
31
62
  },
32
63
  };
33
64
  }
@@ -0,0 +1,7 @@
1
+ const { rateLimit } = require("../../cli/core/middleware/express/rateLimit");
2
+ const { slowDown } = require("../../cli/core/middleware/express/slowDown");
3
+ const { duplicateRequest } = require("../../cli/core/middleware/express/duplicateRequest");
4
+ let specificExpress = () => {
5
+ return { rateLimit, slowDown, duplicateRequest };
6
+ };
7
+ module.exports = { specificExpress };
@@ -1,4 +1,3 @@
1
- const appRoot = require("app-root-path");
2
1
  const md5 = require("md5");
3
2
  const secret = require("./salt").salt;
4
3
  const { findPassportPk } = require("../../cli/core/helpers/poolEntity");
@@ -7,7 +6,7 @@ async function FindOne(fields, fieldCondArr, cb) {
7
6
  try {
8
7
  const passport_config = require(appRoot + "/passport.config.js");
9
8
  let stm = '';
10
- let cond = '1';
9
+ let cond = '1=1';
11
10
  let passportTable = await [passport_config.model.table || "users"];
12
11
  const pool = await eval("sql." + passport_config.model.name);
13
12
  let expectFields = await (fields[0]) ? fields : (passport_config.model.fields.length) ? passport_config.model.fields : [];
@@ -15,15 +14,17 @@ async function FindOne(fields, fieldCondArr, cb) {
15
14
  if(err) {
16
15
  cb(err, null);
17
16
  } else {
17
+ let dynReplacement = [];
18
18
  // Generate condition
19
- await Object.keys(fieldCondArr).forEach(key => {
20
- cond += ' AND ' + key + '=' + fieldCondArr[key]
19
+ Object.keys(fieldCondArr).forEach(key => {
20
+ cond += ` AND ${key} = ?`;
21
+ dynReplacement.push(fieldCondArr[key]);
21
22
  });
22
23
  // check base pool
23
24
  if (pool_base == "basic") {
24
25
  // pool base is MySQL
25
- stm += 'SELECT ?? FROM ?? WHERE ' + cond;
26
- await pool.query(stm, [passportFields, passportTable], (err, row) => {
26
+ stm += 'SELECT ?? FROM ?? WHERE ' + cond + ' LIMIT 1;';
27
+ await pool.query(stm, [passportFields, passportTable, ...dynReplacement], (err, row) => {
27
28
  if(err) {
28
29
  cb(err, null);
29
30
  } else {
@@ -35,11 +36,26 @@ async function FindOne(fields, fieldCondArr, cb) {
35
36
  try {
36
37
  stm += `SELECT ${passportFields} FROM ${passportTable} WHERE ` + cond;
37
38
  let result = await pool.query(stm, {
39
+ replacements: [...dynReplacement],
38
40
  type: QueryTypes.SELECT
39
41
  });
40
42
  return cb(null, result);
41
43
  } catch (error) {
42
- return cb(error.errors[0], null);
44
+ if(error.sql) {
45
+ delete error.sql;
46
+ if(error.parent) {
47
+ delete error.parent;
48
+ }
49
+ if(error.original) {
50
+ delete error.original.sql;
51
+ }
52
+ if(error.parameters) {
53
+ delete error.parameters;
54
+ }
55
+ return cb(error, null);
56
+ } else {
57
+ return cb(String(error), null);
58
+ }
43
59
  }
44
60
  } else {
45
61
  return cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
@@ -71,14 +87,14 @@ async function Store(fields, cb) {
71
87
  }
72
88
  if(key == passwordField) {
73
89
  haveUsernameAndPassword += 1;
90
+ // asign pwd hash
91
+ fields[passwordField] = md5(fields[passwordField] + secret);
74
92
  }
75
93
  keys.push(key);
76
94
  values.push(fields[key]);
77
95
  escaped.push('?');
78
96
  });
79
97
  if(haveUsernameAndPassword > 1) {
80
- // asign password hash
81
- fields[passwordField] = md5(fields[passwordField] + secret);
82
98
  // check base pool
83
99
  if (pool_base == "basic") {
84
100
  // pool base is MySQL
@@ -108,7 +124,25 @@ async function Store(fields, cb) {
108
124
  affectedRows: result[1]
109
125
  });
110
126
  } catch (error) {
111
- return cb(error.errors[0], null);
127
+ if(pool.options.logging) {
128
+ return cb(error, null);
129
+ } else {
130
+ if(error.sql) {
131
+ delete error.sql;
132
+ if(error.parent) {
133
+ delete error.parent;
134
+ }
135
+ if(error.original) {
136
+ delete error.original.sql;
137
+ }
138
+ if(error.parameters) {
139
+ delete error.parameters;
140
+ }
141
+ return cb(error, null);
142
+ } else {
143
+ return cb(String(error), null);
144
+ }
145
+ }
112
146
  }
113
147
  } else {
114
148
  return cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
@@ -155,7 +189,7 @@ async function Update(someFields, id, cb) {
155
189
  cb(error, null);
156
190
  } else {
157
191
  cb(null, {
158
- updateId: parseInt(id),
192
+ updateId: (result.changedRows) ? parseInt(id) : null,
159
193
  affectedRows: result.changedRows
160
194
  });
161
195
  }
@@ -173,17 +207,59 @@ async function Update(someFields, id, cb) {
173
207
  type: QueryTypes.UPDATE
174
208
  }).then((result) => {
175
209
  return cb(null, {
176
- updateId: parseInt(id),
177
- affectedRows: result[1]
210
+ updateId: (result[1]) ? parseInt(id) : null,
211
+ affectedRows: result[1],
178
212
  });
179
- }).catch((err) => {
180
- return cb(err.errors[0], null);
213
+ }).catch((error) => {
214
+ if(pool.options.logging) {
215
+ return cb(error, null);
216
+ } else {
217
+ if(error.sql) {
218
+ delete error.sql;
219
+ if(error.errors) {
220
+ delete error.errors;
221
+ }
222
+ if(error.parent) {
223
+ delete error.parent;
224
+ }
225
+ if(error.original) {
226
+ delete error.original.sql;
227
+ }
228
+ if(error.parameters) {
229
+ delete error.parameters;
230
+ }
231
+ return cb(error, null);
232
+ } else {
233
+ return cb(String(error), null);
234
+ }
235
+ }
181
236
  });
182
- }).catch((err) => {
183
- return cb(err, null);
237
+ }).catch((error) => {
238
+ if(pool.options.logging) {
239
+ return cb(error, null);
240
+ } else {
241
+ if(error.sql) {
242
+ delete error.sql;
243
+ if(error.errors) {
244
+ delete error.errors;
245
+ }
246
+ if(error.parent) {
247
+ delete error.parent;
248
+ }
249
+ if(error.original) {
250
+ delete error.original.sql;
251
+ }
252
+ if(error.parameters) {
253
+ delete error.parameters;
254
+ }
255
+ return cb(error, null);
256
+ } else {
257
+ return cb(String(error), null);
258
+ }
259
+ }
184
260
  });
185
261
  } catch (error) {
186
- return cb(error.errors[0], null);
262
+ return cb(error, null);
187
263
  }
188
264
  } else {
189
265
  return cb({ error: "The Base pool error. UNKNOWN pool_base = '"+ pool_base +"'" }, null);
@@ -1,2 +0,0 @@
1
- const { whitelist, sign } = require("./whitelist/cors");
2
- module.exports = { whitelist, sign };