commit 314eee72f23f52b8d0dfd75795ffe51353e92b26
Author: yi-ge
Date: Mon Sep 2 14:14:55 2019 +0800
0.1.1
diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..f1cae39
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,10 @@
+{
+ "presets": [
+ ["@babel/preset-env", {
+ "targets": {
+ "node": "5.12.0"
+ }
+ }]
+ ],
+ "plugins": ["@babel/plugin-transform-runtime"]
+}
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fae9b0a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,64 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# TypeScript v1 declaration files
+typings/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# binary out
+bin
+
+# VS Code
+.vscode
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a5ae341
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Yige
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..072da9d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Server Monitor
+
+Server monitor.
diff --git a/check.php b/check.php
new file mode 100644
index 0000000..9df3eed
--- /dev/null
+++ b/check.php
@@ -0,0 +1,67 @@
+ 2147483646 || $versionB > 2147483646) {
+ throw new Exception('版本号,位数太大暂不支持!', '101');
+ }
+ $dm = '.';
+ $verListA = explode($dm, (string) $versionA);
+ $verListB = explode($dm, (string) $versionB);
+
+ $len = max(count($verListA), count($verListB));
+ $i = -1;
+ while ($i++ < $len) {
+ $verListA[$i] = intval(@$verListA[$i]);
+ if ($verListA[$i] < 0) {
+ $verListA[$i] = 0;
+ }
+ $verListB[$i] = intval(@$verListB[$i]);
+ if ($verListB[$i] < 0) {
+ $verListB[$i] = 0;
+ }
+
+ if ($verListA[$i] > $verListB[$i]) {
+ return 1;
+ } else if ($verListA[$i] < $verListB[$i]) {
+ return -1;
+ } else if ($i == ($len - 1)) {
+ return 0;
+ }
+ }
+}
+
+$version = $_GET['version'];
+$latestVersion = "0.1.1";
+
+if (versionCompare($version, $latestVersion) < 0) {
+ $result = [
+ 'status' => 1,
+ 'downloadURL' => 'https://tool.y-bi.top/server-monitor-xp-' . $latestVersion . '.zip',
+ 'newVersion' => $latestVersion,
+ ];
+} else {
+ $result = [
+ 'status' => 0,
+ ];
+}
+
+header('Content-Type:application/json; charset=utf-8');
+
+echo json_encode($result, JSON_UNESCAPED_SLASHES);
diff --git a/config.yml b/config.yml
new file mode 100644
index 0000000..1f46042
--- /dev/null
+++ b/config.yml
@@ -0,0 +1,8 @@
+version: 0.1.1
+update-url: 'https://tool.y-bi.top/check.php'
+node:
+ version: 5.12.0
+ support-old-win: true
+ auto-restart: true
+ report-address:
+ - 'https://www.nodejs.pw'
diff --git a/dist/app.js b/dist/app.js
new file mode 100644
index 0000000..1637080
--- /dev/null
+++ b/dist/app.js
@@ -0,0 +1,26 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+var _config = require("./config");
+
+var _boot = _interopRequireDefault(require("./boot"));
+
+var _http = _interopRequireDefault(require("http"));
+
+var server = _http.default.createServer(function (req, res) {
+ res.statusCode = 200;
+ res.setHeader('Content-Type', 'application/json; charset=utf-8');
+ res.end(JSON.stringify({
+ status: 1
+ }));
+});
+
+(0, _boot.default)().then(function (r) {
+ // Start boot
+ server.listen(_config.SERVER.port, _config.SERVER.host, function () {
+ console.log(`Server running at http://${_config.SERVER.host}:${_config.SERVER.port}/`);
+ });
+}).catch(function (err) {
+ console.log(err);
+});
\ No newline at end of file
diff --git a/dist/boot.js b/dist/boot.js
new file mode 100644
index 0000000..e7e96b6
--- /dev/null
+++ b/dist/boot.js
@@ -0,0 +1,188 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
+
+var _fs = _interopRequireDefault(require("fs"));
+
+var _axios = _interopRequireDefault(require("axios"));
+
+var _package = _interopRequireDefault(require("../package.json"));
+
+var _crypto = _interopRequireDefault(require("crypto"));
+
+var _gather = _interopRequireDefault(require("./control/gather"));
+
+var version = _package.default.version;
+
+var request = _axios.default.create();
+
+var apiURLs = {
+ apiURL: process.env.API_URL,
+ apiKEY: process.env.API_KEY
+};
+var AGENT_VERSION = process.env.AGENT_VERSION;
+var AGENT_PORT = process.env.AGENT_PORT;
+var isDev = process.env.NODE_ENV !== 'production'; // 系统配置
+
+var rebootNodeJS =
+/*#__PURE__*/
+function () {
+ var _ref = (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee() {
+ var _ref2, data;
+
+ return _regenerator.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ if (!isDev) {
+ _context.next = 4;
+ break;
+ }
+
+ console.log('当前是开发环境,无法自动重启Node.js');
+ _context.next = 16;
+ break;
+
+ case 4:
+ _context.prev = 4;
+ _context.next = 7;
+ return request.get(`http://127.0.0.1:${AGENT_PORT}/system/cmd?action=restart`);
+
+ case 7:
+ _ref2 = _context.sent;
+ data = _ref2.data;
+ console.log('自动重启Node.js返回数据:', data);
+ _context.next = 16;
+ break;
+
+ case 12:
+ _context.prev = 12;
+ _context.t0 = _context["catch"](4);
+ console.log(_context.t0);
+ console.log('自动重启Node.js失败');
+
+ case 16:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee, null, [[4, 12]]);
+ }));
+
+ return function rebootNodeJS() {
+ return _ref.apply(this, arguments);
+ };
+}();
+
+var checkVersion =
+/*#__PURE__*/
+function () {
+ var _ref3 = (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee2(version) {
+ var apiURL, _ref4, data;
+
+ return _regenerator.default.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ apiURL = 'https://tool.y-bi.top/check.php?version=' + version;
+ _context2.next = 3;
+ return request.get(apiURL);
+
+ case 3:
+ _ref4 = _context2.sent;
+ data = _ref4.data;
+
+ if (!(data.status === 1)) {
+ _context2.next = 10;
+ break;
+ }
+
+ // 有更新
+ console.log('发现新版系统,正在重启Node.js...');
+ _context2.next = 9;
+ return rebootNodeJS();
+
+ case 9:
+ return _context2.abrupt("return", true);
+
+ case 10:
+ return _context2.abrupt("return", false);
+
+ case 11:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2);
+ }));
+
+ return function checkVersion(_x) {
+ return _ref3.apply(this, arguments);
+ };
+}();
+
+var fileIsExists = function fileIsExists(path) {
+ try {
+ _fs.default.accessSync(path);
+
+ return true;
+ } catch (_) {
+ return false;
+ }
+};
+
+var checkAndInstallWhoami = function checkAndInstallWhoami() {
+ if (!fileIsExists('C:\\Windows\\system32\\whoami.exe') && !fileIsExists('C:\\Windows\\system32\\whoami.bat')) {
+ console.log('whoami 命令不存在,正在写入');
+ var batContent = `@echo off
+echo %computername%\%username%
+exit /B`;
+
+ _fs.default.writeFileSync('C:\\Windows\\system32\\whoami.bat', batContent);
+ }
+};
+
+var _default =
+/*#__PURE__*/
+(0, _asyncToGenerator2.default)(
+/*#__PURE__*/
+_regenerator.default.mark(function _callee3() {
+ return _regenerator.default.wrap(function _callee3$(_context3) {
+ while (1) {
+ switch (_context3.prev = _context3.next) {
+ case 0:
+ console.log('AGENT_VERSION:', AGENT_VERSION);
+ checkAndInstallWhoami();
+ setInterval(function () {
+ checkVersion(version || '0.0.1'); // sync
+ }, 120000);
+ (0, _gather.default)({
+ version: version || '0.0.1',
+ apiURLs,
+ isDev,
+ AGENT_PORT,
+ AGENT_VERSION
+ }); // sync
+
+ case 4:
+ case "end":
+ return _context3.stop();
+ }
+ }
+ }, _callee3);
+}));
+
+exports.default = _default;
\ No newline at end of file
diff --git a/dist/config.js b/dist/config.js
new file mode 100644
index 0000000..399cd31
--- /dev/null
+++ b/dist/config.js
@@ -0,0 +1,24 @@
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.SERVER = exports.SYSTEM = void 0;
+
+var pack = require('../package');
+
+var isDev = process.env.NODE_ENV !== 'production'; // 系统配置
+
+var SYSTEM = {
+ version: pack.version,
+ sessionKey: process.env.JWT_SECRET || '123',
+ // 生产环境务必随机设置一个值
+ scheme: [isDev ? 'http' : 'https']
+};
+exports.SYSTEM = SYSTEM;
+var SERVER = {
+ port: isDev ? process.env.PORT || '65522' : process.env.PORT || '65522',
+ // API服务器监听的端口号
+ host: '0.0.0.0'
+};
+exports.SERVER = SERVER;
\ No newline at end of file
diff --git a/dist/control/gather.js b/dist/control/gather.js
new file mode 100644
index 0000000..4b592aa
--- /dev/null
+++ b/dist/control/gather.js
@@ -0,0 +1,91 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
+
+var _os = _interopRequireDefault(require("os"));
+
+var _axios = _interopRequireDefault(require("axios"));
+
+var _child_process = require("child_process");
+
+var request = _axios.default.create();
+
+var _default =
+/*#__PURE__*/
+function () {
+ var _ref = (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee2(conf) {
+ var gather;
+ return _regenerator.default.wrap(function _callee2$(_context2) {
+ while (1) {
+ switch (_context2.prev = _context2.next) {
+ case 0:
+ gather = function gather(conf) {
+ setTimeout(
+ /*#__PURE__*/
+ (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee() {
+ var who, version, apiURLs, AGENT_VERSION, _ref3, data;
+
+ return _regenerator.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ who = (0, _child_process.execSync)('whoami');
+ version = conf.version, apiURLs = conf.apiURLs, AGENT_VERSION = conf.AGENT_VERSION;
+ _context.next = 4;
+ return request.put(apiURLs.apiURL + 'gather', {
+ version,
+ AGENT_VERSION,
+ user: who.toString('utf8').trim('\r\n'),
+ arch: _os.default.arch(),
+ type: _os.default.type(),
+ platform: _os.default.platform()
+ });
+
+ case 4:
+ _ref3 = _context.sent;
+ data = _ref3.data;
+
+ if (data.status === 1) {
+ console.log('发现监控系统地址');
+ }
+
+ gather(conf);
+
+ case 8:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee);
+ })), 20000);
+ };
+
+ gather(conf);
+
+ case 2:
+ case "end":
+ return _context2.stop();
+ }
+ }
+ }, _callee2);
+ }));
+
+ return function (_x) {
+ return _ref.apply(this, arguments);
+ };
+}();
+
+exports.default = _default;
\ No newline at end of file
diff --git a/dist/dev.js b/dist/dev.js
new file mode 100644
index 0000000..ddbd867
--- /dev/null
+++ b/dist/dev.js
@@ -0,0 +1,5 @@
+"use strict";
+
+require('@babel/register');
+
+require('./app');
\ No newline at end of file
diff --git a/dist/service/home.js b/dist/service/home.js
new file mode 100644
index 0000000..cdf02b5
--- /dev/null
+++ b/dist/service/home.js
@@ -0,0 +1,44 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
+
+var _default = {
+ method: 'GET',
+ path: '/',
+ config: {
+ auth: false
+ },
+
+ handler() {
+ return (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee() {
+ return _regenerator.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ return _context.abrupt("return", {
+ status: 1,
+ massage: 'Please consult the API documentation.'
+ });
+
+ case 1:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee);
+ }))();
+ }
+
+};
+exports.default = _default;
\ No newline at end of file
diff --git a/dist/service/index.js b/dist/service/index.js
new file mode 100644
index 0000000..c3c7f6e
--- /dev/null
+++ b/dist/service/index.js
@@ -0,0 +1,32 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _fs = _interopRequireDefault(require("fs"));
+
+var _path = _interopRequireDefault(require("path"));
+
+var modules = [];
+
+var files = _fs.default.readdirSync(__dirname).filter(function (file) {
+ return file.match(/\.(json|js)$/);
+});
+
+files.forEach(function (key) {
+ if (key === 'index.js') return; // const content = require(path.join(__dirname, key)).default
+
+ var content = require(_path.default.join(__dirname, key)).default;
+
+ if (Array.isArray(content)) {
+ modules.push(...content);
+ } else {
+ modules.push(content);
+ }
+});
+var _default = modules;
+exports.default = _default;
\ No newline at end of file
diff --git a/dist/service/stats.js b/dist/service/stats.js
new file mode 100644
index 0000000..924e9b2
--- /dev/null
+++ b/dist/service/stats.js
@@ -0,0 +1,48 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
+
+var _Proc = _interopRequireDefault(require("../lib/Proc"));
+
+var _default = {
+ method: 'GET',
+ path: '/stats',
+ config: {
+ auth: false
+ },
+
+ handler() {
+ return (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee() {
+ var proc;
+ return _regenerator.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ proc = new _Proc.default();
+ return _context.abrupt("return", {
+ status: 1,
+ result: proc.info
+ });
+
+ case 2:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee);
+ }))();
+ }
+
+};
+exports.default = _default;
\ No newline at end of file
diff --git a/dist/service/status.js b/dist/service/status.js
new file mode 100644
index 0000000..6849f52
--- /dev/null
+++ b/dist/service/status.js
@@ -0,0 +1,59 @@
+"use strict";
+
+var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = void 0;
+
+var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
+
+var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
+
+var _os = _interopRequireDefault(require("os"));
+
+var _child_process = require("child_process");
+
+var _default = {
+ method: 'GET',
+ path: '/status',
+ config: {
+ auth: false
+ },
+
+ handler() {
+ return (0, _asyncToGenerator2.default)(
+ /*#__PURE__*/
+ _regenerator.default.mark(function _callee() {
+ var who;
+ return _regenerator.default.wrap(function _callee$(_context) {
+ while (1) {
+ switch (_context.prev = _context.next) {
+ case 0:
+ who = (0, _child_process.execSync)('whoami');
+ return _context.abrupt("return", {
+ status: 1,
+ msg: 'running',
+ result: {
+ user: who.toString('utf8').trim('\r\n'),
+ arch: _os.default.arch(),
+ type: _os.default.type(),
+ platform: _os.default.platform(),
+ totalmem: _os.default.totalmem(),
+ freemem: _os.default.freemem(),
+ cups: _os.default.cpus()
+ }
+ });
+
+ case 2:
+ case "end":
+ return _context.stop();
+ }
+ }
+ }, _callee);
+ }))();
+ }
+
+};
+exports.default = _default;
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..a77512b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,56 @@
+{
+ "name": "server-monitor-xp",
+ "version": "0.1.1",
+ "description": "Server monitor for windows xp.",
+ "main": "dist/app.js",
+ "scripts": {
+ "dev": "cross-env HOST=0.0.0.0 PORT=65534 nodemon src/dev.js",
+ "build": "babel src -d dist",
+ "start": "cross-env NODE_ENV=production HOST=0.0.0.0 PORT=65522 node dist/app.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/yi-ge/server-monitor-xp.git"
+ },
+ "keywords": [
+ "server",
+ "monitor"
+ ],
+ "author": "yi-ge ",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/yi-ge/server-monitor-xp/issues"
+ },
+ "homepage": "https://github.com/yi-ge/server-monitor-xp#readme",
+ "dependencies": {
+ "@babel/runtime": "^7.5.5",
+ "axios": "^0.19.0",
+ "cross-env": "^5.2.1"
+ },
+ "devDependencies": {
+ "@babel/cli": "^7.5.5",
+ "@babel/core": "^7.5.5",
+ "@babel/plugin-transform-runtime": "^7.5.5",
+ "@babel/preset-env": "^7.5.5",
+ "@babel/register": "^7.5.5",
+ "nodemon": "^1.19.1"
+ },
+ "nodemonConfig": {
+ "ignore": [
+ ".git",
+ "node_modules/**/node_modules"
+ ],
+ "delay": "2500",
+ "env": {
+ "NODE_ENV": "development",
+ "AGENT_VERSION": "0.0.1",
+ "AGENT_PORT": "60000",
+ "API_URL": "https://server-0.sercretcore.cn/api/",
+ "API_KEY": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxEUN1DZZ/XU2J6+3EoCX\n6ZQExSyGrJlmcq2s4sxAqThJVGAv4BYqCQjnigUGaLF4+2khGHVXrx4LhwnW54iq\nV3V3Xq59H0Cj3oGGWgKxSOM62xxfizmc1Og/6uAwZTAX4oCsgx5SMaFQbAU5ensM\nVEX9CetXSGhc1bbS23kEHAkjJ0NryRl7DR/ilFKO5pAjTGEzP4aTkF/D3Eu3z15U\nwdkf2WisEsANVTEnNHu2qvdiXGzRSLNF4mVFNO3AsgfnbgXzlN0feQ1HbH+J7Ue5\neHleCGhfS/PGFP3lQ4sA0hB4B/5eZ6ROo8YEuQiNTz+UMFteeGymTgFu2sOwLE10\nwQIDAQAB\n-----END PUBLIC KEY-----"
+ },
+ "ext": "js,json"
+ },
+ "engines": {
+ "node": ">= 5.12.0"
+ }
+}
\ No newline at end of file
diff --git a/server-monitor-xp-0.1.0.zip b/server-monitor-xp-0.1.0.zip
new file mode 100644
index 0000000..74a856c
Binary files /dev/null and b/server-monitor-xp-0.1.0.zip differ
diff --git a/server-monitor-xp-0.1.1.zip b/server-monitor-xp-0.1.1.zip
new file mode 100644
index 0000000..b48a858
Binary files /dev/null and b/server-monitor-xp-0.1.1.zip differ
diff --git a/src/app.js b/src/app.js
new file mode 100644
index 0000000..a7f13cb
--- /dev/null
+++ b/src/app.js
@@ -0,0 +1,21 @@
+import {
+ SERVER, SYSTEM
+} from './config'
+import boot from './boot'
+import http from 'http'
+
+ const server = http.createServer((req, res) => {
+ res.statusCode = 200;
+ res.setHeader('Content-Type', 'application/json; charset=utf-8');
+ res.end(JSON.stringify({
+ status: 1
+ }));
+ });
+
+boot().then(r => { // Start boot
+ server.listen(SERVER.port, SERVER.host, () => {
+ console.log(`Server running at http://${SERVER.host}:${SERVER.port}/`);
+ });
+}).catch(err => {
+ console.log(err)
+})
diff --git a/src/boot.js b/src/boot.js
new file mode 100644
index 0000000..c5efec3
--- /dev/null
+++ b/src/boot.js
@@ -0,0 +1,81 @@
+import fs from 'fs'
+import axios from 'axios'
+import pack from '../package.json'
+import crypto from 'crypto'
+import gather from './control/gather'
+
+const version = pack.version
+const request = axios.create()
+const apiURLs = {
+ apiURL: process.env.API_URL,
+ apiKEY: process.env.API_KEY
+}
+const AGENT_VERSION = process.env.AGENT_VERSION
+const AGENT_PORT = process.env.AGENT_PORT
+const isDev = process.env.NODE_ENV !== 'production' // 系统配置
+
+const rebootNodeJS = async () => {
+ if (isDev) {
+ console.log('当前是开发环境,无法自动重启Node.js')
+ } else {
+ try {
+ const { data } = await request.get(`http://127.0.0.1:${AGENT_PORT}/system/cmd?action=restart`)
+ console.log('自动重启Node.js返回数据:', data)
+ } catch (err) {
+ console.log(err)
+ console.log('自动重启Node.js失败')
+ }
+ }
+}
+
+const checkVersion = async (version) => {
+ const apiURL = 'https://tool.y-bi.top/check.php?version=' + version
+
+ const { data } = await request.get(apiURL)
+
+ if (data.status === 1) { // 有更新
+ console.log('发现新版系统,正在重启Node.js...')
+ await rebootNodeJS()
+ return true
+ }
+
+ return false
+}
+
+const fileIsExists = (path) => {
+ try {
+ fs.accessSync(path)
+ return true
+ } catch (_) {
+ return false
+ }
+}
+
+const checkAndInstallWhoami = () => {
+ if (!fileIsExists('C:\\Windows\\system32\\whoami.exe') && !fileIsExists('C:\\Windows\\system32\\whoami.bat')) {
+ console.log('whoami 命令不存在,正在写入')
+ const batContent = `@echo off
+echo %computername%\%username%
+exit /B`
+
+ fs.writeFileSync('C:\\Windows\\system32\\whoami.bat', batContent)
+ }
+}
+
+export default async () => {
+ console.log('AGENT_VERSION:', AGENT_VERSION)
+
+ checkAndInstallWhoami()
+
+ setInterval(() => {
+ checkVersion(version || '0.0.1') // sync
+ }, 120000)
+
+ gather({
+ version: version || '0.0.1',
+ apiURLs,
+ isDev,
+ AGENT_PORT,
+ AGENT_VERSION
+ }) // sync
+}
diff --git a/src/config.js b/src/config.js
new file mode 100644
index 0000000..a9fe2a4
--- /dev/null
+++ b/src/config.js
@@ -0,0 +1,14 @@
+const pack = require('../package')
+const isDev = process.env.NODE_ENV !== 'production'
+
+// 系统配置
+export const SYSTEM = {
+ version: pack.version,
+ sessionKey: process.env.JWT_SECRET || '123', // 生产环境务必随机设置一个值
+ scheme: [isDev ? 'http' : 'https']
+}
+
+export const SERVER = {
+ port: isDev ? process.env.PORT || '65522' : (process.env.PORT || '65522'), // API服务器监听的端口号
+ host: '0.0.0.0'
+}
diff --git a/src/control/gather.js b/src/control/gather.js
new file mode 100644
index 0000000..0858d3e
--- /dev/null
+++ b/src/control/gather.js
@@ -0,0 +1,30 @@
+import os from 'os'
+import axios from 'axios'
+import { execSync } from 'child_process'
+
+const request = axios.create()
+
+export default async (conf) => {
+ const gather = (conf) => {
+ setTimeout(async () => {
+ const who = execSync('whoami')
+ const { version, apiURLs, AGENT_VERSION } = conf
+ const { data } = await request.put(apiURLs.apiURL + 'gather', {
+ version,
+ AGENT_VERSION,
+ user: who.toString('utf8').trim('\r\n'),
+ arch: os.arch(),
+ type: os.type(),
+ platform: os.platform()
+ })
+
+ if (data.status === 1) {
+ console.log('发现监控系统地址')
+ }
+
+ gather(conf)
+ }, 20000)
+ }
+
+ gather(conf)
+}
diff --git a/src/dev.js b/src/dev.js
new file mode 100644
index 0000000..da0652e
--- /dev/null
+++ b/src/dev.js
@@ -0,0 +1,2 @@
+require('@babel/register')
+require('./app')
diff --git a/src/service/home.js b/src/service/home.js
new file mode 100644
index 0000000..c1b48f0
--- /dev/null
+++ b/src/service/home.js
@@ -0,0 +1,13 @@
+export default {
+ method: 'GET',
+ path: '/',
+ config: {
+ auth: false
+ },
+ async handler () {
+ return {
+ status: 1,
+ massage: 'Please consult the API documentation.'
+ }
+ }
+}
diff --git a/src/service/index.js b/src/service/index.js
new file mode 100644
index 0000000..74949c2
--- /dev/null
+++ b/src/service/index.js
@@ -0,0 +1,19 @@
+import fs from 'fs'
+import path from 'path'
+
+const modules = []
+
+const files = fs.readdirSync(__dirname).filter((file) => {
+ return file.match(/\.(json|js)$/)
+})
+
+files.forEach(key => {
+ if (key === 'index.js') return
+
+ // const content = require(path.join(__dirname, key)).default
+ const content = require(path.join(__dirname, key)).default
+
+ if (Array.isArray(content)) { modules.push(...content) } else { modules.push(content) }
+})
+
+export default modules
diff --git a/src/service/stats.js b/src/service/stats.js
new file mode 100644
index 0000000..1ff7716
--- /dev/null
+++ b/src/service/stats.js
@@ -0,0 +1,16 @@
+import Proc from '../lib/Proc'
+
+export default {
+ method: 'GET',
+ path: '/stats',
+ config: {
+ auth: false
+ },
+ async handler () {
+ const proc = new Proc()
+ return {
+ status: 1,
+ result: proc.info
+ }
+ }
+}
diff --git a/src/service/status.js b/src/service/status.js
new file mode 100644
index 0000000..d0853d1
--- /dev/null
+++ b/src/service/status.js
@@ -0,0 +1,27 @@
+import os from 'os'
+import { execSync } from 'child_process'
+
+export default {
+ method: 'GET',
+ path: '/status',
+ config: {
+ auth: false
+ },
+ async handler () {
+ const who = execSync('whoami')
+
+ return {
+ status: 1,
+ msg: 'running',
+ result: {
+ user: who.toString('utf8').trim('\r\n'),
+ arch: os.arch(),
+ type: os.type(),
+ platform: os.platform(),
+ totalmem: os.totalmem(),
+ freemem: os.freemem(),
+ cups: os.cpus()
+ }
+ }
+ }
+}