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.
Files changed (45) hide show
  1. package/com/mqtt/drive.js +12 -4
  2. package/com/mqtt/index.js +60 -25
  3. package/com/mqtt/script.tpl.js +2 -2
  4. package/com/nav/tpl/admin_pc/page_channel.vue +5 -5
  5. package/com/nav/tpl/admin_pc/page_config.vue +5 -5
  6. package/com/nav/tpl/admin_pc/page_config_form.vue +1 -1
  7. package/com/nav/tpl/admin_pc/page_default.vue +5 -5
  8. package/com/nav/tpl/admin_pc/page_form.vue +1 -1
  9. package/com/nav/tpl/admin_pc/page_lang.vue +5 -5
  10. package/com/nav/tpl/admin_pc/page_nav.vue +5 -5
  11. package/com/nav/tpl/admin_pc/page_table.vue +5 -5
  12. package/com/nav/tpl/admin_pc/page_type.vue +5 -5
  13. package/com/nav/tpl/admin_pc/page_view.vue +1 -1
  14. package/com/nav/tpl/dev_pc/page_channel.vue +5 -5
  15. package/com/nav/tpl/dev_pc/page_config.vue +5 -5
  16. package/com/nav/tpl/dev_pc/page_default.vue +5 -5
  17. package/com/nav/tpl/dev_pc/page_form.vue +1 -1
  18. package/com/nav/tpl/dev_pc/page_nav.vue +5 -5
  19. package/com/nav/tpl/dev_pc/page_table.vue +5 -5
  20. package/com/nav/tpl/dev_pc/page_type.vue +6 -6
  21. package/com/nav/tpl/home_pc/page_channel.vue +5 -5
  22. package/com/nav/tpl/home_pc/page_default.vue +5 -5
  23. package/com/nav/tpl/home_pc/page_form.vue +1 -1
  24. package/com/nav/tpl/home_pc/page_list.vue +5 -5
  25. package/com/nav/tpl/home_pc/page_nav.vue +5 -5
  26. package/com/nav/tpl/home_pc/page_type.vue +5 -5
  27. package/com/nav/tpl/home_pc/page_view.vue +1 -1
  28. package/com/nav/tpl/home_phone/page_channel.vue +5 -5
  29. package/com/nav/tpl/home_phone/page_default.vue +5 -5
  30. package/com/nav/tpl/home_phone/page_form.vue +1 -1
  31. package/com/nav/tpl/home_phone/page_list.vue +5 -5
  32. package/com/nav/tpl/home_phone/page_nav.vue +5 -5
  33. package/com/nav/tpl/home_phone/page_type.vue +5 -5
  34. package/com/nav/tpl/home_phone/page_view.vue +1 -1
  35. package/com/pendant/index.js +39 -39
  36. package/com/sql/drive.js +49 -4
  37. package/com/template/index.js +141 -141
  38. package/common/middleware/web_waf/index.js +49 -39
  39. package/core/app/index.js +711 -710
  40. package/core/plugin/index.js +13 -43
  41. package/core/store/index.js +146 -146
  42. package/package.json +21 -17
  43. package/server.js +7 -0
  44. package/com/mqtt/mm_mqtt.js +0 -446
  45. package/core/store/sql.js +0 -1488
@@ -85,45 +85,45 @@ class Pendant extends Manager {
85
85
  */
86
86
  Pendant.prototype.Drive = Drive;
87
87
 
88
- /**
89
- * 加载列表
90
- * @param {Array} list 文件列表
91
- */
92
- Pendant.prototype.loadList = async function (list) {
93
- var _this = this;
88
+ // /**
89
+ // * 加载列表
90
+ // * @param {Array} list 文件列表
91
+ // */
92
+ // Pendant.prototype.loadList = async function (list) {
93
+ // var _this = this;
94
94
 
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
- };
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
- group_by: '',
130
+ groupby: '',
131
131
  // 排序方式 例如: `diJia` ASC
132
- order_by: '',
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.orderBy;
1061
+ var order_by = pm.orderby || cg.orderby;
1017
1062
  delete pm.orderby;
1018
1063
  var group_by =
1019
- validateIden(pm.groupby || cg.groupBy) || cg.groupBy || '';
1064
+ validateIden(pm.groupby || cg.groupby) || cg.groupby || '';
1020
1065
  delete pm.groupby;
1021
1066
  var f = db.config.filter;
1022
1067
  // 设置查询字段
@@ -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 { Ip } = require('mm_ip');
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
- // 使用mm_ip进行IP检查和频率限制
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
- * @returns {boolean} 是否允许访问
74
+ * @param {object} cg 配置对象
75
+ * @returns {Promise<boolean>} 是否允许访问
100
76
  */
101
- _checkIpAccess(ip) {
102
- return true;
77
+ async _checkIpAccess(ip, cg) {
78
+ if (!ip) {
79
+ return true;
80
+ }
103
81
  try {
104
- // 使用mm_ip的record方法进行综合检查(包含白名单、黑名单、频率限制)
105
- return $.ip.record(ip);
82
+ if (await this._checkIpBlocked(ip, cg)) {
83
+ return false;
84
+ }
85
+ return await this._checkRateLimit(ip, cg);
106
86
  } catch {
107
- // 如果mm_ip不可用,使用备用方案
108
- this.log('warn', 'mm_ip不可用,使用备用IP检查');
87
+ return true;
88
+ }
89
+ },
109
90
 
110
- // 备用方案:检查本地白名单
111
- const LOCAL_WHITE_LIST = ['127.0.0.1', '::1', 'localhost'];
112
- return LOCAL_WHITE_LIST.includes(ip);
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
  /**