mm_os 3.3.1 → 4.0.1

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 (380) hide show
  1. package/LICENSE +21 -201
  2. package/README.md +498 -99
  3. package/README_EN.md +505 -0
  4. package/adapter/adapter.js +431 -0
  5. package/adapter/custom_persistence.js +660 -0
  6. package/adapter/mqtt.js +273 -0
  7. package/adapter/socket.js +113 -0
  8. package/adapter/web.js +67 -0
  9. package/adapter/websocket.js +146 -0
  10. package/com/api/com.json +5 -0
  11. package/{core/com → com}/api/config.tpl.json +8 -8
  12. package/com/api/drive.js +708 -0
  13. package/com/api/index.js +198 -0
  14. package/com/api/oauth.js +200 -0
  15. package/com/api/script.tpl.js +32 -0
  16. package/com/cmd/README.md +11 -0
  17. package/com/cmd/com.json +5 -0
  18. package/com/cmd/config.tpl.json +122 -0
  19. package/com/cmd/drive.js +1548 -0
  20. package/com/cmd/index.js +1066 -0
  21. package/com/cmd/msg.json +48 -0
  22. package/com/cmd/nlp.js +525 -0
  23. package/com/cmd/script.tpl.js +32 -0
  24. package/com/db/com.json +5 -0
  25. package/com/db/drive.js +1999 -0
  26. package/com/db/index.js +242 -0
  27. package/{core/com → com}/event/README.md +4 -4
  28. package/com/event/com.json +5 -0
  29. package/{core/com → com}/event/config.tpl.json +18 -18
  30. package/com/event/drive.js +59 -0
  31. package/com/event/index.js +409 -0
  32. package/com/event/script.tpl.js +23 -0
  33. package/com/mqtt/com.json +5 -0
  34. package/{core/com → com}/mqtt/config.tpl.json +3 -5
  35. package/com/mqtt/drive.js +676 -0
  36. package/com/mqtt/index.js +822 -0
  37. package/com/mqtt/mm_mqtt.js +425 -0
  38. package/com/mqtt/script.tpl.js +723 -0
  39. package/com/nav/com.json +5 -0
  40. package/com/nav/config.tpl.json +84 -0
  41. package/com/nav/drive.js +702 -0
  42. package/com/nav/index.js +231 -0
  43. package/{core/com → com}/nav/tpl/admin_pc/page_config.vue +280 -280
  44. package/{core/com → com}/nav/tpl/admin_pc/page_config_form.vue +194 -194
  45. package/com/nav/tpl/admin_pc/page_form.vue +180 -0
  46. package/com/nav/tpl/admin_pc/page_view.vue +124 -0
  47. package/com/nav/tpl/dev_pc/page_default.vue +247 -0
  48. package/com/nav/tpl/dev_pc/page_type.vue +313 -0
  49. package/com/nav/tpl/home_pc/page_default.vue +234 -0
  50. package/com/nav/tpl/home_pc/page_form.vue +137 -0
  51. package/com/nav/tpl/home_pc/page_list.vue +234 -0
  52. package/com/nav/tpl/home_pc/page_nav.vue +221 -0
  53. package/com/nav/tpl/home_pc/page_type.vue +234 -0
  54. package/com/nav/tpl/home_pc/page_view.vue +125 -0
  55. package/com/nav/tpl/home_phone/page_channel.vue +234 -0
  56. package/com/nav/tpl/home_phone/page_default.vue +234 -0
  57. package/com/nav/tpl/home_phone/page_form.vue +137 -0
  58. package/com/nav/tpl/home_phone/page_nav.vue +237 -0
  59. package/com/nav/tpl/home_phone/page_type.vue +234 -0
  60. package/com/nav/tpl/home_phone/page_view.vue +125 -0
  61. package/com/nav/viewmodel.js +446 -0
  62. package/com/param/com.json +5 -0
  63. package/{core/com → com}/param/config.tpl.json +7 -1
  64. package/com/param/drive.js +502 -0
  65. package/com/param/index.js +155 -0
  66. package/com/param/script.tpl.js +12 -0
  67. package/com/pendant/com.json +5 -0
  68. package/{core/com/component → com/pendant}/config.tpl.json +15 -13
  69. package/com/pendant/drive.js +204 -0
  70. package/com/pendant/index.js +441 -0
  71. package/com/pendant/pendant.html +16 -0
  72. package/com/pendant/script.tpl.js +18 -0
  73. package/com/socket/com.json +5 -0
  74. package/com/socket/config.tpl.json +12 -0
  75. package/com/socket/drive.js +651 -0
  76. package/com/socket/index.js +351 -0
  77. package/com/socket/script.tpl.js +41 -0
  78. package/com/sql/com.json +5 -0
  79. package/{core/com → com}/sql/config.tpl.json +13 -9
  80. package/com/sql/drive.js +1259 -0
  81. package/com/sql/index.js +150 -0
  82. package/com/sql/script.tpl.js +47 -0
  83. package/com/static/com.json +5 -0
  84. package/{core/com → com}/static/config.tpl.json +10 -6
  85. package/com/static/drive.js +194 -0
  86. package/com/static/index.js +226 -0
  87. package/com/static/script.tpl.js +28 -0
  88. package/com/task/com.json +5 -0
  89. package/{core/com → com}/task/config.tpl.json +4 -6
  90. package/com/task/drive.js +405 -0
  91. package/com/task/index.js +148 -0
  92. package/com/task/script.tpl.js +37 -0
  93. package/com/template/com.json +5 -0
  94. package/com/template/config.tpl.json +16 -0
  95. package/com/template/drive.js +80 -0
  96. package/com/template/index.js +141 -0
  97. package/com.js +156 -0
  98. package/common/README.md +2 -0
  99. package/common/handler/msg/handler.json +22 -0
  100. package/common/handler/msg/index.js +23 -0
  101. package/common/handler/player/handler.json +22 -0
  102. package/common/handler/player/index.js +287 -0
  103. package/common/handler/user/handler.json +22 -0
  104. package/common/handler/user/index.js +23 -0
  105. package/common/middleware/web_after/index.js +29 -0
  106. package/common/middleware/web_after/middleware.json +9 -0
  107. package/common/middleware/web_base/index.js +113 -0
  108. package/common/middleware/web_base/middleware.json +19 -0
  109. package/common/middleware/web_before/index.js +33 -0
  110. package/common/middleware/web_before/middleware.json +9 -0
  111. package/common/middleware/web_cors/index.js +87 -0
  112. package/common/middleware/web_cors/middleware.json +24 -0
  113. package/common/middleware/web_error/index.js +119 -0
  114. package/common/middleware/web_error/middleware.json +18 -0
  115. package/common/middleware/web_ip/index.js +15 -0
  116. package/common/middleware/web_ip/middleware.json +14 -0
  117. package/common/middleware/web_logger/index.js +156 -0
  118. package/common/middleware/web_logger/middleware.json +14 -0
  119. package/common/middleware/web_main/index.js +24 -0
  120. package/common/middleware/web_main/middleware.json +9 -0
  121. package/common/middleware/web_static/index.js +73 -0
  122. package/common/middleware/web_static/middleware.json +54 -0
  123. package/common/middleware/web_waf/index.js +385 -0
  124. package/common/middleware/web_waf/middleware.json +13 -0
  125. package/common/model/msg/index.js +88 -0
  126. package/common/model/msg/model.json +401 -0
  127. package/common/model/player/index.js +63 -0
  128. package/common/model/player/model.json +185 -0
  129. package/common/model/user/index.js +11 -0
  130. package/common/model/user/model.json +219 -0
  131. package/core/app/config.tpl.json +67 -0
  132. package/core/app/index.js +632 -0
  133. package/core/app/script.tpl.js +52 -0
  134. package/core/channel/index.js +899 -0
  135. package/core/channel/matcher.js +585 -0
  136. package/core/com/config.tpl.json +16 -0
  137. package/core/com/index.js +74 -0
  138. package/core/com/script.tpl.js +5 -0
  139. package/core/component/component.js +42 -0
  140. package/core/component/config.tpl.json +63 -0
  141. package/core/component/index.js +273 -0
  142. package/core/component/script.tpl.js +19 -0
  143. package/core/controller/config.tpl.json +14 -0
  144. package/core/controller/index.js +373 -0
  145. package/core/controller/script.tpl.js +27 -0
  146. package/core/factory/config.tpl.json +14 -0
  147. package/core/factory/entity.js +275 -0
  148. package/core/factory/index.js +241 -0
  149. package/core/factory/script.tpl.js +16 -0
  150. package/core/game/bat/index.js +137 -0
  151. package/core/game/bat/world.js +622 -0
  152. package/core/game/config.tpl.json +16 -0
  153. package/core/game/entity_admin.js +230 -0
  154. package/core/game/index.js +186 -0
  155. package/core/handler/config.tpl.json +22 -0
  156. package/core/handler/index.js +181 -0
  157. package/core/handler/script.tpl.js +23 -0
  158. package/core/logic/config.tpl.json +14 -0
  159. package/core/logic/index.js +59 -0
  160. package/core/logic/script.tpl.js +19 -0
  161. package/core/middleware/config.tpl.json +16 -0
  162. package/core/middleware/index.js +125 -0
  163. package/core/middleware/script.tpl.js +37 -0
  164. package/core/mod/config.tpl.json +22 -0
  165. package/core/mod/index.js +130 -0
  166. package/core/mod/script.tpl.js +34 -0
  167. package/core/model/config.tpl.json +219 -0
  168. package/core/model/index.js +272 -0
  169. package/core/model/model.js +27 -0
  170. package/core/model/script.tpl.js +20 -0
  171. package/core/notifier/config.tpl.json +14 -0
  172. package/core/notifier/index.js +77 -0
  173. package/core/notifier/script.tpl.js +20 -0
  174. package/core/plugin/config.tpl.json +24 -0
  175. package/core/plugin/index.js +232 -0
  176. package/core/plugin/script.tpl.js +51 -0
  177. package/core/pusher/config.tpl.json +14 -0
  178. package/core/pusher/index.js +161 -0
  179. package/core/pusher/script.tpl.js +20 -0
  180. package/core/room/bat/index.js +170 -0
  181. package/core/room/bat/room.js +524 -0
  182. package/core/room/config.tpl.json +20 -0
  183. package/core/room/index.js +249 -0
  184. package/core/room/room.js +61 -0
  185. package/core/scene/config.tpl.json +14 -0
  186. package/core/scene/index.js +466 -0
  187. package/core/scene/loop.js +1255 -0
  188. package/core/scene/map.js +28 -0
  189. package/core/scene/script.tpl.js +22 -0
  190. package/core/sender/config.tpl.json +14 -0
  191. package/core/sender/index.js +79 -0
  192. package/core/sender/script.tpl.js +20 -0
  193. package/core/service/config.tpl.json +14 -0
  194. package/core/service/index.js +100 -0
  195. package/core/service/script.tpl.js +25 -0
  196. package/core/store/config.tpl.json +26 -0
  197. package/core/store/index.js +1755 -0
  198. package/core/store/script.tpl.js +22 -0
  199. package/core/store/sql.js +1464 -0
  200. package/core/system/config.tpl.json +18 -0
  201. package/core/system/index.js +312 -0
  202. package/core/system/script.tpl.js +77 -0
  203. package/core/view/config.tpl.json +14 -0
  204. package/core/view/index.js +91 -0
  205. package/core/view/script.tpl.js +20 -0
  206. package/core/zone/bat/index.js +725 -0
  207. package/core/zone/config.tpl.json +54 -0
  208. package/core/zone/index.js +614 -0
  209. package/core/zone/script.tpl.js +10 -0
  210. package/core/zone/zone_bat.js +136 -0
  211. package/core//345/237/272/347/261/273/346/250/241/345/235/227/346/270/205/345/215/225.md +24 -0
  212. package/index.js +17 -333
  213. package/os.js +57 -0
  214. package/package.json +65 -55
  215. package/server.js +598 -0
  216. package/README.en.md +0 -36
  217. package/conf.json +0 -3
  218. package/core/base/mqtt/index.js +0 -1110
  219. package/core/base/mqtt/lib.js +0 -40
  220. package/core/base/web/index.js +0 -245
  221. package/core/com/api/com.json +0 -4
  222. package/core/com/api/drive.js +0 -668
  223. package/core/com/api/index.js +0 -108
  224. package/core/com/api/oauth.js +0 -158
  225. package/core/com/api/script.js +0 -32
  226. package/core/com/app/README.md +0 -3
  227. package/core/com/app/com.json +0 -4
  228. package/core/com/app/config.tpl.json +0 -16
  229. package/core/com/app/drive.js +0 -309
  230. package/core/com/app/index.js +0 -211
  231. package/core/com/app/script.js +0 -155
  232. package/core/com/cmd/com.json +0 -4
  233. package/core/com/cmd/config.tpl.json +0 -66
  234. package/core/com/cmd/drive.js +0 -513
  235. package/core/com/cmd/index.js +0 -354
  236. package/core/com/cmd/old/5w2h.js +0 -54
  237. package/core/com/cmd/old/drive.js +0 -423
  238. package/core/com/cmd/script.js +0 -11
  239. package/core/com/component/README.md +0 -3
  240. package/core/com/component/com.json +0 -4
  241. package/core/com/component/component.html +0 -16
  242. package/core/com/component/drive.js +0 -197
  243. package/core/com/component/index.js +0 -312
  244. package/core/com/component/script.js +0 -18
  245. package/core/com/db/com.json +0 -4
  246. package/core/com/db/drive.js +0 -1160
  247. package/core/com/db/index.js +0 -176
  248. package/core/com/event/com.json +0 -4
  249. package/core/com/event/drive.js +0 -133
  250. package/core/com/event/index.js +0 -345
  251. package/core/com/event/script.js +0 -26
  252. package/core/com/eventer/com.js +0 -477
  253. package/core/com/eventer/com.json +0 -4
  254. package/core/com/middleware/com.js +0 -154
  255. package/core/com/middleware/com.json +0 -4
  256. package/core/com/middleware/config.tpl.json +0 -8
  257. package/core/com/middleware/script.js +0 -9
  258. package/core/com/mqtt/com.json +0 -4
  259. package/core/com/mqtt/drive.js +0 -600
  260. package/core/com/mqtt/index.js +0 -572
  261. package/core/com/mqtt/mm_mqtt.js +0 -330
  262. package/core/com/mqtt/script.js +0 -604
  263. package/core/com/msg/com.js +0 -296
  264. package/core/com/msg/com.json +0 -4
  265. package/core/com/nav/com.json +0 -4
  266. package/core/com/nav/config.tpl.json +0 -75
  267. package/core/com/nav/drive.js +0 -549
  268. package/core/com/nav/index.js +0 -182
  269. package/core/com/nav/tpl/admin_pc/page_form.vue +0 -180
  270. package/core/com/nav/tpl/admin_pc/page_view.vue +0 -124
  271. package/core/com/nav/tpl/dev_pc/page_default.vue +0 -247
  272. package/core/com/nav/tpl/dev_pc/page_type.vue +0 -313
  273. package/core/com/nav/tpl/home_pc/page_default.vue +0 -234
  274. package/core/com/nav/tpl/home_pc/page_form.vue +0 -137
  275. package/core/com/nav/tpl/home_pc/page_list.vue +0 -234
  276. package/core/com/nav/tpl/home_pc/page_nav.vue +0 -221
  277. package/core/com/nav/tpl/home_pc/page_type.vue +0 -234
  278. package/core/com/nav/tpl/home_pc/page_view.vue +0 -125
  279. package/core/com/nav/tpl/home_phone/page_channel.vue +0 -234
  280. package/core/com/nav/tpl/home_phone/page_default.vue +0 -234
  281. package/core/com/nav/tpl/home_phone/page_form.vue +0 -137
  282. package/core/com/nav/tpl/home_phone/page_nav.vue +0 -237
  283. package/core/com/nav/tpl/home_phone/page_type.vue +0 -234
  284. package/core/com/nav/tpl/home_phone/page_view.vue +0 -125
  285. package/core/com/nav/viewmodel.js +0 -296
  286. package/core/com/param/drive.js +0 -366
  287. package/core/com/param/index.js +0 -80
  288. package/core/com/param/script.js +0 -12
  289. package/core/com/param/test.js +0 -98
  290. package/core/com/plugin/README.md +0 -3
  291. package/core/com/plugin/com.json +0 -4
  292. package/core/com/plugin/config.tpl.json +0 -26
  293. package/core/com/plugin/drive.js +0 -536
  294. package/core/com/plugin/index.js +0 -259
  295. package/core/com/plugin/script.js +0 -213
  296. package/core/com/rpc/com.json +0 -4
  297. package/core/com/rpc/drive.js +0 -160
  298. package/core/com/rpc/index.js +0 -87
  299. package/core/com/rpc/rpc.js +0 -118
  300. package/core/com/socket/com.json +0 -4
  301. package/core/com/socket/config.tpl.json +0 -14
  302. package/core/com/socket/drive.js +0 -403
  303. package/core/com/socket/index.js +0 -62
  304. package/core/com/socket/script.js +0 -42
  305. package/core/com/sql/drive.js +0 -1087
  306. package/core/com/sql/index.js +0 -83
  307. package/core/com/sql/script.js +0 -48
  308. package/core/com/static/com.json +0 -4
  309. package/core/com/static/drive.js +0 -220
  310. package/core/com/static/index.js +0 -149
  311. package/core/com/static/script.js +0 -28
  312. package/core/com/task/com.json +0 -4
  313. package/core/com/task/drive.js +0 -403
  314. package/core/com/task/index.js +0 -110
  315. package/core/com/task/script.js +0 -37
  316. package/core/com/timer/com.js +0 -217
  317. package/core/com/timer/com.json +0 -4
  318. package/core/com/tpl/com.js +0 -19
  319. package/core/com/tpl/com.json +0 -4
  320. package/lib/actions.js +0 -50
  321. package/lib/base.js +0 -361
  322. package/lib/com.js +0 -29
  323. package/lib/ref.js +0 -121
  324. package/middleware/cors/index.js +0 -119
  325. package/middleware/cors/middleware.json +0 -20
  326. package/middleware/csrf/index.js +0 -202
  327. package/middleware/csrf/middleware.json +0 -24
  328. package/middleware/ip_firewall/index.js +0 -476
  329. package/middleware/ip_firewall/middleware.json +0 -109
  330. package/middleware/mqtt_base/index.js +0 -10
  331. package/middleware/mqtt_base/middleware.json +0 -11
  332. package/middleware/security_audit/index.js +0 -543
  333. package/middleware/security_audit/middleware.json +0 -48
  334. package/middleware/waf/index.js +0 -343
  335. package/middleware/waf/middleware.json +0 -10
  336. package/middleware/waf_ddos/index.js +0 -520
  337. package/middleware/waf_ddos/middleware.json +0 -38
  338. package/middleware/waf_xss/index.js +0 -269
  339. package/middleware/waf_xss/middleware.json +0 -18
  340. package/middleware/web_after/index.js +0 -33
  341. package/middleware/web_after/middleware.json +0 -10
  342. package/middleware/web_base/index.js +0 -90
  343. package/middleware/web_base/middleware.json +0 -10
  344. package/middleware/web_before/index.js +0 -27
  345. package/middleware/web_before/middleware.json +0 -10
  346. package/middleware/web_check/index.js +0 -28
  347. package/middleware/web_check/middleware.json +0 -10
  348. package/middleware/web_main/index.js +0 -28
  349. package/middleware/web_main/middleware.json +0 -10
  350. package/middleware/web_proxy/index.js +0 -37
  351. package/middleware/web_proxy/middleware.json +0 -10
  352. package/middleware/web_render/index.js +0 -87
  353. package/middleware/web_render/middleware.json +0 -10
  354. package/middleware/web_socket/index.js +0 -34
  355. package/middleware/web_socket/middleware.json +0 -10
  356. package/middleware/web_static/index.js +0 -115
  357. package/middleware/web_static/middleware.json +0 -10
  358. /package/{core/com → com}/api/README.md +0 -0
  359. /package/{core/com → com}/db/README.md +0 -0
  360. /package/{core/com → com}/mqtt/README.md +0 -0
  361. /package/{core/com → com}/nav/README.md +0 -0
  362. /package/{core/com → com}/nav/tpl/admin_pc/page_channel.vue +0 -0
  363. /package/{core/com → com}/nav/tpl/admin_pc/page_default.vue +0 -0
  364. /package/{core/com → com}/nav/tpl/admin_pc/page_lang.vue +0 -0
  365. /package/{core/com → com}/nav/tpl/admin_pc/page_nav.vue +0 -0
  366. /package/{core/com → com}/nav/tpl/admin_pc/page_table.vue +0 -0
  367. /package/{core/com → com}/nav/tpl/admin_pc/page_type.vue +0 -0
  368. /package/{core/com → com}/nav/tpl/dev_pc/page_channel.vue +0 -0
  369. /package/{core/com → com}/nav/tpl/dev_pc/page_config.vue +0 -0
  370. /package/{core/com → com}/nav/tpl/dev_pc/page_form.vue +0 -0
  371. /package/{core/com → com}/nav/tpl/dev_pc/page_nav.vue +0 -0
  372. /package/{core/com → com}/nav/tpl/dev_pc/page_table.vue +0 -0
  373. /package/{core/com → com}/nav/tpl/home_pc/page_channel.vue +0 -0
  374. /package/{core/com → com}/nav/tpl/home_phone/page_list.vue +0 -0
  375. /package/{core/com → com}/param/README.md +0 -0
  376. /package/{core/com/cmd → com/pendant}/README.md +0 -0
  377. /package/{core/com → com}/socket/README.md +0 -0
  378. /package/{core/com → com}/sql/README.md +0 -0
  379. /package/{core/com → com}/static/README.md +0 -0
  380. /package/{core/com → com}/task/README.md +0 -0
