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() + } + } + } +}