From 644b9f1de2bba59501bebe39bc347e13e576c0cb Mon Sep 17 00:00:00 2001 From: chaoszhu Date: Thu, 11 Jul 2024 12:13:33 +0800 Subject: [PATCH] =?UTF-8?q?:arrow=5Fup:=20=E5=8D=87=E7=BA=A7=E4=BE=9D?= =?UTF-8?q?=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + README.md | 8 +- client/package.json | 16 +- package.json | 8 +- server/.env.template | 2 + server/app/config/index.js | 4 +- server/app/controller/user.js | 2 +- server/app/init.js | 2 +- server/app/middlewares/body.js | 2 +- server/app/middlewares/response.js | 1 + server/app/socket/clients.js | 2 +- server/app/socket/monitor.js | 2 +- server/app/utils/encrypt.js | 2 +- server/app/utils/verify-auth.js | 4 +- server/bin/www | 2 +- server/index.js | 1 + server/package.json | 53 +- web/package.json | 65 +- web/src/App.vue | 12 +- web/src/plugins/element.js | 5 + web/src/store/index.js | 2 +- web/src/views/list/components/ssh-form.vue | 4 +- web/src/views/login/index.vue | 6 +- .../views/terminal/components/info-side.vue | 2 +- web/vite.config.js | 14 - yarn.lock | 3024 +++++++---------- 26 files changed, 1350 insertions(+), 1897 deletions(-) create mode 100644 server/.env.template diff --git a/.gitignore b/.gitignore index 70e3ed3..4790d71 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ server/app/logs/* server/app/db/* !server/app/db/README.md plan.md +.env +.env.local diff --git a/README.md b/README.md index b1c4f04..72b8076 100644 --- a/README.md +++ b/README.md @@ -167,10 +167,10 @@ wget -qO- --no-check-certificate https://ghproxy.com/https://raw.githubuserconte ## 开发 -1. 拉取代码,准备nodejs环境>=16 -2. cd到项目根目录,yarn执行安装依赖 -3. cd web 启动前端 npm run dev -4. cd server 启动服务端 npm run local +1. 拉取代码,环境 `nodejs``>=20` +2. cd到项目根目录,`yarn install` 执行安装依赖 +3. `yarn dev`启动项目 +4. web: `http://localhost:18090/` ## Q&A diff --git a/client/package.json b/client/package.json index 369ca5f..f6dd716 100644 --- a/client/package.json +++ b/client/package.json @@ -21,15 +21,15 @@ ] }, "dependencies": { - "axios": "^0.21.4", - "koa": "^2.13.1", - "node-os-utils": "^1.3.6", - "node-schedule": "^2.1.0", - "socket.io": "^4.4.1" + "axios": "^1.7.2", + "koa": "^2.15.3", + "node-os-utils": "^1.3.7", + "node-schedule": "^2.1.1", + "socket.io": "^4.7.5" }, "devDependencies": { - "eslint": "^7.32.0", - "nodemon": "^2.0.15", - "pkg": "5.6" + "eslint": "^9.6.0", + "nodemon": "^3.1.4", + "pkg": "5.8" } } diff --git a/package.json b/package.json index 592f018..79f6b10 100644 --- a/package.json +++ b/package.json @@ -22,13 +22,15 @@ "author": "chaoszhu", "license": "ISC", "scripts": { - "dev": "concurrently \"yarn workspace web run dev\" \"yarn workspace server run local\"" + "dev": "concurrently \"yarn workspace web run dev\" \"yarn workspace server run local\"", + "clean": "rimraf web/node_modules server/node_modules client/node_modules node_modules" }, "bugs": { "url": "https://github.com/chaos-zhu/easynode/issues" }, "homepage": "https://github.com/chaos-zhu/easynode#readme", - "dependencies": { - "concurrently": "^8.2.2" + "devDependencies": { + "concurrently": "^8.2.2", + "rimraf": "^6.0.1" } } diff --git a/server/.env.template b/server/.env.template new file mode 100644 index 0000000..03c8c62 --- /dev/null +++ b/server/.env.template @@ -0,0 +1,2 @@ +# 启动debug日志 0:关闭 1:开启 +DEBUG=1 diff --git a/server/app/config/index.js b/server/app/config/index.js index 77bafc4..f998840 100644 --- a/server/app/config/index.js +++ b/server/app/config/index.js @@ -1,5 +1,7 @@ const path = require('path') +consola.info('debug日志:', process.env.DEBUG === '1' ? '开启' : '关闭') + module.exports = { httpPort: 8082, clientPort: 22022, // 暂不支持更改 @@ -15,6 +17,6 @@ module.exports = { apiPrefix: '/api/v1', logConfig: { outDir: path.join(process.cwd(),'./app/logs'), - recordLog: true // 是否记录日志 + recordLog: process.env.DEBUG === '1' // 是否记录日志 } } diff --git a/server/app/controller/user.js b/server/app/controller/user.js index 7ba12a5..469305b 100644 --- a/server/app/controller/user.js +++ b/server/app/controller/user.js @@ -51,7 +51,7 @@ const login = async ({ res, request }) => { try { // console.log('ciphertext', ciphertext) let password = await RSADecryptSync(ciphertext) - // console.log('Decrypt解密password:', password) + console.log('Decrypt解密password:', password) let { pwd } = await readKey() if(password === 'admin' && pwd === 'admin') { const token = await beforeLoginHandler(clientIp, jwtExpires) diff --git a/server/app/init.js b/server/app/init.js index d560706..b598f5b 100644 --- a/server/app/init.js +++ b/server/app/init.js @@ -20,7 +20,7 @@ async function initRsa() { let keyObj = await readKey() if(keyObj.privateKey && keyObj.publicKey) return consola.info('公私钥已存在[重新生成会导致已保存的ssh密钥信息失效]') let key = new NodeRSA({ b: 1024 }) - key.setOptions({ encryptionScheme: 'pkcs1' }) + key.setOptions({ encryptionScheme: 'pkcs1', environment: "browser" }) let privateKey = key.exportKey('pkcs1-private-pem') let publicKey = key.exportKey('pkcs8-public-pem') keyObj.privateKey = await AESEncryptSync(privateKey) // 加密私钥 diff --git a/server/app/middlewares/body.js b/server/app/middlewares/body.js index 382cccb..fe1bb9c 100644 --- a/server/app/middlewares/body.js +++ b/server/app/middlewares/body.js @@ -1,4 +1,4 @@ -const koaBody = require('koa-body') +const { koaBody } = require('koa-body') const { uploadDir } = require('../config') module.exports = koaBody({ diff --git a/server/app/middlewares/response.js b/server/app/middlewares/response.js index 50c9b60..67f2091 100644 --- a/server/app/middlewares/response.js +++ b/server/app/middlewares/response.js @@ -22,6 +22,7 @@ const responseHandler = async (ctx, next) => { try { await next() // 每个中间件都需等待next完成调用,不然会返回404给前端!!! } catch (err) { + console.dir(err) consola.error('中间件错误:', err) if (err.status) ctx.res.fail({ status: err.status, msg: err.message }) // 自己主动抛出的错误 throwError diff --git a/server/app/socket/clients.js b/server/app/socket/clients.js index ddd3e29..326dd3b 100644 --- a/server/app/socket/clients.js +++ b/server/app/socket/clients.js @@ -15,7 +15,7 @@ async function getClientsInfo(socketId) { forceNew: true, timeout: 5000, reconnectionDelay: 3000, - reconnectionAttempts: 100 + reconnectionAttempts: 3 }) // 将与客户端连接的socket实例保存起来,web端断开时关闭这些连接 clientSockets[socketId].push(clientSocket) diff --git a/server/app/socket/monitor.js b/server/app/socket/monitor.js index 5a45a89..cddab63 100644 --- a/server/app/socket/monitor.js +++ b/server/app/socket/monitor.js @@ -18,7 +18,7 @@ async function getIpInfo() { function ipSchedule() { let rule1 = new schedule.RecurrenceRule() - rule1.second = [0, 30] + rule1.second = [0] schedule.scheduleJob(rule1, () => { let { query, country, city } = ipInfo || {} if(query && country && city) return diff --git a/server/app/utils/encrypt.js b/server/app/utils/encrypt.js index ac601cd..f2501e7 100644 --- a/server/app/utils/encrypt.js +++ b/server/app/utils/encrypt.js @@ -9,7 +9,7 @@ const RSADecryptSync = async (ciphertext) => { let { privateKey } = await readKey() privateKey = await AESDecryptSync(privateKey) // 先解密私钥 const rsakey = new NodeRSA(privateKey) - rsakey.setOptions({ encryptionScheme: 'pkcs1' }) // Must Set It When Frontend Use jsencrypt + rsakey.setOptions({ encryptionScheme: 'pkcs1', environment: "browser" }) // Must Set It When Frontend Use jsencrypt const plaintext = rsakey.decrypt(ciphertext, 'utf8') return plaintext } diff --git a/server/app/utils/verify-auth.js b/server/app/utils/verify-auth.js index 56da11e..6304400 100644 --- a/server/app/utils/verify-auth.js +++ b/server/app/utils/verify-auth.js @@ -12,9 +12,9 @@ const enumLoginCode = { // 校验token与登录IP const verifyAuthSync = async (token, clientIp) => { consola.info('verifyAuthSync IP:', clientIp) - token = await AESDecryptSync(token) // 先aes解密 - const { commonKey } = await readKey() try { + token = await AESDecryptSync(token) // 先aes解密 + const { commonKey } = await readKey() const { exp } = jwt.verify(token, commonKey) if (Date.now() > (exp * 1000)) return { code: -1, msg: 'token expires' } // 过期 return { code: enumLoginCode.SUCCESS, msg: 'success' } // 验证成功 diff --git a/server/bin/www b/server/bin/www index a8611d0..be8f123 100755 --- a/server/bin/www +++ b/server/bin/www @@ -1,3 +1,3 @@ #!/usr/bin/env node console.log('start time', new Date()) -require('../app/main.js') +require('../index.js') diff --git a/server/index.js b/server/index.js index e455fee..110576d 100644 --- a/server/index.js +++ b/server/index.js @@ -1 +1,2 @@ +require('dotenv').config() require('./app/main.js') diff --git a/server/package.json b/server/package.json index 0711d3f..abd2287 100644 --- a/server/package.json +++ b/server/package.json @@ -9,12 +9,12 @@ "assets": "./*" }, "scripts": { - "local": "cross-env EXEC_ENV=local nodemon ./app/main.js", - "server": "cross-env EXEC_ENV=production nodemon ./app/main.js", - "start": "node ./app/main.js", - "pkgwin": "pkg . -t node16-win-x64", - "pkglinux:x86": "pkg . -t node16-linux-x64", - "pkglinux:arm": "pkg . -t node16-linux-arm64" + "local": "cross-env EXEC_ENV=local nodemon ./app/index.js", + "prod": "cross-env EXEC_ENV=production nodemon ./app/index.js", + "start": "node ./app/index.js", + "pkgwin": "pkg . -t node20-win-x64", + "pkglinux:x86": "pkg . -t node20-linux-x64", + "pkglinux:arm": "pkg . -t node20-linux-arm64" }, "keywords": [], "author": "", @@ -27,34 +27,35 @@ "dependencies": { "@koa/cors": "^5.0.0", "@seald-io/nedb": "^4.0.4", - "axios": "^0.21.4", - "consola": "^2.15.3", + "axios": "^1.7.2", + "consola": "^3.2.3", "cross-env": "^7.0.3", "crypto-js": "^4.2.0", + "dotenv": "^16.4.5", "global": "^4.4.0", - "jsonwebtoken": "^9.0.0", - "koa": "^2.13.1", - "koa-body": "^4.2.0", + "jsonwebtoken": "^9.0.2", + "koa": "^2.15.3", + "koa-body": "^6.0.1", "koa-compose": "^4.1.0", - "koa-compress": "^5.1.0", - "koa-jwt": "^4.0.3", - "koa-router": "^10.0.0", - "koa-sslify": "^5.0.0", + "koa-compress": "^5.1.1", + "koa-jwt": "^4.0.4", + "koa-router": "^12.0.1", + "koa-sslify": "^5.0.1", "koa-static": "^5.0.0", "koa2-connect-history-api-fallback": "^0.1.3", - "log4js": "^6.4.4", - "node-os-utils": "^1.3.6", + "log4js": "^6.9.1", + "node-os-utils": "^1.3.7", "node-rsa": "^1.1.1", - "node-schedule": "^2.1.0", - "nodemailer": "^6.7.5", - "socket.io": "^4.4.1", - "socket.io-client": "^4.5.1", - "ssh2": "^1.10.0", - "ssh2-sftp-client": "^9.0.1" + "node-schedule": "^2.1.1", + "nodemailer": "^6.9.14", + "socket.io": "^4.7.5", + "socket.io-client": "^4.7.5", + "ssh2": "^1.15.0", + "ssh2-sftp-client": "^10.0.3" }, "devDependencies": { - "eslint": "^7.32.0", - "nodemon": "^2.0.15", - "pkg": "5.6" + "eslint": "^9.6.0", + "nodemon": "^3.1.4", + "pkg": "5.8" } } diff --git a/web/package.json b/web/package.json index 8c29bc6..459c066 100644 --- a/web/package.json +++ b/web/package.json @@ -10,30 +10,30 @@ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore" }, "dependencies": { - "@codemirror/lang-cpp": "^6.0.1", - "@codemirror/lang-css": "^6.0.0", - "@codemirror/lang-html": "^6.1.0", - "@codemirror/lang-java": "^6.0.0", - "@codemirror/lang-javascript": "^6.0.1", - "@codemirror/lang-json": "^6.0.0", - "@codemirror/lang-markdown": "^6.0.0", - "@codemirror/lang-php": "^6.0.0", - "@codemirror/lang-python": "^6.0.0", - "@codemirror/lang-sql": "^6.0.0", - "@codemirror/lang-xml": "^6.0.0", - "@codemirror/language": "^6.2.0", - "@codemirror/legacy-modes": "^6.1.0", - "@codemirror/theme-one-dark": "^6.0.0", - "axios": "^0.26.1", + "@codemirror/lang-cpp": "^6.0.2", + "@codemirror/lang-css": "^6.2.1", + "@codemirror/lang-html": "^6.4.9", + "@codemirror/lang-java": "^6.0.1", + "@codemirror/lang-javascript": "^6.2.2", + "@codemirror/lang-json": "^6.0.1", + "@codemirror/lang-markdown": "^6.2.5", + "@codemirror/lang-php": "^6.0.1", + "@codemirror/lang-python": "^6.1.6", + "@codemirror/lang-sql": "^6.7.0", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.10.2", + "@codemirror/legacy-modes": "^6.4.0", + "@codemirror/theme-one-dark": "^6.1.2", + "axios": "^1.7.2", "codemirror": "^6.0.1", - "crypto-js": "^4.1.1", - "element-plus": "^2.1.7", - "jsencrypt": "^3.0.0-rc.1", - "pinia": "^2.0.16", - "socket.io-client": "^4.4.1", - "vue": "^3.2.31", - "vue-codemirror": "^6.0.0", - "vue-router": "^4.0.14", + "crypto-js": "^4.2.0", + "element-plus": "^2.7.6", + "jsencrypt": "^3.3.2", + "pinia": "^2.1.7", + "socket.io-client": "^4.7.5", + "vue": "^3.4.31", + "vue-codemirror": "^6.1.1", + "vue-router": "^4.4.0", "xterm": "^4.19.0", "xterm-addon-fit": "^0.5.0", "xterm-addon-search": "^0.9.0", @@ -41,16 +41,15 @@ "xterm-addon-web-links": "^0.6.0" }, "devDependencies": { - "@vitejs/plugin-vue": "^2.3.1", - "@vitejs/plugin-vue-jsx": "^1.3.9", - "eslint": "^8.5.0", - "eslint-plugin-vue": "^8.2.0", - "sass": "^1.49.11", - "unplugin-auto-import": "^0.6.9", - "unplugin-vue-components": "^0.18.5", - "vite": "^2.9.1", + "@vitejs/plugin-vue": "^5.0.5", + "@vitejs/plugin-vue-jsx": "^4.0.0", + "eslint": "^9.6.0", + "eslint-plugin-vue": "^9.27.0", + "sass": "^1.77.7", + "unplugin-auto-import": "^0.17.6", + "unplugin-vue-components": "^0.27.2", + "vite": "^5.3.3", "vite-plugin-compression": "^0.5.1", - "vite-plugin-style-import": "^1.4.1", - "vue-eslint-parser": "^9.0.2" + "vue-eslint-parser": "^9.4.3" } } diff --git a/web/src/App.vue b/web/src/App.vue index af50110..358d39d 100644 --- a/web/src/App.vue +++ b/web/src/App.vue @@ -4,17 +4,11 @@ -