mm_os 4.3.6 → 4.3.7
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/com/mqtt/drive.js +12 -4
- package/com/mqtt/index.js +60 -25
- package/com/mqtt/script.tpl.js +2 -2
- package/com/nav/tpl/admin_pc/page_channel.vue +5 -5
- package/com/nav/tpl/admin_pc/page_config.vue +5 -5
- package/com/nav/tpl/admin_pc/page_config_form.vue +1 -1
- package/com/nav/tpl/admin_pc/page_default.vue +5 -5
- package/com/nav/tpl/admin_pc/page_form.vue +1 -1
- package/com/nav/tpl/admin_pc/page_lang.vue +5 -5
- package/com/nav/tpl/admin_pc/page_nav.vue +5 -5
- package/com/nav/tpl/admin_pc/page_table.vue +5 -5
- package/com/nav/tpl/admin_pc/page_type.vue +5 -5
- package/com/nav/tpl/admin_pc/page_view.vue +1 -1
- package/com/nav/tpl/dev_pc/page_channel.vue +5 -5
- package/com/nav/tpl/dev_pc/page_config.vue +5 -5
- package/com/nav/tpl/dev_pc/page_default.vue +5 -5
- package/com/nav/tpl/dev_pc/page_form.vue +1 -1
- package/com/nav/tpl/dev_pc/page_nav.vue +5 -5
- package/com/nav/tpl/dev_pc/page_table.vue +5 -5
- package/com/nav/tpl/dev_pc/page_type.vue +6 -6
- package/com/nav/tpl/home_pc/page_channel.vue +5 -5
- package/com/nav/tpl/home_pc/page_default.vue +5 -5
- package/com/nav/tpl/home_pc/page_form.vue +1 -1
- package/com/nav/tpl/home_pc/page_list.vue +5 -5
- package/com/nav/tpl/home_pc/page_nav.vue +5 -5
- package/com/nav/tpl/home_pc/page_type.vue +5 -5
- package/com/nav/tpl/home_pc/page_view.vue +1 -1
- package/com/nav/tpl/home_phone/page_channel.vue +5 -5
- package/com/nav/tpl/home_phone/page_default.vue +5 -5
- package/com/nav/tpl/home_phone/page_form.vue +1 -1
- package/com/nav/tpl/home_phone/page_list.vue +5 -5
- package/com/nav/tpl/home_phone/page_nav.vue +5 -5
- package/com/nav/tpl/home_phone/page_type.vue +5 -5
- package/com/nav/tpl/home_phone/page_view.vue +1 -1
- package/com/pendant/index.js +39 -39
- package/com/sql/drive.js +49 -4
- package/com/template/index.js +141 -141
- package/common/middleware/web_waf/index.js +49 -39
- package/core/app/index.js +711 -710
- package/core/plugin/index.js +13 -43
- package/core/store/index.js +146 -146
- package/package.json +21 -17
- package/server.js +7 -0
- package/com/mqtt/mm_mqtt.js +0 -446
- package/core/store/sql.js +0 -1488
package/com/pendant/index.js
CHANGED
|
@@ -85,45 +85,45 @@ class Pendant extends Manager {
|
|
|
85
85
|
*/
|
|
86
86
|
Pendant.prototype.Drive = Drive;
|
|
87
87
|
|
|
88
|
-
/**
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
Pendant.prototype.loadList = async function (list) {
|
|
93
|
-
|
|
88
|
+
// /**
|
|
89
|
+
// * 加载列表
|
|
90
|
+
// * @param {Array} list 文件列表
|
|
91
|
+
// */
|
|
92
|
+
// Pendant.prototype.loadList = async function (list) {
|
|
93
|
+
// var _this = this;
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
};
|
|
95
|
+
// // 遍历文件路径
|
|
96
|
+
// for (var i = 0; i < list.length; i++) {
|
|
97
|
+
// var file = list[i];
|
|
98
|
+
// var dir = file.dirname();
|
|
99
|
+
// // 载入文件
|
|
100
|
+
// var obj = file.loadJson(dir);
|
|
101
|
+
// if (obj) {
|
|
102
|
+
// if (obj.constructor == Array) {
|
|
103
|
+
// for (var n = 0; n < obj.length; n++) {
|
|
104
|
+
// var o = obj[n];
|
|
105
|
+
// // 实例化一个驱动
|
|
106
|
+
// await _this.load(dir, o, file);
|
|
107
|
+
// }
|
|
108
|
+
// } else {
|
|
109
|
+
// await _this.load(dir, obj, file);
|
|
110
|
+
// }
|
|
111
|
+
// } else {
|
|
112
|
+
// var fl = _this.dir_base + "/config.tpl.json";
|
|
113
|
+
// if (fl.hasFile()) {
|
|
114
|
+
// var text = fl.loadText();
|
|
115
|
+
// if (text) {
|
|
116
|
+
// var l = $.slash;
|
|
117
|
+
// var name = file.between("Pendant" + l, l);
|
|
118
|
+
// text = text.replaceAll("{0}", name);
|
|
119
|
+
// var app = file.between("app" + l, l);
|
|
120
|
+
// text = text.replaceAll("{1}", app);
|
|
121
|
+
// file.saveText(text);
|
|
122
|
+
// }
|
|
123
|
+
// }
|
|
124
|
+
// }
|
|
125
|
+
// }
|
|
126
|
+
// };
|
|
127
127
|
|
|
128
128
|
/**
|
|
129
129
|
* 生成字体样式
|
|
@@ -452,7 +452,7 @@ function pendantAdmin(scope, title) {
|
|
|
452
452
|
if (!obj) {
|
|
453
453
|
$.pool.pendant[sc] = new Pendant({
|
|
454
454
|
name: sc,
|
|
455
|
-
title: title
|
|
455
|
+
title: title
|
|
456
456
|
});
|
|
457
457
|
obj = $.pool.pendant[sc];
|
|
458
458
|
}
|
package/com/sql/drive.js
CHANGED
|
@@ -127,9 +127,9 @@ class Drive extends Item {
|
|
|
127
127
|
/* 去重 */
|
|
128
128
|
del_repeat: {
|
|
129
129
|
// 判断重复的字段,例如字段名 number
|
|
130
|
-
|
|
130
|
+
groupby: '',
|
|
131
131
|
// 排序方式 例如: `diJia` ASC
|
|
132
|
-
|
|
132
|
+
orderby: '',
|
|
133
133
|
},
|
|
134
134
|
/* 逻辑符 */
|
|
135
135
|
logic: {},
|
|
@@ -550,6 +550,51 @@ Drive.prototype.add = async function (db, query, body) {
|
|
|
550
550
|
return await this.addMain(db, body);
|
|
551
551
|
};
|
|
552
552
|
|
|
553
|
+
/**
|
|
554
|
+
* 批量添加(主要)
|
|
555
|
+
* @param {object} db 数据库操作类
|
|
556
|
+
* @param {Array} list 添加项列表
|
|
557
|
+
* @returns {object} 返回批量添加结果
|
|
558
|
+
*/
|
|
559
|
+
Drive.prototype.addListMain = async function (db, list) {
|
|
560
|
+
if (!Array.isArray(list) || list.length === 0) {
|
|
561
|
+
return $.ret.error(30001, '参数不能为空');
|
|
562
|
+
}
|
|
563
|
+
var success_num = 0;
|
|
564
|
+
var error_num = 0;
|
|
565
|
+
var errors = [];
|
|
566
|
+
var list_error = [];
|
|
567
|
+
for (var i = 0; i < list.length; i++) {
|
|
568
|
+
var ret = await this.addMain(db, list[i]);
|
|
569
|
+
if (ret.error) {
|
|
570
|
+
error_num++;
|
|
571
|
+
errors.push(ret.error.message);
|
|
572
|
+
list_error.push(list[i]);
|
|
573
|
+
} else {
|
|
574
|
+
success_num++;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
var done = $.ret.bl(success_num > 0, success_num > 0 ? '批量添加成功!' : '批量添加失败!');
|
|
578
|
+
Object.assign(done.result, {
|
|
579
|
+
total: list.length,
|
|
580
|
+
success: success_num,
|
|
581
|
+
error: error_num,
|
|
582
|
+
list_error: list_error,
|
|
583
|
+
errors: errors
|
|
584
|
+
});
|
|
585
|
+
return done;
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* 批量添加
|
|
590
|
+
* @param {object} db 数据库操作类
|
|
591
|
+
* @param {Array} list 添加项列表
|
|
592
|
+
* @returns {object} 返回批量添加结果
|
|
593
|
+
*/
|
|
594
|
+
Drive.prototype.addList = async function (db, list) {
|
|
595
|
+
return await this.addListMain(db, list);
|
|
596
|
+
};
|
|
597
|
+
|
|
553
598
|
/**
|
|
554
599
|
* 删除(主要)
|
|
555
600
|
* @param {object} db 数据库操作类
|
|
@@ -1013,10 +1058,10 @@ Drive.prototype.delRepeatMain = async function (db, params) {
|
|
|
1013
1058
|
var pm = { ...params };
|
|
1014
1059
|
var msg = '';
|
|
1015
1060
|
var cg = this.config.del_repeat;
|
|
1016
|
-
var order_by = pm.orderby || cg.
|
|
1061
|
+
var order_by = pm.orderby || cg.orderby;
|
|
1017
1062
|
delete pm.orderby;
|
|
1018
1063
|
var group_by =
|
|
1019
|
-
validateIden(pm.groupby || cg.
|
|
1064
|
+
validateIden(pm.groupby || cg.groupby) || cg.groupby || '';
|
|
1020
1065
|
delete pm.groupby;
|
|
1021
1066
|
var f = db.config.filter;
|
|
1022
1067
|
// 设置查询字段
|
package/com/template/index.js
CHANGED
|
@@ -1,141 +1,141 @@
|
|
|
1
|
-
const compressing = require("compressing");
|
|
2
|
-
const Manager = require("mm_machine").Manager;
|
|
3
|
-
const Drive = require("./drive").Drive;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 主题模板管理类
|
|
7
|
-
* @class
|
|
8
|
-
*/
|
|
9
|
-
class Template extends Manager {
|
|
10
|
-
/**
|
|
11
|
-
* 配置参数
|
|
12
|
-
* @type {object}
|
|
13
|
-
*/
|
|
14
|
-
static config = {
|
|
15
|
-
/**
|
|
16
|
-
* 名称
|
|
17
|
-
* @type {string}
|
|
18
|
-
*/
|
|
19
|
-
name: "",
|
|
20
|
-
/**
|
|
21
|
-
* 标题
|
|
22
|
-
* @type {string}
|
|
23
|
-
*/
|
|
24
|
-
title: "template管理",
|
|
25
|
-
/**
|
|
26
|
-
* 描述
|
|
27
|
-
* @type {string}
|
|
28
|
-
*/
|
|
29
|
-
description: "这是template管理器",
|
|
30
|
-
/**
|
|
31
|
-
* 检索文件名
|
|
32
|
-
* @type {string}
|
|
33
|
-
*/
|
|
34
|
-
filename: "template.json",
|
|
35
|
-
/**
|
|
36
|
-
* 模板目录
|
|
37
|
-
* @type {string}
|
|
38
|
-
*/
|
|
39
|
-
tpl_dir: __dirname,
|
|
40
|
-
/**
|
|
41
|
-
* 基础目录
|
|
42
|
-
* @type {string}
|
|
43
|
-
*/
|
|
44
|
-
base_dir: "../common/template".fullname(__dirname),
|
|
45
|
-
/**
|
|
46
|
-
* 自定义目录,加载项目自定义资源
|
|
47
|
-
* @type {string}
|
|
48
|
-
*/
|
|
49
|
-
dir: "./static/template".fullname(),
|
|
50
|
-
/**
|
|
51
|
-
* 搜索模式 dir按目录搜索 | file按文件名搜索
|
|
52
|
-
* @type {string}
|
|
53
|
-
*/
|
|
54
|
-
search_way: "file",
|
|
55
|
-
/**
|
|
56
|
-
* 是否懒加载
|
|
57
|
-
* @type {boolean}
|
|
58
|
-
*/
|
|
59
|
-
lazy_load: true,
|
|
60
|
-
/**
|
|
61
|
-
* 模式
|
|
62
|
-
* 1.生产模式,改变文件不会重新加载
|
|
63
|
-
* 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
|
|
64
|
-
* 3.热重载模式,改变配置文件都会加载配置和脚本
|
|
65
|
-
* 4.重载模式,执行完后重新加载脚本,避免变量污染
|
|
66
|
-
* 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
|
|
67
|
-
* @type {number}
|
|
68
|
-
*/
|
|
69
|
-
mode: process.env.NODE_ENV === "production" ? 1 : 3,
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* 构造函数
|
|
74
|
-
* @param {object} config 配置参数
|
|
75
|
-
* @param {object} parent 父项
|
|
76
|
-
*/
|
|
77
|
-
constructor(config, parent) {
|
|
78
|
-
super({ ...Template.config, ...config }, parent);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
Template.prototype.Drive = Drive;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* 解压模板
|
|
86
|
-
* @param {string} file 模板压缩文件
|
|
87
|
-
* @returns {object} 解压后的文件对象
|
|
88
|
-
*/
|
|
89
|
-
Template.prototype.unzip = async function (file) {
|
|
90
|
-
var done = await compressing.zip.uncompress(
|
|
91
|
-
file,
|
|
92
|
-
"/static/template".fullname(),
|
|
93
|
-
);
|
|
94
|
-
return done;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 获取模板
|
|
99
|
-
* @param {string} key 模板键名
|
|
100
|
-
* @returns {object} 模板对象
|
|
101
|
-
*/
|
|
102
|
-
Template.prototype.get = function (key) {
|
|
103
|
-
return this.mods[key];
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* 主题模板模板池
|
|
108
|
-
*/
|
|
109
|
-
if (!$.pool.template) {
|
|
110
|
-
$.pool.template = {};
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* 主题模板管理器,用于创建缓存
|
|
115
|
-
* @param {string} scope 作用域
|
|
116
|
-
* @param {string} title 标题
|
|
117
|
-
* @returns {object} 返回一个缓存类
|
|
118
|
-
*/
|
|
119
|
-
function templateAdmin(scope, title) {
|
|
120
|
-
var sc = scope || $.val.scope + "";
|
|
121
|
-
var obj = $.pool.template[sc];
|
|
122
|
-
if (!obj) {
|
|
123
|
-
$.pool.template[sc] = new Template({
|
|
124
|
-
name: sc,
|
|
125
|
-
title: title,
|
|
126
|
-
});
|
|
127
|
-
obj = $.pool.template[sc];
|
|
128
|
-
}
|
|
129
|
-
return obj;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* @module 导出模板管理器
|
|
134
|
-
*/
|
|
135
|
-
if ($.admin) {
|
|
136
|
-
$.admin.template = templateAdmin;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
module.exports = {
|
|
140
|
-
Template,
|
|
141
|
-
};
|
|
1
|
+
const compressing = require("compressing");
|
|
2
|
+
const Manager = require("mm_machine").Manager;
|
|
3
|
+
const Drive = require("./drive").Drive;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 主题模板管理类
|
|
7
|
+
* @class
|
|
8
|
+
*/
|
|
9
|
+
class Template extends Manager {
|
|
10
|
+
/**
|
|
11
|
+
* 配置参数
|
|
12
|
+
* @type {object}
|
|
13
|
+
*/
|
|
14
|
+
static config = {
|
|
15
|
+
/**
|
|
16
|
+
* 名称
|
|
17
|
+
* @type {string}
|
|
18
|
+
*/
|
|
19
|
+
name: "",
|
|
20
|
+
/**
|
|
21
|
+
* 标题
|
|
22
|
+
* @type {string}
|
|
23
|
+
*/
|
|
24
|
+
title: "template管理",
|
|
25
|
+
/**
|
|
26
|
+
* 描述
|
|
27
|
+
* @type {string}
|
|
28
|
+
*/
|
|
29
|
+
description: "这是template管理器",
|
|
30
|
+
/**
|
|
31
|
+
* 检索文件名
|
|
32
|
+
* @type {string}
|
|
33
|
+
*/
|
|
34
|
+
filename: "template.json",
|
|
35
|
+
/**
|
|
36
|
+
* 模板目录
|
|
37
|
+
* @type {string}
|
|
38
|
+
*/
|
|
39
|
+
tpl_dir: __dirname,
|
|
40
|
+
/**
|
|
41
|
+
* 基础目录
|
|
42
|
+
* @type {string}
|
|
43
|
+
*/
|
|
44
|
+
base_dir: "../common/template".fullname(__dirname),
|
|
45
|
+
/**
|
|
46
|
+
* 自定义目录,加载项目自定义资源
|
|
47
|
+
* @type {string}
|
|
48
|
+
*/
|
|
49
|
+
dir: "./static/template".fullname(),
|
|
50
|
+
/**
|
|
51
|
+
* 搜索模式 dir按目录搜索 | file按文件名搜索
|
|
52
|
+
* @type {string}
|
|
53
|
+
*/
|
|
54
|
+
search_way: "file",
|
|
55
|
+
/**
|
|
56
|
+
* 是否懒加载
|
|
57
|
+
* @type {boolean}
|
|
58
|
+
*/
|
|
59
|
+
lazy_load: true,
|
|
60
|
+
/**
|
|
61
|
+
* 模式
|
|
62
|
+
* 1.生产模式,改变文件不会重新加载
|
|
63
|
+
* 2.热更新模式,改变配置文件会重新加载配置,不重新加载脚本
|
|
64
|
+
* 3.热重载模式,改变配置文件都会加载配置和脚本
|
|
65
|
+
* 4.重载模式,执行完后重新加载脚本,避免变量污染
|
|
66
|
+
* 5.热更新+重载模式,改变配置文件重新加载配置和脚本,执行完后重新加载脚本
|
|
67
|
+
* @type {number}
|
|
68
|
+
*/
|
|
69
|
+
mode: process.env.NODE_ENV === "production" ? 1 : 3,
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 构造函数
|
|
74
|
+
* @param {object} config 配置参数
|
|
75
|
+
* @param {object} parent 父项
|
|
76
|
+
*/
|
|
77
|
+
constructor(config, parent) {
|
|
78
|
+
super({ ...Template.config, ...config }, parent);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
Template.prototype.Drive = Drive;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* 解压模板
|
|
86
|
+
* @param {string} file 模板压缩文件
|
|
87
|
+
* @returns {object} 解压后的文件对象
|
|
88
|
+
*/
|
|
89
|
+
Template.prototype.unzip = async function (file) {
|
|
90
|
+
var done = await compressing.zip.uncompress(
|
|
91
|
+
file,
|
|
92
|
+
"/static/template".fullname(),
|
|
93
|
+
);
|
|
94
|
+
return done;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 获取模板
|
|
99
|
+
* @param {string} key 模板键名
|
|
100
|
+
* @returns {object} 模板对象
|
|
101
|
+
*/
|
|
102
|
+
Template.prototype.get = function (key) {
|
|
103
|
+
return this.mods[key];
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 主题模板模板池
|
|
108
|
+
*/
|
|
109
|
+
if (!$.pool.template) {
|
|
110
|
+
$.pool.template = {};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 主题模板管理器,用于创建缓存
|
|
115
|
+
* @param {string} scope 作用域
|
|
116
|
+
* @param {string} title 标题
|
|
117
|
+
* @returns {object} 返回一个缓存类
|
|
118
|
+
*/
|
|
119
|
+
function templateAdmin(scope, title) {
|
|
120
|
+
var sc = scope || $.val.scope + "";
|
|
121
|
+
var obj = $.pool.template[sc];
|
|
122
|
+
if (!obj) {
|
|
123
|
+
$.pool.template[sc] = new Template({
|
|
124
|
+
name: sc,
|
|
125
|
+
title: title,
|
|
126
|
+
});
|
|
127
|
+
obj = $.pool.template[sc];
|
|
128
|
+
}
|
|
129
|
+
return obj;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @module 导出模板管理器
|
|
134
|
+
*/
|
|
135
|
+
if ($.admin) {
|
|
136
|
+
$.admin.template = templateAdmin;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = {
|
|
140
|
+
Template,
|
|
141
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
const
|
|
1
|
+
const rateLimit = require('mm_kernel/common/mod/filter/rate_limit/index.js');
|
|
2
|
+
const ipBlock = require('mm_kernel/common/mod/filter/ip_block/index.js');
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* web防火墙
|
|
@@ -15,9 +16,6 @@ module.exports = {
|
|
|
15
16
|
// 获取配置
|
|
16
17
|
let cg = { ...this.config, ...adapter.web.config };
|
|
17
18
|
|
|
18
|
-
// 初始化全局IP管理器
|
|
19
|
-
this._initIpManager(cg);
|
|
20
|
-
|
|
21
19
|
// 设置WAF中间件
|
|
22
20
|
let self = this;
|
|
23
21
|
web.use(async (ctx, next) => {
|
|
@@ -28,29 +26,6 @@ module.exports = {
|
|
|
28
26
|
});
|
|
29
27
|
},
|
|
30
28
|
|
|
31
|
-
/**
|
|
32
|
-
* 初始化IP管理器
|
|
33
|
-
* @private
|
|
34
|
-
* @param {object} config 配置对象
|
|
35
|
-
*/
|
|
36
|
-
_initIpManager(config) {
|
|
37
|
-
// 确保全局IP管理器存在
|
|
38
|
-
if (!$.ip || ($.ip && !$.is_plugin)) {
|
|
39
|
-
$.ip = new Ip();
|
|
40
|
-
$.is_plugin = true;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// 配置IP管理器
|
|
44
|
-
if (config && config.web) {
|
|
45
|
-
let ipConfig = {
|
|
46
|
-
auto_black_enable: config.web.auto_black_enable !== false,
|
|
47
|
-
max_req_per_min: config.web.max_req_per_min || 100,
|
|
48
|
-
auto_black_limit: config.web.auto_black_threshold || 50
|
|
49
|
-
};
|
|
50
|
-
$.ip.setConfig(ipConfig);
|
|
51
|
-
}
|
|
52
|
-
},
|
|
53
|
-
|
|
54
29
|
/**
|
|
55
30
|
* 处理WAF检查
|
|
56
31
|
* @private
|
|
@@ -70,8 +45,8 @@ module.exports = {
|
|
|
70
45
|
return true;
|
|
71
46
|
}
|
|
72
47
|
|
|
73
|
-
//
|
|
74
|
-
if (!this._checkIpAccess(ip)) {
|
|
48
|
+
// IP黑白名单与频率限制检查
|
|
49
|
+
if (!(await this._checkIpAccess(ip, cg))) {
|
|
75
50
|
this._sendWafResponse(ctx, 403, '访问被WAF阻止,IP访问受限');
|
|
76
51
|
return false;
|
|
77
52
|
}
|
|
@@ -96,21 +71,56 @@ module.exports = {
|
|
|
96
71
|
* 检查IP访问权限
|
|
97
72
|
* @private
|
|
98
73
|
* @param {string} ip IP地址
|
|
99
|
-
* @
|
|
74
|
+
* @param {object} cg 配置对象
|
|
75
|
+
* @returns {Promise<boolean>} 是否允许访问
|
|
100
76
|
*/
|
|
101
|
-
_checkIpAccess(ip) {
|
|
102
|
-
|
|
77
|
+
async _checkIpAccess(ip, cg) {
|
|
78
|
+
if (!ip) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
103
81
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
82
|
+
if (await this._checkIpBlocked(ip, cg)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
return await this._checkRateLimit(ip, cg);
|
|
106
86
|
} catch {
|
|
107
|
-
|
|
108
|
-
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
},
|
|
109
90
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
91
|
+
/**
|
|
92
|
+
* 检查IP是否在黑名单中
|
|
93
|
+
* @private
|
|
94
|
+
* @param {string} ip IP地址
|
|
95
|
+
* @param {object} cg 配置对象
|
|
96
|
+
* @returns {Promise<boolean>} 是否被拦截
|
|
97
|
+
*/
|
|
98
|
+
async _checkIpBlocked(ip, cg) {
|
|
99
|
+
var blacklist = (cg && cg.web && cg.web.ip_blacklist) || [];
|
|
100
|
+
if (blacklist.length === 0) {
|
|
101
|
+
return false;
|
|
113
102
|
}
|
|
103
|
+
var ctx = { input: { ip: ip }, output: {}, meta: {} };
|
|
104
|
+
var done = await ipBlock.main(ctx, { blacklist: blacklist });
|
|
105
|
+
return done.blocked;
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* 检查请求频率是否超限
|
|
110
|
+
* @private
|
|
111
|
+
* @param {string} ip IP地址
|
|
112
|
+
* @param {object} cg 配置对象
|
|
113
|
+
* @returns {Promise<boolean>} 是否允许访问
|
|
114
|
+
*/
|
|
115
|
+
async _checkRateLimit(ip, cg) {
|
|
116
|
+
var max_req = (cg && cg.web && cg.web.max_req_per_min) || 100;
|
|
117
|
+
var ctx = { input: {}, output: {}, meta: {} };
|
|
118
|
+
var done = await rateLimit.main(ctx, {
|
|
119
|
+
key: 'waf:' + ip,
|
|
120
|
+
max_requests: max_req,
|
|
121
|
+
window_ms: 60000
|
|
122
|
+
});
|
|
123
|
+
return !done.blocked;
|
|
114
124
|
},
|
|
115
125
|
|
|
116
126
|
/**
|