@@ -1,269 +0,0 @@
1
- const mm_expand = require('mm_expand');
2
-
3
- /**
4
- * XSS攻击防护中间件
5
- */
6
- class Middleware {
7
- /**
8
- * 构造函数
9
- */
10
- constructor() {
11
- this.default = {
12
- // 过滤模式: sanitize(清理) | encode(编码) | both(同时进行)
13
- mode: 'both',
14
- // 是否过滤URL参数
15
- query: true,
16
- // 是否过滤表单数据
17
- body: true,
18
- // 是否过滤Cookie
19
- cookie: true,
20
- // 白名单标签
21
- allowedTags: ['p', 'span', 'b', 'i', 'u', 'strong', 'em', 'br'],
22
- // 白名单属性
23
- allowedAttributes: ['id', 'class', 'style'],
24
- // 是否记录XSS攻击尝试
25
- log: true,
26
- // 是否阻止恶意请求
27
- block: true
28
- };
29
- }
30
-
31
- /**
32
- * 初始化中间件
33
- * @param {Object} config 配置项
34
- */
35
- init(config) {
36
- config = Object.assign({}, this.default, config);
37
- this.config = config;
38
- return function() {
39
- // 返回中间件的run方法作为实际的处理函数
40
- return function(ctx, next) {
41
- return middleware.run(ctx, next);
42
- };
43
- };
44
- }
45
-
46
- /**
47
- * 获取客户端真实IP
48
- * 在代理环境中,优先从代理头获取真实IP
49
- * @param {Object} ctx Koa上下文
50
- * @returns {String} 客户端真实IP
51
- */
52
- getClientIp(ctx) {
53
- const headers = ctx.headers;
54
- // 优先检查常用代理头获取真实IP
55
- // 注意:X-Forwarded-For 可能包含多个IP,取第一个非未知IP的值
56
- const xForwardedFor = headers['x-forwarded-for'];
57
- if (xForwardedFor) {
58
- // X-Forwarded-For 格式通常为: client, proxy1, proxy2
59
- const ips = xForwardedFor.split(',').map(ip => ip.trim());
60
- for (let i = 0; i < ips.length; i++) {
61
- const ip = ips[i];
62
- if (ip && ip !== 'unknown' && ip !== '127.0.0.1' && ip !== '::1') {
63
- return ip;
64
- }
65
- }
66
- }
67
-
68
- // 检查其他常见的代理头
69
- return headers['x-real-ip'] ||
70
- headers['x-client-ip'] ||
71
- headers['cf-connecting-ip'] || // CloudFlare
72
- headers['fastly-client-ip'] || // Fastly
73
- headers['true-client-ip'] || // Akamai and Cloudflare
74
- ctx.ip; // 默认回退到ctx.ip
75
- }
76
-
77
- /**
78
- * 执行中间件
79
- * @param {Object} ctx Koa上下文
80
- * @param {Function} next 下一个中间件
81
- */
82
- async run(ctx, next) {
83
- const config = this.config;
84
- let hasXSS = false;
85
- let attackInfo = {};
86
-
87
- // 清理URL查询参数
88
- if (config.query && ctx.query) {
89
- for (let key in ctx.query) {
90
- const original = ctx.query[key];
91
- const sanitized = this.sanitizeInput(original, config);
92
- if (original !== sanitized) {
93
- ctx.query[key] = sanitized;
94
- hasXSS = true;
95
- attackInfo[`query.${key}`] = { original, sanitized };
96
- }
97
- }
98
- }
99
-
100
- // 清理请求体数据
101
- if (config.body && ctx.request.body) {
102
- this.cleanObject(ctx.request.body, config, attackInfo, 'body', hasXSS);
103
- }
104
-
105
- // 清理Cookie
106
- if (config.cookie && ctx.cookies) {
107
- const cookies = ctx.headers.cookie;
108
- if (cookies) {
109
- // 记录Cookie中的XSS尝试但不修改,因为修改Cookie需要重新设置
110
- const cookieArr = cookies.split(';');
111
- for (let cookie of cookieArr) {
112
- const [name, value] = cookie.split('=').map(item => item.trim());
113
- const sanitized = this.sanitizeInput(decodeURIComponent(value), config);
114
- if (value !== sanitized) {
115
- hasXSS = true;
116
- attackInfo[`cookie.${name}`] = { original: value, sanitized };
117
- }
118
- }
119
- }
120
- }
121
-
122
- // 记录XSS攻击尝试
123
- if (hasXSS && config.log && $.log) {
124
- $.log.warn('XSS Attack Attempt Detected:', {
125
- ip: this.getClientIp(ctx),
126
- path: ctx.path,
127
- method: ctx.method,
128
- attackInfo
129
- });
130
- }
131
-
132
- // 阻止恶意请求
133
- if (hasXSS && config.block) {
134
- ctx.status = 403;
135
- ctx.body = {
136
- code: 403,
137
- msg: 'Forbidden: Potential XSS attack detected'
138
- };
139
- return;
140
- }
141
-
142
- // 添加安全响应头
143
- this.addSecurityHeaders(ctx);
144
-
145
- await next();
146
- }
147
-
148
- /**
149
- * 递归清理对象中的XSS内容
150
- * @param {Object} obj 要清理的对象
151
- * @param {Object} config 配置项
152
- * @param {Object} attackInfo 攻击信息收集对象
153
- * @param {String} prefix 路径前缀
154
- * @param {Boolean} hasXSS 是否已发现XSS
155
- */
156
- cleanObject(obj, config, attackInfo, prefix, hasXSS) {
157
- if (!obj || typeof obj !== 'object') return;
158
-
159
- for (let key in obj) {
160
- const path = `${prefix}.${key}`;
161
- if (typeof obj[key] === 'string') {
162
- const original = obj[key];
163
- const sanitized = this.sanitizeInput(original, config);
164
- if (original !== sanitized) {
165
- obj[key] = sanitized;
166
- hasXSS = true;
167
- attackInfo[path] = { original, sanitized };
168
- }
169
- } else if (typeof obj[key] === 'object') {
170
- this.cleanObject(obj[key], config, attackInfo, path, hasXSS);
171
- }
172
- }
173
- }
174
-
175
- /**
176
- * 清理输入内容
177
- * @param {String} input 输入内容
178
- * @param {Object} config 配置项
179
- * @returns {String} 清理后的内容
180
- */
181
- sanitizeInput(input, config) {
182
- if (!input || typeof input !== 'string') return input;
183
-
184
- let output = input;
185
-
186
- // 根据模式选择清理方式
187
- if (config.mode === 'sanitize' || config.mode === 'both') {
188
- output = this.sanitizeHTML(output, config);
189
- }
190
-
191
- if (config.mode === 'encode' || config.mode === 'both') {
192
- output = this.encodeHTML(output);
193
- }
194
-
195
- return output;
196
- }
197
-
198
- /**
199
- * 清理HTML内容
200
- * @param {String} html HTML内容
201
- * @param {Object} config 配置项
202
- * @returns {String} 清理后的内容
203
- */
204
- sanitizeHTML(html, config) {
205
- // 简单的HTML标签清理实现
206
- // 在生产环境中,可以使用更强大的库如DOMPurify
207
- let clean = html;
208
-
209
- // 移除所有脚本标签
210
- clean = clean.replace(/<script[^>]*>.*?<\/script>/gi, '');
211
-
212
- // 移除所有事件处理器
213
- clean = clean.replace(/\s+on\w+\s*=\s*["\']?[^"\'>\s]+/gi, '');
214
-
215
- // 移除危险的URL协议
216
- clean = clean.replace(/(src|href|data|action)\s*=\s*["\']?(javascript|data|vbscript):/gi, '$1=');
217
-
218
- return clean;
219
- }
220
-
221
- /**
222
- * 编码HTML特殊字符
223
- * @param {String} html HTML内容
224
- * @returns {String} 编码后的内容
225
- */
226
- encodeHTML(html) {
227
- return String(html)
228
- .replace(/&/g, '&amp;')
229
- .replace(/</g, '&lt;')
230
- .replace(/>/g, '&gt;')
231
- .replace(/"/g, '&quot;')
232
- .replace(/'/g, '&#39;');
233
- }
234
-
235
- /**
236
- * 添加安全响应头
237
- * @param {Object} ctx Koa上下文
238
- */
239
- addSecurityHeaders(ctx) {
240
- // X-XSS-Protection 头
241
- ctx.set('X-XSS-Protection', '1; mode=block');
242
-
243
- // Content-Security-Policy 头
244
- ctx.set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;");
245
- }
246
- }
247
-
248
- // 创建中间件实例
249
- const middleware = new Middleware();
250
-
251
- // 导出符合系统期望的函数
252
- exports = module.exports = function(server, config) {
253
- // 初始化中间件
254
- const handlerFactory = middleware.init(config);
255
- const middlewareHandler = handlerFactory();
256
-
257
- // 直接使用server.use注册中间件
258
- server.use(middlewareHandler);
259
-
260
- // 记录中间件初始化信息
261
- if ($.log && $.log.info) {
262
- $.log.info(`XSS防护中间件已加载: 模式=${middleware.config.mode}, 过滤=${middleware.config.query ? 'query' : ''}${middleware.config.body ? ' body' : ''}${middleware.config.cookie ? ' cookie' : ''}`);
263
- }
264
-
265
- return server;
266
- };
267
-
268
- // 保留原始实例,以便其他方式调用
269
- exports.middleware = middleware;
@@ -1,18 +0,0 @@
1
- {
2
- "name": "waf_xss",
3
- "title": "XSS攻击防护中间件",
4
- "type": "web_before",
5
- "state": 1,
6
- "sort": 10,
7
- "desc": "提供全面的XSS攻击防护,包括输入过滤和安全响应头设置",
8
- "config": {
9
- "mode": "both",
10
- "query": true,
11
- "body": true,
12
- "cookie": true,
13
- "allowedTags": ["p", "span", "b", "i", "u", "strong", "em", "br"],
14
- "allowedAttributes": ["id", "class", "style"],
15
- "log": true,
16
- "block": true
17
- }
18
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * web请求之后
3
- * @param {Object} server 服务
4
- * @param {Object} config 配置参数
5
- */
6
- module.exports = function(server, config) {
7
- server.use(async (ctx, next) => {
8
- try {
9
- // 先让其他中间件执行
10
- await next();
11
-
12
- // 然后执行after逻辑
13
- try {
14
- if (ctx.path !== "/favicon.ico") {
15
- await $.eventer.run('web_after', ctx, ctx.db);
16
- var event = $.event_admin('api');
17
- var ret = await event.after(ctx.path, ctx, ctx.db);
18
- if (ret) {
19
- ctx.body = ret;
20
- }
21
- }
22
- } catch (afterError) {
23
- $.log.error('web_after事件执行错误:', afterError);
24
- // 即使after事件出错,也不影响响应结果
25
- }
26
- } catch (error) {
27
- $.log.error('web_after中间件错误:', error);
28
- // 注意:这里不需要再次调用next(),因为已经在try块中调用过了
29
- }
30
- });
31
-
32
- return server;
33
- };
@@ -1,10 +0,0 @@
1
- {
2
- "name": "web_after",
3
- "title": "web请求后",
4
- "description": "用于追加处理",
5
- "version": "1.0",
6
- "type": "web",
7
- "process_type": "common_before",
8
- "sort": 150,
9
- "state": 1
10
- }
@@ -1,90 +0,0 @@
1
- const xmlParser = require("mm_xml");
2
- const session = require('mm_session');
3
- const compress = require('koa-compress');
4
- const { koaBody } = require('koa-body');
5
- const send = require('koa-send');
6
-
7
- /**
8
- * web基础
9
- * @param {Object} server 服务
10
- * @param {Object} config 配置参数
11
- */
12
- module.exports = function(server, config) {
13
- /**
14
- * 发送文件
15
- */
16
- server.use(async (ctx, next) => {
17
- try {
18
- ctx.send = async function(src) {
19
- try {
20
- await send(ctx, src);
21
- } catch (sendError) {
22
- $.log.error('文件发送错误:', sendError);
23
- // 可以选择抛出错误让上层处理,或者静默处理
24
- throw sendError;
25
- }
26
- }
27
- await next();
28
- } catch (error) {
29
- $.log.error('web_base中间件(文件发送设置)错误:', error);
30
- // 出错时默认允许请求继续处理
31
- await next();
32
- }
33
- });
34
-
35
- // 设置session 保存时长2小时
36
- server.use(session({
37
- maxAge: $.login_period || config.maxAge || 7200
38
- }));
39
-
40
- // 使用压缩
41
- if (config.compress) {
42
- server.use(
43
- compress({
44
- filter: function(content_type) {
45
- // 只有在请求的content-type中有gzip类型,我们才会考虑压缩,因为zlib是压缩成gzip类型的
46
- return /text/i.test(content_type);
47
- },
48
- // 阀值,当数据超过1kb的时候,可以压缩
49
- threshold: 1024,
50
- // zlib是node的压缩模块
51
- flush: require('zlib').Z_SYNC_FLUSH
52
- })
53
- );
54
- }
55
-
56
- // 解析 text/xml
57
- server.use(xmlParser());
58
-
59
- var func = koaBody({
60
- jsonLimit: config.jsonLimit || '20mb',
61
- multipart: true,
62
- formidable: {
63
- // 设置上传文件大小最大限制,默认20M
64
- maxFileSize: 2000 * 1024 * 1024
65
- }
66
- });
67
-
68
- // 解析 application/json、application/x-www-form-urlencoded、text/plain
69
- // 接收主体
70
- server.use(async (ctx, next) => {
71
- try {
72
- if (!ctx.request.body) {
73
- try {
74
- await func(ctx, next);
75
- } catch (parseError) {
76
- $.log.error('请求体解析错误:', parseError);
77
- // 解析错误时,确保请求继续处理
78
- await next();
79
- }
80
- } else {
81
- await next();
82
- }
83
- } catch (error) {
84
- $.log.error('web_base中间件(请求体解析)错误:', error);
85
- // 出错时默认允许请求继续处理
86
- await next();
87
- }
88
- });
89
- return server;
90
- };
@@ -1,10 +0,0 @@
1
- {
2
- "name": "web_base",
3
- "title": "web基本功能",
4
- "description": "用于网站常规功能",
5
- "version": "1.0",
6
- "type": "web",
7
- "process_type": "common_before",
8
- "sort": 70,
9
- "state": 1
10
- }
@@ -1,27 +0,0 @@
1
- /**
2
- * web请求之前
3
- * @param {Object} server 服务
4
- * @param {Object} config 配置参数
5
- */
6
- module.exports = function(server, config) {
7
- // 使用路由(主要)
8
- server.use(async (ctx, next) => {
9
- if (!ctx.db) {
10
- ctx.db = {
11
- ret: null
12
- };
13
- }
14
- if (ctx.path !== "/favicon.ico") {
15
- await $.eventer.run('web_before', ctx, ctx.db);
16
- var event = $.event_admin('api');
17
- var ret = await event.before(ctx.path, ctx, ctx.db);
18
- // console.log("before阶段", ret);
19
- if (ret) {
20
- ctx.body = ret;
21
- }
22
- }
23
- await next();
24
- });
25
-
26
- return server;
27
- };
@@ -1,10 +0,0 @@
1
- {
2
- "name": "web_before",
3
- "title": "web请求前",
4
- "description": "用于",
5
- "version": "1.0",
6
- "type": "web",
7
- "process_type": "common_before",
8
- "sort": 80,
9
- "state": 1
10
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * web验证
3
- * @param {Object} server 服务
4
- * @param {Object} config 配置参数
5
- */
6
- module.exports = function(server, config) {
7
- // 使用路由(主要)
8
- server.use(async (ctx, next) => {
9
- try {
10
- if (ctx.path !== "/favicon.ico") {
11
- await $.eventer.run('web_check', ctx, ctx.db);
12
- var event = $.event_admin('api');
13
- var ret = await event.check(ctx.path, ctx, ctx.db);
14
- // console.log("check阶段", ret);
15
- if (ret) {
16
- ctx.body = ret;
17
- }
18
- }
19
- await next();
20
- } catch (error) {
21
- $.log.error('web_check中间件错误:', error);
22
- // 确保请求可以继续处理
23
- await next();
24
- }
25
- });
26
-
27
- return server;
28
- };
@@ -1,10 +0,0 @@
1
- {
2
- "name": "web_check",
3
- "title": "web请求验证",
4
- "description": "用于验证请求,拦截不符合调条件的请求",
5
- "version": "1.0",
6
- "type": "web",
7
- "process_type": "common_before",
8
- "sort": 90,
9
- "state": 1
10
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * web请求
3
- * @param {Object} server 服务
4
- * @param {Object} config 配置参数
5
- */
6
- module.exports = function(server, config) {
7
- // 使用路由(主要)
8
- server.use(async (ctx, next) => {
9
- try {
10
- if (ctx.path !== "/favicon.ico") {
11
- await $.eventer.run('web_main', ctx, ctx.db);
12
- var event = $.event_admin('api');
13
- var ret = await event.main(ctx.path, ctx, ctx.db);
14
- // console.log("main阶段", ret);
15
- if (ret) {
16
- ctx.body = ret;
17
- }
18
- }
19
- await next();
20
- } catch (error) {
21
- $.log.error('web_main中间件错误:', error);
22
- // 确保请求可以继续处理
23
- await next();
24
- }
25
- });
26
-
27
- return server;
28
- };
@@ -1,10 +0,0 @@
1
- {
2
- "name": "web_main",
3
- "title": "web请求主要",
4
- "description": "用于处理主要请求",
5
- "version": "1.0",
6
- "type": "web",
7
- "process_type": "common_before",
8
- "sort": 100,
9
- "state": 1
10
- }
@@ -1,37 +0,0 @@
1
- const {
2
- proxy,
3
- proxyTo,
4
- isMatch
5
- } = require('mm_koa_proxy');
6
-
7
- /**
8
- * 代理请求
9
- * @param {Object} server 服务
10
- * @param {Object} config 配置参数
11
- */
12
- module.exports = function(server, config) {
13
- if (config && config.proxy) {
14
- var options = config.proxy;
15
- if (options.targets) {
16
- server.use(async (ctx, next) => {
17
- try {
18
- // 先设置用户信息头
19
- if (ctx.session && ctx.session.user) {
20
- ctx.request.header['user_id'] = ctx.session.user.user_id;
21
- }
22
- // 创建一个代理处理器
23
- const proxyHandler = proxy(options, function(op, ctxProxy, nextProxy) {
24
- return nextProxy();
25
- });
26
- // 执行代理
27
- await proxyHandler(ctx, next);
28
- } catch (error) {
29
- $.log.error('web_proxy中间件错误:', error);
30
- // 出错时默认允许请求继续处理
31
- await next();
32
- }
33
- });
34
- }
35
- }
36
- return server;
37
- };
@@ -1,10 +0,0 @@
1
- {
2
- "name": "web_proxy",
3
- "title": "web代理服务",
4
- "description": "用于将特定路由转发到别的服务端上做处理",
5
- "version": "1.0",
6
- "type": "web",
7
- "process_type": "worker",
8
- "sort": 110,
9
- "state": 1
10
- }
@@ -1,87 +0,0 @@
1
- /**
2
- * 调用函数
3
- * @param {Object} ret 设置响应结果
4
- * @param {Object} res 响应器
5
- * @param {String} t 请求类型
6
- * @return {String} 处理后的响应结果
7
- */
8
- function render_body(ret, res, t) {
9
- var type;
10
- if (res.type) {
11
- type = res.type;
12
- }
13
- var tp = typeof(ret);
14
- if (tp === "object") {
15
- if (!type) {
16
- /// 设置响应头
17
- if (t.indexOf('xml') !== -1) {
18
- type = t;
19
- } else {
20
- type = "application/json; charset=utf-8";
21
- }
22
- res.type = type;
23
- } else {
24
- if (type.indexOf('json') !== -1) {
25
- type = "application/json; charset=utf-8";
26
- } else if (type.indexOf('html') !== -1) {
27
- type = "text/html";
28
- } else if (type.indexOf('xml') !== -1) {
29
- type = "text/xml; charset=utf-8";
30
- } else {
31
- type = "text/plain; charset=utf-8";
32
- }
33
- res.type = type;
34
- }
35
-
36
- if (type.indexOf('/xml') !== -1) {
37
- return $.toXml(ret);
38
- } else {
39
- return JSON.stringify(ret);
40
- }
41
- } else if (tp === "string") {
42
- ret = ret.trim();
43
- if (!type) {
44
- if (ret.startWith('{') && ret.endWith('}')) {
45
- res.type = "application/json; charset=utf-8";
46
- } else if (ret.startWith('[') && ret.endWith(']')) {
47
- res.type = "application/json; charset=utf-8";
48
- } else if (ret.endWith("</html>")) {
49
- res.type = "text/html";
50
- } else {
51
- res.type = "text/plain; charset=utf-8";
52
- }
53
- }
54
- }
55
- return ret;
56
- };
57
-
58
- /**
59
- * web渲染
60
- * @param {Object} server 服务
61
- * @param {Object} config 配置参数
62
- */
63
- module.exports = function(server, config) {
64
- // 使用路由(主要)
65
- server.use(async (ctx, next) => {
66
- try {
67
- if (ctx.path !== "/favicon.ico") {
68
- await $.eventer.run('web_render', ctx, ctx.db);
69
- var event = $.event_admin('api');
70
- var ret = await event.render(ctx.path, ctx, ctx.db);
71
- if (!ctx.body && ret) {
72
- ctx.body = ret;
73
- }
74
- if (ctx.body) {
75
- ctx.body = render_body(ctx.body, ctx.response, ctx.request.type);
76
- }
77
- }
78
- await next();
79
- } catch (error) {
80
- $.log.error('web_render中间件错误:', error);
81
- // 确保请求可以继续处理
82
- await next();
83
- }
84
- });
85
-
86
- return server;
87
- };