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.
- package/README.md +490 -168
- 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
package/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const {
|
|
2
|
-
module.exports = {
|
|
1
|
+
const { Schema, Guard, Store, Update, specificExpress } = require("./packages/lib/index");
|
|
2
|
+
module.exports = { Schema, Guard, Store, Update, Express: specificExpress() };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beech-api",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"description": "Command line interface for rapid Beech API development",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -35,13 +35,19 @@
|
|
|
35
35
|
"axios": "^0.26.1",
|
|
36
36
|
"child-process-promise": "^2.2.1",
|
|
37
37
|
"cli-clear": "^1.0.4",
|
|
38
|
+
"compression": "^1.7.5",
|
|
38
39
|
"cookie-parser": "1.4.3",
|
|
39
40
|
"cors": "^2.8.1",
|
|
41
|
+
"crypto-js": "^4.2.0",
|
|
40
42
|
"cryptr": "^6.3.0",
|
|
41
43
|
"express": "4.19.2",
|
|
44
|
+
"express-duplicate-request": "^1.0.3",
|
|
45
|
+
"express-rate-limit": "^7.4.0",
|
|
42
46
|
"express-session": "^1.17.1",
|
|
47
|
+
"express-slow-down": "^2.0.3",
|
|
43
48
|
"express-validator": "2.21.0",
|
|
44
49
|
"fs": "0.0.1-security",
|
|
50
|
+
"helmet": "^8.1.0",
|
|
45
51
|
"inquirer": "8.2.4",
|
|
46
52
|
"jsonwebtoken": "^8.5.1",
|
|
47
53
|
"log-update": "^4.0.0",
|
|
@@ -62,6 +68,7 @@
|
|
|
62
68
|
"passport-oauth": "^1.0.0",
|
|
63
69
|
"path": "^0.12.7",
|
|
64
70
|
"sequelize": "^6.21.3",
|
|
71
|
+
"tedious": "^18.6.1",
|
|
65
72
|
"walk": "^2.3.14"
|
|
66
73
|
},
|
|
67
74
|
"devDependencies": {
|
package/packages/cli/beech
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* The beech api (cli) package generator and server (bash for developer and production build)
|
|
5
5
|
*
|
|
6
6
|
* @author bombkiml
|
|
7
|
-
* @version 3.
|
|
8
|
-
* @built Apr
|
|
7
|
+
* @version 3.8
|
|
8
|
+
* @built Apr 30, 2024 at 16:53:09
|
|
9
9
|
*
|
|
10
10
|
*/
|
|
11
11
|
(process.argv[2]) ? require('./core/generator/index') : require('./core/index')
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
const logUpdate = require("log-update");
|
|
3
3
|
const clear = require("cli-clear");
|
|
4
4
|
const inquirer = require('inquirer');
|
|
@@ -63,7 +63,7 @@ class Beech {
|
|
|
63
63
|
type: "checkbox",
|
|
64
64
|
name: "freature",
|
|
65
65
|
message: "[93mCheck the features needed for your project:[0m",
|
|
66
|
-
choices: [ "
|
|
66
|
+
choices: [ "Job Scheduler", "Basic Helper", "Passport / JWT / Official Strategy Google, Facebook" ],
|
|
67
67
|
} ]).then(resFreat => {
|
|
68
68
|
logUpdate(": Initialize...");
|
|
69
69
|
setTimeout(() => {
|
|
@@ -96,12 +96,12 @@ class Beech {
|
|
|
96
96
|
}
|
|
97
97
|
} else if (this.option == "update") {
|
|
98
98
|
// upgrade the beech-api package
|
|
99
|
+
let isGlobalNpm = "npm install beech-api";
|
|
99
100
|
let isGlobalYarn = "yarn add beech-api";
|
|
100
|
-
let isGlobalNpm = "npm update beech-api";
|
|
101
101
|
let processUpdate = null;
|
|
102
102
|
let lineStdout = "";
|
|
103
103
|
if (this.argument == '-g' || this.argument == '--global') {
|
|
104
|
-
isGlobalNpm = "npm
|
|
104
|
+
isGlobalNpm = "npm install beech-api -g --force";
|
|
105
105
|
isGlobalYarn = "yarn global add beech-api";
|
|
106
106
|
}
|
|
107
107
|
// prompt select
|
|
@@ -116,7 +116,9 @@ class Beech {
|
|
|
116
116
|
setTimeout(() => {
|
|
117
117
|
if(selectedPackage.package == "NPM") {
|
|
118
118
|
processUpdate = this.cmd.get(isGlobalNpm, (err) => {
|
|
119
|
-
if (err) {
|
|
119
|
+
if (err) {
|
|
120
|
+
logUpdate("\n[101m OperationalError [0m The operation was rejected by your operating system. \n[91mEPERM:[0m operation not permitted CMD: '[93mnpm install beech-api -g --force[0m'");
|
|
121
|
+
}
|
|
120
122
|
});
|
|
121
123
|
// npm install line shoutout
|
|
122
124
|
processUpdate.stdout.on('data', (npmData) => {
|
|
@@ -201,9 +203,9 @@ class Beech {
|
|
|
201
203
|
let freatureLength = freatureArr.length;
|
|
202
204
|
if (freatureLength) {
|
|
203
205
|
freatureArr.map((f, key) => {
|
|
204
|
-
if (f.split(' ')[ 0 ] == "
|
|
205
|
-
(process.env.NODE_ENV == "development") ? this.cmd.get('cd ' + argument + ' && node cli/bin/beech-app.js
|
|
206
|
-
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing
|
|
206
|
+
if (f.split(' ')[ 0 ] == "Job") {
|
|
207
|
+
(process.env.NODE_ENV == "development") ? this.cmd.get('cd ' + argument + ' && node cli/bin/beech-app.js skd init') : this.cmd.get('cd ' + argument + ' && beech skd init');
|
|
208
|
+
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Job Scheduler");
|
|
207
209
|
}
|
|
208
210
|
if (f.split(' ')[ 0 ] == "Basic") {
|
|
209
211
|
this.makeFolder(helperPath).then(this.copy.bind(this, tmpBasicHelperFile, pasteBasicHelperFile))
|
|
@@ -1,97 +1,147 @@
|
|
|
1
|
-
const passport = require(
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if(info) {
|
|
23
|
-
if (info.name == 'TokenExpiredError') {
|
|
24
|
-
return res.status(401).json({
|
|
25
|
-
code: 401,
|
|
26
|
-
status: 'TOKEN_EXPIRED',
|
|
27
|
-
message: info
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
if (info.name == 'Error') {
|
|
31
|
-
return res.status(401).json({
|
|
32
|
-
code: 401,
|
|
33
|
-
status: 'NO_AUTH_TOKEN',
|
|
34
|
-
message: {
|
|
35
|
-
name: 'NoTokenError',
|
|
36
|
-
message: 'No auth token'
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
if (info.name == 'SyntaxError') {
|
|
41
|
-
return res.status(401).json({
|
|
42
|
-
code: 401,
|
|
43
|
-
status: 'PAYLOAD_SYNTAX_ERROR',
|
|
44
|
-
message: {
|
|
45
|
-
name: 'SyntaxError',
|
|
46
|
-
message: 'Unexpected token < in JSON at position 0'
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
return res.status(401).json({
|
|
52
|
-
code: 401,
|
|
53
|
-
status: 'UNAUTHORIZED_USER',
|
|
54
|
-
message: info
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
// Check application key allow
|
|
58
|
-
const p1 = new Promise((resolve) => {
|
|
59
|
-
if (_passport_config_.app_key_allow) {
|
|
60
|
-
if (req.headers.app_key) {
|
|
61
|
-
if (_config_.main_config.app_key == req.headers.app_key) {
|
|
62
|
-
resolve(true);
|
|
63
|
-
} else {
|
|
64
|
-
res.status(401).json({
|
|
65
|
-
code: 401,
|
|
66
|
-
status: "BAD_REQUEST",
|
|
67
|
-
message: "Unauthorized with wrong key."
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
} else {
|
|
71
|
-
res.status(422).json({
|
|
72
|
-
code: 422,
|
|
73
|
-
status: "BAD_ENTIRY",
|
|
74
|
-
message: "Unprocessable Entity."
|
|
75
|
-
});
|
|
76
|
-
}
|
|
1
|
+
const passport = require("passport");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const { checkRoleMiddleware } = require("../middleware/express/jwtCheckAllow");
|
|
4
|
+
const passport_config_file = appRoot + "/passport.config.js";
|
|
5
|
+
var passport_config;
|
|
6
|
+
if (fs.existsSync(passport_config_file)) {
|
|
7
|
+
passport_config = require(passport_config_file);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const byPassCredentials = (options, _res = {}, _next = () => {}) => {
|
|
11
|
+
if(!options.length) {
|
|
12
|
+
if(passport_config.jwt_broken_role ? passport_config.jwt_broken_role.length > 0 : false) {
|
|
13
|
+
// CASE: jwt_broken_role DEFUALT is set
|
|
14
|
+
return [credentials, checkRoleMiddleware(passport_config.jwt_broken_role)(options, _res, _next)];
|
|
15
|
+
} else {
|
|
16
|
+
if(!Object.keys(options).length) {
|
|
17
|
+
return [credentials];
|
|
18
|
+
} else {
|
|
19
|
+
if("headers" in options) {
|
|
20
|
+
// CASE: Only Credentials
|
|
21
|
+
return [credentials(options, _res, _next)];
|
|
77
22
|
} else {
|
|
78
|
-
|
|
23
|
+
// CASE: jwt_broken_role DEFUALT is not set
|
|
24
|
+
return [credentials];
|
|
79
25
|
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
} else {
|
|
29
|
+
// CASE: options Credentials is set
|
|
30
|
+
return [credentials, checkRoleMiddleware(options)];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const credentials = (req, res, next) => {
|
|
35
|
+
if (passport_config.jwt_allow === true) {
|
|
36
|
+
const auth_endpoint = (passport_config.auth_endpoint) ? (passport_config.auth_endpoint[ 0 ] === "/" ? passport_config.auth_endpoint : "/" + passport_config.auth_endpoint) : "/authentication";
|
|
37
|
+
if(auth_endpoint.split("/")[1] == req.params.hash) {
|
|
38
|
+
return next();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return passport.authenticate("jwt", {
|
|
43
|
+
session: false,
|
|
44
|
+
}, (err, user, info) => {
|
|
45
|
+
// error check
|
|
46
|
+
if (err) {
|
|
47
|
+
console.log(err, info);
|
|
48
|
+
return res.status(401).json({
|
|
49
|
+
code: 401,
|
|
50
|
+
error: "UNAUTHORIZED",
|
|
51
|
+
message: {
|
|
52
|
+
name: "WrongTokenError",
|
|
53
|
+
message: "token error.",
|
|
54
|
+
},
|
|
55
|
+
/* dev: { err, info }, */ // for dev info
|
|
80
56
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// When wrong all case above.
|
|
88
|
-
res.status(401).json({
|
|
57
|
+
}
|
|
58
|
+
// anything token check
|
|
59
|
+
if (!user) {
|
|
60
|
+
if (info) {
|
|
61
|
+
if (info.name == "TokenExpiredError") {
|
|
62
|
+
return res.status(401).json({
|
|
89
63
|
code: 401,
|
|
90
|
-
status: "
|
|
91
|
-
message:
|
|
64
|
+
status: "TOKEN_EXPIRED",
|
|
65
|
+
message: info,
|
|
92
66
|
});
|
|
93
67
|
}
|
|
68
|
+
if (info.name == "Error") {
|
|
69
|
+
return res.status(401).json({
|
|
70
|
+
code: 401,
|
|
71
|
+
status: "NO_AUTH_TOKEN",
|
|
72
|
+
message: {
|
|
73
|
+
name: "NoTokenError",
|
|
74
|
+
message: "No auth token",
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (info.name == "SyntaxError") {
|
|
79
|
+
return res.status(401).json({
|
|
80
|
+
code: 401,
|
|
81
|
+
status: "PAYLOAD_SYNTAX_ERROR",
|
|
82
|
+
message: {
|
|
83
|
+
name: "SyntaxError",
|
|
84
|
+
message: "Unexpected token < in JSON at position 0",
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return res.status(401).json({
|
|
90
|
+
code: 401,
|
|
91
|
+
status: "UNAUTHORIZED_USER",
|
|
92
|
+
message: info || {
|
|
93
|
+
name: "TokenError",
|
|
94
|
+
message: "Unauthorized token."
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
} else {
|
|
98
|
+
// Perfectly user jwt
|
|
99
|
+
return next();
|
|
100
|
+
}
|
|
101
|
+
})(req, res, next);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const credentialsGuard = (req, res, next) => {
|
|
105
|
+
checkAppKey(req, res, (checked) => {
|
|
106
|
+
if (checked) {
|
|
107
|
+
// Perfectly
|
|
108
|
+
next();
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function checkAppKey(req, res, cb) {
|
|
114
|
+
if (_passport_config_.app_key_allow) {
|
|
115
|
+
if (req.headers.app_key) {
|
|
116
|
+
if (_config_.main_config.app_key == req.headers.app_key) {
|
|
117
|
+
return cb(true);
|
|
118
|
+
} else {
|
|
119
|
+
res.status(400).json({
|
|
120
|
+
code: 400,
|
|
121
|
+
status: 'BAD_REQUEST',
|
|
122
|
+
message: "Bad request.",
|
|
123
|
+
info: {
|
|
124
|
+
status: "BAD_VALUE",
|
|
125
|
+
message: "Bad with wrong key."
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
return cb(false);
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
res.status(400).json({
|
|
132
|
+
code: 400,
|
|
133
|
+
status: 'BAD_REQUEST',
|
|
134
|
+
message: "Bad request.",
|
|
135
|
+
info: {
|
|
136
|
+
status: "BAD_ENTITY",
|
|
137
|
+
message: "Bad with app entity key.",
|
|
138
|
+
},
|
|
94
139
|
});
|
|
95
|
-
|
|
140
|
+
return cb(false);
|
|
141
|
+
}
|
|
142
|
+
} else {
|
|
143
|
+
return cb(true);
|
|
96
144
|
}
|
|
97
|
-
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
module.exports = { byPassCredentials, credentials, credentialsGuard };
|