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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beech-api",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.9.0-beta.9-rc",
|
|
4
4
|
"description": "Command line interface for rapid Beech API development",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"api",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
},
|
|
19
19
|
"authors": "bombkiml",
|
|
20
20
|
"bin": {
|
|
21
|
-
"beech-app": "
|
|
22
|
-
"beech-service": "
|
|
23
|
-
"beech": "
|
|
21
|
+
"beech-app": "packages/cli/bin/beech-app.js",
|
|
22
|
+
"beech-service": "packages/cli/bin/beech-service.js",
|
|
23
|
+
"beech": "packages/cli/core/generator/index.js"
|
|
24
24
|
},
|
|
25
25
|
"bugs": {
|
|
26
26
|
"url": "https://github.com/bombkiml/beech-api/issues"
|
|
@@ -28,20 +28,21 @@
|
|
|
28
28
|
"homepage": "https://github.com/bombkiml/beech-api/blob/master/README.md",
|
|
29
29
|
"deprecated": false,
|
|
30
30
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
31
|
+
"node": ">=16.20"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"app-root-path": "^3.0.0",
|
|
35
|
-
"axios": "^
|
|
35
|
+
"axios": "^1.8.4",
|
|
36
36
|
"child-process-promise": "^2.2.1",
|
|
37
37
|
"cli-clear": "^1.0.4",
|
|
38
38
|
"compression": "^1.7.5",
|
|
39
|
-
"cookie-parser": "1.4.
|
|
39
|
+
"cookie-parser": "^1.4.7",
|
|
40
40
|
"cors": "^2.8.1",
|
|
41
|
+
"cron": "^4.4.0",
|
|
41
42
|
"crypto-js": "^4.2.0",
|
|
42
43
|
"cryptr": "^6.3.0",
|
|
43
|
-
"express": "4.
|
|
44
|
-
"express-duplicate-request": "^1.0.
|
|
44
|
+
"express": "^4.20.0",
|
|
45
|
+
"express-duplicate-request": "^1.0.5",
|
|
45
46
|
"express-rate-limit": "^7.4.0",
|
|
46
47
|
"express-session": "^1.17.1",
|
|
47
48
|
"express-slow-down": "^2.0.3",
|
|
@@ -49,14 +50,14 @@
|
|
|
49
50
|
"fs": "0.0.1-security",
|
|
50
51
|
"helmet": "^8.1.0",
|
|
51
52
|
"inquirer": "8.2.4",
|
|
52
|
-
"jsonwebtoken": "^
|
|
53
|
+
"jsonwebtoken": "^9.0.2",
|
|
53
54
|
"log-update": "^4.0.0",
|
|
54
55
|
"md5": "^2.3.0",
|
|
55
56
|
"method-override": "^3.0.0",
|
|
56
57
|
"mkdirp": "^2.1.6",
|
|
57
58
|
"module-alias": "^2.2.2",
|
|
58
59
|
"mysql": "^2.18.1",
|
|
59
|
-
"mysql2": "^
|
|
60
|
+
"mysql2": "^3.14.0",
|
|
60
61
|
"node-cmd": "^3.0.0",
|
|
61
62
|
"node-emoji": "^1.11.0",
|
|
62
63
|
"node-notifier": "^10.0.1",
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"walk": "^2.3.14"
|
|
73
74
|
},
|
|
74
75
|
"devDependencies": {
|
|
75
|
-
"jest": "^
|
|
76
|
+
"jest": "^30.2.0",
|
|
76
77
|
"nodemon": "^3.1.0",
|
|
77
78
|
"sequelize-cli": "^5.5.1"
|
|
78
79
|
},
|
|
@@ -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');
|
|
@@ -52,8 +52,8 @@ class Beech {
|
|
|
52
52
|
inquirer.prompt([ {
|
|
53
53
|
type: "list",
|
|
54
54
|
name: "sql",
|
|
55
|
-
message: "[93mPlease pick a
|
|
56
|
-
choices: [ "Basic (mysql only)", "Sequelize (mysql, sqlite, mariadb, postgres, mssql)" ],
|
|
55
|
+
message: "[93mPlease pick a pool base engine:[0m",
|
|
56
|
+
choices: [ "Basic (mysql only)", "Sequelize ORM tool (mysql, sqlite, mariadb, postgres, mssql)" ],
|
|
57
57
|
} ]).then(async resSql => {
|
|
58
58
|
if (resSql.sql.split(' ')[ 0 ] != "Basic") {
|
|
59
59
|
tmpGloablConfigFile = await __dirname + '/../core/configure/global.config-sequelize.js';
|
|
@@ -231,7 +231,7 @@ class Beech {
|
|
|
231
231
|
successfully() {
|
|
232
232
|
clear();
|
|
233
233
|
console.log("[94mBeech CLI v" + require(__dirname + "/../../../package.json").version);
|
|
234
|
-
console.log('\n[102m[90m Passed [0m[0m The project has been successfully created.\n\n [37m$[0m [36mcd ' + this.argument + '[0m\n [37m$[0m [36mnpm
|
|
234
|
+
console.log('\n[102m[90m Passed [0m[0m The project has been successfully created.\n\n [37m$[0m [36mcd ' + this.argument + '[0m\n [37m$[0m [36mnpm run dev[0m or [36myarn dev[0m');
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
async contentReplace(pathFile, textCondition) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
const logUpdate = require("log-update");
|
|
3
3
|
const notifier = require("node-notifier");
|
|
4
4
|
const path = require("path");
|
|
@@ -20,6 +20,14 @@ class Beech {
|
|
|
20
20
|
return new Promise(async (resolve, reject) => {
|
|
21
21
|
try {
|
|
22
22
|
if (this.option == "serve") {
|
|
23
|
+
// Show comiling msg
|
|
24
|
+
const frames = ['\n[36m[-] Compiling[0m', '\n[36m[\\] Compiling.[0m', '\n[36m[|] Compiling..[0m', '\n[36m[/] Compiling...[0m'];
|
|
25
|
+
let i = 0;
|
|
26
|
+
var refreshCompileIntervalId = setInterval(() => {
|
|
27
|
+
const frame = frames[i = ++i % frames.length];
|
|
28
|
+
logUpdate(`${frame}`);
|
|
29
|
+
}, 300);
|
|
30
|
+
// option logic for silent notify
|
|
23
31
|
let turnNoti = true;
|
|
24
32
|
if (this.argument == "--silent" || this.argument == "-S") {
|
|
25
33
|
turnNoti = false;
|
|
@@ -30,15 +38,32 @@ class Beech {
|
|
|
30
38
|
testServ.listen(this._config_.main_config.app_port, async () => {
|
|
31
39
|
await testServ.close();
|
|
32
40
|
// Start real service.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
this.serviceDevStart(this.argument, (err, run) => {
|
|
42
|
+
if(!err && run) {
|
|
43
|
+
// Check turn on noti
|
|
44
|
+
if (turnNoti) {
|
|
45
|
+
this.notiCompile();
|
|
46
|
+
}
|
|
47
|
+
// Delay for new replace Compiling msg to Running
|
|
48
|
+
setTimeout(() => {
|
|
49
|
+
clearInterval(refreshCompileIntervalId);
|
|
50
|
+
logUpdate("\n[36m[OK] Running...[0m");
|
|
51
|
+
}, 1500);
|
|
52
|
+
} else {
|
|
53
|
+
setTimeout(() => {
|
|
54
|
+
clearInterval(refreshCompileIntervalId);
|
|
55
|
+
logUpdate("\n[101m[ERR] Failed... [0m", err);
|
|
56
|
+
reject();
|
|
57
|
+
}, 1000);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
38
60
|
}).on('error', (err) => {
|
|
61
|
+
clearInterval(refreshCompileIntervalId);
|
|
39
62
|
console.log("\n[101m Faltal [0m", err);
|
|
63
|
+
reject();
|
|
40
64
|
})
|
|
41
65
|
} else {
|
|
66
|
+
clearInterval(refreshCompileIntervalId);
|
|
42
67
|
resolve("\n[101m Faltal [0m The app.conifg.js file is not found.");
|
|
43
68
|
}
|
|
44
69
|
} else if (!this.option || this.option == "-h" || this.option == "?" || this.option == "--help") {
|
|
@@ -60,28 +85,40 @@ class Beech {
|
|
|
60
85
|
});
|
|
61
86
|
}
|
|
62
87
|
|
|
63
|
-
serviceDevStart(argument) {
|
|
64
|
-
logUpdate("[36mCompiling...[0m");
|
|
88
|
+
serviceDevStart(argument, cb) {
|
|
65
89
|
let promise = null;
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
75
|
-
Promise.all([spawnData]).then((childProcess) => {
|
|
76
|
-
childProcess[0].stdout.on('data', (data) => {
|
|
77
|
-
console.log(data.toString().slice(0, -1));
|
|
78
|
-
});
|
|
79
|
-
childProcess[0].stderr.on('data', (data) => {
|
|
80
|
-
if(data.toString().slice(0, 8) != "Ignoring" && data.toString().match(/\[SEQUELIZE0006\]/g) != "[SEQUELIZE0006]") {
|
|
81
|
-
console.log(data.toString());
|
|
90
|
+
try {
|
|
91
|
+
const spawnData = new Promise((resolve) => {
|
|
92
|
+
// check Dev. run service
|
|
93
|
+
if(argument == "-D" || argument == "--dev") {
|
|
94
|
+
console.log("\n[101m Starting Beech service in Development mode [0m");
|
|
95
|
+
promise = this.spawn('npx', ['nodemon', '-q', './cli/beech']); // For Dev.
|
|
96
|
+
} else {
|
|
97
|
+
promise = this.spawn('npx', ['nodemon', '-q', './node_modules/beech-api/packages/cli/beech']); // For Prd.
|
|
82
98
|
}
|
|
99
|
+
resolve(promise.childProcess);
|
|
83
100
|
});
|
|
84
|
-
|
|
101
|
+
Promise.all([spawnData]).then((childProcess) => {
|
|
102
|
+
childProcess[0].stdout.on('data', (data) => {
|
|
103
|
+
console.log(data.toString().slice(0, -1));
|
|
104
|
+
});
|
|
105
|
+
// Check process error
|
|
106
|
+
childProcess[0].stderr.on('data', (data) => {
|
|
107
|
+
// Check Error from std Allow for Mysql version error
|
|
108
|
+
if(data.toString().slice(0, 8) != "Ignoring" && data.toString().match(/\[SEQUELIZE0006\]/g) != "[SEQUELIZE0006]") {
|
|
109
|
+
if(data.toString().slice(0, 13) == "node:internal") {
|
|
110
|
+
cb(data.toString(), false);
|
|
111
|
+
} else {
|
|
112
|
+
console.log(data.toString());
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// Callback first
|
|
117
|
+
cb(null, true);
|
|
118
|
+
});
|
|
119
|
+
} catch (error) {
|
|
120
|
+
cb(error, false);
|
|
121
|
+
}
|
|
85
122
|
}
|
|
86
123
|
|
|
87
124
|
notiCompile() {
|
|
@@ -11,7 +11,9 @@ const byPassCredentials = (options, _res = {}, _next = () => {}) => {
|
|
|
11
11
|
if(!options.length) {
|
|
12
12
|
if(passport_config.jwt_broken_role ? passport_config.jwt_broken_role.length > 0 : false) {
|
|
13
13
|
// CASE: jwt_broken_role DEFUALT is set
|
|
14
|
-
return
|
|
14
|
+
return credentials(options, _res, () => {
|
|
15
|
+
return checkRoleMiddleware(passport_config.jwt_broken_role)(options, _res, _next);
|
|
16
|
+
});
|
|
15
17
|
} else {
|
|
16
18
|
if(!Object.keys(options).length) {
|
|
17
19
|
return [credentials];
|
|
@@ -34,78 +36,117 @@ const byPassCredentials = (options, _res = {}, _next = () => {}) => {
|
|
|
34
36
|
const credentials = (req, res, next) => {
|
|
35
37
|
if (passport_config.jwt_allow === true) {
|
|
36
38
|
const auth_endpoint = (passport_config.auth_endpoint) ? (passport_config.auth_endpoint[ 0 ] === "/" ? passport_config.auth_endpoint : "/" + passport_config.auth_endpoint) : "/authentication";
|
|
37
|
-
|
|
38
|
-
|
|
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
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
// anything token check
|
|
59
|
-
if (!user) {
|
|
60
|
-
if (info) {
|
|
61
|
-
if (info.name == "TokenExpiredError") {
|
|
62
|
-
return res.status(401).json({
|
|
63
|
-
code: 401,
|
|
64
|
-
status: "TOKEN_EXPIRED",
|
|
65
|
-
message: info,
|
|
66
|
-
});
|
|
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
|
-
});
|
|
39
|
+
const slashOneIsHash = auth_endpoint.split("/")[1];
|
|
40
|
+
if(req.params === undefined) {
|
|
41
|
+
// Request is not valid
|
|
42
|
+
console.log("\n[101m REQUEST|OPTION [0m Error: Request is not valid, missing params.");
|
|
43
|
+
return;
|
|
97
44
|
} else {
|
|
98
|
-
//
|
|
99
|
-
|
|
45
|
+
// Check first HASH equal Authentication
|
|
46
|
+
if(slashOneIsHash == req.params.hash) {
|
|
47
|
+
// Bypass authentication for auth endpoint
|
|
48
|
+
return next();
|
|
49
|
+
} else {
|
|
50
|
+
return passport.authenticate("jwt", {
|
|
51
|
+
session: false,
|
|
52
|
+
}, (err, user, info) => {
|
|
53
|
+
// error check
|
|
54
|
+
if (err) {
|
|
55
|
+
console.log(err, info);
|
|
56
|
+
return res.status(401).json({
|
|
57
|
+
code: 401,
|
|
58
|
+
error: "UNAUTHORIZED",
|
|
59
|
+
message: {
|
|
60
|
+
name: "WrongTokenError",
|
|
61
|
+
message: "token error.",
|
|
62
|
+
},
|
|
63
|
+
/* dev: { err, info }, */ // for dev info
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
// anything token check
|
|
67
|
+
if (!user) {
|
|
68
|
+
if (info) {
|
|
69
|
+
if (info.name == "TokenExpiredError") {
|
|
70
|
+
return res.status(401).json({
|
|
71
|
+
code: 401,
|
|
72
|
+
status: "TOKEN_EXPIRED",
|
|
73
|
+
message: info,
|
|
74
|
+
});
|
|
75
|
+
} else if (info.name == "Error") {
|
|
76
|
+
return res.status(401).json({
|
|
77
|
+
code: 401,
|
|
78
|
+
status: "NO_AUTH_TOKEN",
|
|
79
|
+
message: {
|
|
80
|
+
name: "NoTokenError",
|
|
81
|
+
message: "No auth token",
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
} else if (info.name == "SyntaxError") {
|
|
85
|
+
return res.status(401).json({
|
|
86
|
+
code: 401,
|
|
87
|
+
status: "PAYLOAD_SYNTAX_ERROR",
|
|
88
|
+
message: {
|
|
89
|
+
name: "SyntaxError",
|
|
90
|
+
message: "Unexpected token < in JSON at position 0",
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
} else if (info.name == "JsonWebTokenError") {
|
|
94
|
+
return res.status(401).json({
|
|
95
|
+
code: 401,
|
|
96
|
+
status: "INVALID_TOKEN",
|
|
97
|
+
message: {
|
|
98
|
+
name: "JsonWebTokenError",
|
|
99
|
+
message: "invalid token.",
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
return res.status(401).json({
|
|
104
|
+
code: 401,
|
|
105
|
+
status: "OTHER_TOKEN_ERR",
|
|
106
|
+
message: {
|
|
107
|
+
name: "OtherTokenError",
|
|
108
|
+
message: String(info),
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
return res.status(401).json({
|
|
114
|
+
code: 401,
|
|
115
|
+
status: "UNAUTHORIZED_USER",
|
|
116
|
+
message: info || {
|
|
117
|
+
name: "TokenError",
|
|
118
|
+
message: String(info),
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
// Perfectly user jwt
|
|
124
|
+
return next();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
)(req, res, next);
|
|
129
|
+
}
|
|
100
130
|
}
|
|
101
|
-
}
|
|
131
|
+
} else {
|
|
132
|
+
// Bypass authentication
|
|
133
|
+
return next();
|
|
134
|
+
}
|
|
102
135
|
}
|
|
103
136
|
|
|
104
137
|
const credentialsGuard = (req, res, next) => {
|
|
105
|
-
checkAppKey(req, res, (
|
|
106
|
-
if (
|
|
138
|
+
checkAppKey(req, res, (err) => {
|
|
139
|
+
if (!err) {
|
|
107
140
|
// Perfectly
|
|
108
141
|
next();
|
|
142
|
+
} else {
|
|
143
|
+
// Bad Request
|
|
144
|
+
return res.status(400).json({
|
|
145
|
+
code: 400,
|
|
146
|
+
status: 'BAD_REQUEST',
|
|
147
|
+
message: "Bad request.",
|
|
148
|
+
info: err,
|
|
149
|
+
});
|
|
109
150
|
}
|
|
110
151
|
});
|
|
111
152
|
}
|
|
@@ -114,33 +155,19 @@ function checkAppKey(req, res, cb) {
|
|
|
114
155
|
if (_passport_config_.app_key_allow) {
|
|
115
156
|
if (req.headers.app_key) {
|
|
116
157
|
if (_config_.main_config.app_key == req.headers.app_key) {
|
|
117
|
-
|
|
158
|
+
// Perfectly
|
|
159
|
+
cb(null, true);
|
|
118
160
|
} else {
|
|
119
|
-
|
|
120
|
-
|
|
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);
|
|
161
|
+
// Wrong App key
|
|
162
|
+
cb({ status: "BAD_VALUE", message: "Bad with wrong key." }, false);
|
|
129
163
|
}
|
|
130
164
|
} else {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
status: 'BAD_REQUEST',
|
|
134
|
-
message: "Bad request.",
|
|
135
|
-
info: {
|
|
136
|
-
status: "BAD_ENTITY",
|
|
137
|
-
message: "Bad with app entity key.",
|
|
138
|
-
},
|
|
139
|
-
});
|
|
140
|
-
return cb(false);
|
|
165
|
+
// No App key
|
|
166
|
+
cb({ status: "BAD_ENTITY", message: "Bad with app entity key." }, false);
|
|
141
167
|
}
|
|
142
168
|
} else {
|
|
143
|
-
|
|
169
|
+
// App key not allow, bypass
|
|
170
|
+
cb(null, true);
|
|
144
171
|
}
|
|
145
172
|
}
|
|
146
173
|
|
|
@@ -24,9 +24,38 @@ module.exports = {
|
|
|
24
24
|
if (passport_config.jwt_allow === true) {
|
|
25
25
|
// Check if the APP_KEY is allow
|
|
26
26
|
if(passport_config.app_key_allow) {
|
|
27
|
-
|
|
27
|
+
// All allow JWT & APP_KEY
|
|
28
|
+
//global.Credentials = [credentialsGuard, byPassCredentials]; // perfect
|
|
29
|
+
global.Credentials = (..._options) => {
|
|
30
|
+
const [option_or_req, res, next] = _options;
|
|
31
|
+
if (_options.length === 3) {
|
|
32
|
+
// Used as: app.use(Credentials)
|
|
33
|
+
return credentialsGuard(option_or_req, res, () => {
|
|
34
|
+
return byPassCredentials(option_or_req, res, next);
|
|
35
|
+
});
|
|
36
|
+
} else if (_options.length === 0) {
|
|
37
|
+
// Used as: app.use(Credentials())
|
|
38
|
+
return [credentialsGuard, byPassCredentials];
|
|
39
|
+
} else {
|
|
40
|
+
// Used as: app.use(Credentials([...] ))
|
|
41
|
+
return [credentialsGuard, byPassCredentials(option_or_req)];
|
|
42
|
+
}
|
|
43
|
+
};
|
|
28
44
|
} else {
|
|
29
|
-
|
|
45
|
+
// Only allow JWT
|
|
46
|
+
global.Credentials = (..._options) => {
|
|
47
|
+
const [option_or_req, res, next] = _options;
|
|
48
|
+
if (_options.length === 3) {
|
|
49
|
+
// Used as: app.use(Credentials)
|
|
50
|
+
return byPassCredentials(option_or_req, res, next);
|
|
51
|
+
} else if (_options.length === 0) {
|
|
52
|
+
// Used as: app.use(Credentials())
|
|
53
|
+
return byPassCredentials;
|
|
54
|
+
} else {
|
|
55
|
+
// Used as: app.use(Credentials([...]))
|
|
56
|
+
return byPassCredentials(option_or_req);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
30
59
|
}
|
|
31
60
|
// loop check db connect is true
|
|
32
61
|
fs.readFile("./app.config.js", "utf-8", (err, data) => {
|
|
@@ -52,16 +81,61 @@ module.exports = {
|
|
|
52
81
|
}
|
|
53
82
|
});
|
|
54
83
|
} else if (passport_config.app_key_allow === true) {
|
|
55
|
-
|
|
84
|
+
// Only allow APP_KEY
|
|
85
|
+
global.Credentials = (..._options) => {
|
|
86
|
+
const [option_or_req, res, next] = _options;
|
|
87
|
+
if (_options.length === 3) {
|
|
88
|
+
// Used as: app.use(Credentials)
|
|
89
|
+
return credentialsGuard(option_or_req, res, () => {
|
|
90
|
+
return next();
|
|
91
|
+
});
|
|
92
|
+
} else if (_options.length === 0) {
|
|
93
|
+
// Used as: app.use(Credentials())
|
|
94
|
+
return [credentialsGuard];
|
|
95
|
+
|
|
96
|
+
} else {
|
|
97
|
+
// Used as: app.use(Credentials([...] ))
|
|
98
|
+
return [credentialsGuard];
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
// Resolve it
|
|
56
102
|
resolve([true, false, null]);
|
|
57
103
|
} else {
|
|
58
|
-
|
|
104
|
+
// Neither APP_KEY nor JWT allow
|
|
105
|
+
global.Credentials = (..._options) => {
|
|
106
|
+
const [option_or_req, res, next] = _options;
|
|
107
|
+
if (_options.length === 3) {
|
|
108
|
+
// Used as: app.use(Credentials)
|
|
109
|
+
return next();
|
|
110
|
+
} else if (_options.length === 0) {
|
|
111
|
+
// Used as: app.use(Credentials())
|
|
112
|
+
return [];
|
|
113
|
+
} else {
|
|
114
|
+
// Used as: app.use(Credentials([...] ))
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
// Resolve it
|
|
59
119
|
resolve([true, false, null]);
|
|
60
120
|
}
|
|
61
121
|
} else {
|
|
62
|
-
|
|
122
|
+
// Passport config file not found
|
|
123
|
+
global.Credentials = (..._options) => {
|
|
124
|
+
const [option_or_req, res, next] = _options;
|
|
125
|
+
if (_options.length === 3) {
|
|
126
|
+
// Used as: app.use(Credentials)
|
|
127
|
+
return next();
|
|
128
|
+
} else {
|
|
129
|
+
// Used as: app.use(Credentials() or Credentials([...] ))
|
|
130
|
+
return [];
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Old logic
|
|
63
135
|
//const Requests = require("./_Request");
|
|
64
|
-
//global.Credentials = (_options = {}, _res, _next) => [Requests.requests];
|
|
136
|
+
//global.Credentials = (_options = {}, _res, _next) => [Requests.requests]; // ----> [Closed] TODO check passport.config file if not exists show error when file src/ using the JWT (maybe for show JWT is ON/OFF)
|
|
137
|
+
|
|
138
|
+
// Resolve it
|
|
65
139
|
resolve([false, null, null]);
|
|
66
140
|
}
|
|
67
141
|
});
|
|
@@ -80,10 +154,12 @@ module.exports = {
|
|
|
80
154
|
var passportPasswordField = passport_config.model.password_field || "password";
|
|
81
155
|
var passportTable = passport_config.model.table || "users";
|
|
82
156
|
var pool = eval("sql." + passport_config.model.name);
|
|
157
|
+
// Check your assign auth fields
|
|
83
158
|
checkAuthFields(pool_base, pool, passportTable, passport_config.model.fields, (err, msg) => {
|
|
84
159
|
if(err) {
|
|
85
|
-
console.
|
|
160
|
+
console.log("\n[101m Error [0m", err);
|
|
86
161
|
return;
|
|
162
|
+
//throw err;
|
|
87
163
|
} else {
|
|
88
164
|
// find passport primary key
|
|
89
165
|
findPassportPk(pool_base, pool, passportTable, passport_config.model.fields, (err, passportFields) => {
|
|
@@ -163,42 +239,38 @@ module.exports = {
|
|
|
163
239
|
} else if (pool_base == "sequelize") {
|
|
164
240
|
// pool base is Sequelize
|
|
165
241
|
try {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
|
|
175
|
-
}).catch((error) => {
|
|
176
|
-
if(pool.options.logging) {
|
|
177
|
-
return done(error, null);
|
|
178
|
-
} else {
|
|
179
|
-
if(error.sql) {
|
|
180
|
-
delete error.sql;
|
|
181
|
-
if(error.errors) {
|
|
182
|
-
delete error.errors;
|
|
183
|
-
}
|
|
184
|
-
if(error.parent) {
|
|
185
|
-
delete error.parent;
|
|
186
|
-
}
|
|
187
|
-
if(error.original) {
|
|
188
|
-
delete error.original.sql;
|
|
189
|
-
}
|
|
190
|
-
if(error.parameters) {
|
|
191
|
-
delete error.parameters;
|
|
192
|
-
}
|
|
193
|
-
return done(error, null);
|
|
242
|
+
// Function Find table primaryKey
|
|
243
|
+
const findPkOfTable = () => {
|
|
244
|
+
return new Promise(async (resolve, reject) => {
|
|
245
|
+
try {
|
|
246
|
+
const tableInfo = await pool.getQueryInterface().describeTable(String(passportTable));
|
|
247
|
+
const primaryKeys = Object.entries(tableInfo).filter(([columnName, columnInfo]) => columnInfo.primaryKey).map(([columnName]) => columnName);
|
|
248
|
+
if(primaryKeys.length) {
|
|
249
|
+
resolve(primaryKeys);
|
|
194
250
|
} else {
|
|
195
|
-
|
|
251
|
+
resolve([Object.keys(tableInfo)[0]]);
|
|
196
252
|
}
|
|
253
|
+
} catch (error) {
|
|
254
|
+
reject(`Query Interface ${error}`);
|
|
197
255
|
}
|
|
198
256
|
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
|
|
257
|
+
}
|
|
258
|
+
// Find table primaryKey
|
|
259
|
+
findPkOfTable()
|
|
260
|
+
.then((fieldPk) => {
|
|
261
|
+
pool.query("SELECT " + passportFields + " FROM " + passportTable + " WHERE " + fieldPk + " = :pk", {
|
|
262
|
+
replacements: {
|
|
263
|
+
pk: + jwtPayload[fieldPk]
|
|
264
|
+
},
|
|
265
|
+
type: QueryTypes.SELECT,
|
|
266
|
+
}).then((result) => {
|
|
267
|
+
return done(null, JSON.parse(JSON.stringify(result[ 0 ] || null)));
|
|
268
|
+
}).catch((err) => {
|
|
269
|
+
return done(err, null);
|
|
270
|
+
});
|
|
271
|
+
}).catch(err => {
|
|
272
|
+
return done(err, null);
|
|
273
|
+
});
|
|
202
274
|
} catch (error) {
|
|
203
275
|
return done(error, null);
|
|
204
276
|
}
|
|
@@ -24,7 +24,7 @@ module.exports = {
|
|
|
24
24
|
// The fields for authenticate, default fields: (`username` and `password`)
|
|
25
25
|
username_field: "",
|
|
26
26
|
password_field: "",
|
|
27
|
-
// JWT playload data
|
|
27
|
+
// JWT playload data, You can add it. Example: ["name", "email", ...]
|
|
28
28
|
fields: [],
|
|
29
29
|
// Other fields add for authentication.
|
|
30
30
|
guard: {
|
|
@@ -27,7 +27,7 @@ mysqlInProcess = (database_config, headDbShow, cb) => {
|
|
|
27
27
|
// check hash ?
|
|
28
28
|
if(val.username && val.password) {
|
|
29
29
|
if(val.username.length < 55 || val.password < 55) {
|
|
30
|
-
return cb("Error:
|
|
30
|
+
return cb("Error: Incorrect Hash access for connect to database.\n", null);
|
|
31
31
|
}
|
|
32
32
|
let accessDb = [];
|
|
33
33
|
[val.username, val.password].map((e, k) => {
|