diff --git a/CHANGELOG.md b/CHANGELOG.md index d812966..fbdc254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## [2.3.0](https://github.com/chaos-zhu/easynode/releases) (2024-10-xx) +## [2.2.5](https://github.com/chaos-zhu/easynode/releases) (2024-10-xx) ### Features diff --git a/server/app/controller/ssh.js b/server/app/controller/ssh.js index 87043a1..c1df398 100644 --- a/server/app/controller/ssh.js +++ b/server/app/controller/ssh.js @@ -15,7 +15,7 @@ async function getSSHList({ res }) { const addSSH = async ({ res, request }) => { let { body: { name, authType, password, privateKey, tempKey } } = request let record = { name, authType, password, privateKey } - if(!name || !record[authType]) return res.fail({ data: false, msg: '参数错误' }) + if (!name || !record[authType]) return res.fail({ data: false, msg: '参数错误' }) let sshRecord = await readSSHRecord() if (sshRecord.some(item => item.name === name)) return res.fail({ data: false, msg: '已存在同名凭证' }) @@ -35,11 +35,11 @@ const addSSH = async ({ res, request }) => { const updateSSH = async ({ res, request }) => { let { body: { id, name, authType, password, privateKey, date, tempKey } } = request let record = { name, authType, password, privateKey, date } - if(!id || !name) return res.fail({ data: false, msg: '请输入凭据名称' }) + if (!id || !name) return res.fail({ data: false, msg: '请输入凭据名称' }) let sshRecord = await readSSHRecord() let idx = sshRecord.findIndex(item => item._id === id) if (sshRecord.some(item => item.name === name && item.date !== date)) return res.fail({ data: false, msg: '已存在同名凭证' }) - if(idx === -1) res.fail({ data: false, msg: '请输入凭据名称' }) + if (idx === -1) res.fail({ data: false, msg: '请输入凭据名称' }) const oldRecord = sshRecord[idx] // 判断原记录是否存在当前更新记录的认证方式 if (!oldRecord[authType] && !record[authType]) return res.fail({ data: false, msg: `请输入${ authType === 'password' ? '密码' : '密钥' }` }) @@ -64,7 +64,7 @@ const removeSSH = async ({ res, request }) => { let { params: { id } } = request let sshRecord = await readSSHRecord() let idx = sshRecord.findIndex(item => item._id === id) - if(idx === -1) return res.fail({ msg: '凭证不存在' }) + if (idx === -1) return res.fail({ msg: '凭证不存在' }) sshRecord.splice(idx, 1) // 将删除的凭证id从host中删除 let hostList = await readHostList() @@ -79,14 +79,14 @@ const removeSSH = async ({ res, request }) => { } const getCommand = async ({ res, request }) => { - let { host } = request.query - if(!host) return res.fail({ data: false, msg: '参数错误' }) + let { hostId } = request.query + if (!hostId) return res.fail({ data: false, msg: '参数错误' }) let hostInfo = await readHostList() - let record = hostInfo?.find(item => item.host === host) - consola.info('查询登录后执行的指令:', host) - if(!record) return res.fail({ data: false, msg: 'host not found' }) // host不存在 + let record = hostInfo?.find(item => item._id === hostId) + consola.info('查询登录后执行的指令:', hostId) + if (!record) return res.fail({ data: false, msg: 'host not found' }) // host不存在 const { command } = record - if(!command) return res.success({ data: false }) // command不存在 + if (!command) return res.success({ data: false }) // command不存在 res.success({ data: command }) // 存在 } diff --git a/server/app/socket/terminal.js b/server/app/socket/terminal.js index 997716e..514dcdd 100644 --- a/server/app/socket/terminal.js +++ b/server/app/socket/terminal.js @@ -25,36 +25,36 @@ function createInteractiveShell(socket, sshClient) { }) } -function execShell(sshClient, command = '', callback) { - if (!command) return - let result = '' - sshClient.exec(`source ~/.bashrc && ${ command }`, (err, stream) => { - if (err) return callback(err.toString()) - stream - .on('data', (data) => { - result += data.toString() - }) - .stderr - .on('data', (data) => { - result += data.toString() - }) - .on('close', () => { - consola.info('一次性指令执行完成:', command) - callback(result) - }) - .on('error', (error) => { - console.log('Error:', error.toString()) - }) - }) -} +// function execShell(sshClient, command = '', callback) { +// if (!command) return +// let result = '' +// sshClient.exec(`source ~/.bashrc && ${ command }`, (err, stream) => { +// if (err) return callback(err.toString()) +// stream +// .on('data', (data) => { +// result += data.toString() +// }) +// .stderr +// .on('data', (data) => { +// result += data.toString() +// }) +// .on('close', () => { +// consola.info('一次性指令执行完成:', command) +// callback(result) +// }) +// .on('error', (error) => { +// console.log('Error:', error.toString()) +// }) +// }) +// } -async function createTerminal(ip, socket, sshClient) { +async function createTerminal(hostId, socket, sshClient) { // eslint-disable-next-line no-async-promise-executor return new Promise(async (resolve) => { const hostList = await readHostList() - const targetHostInfo = hostList.find(item => item.host === ip) || {} + const targetHostInfo = hostList.find(item => item._id === hostId) || {} let { authType, host, port, username, name } = targetHostInfo - if (!host) return socket.emit('create_fail', `查找【${ ip }】凭证信息失败`) + if (!host) return socket.emit('create_fail', `查找hostId【${ hostId }】凭证信息失败`) let authInfo = { host, port, username } // 统一使用commonKey解密 try { @@ -122,7 +122,7 @@ module.exports = (httpServer) => { } consola.success('terminal websocket 已连接') let sshClient = null - socket.on('create', async ({ host: ip, token }) => { + socket.on('create', async ({ hostId, token }) => { const { code } = await verifyAuthSync(token, requestIP) if (code !== 1) { socket.emit('token_verify_fail') @@ -149,7 +149,7 @@ module.exports = (httpServer) => { socket.on('resize', resizeShell) // 重连 socket.on('reconnect_terminal', async () => { - consola.info('重连终端: ', ip) + consola.info('重连终端: ', hostId) socket.off('input', listenerInput) // 取消监听,重新注册监听,操作新的stream socket.off('resize', resizeShell) sshClient?.end() @@ -159,13 +159,13 @@ module.exports = (httpServer) => { setTimeout(async () => { // 初始化新的SSH客户端对象 sshClient = new SSHClient() - stream = await createTerminal(ip, socket, sshClient) + stream = await createTerminal(hostId, socket, sshClient) socket.emit('reconnect_terminal_success') socket.on('input', listenerInput) socket.on('resize', resizeShell) }, 3000) }) - stream = await createTerminal(ip, socket, sshClient) + stream = await createTerminal(hostId, socket, sshClient) }) socket.on('disconnect', (reason) => { diff --git a/web/src/api/index.js b/web/src/api/index.js index 0298e6d..9778d27 100644 --- a/web/src/api/index.js +++ b/web/src/api/index.js @@ -22,8 +22,8 @@ export default { // existSSH(host) { // return axios({ url: '/exist-ssh', method: 'post', data: { host } }) // }, - getCommand(host) { - return axios({ url: '/command', method: 'get', params: { host } }) + getCommand(hostId) { + return axios({ url: '/command', method: 'get', params: { hostId } }) }, getHostList() { return axios({ url: '/host-list', method: 'get' }) diff --git a/web/src/views/terminal/components/terminal-tab.vue b/web/src/views/terminal/components/terminal-tab.vue index 1b40b89..8f96c08 100644 --- a/web/src/views/terminal/components/terminal-tab.vue +++ b/web/src/views/terminal/components/terminal-tab.vue @@ -69,7 +69,7 @@ const theme = computed(() => props.theme) const fontSize = computed(() => props.fontSize) const background = computed(() => props.background) const hostObj = computed(() => props.hostObj) -const host = computed(() => hostObj.value.host) +const hostId = computed(() => hostObj.value.id) let menuCollapse = computed(() => $store.menuCollapse) watch(menuCollapse, () => { @@ -114,7 +114,7 @@ watch(curStatus, () => { }) const getCommand = async () => { - let { data } = await $api.getCommand(host.value) + let { data } = await $api.getCommand(hostId.value) if (data) command.value = data } @@ -125,9 +125,9 @@ const connectIO = () => { reconnectionAttempts: 1 }) socket.value.on('connect', () => { - console.log('/terminal socket已连接:', host.value) + console.log('/terminal socket已连接:', hostId.value) socketConnected.value = true - socket.value.emit('create', { host: host.value, token: token.value }) + socket.value.emit('create', { hostId: hostId.value, token: token.value }) socket.value.on('connect_terminal_success', () => { if (hasRegisterEvent.value) return // 以下事件连接成功后仅可注册一次, 否则会多次触发. 除非socket重连 hasRegisterEvent.value = true @@ -159,7 +159,7 @@ const connectIO = () => { socket.value.on('connect_close', () => { if (curStatus.value === CONNECT_FAIL) return // 连接失败不需要自动重连 curStatus.value = RECONNECTING - console.warn('连接断开,3秒后自动重连: ', host.value) + console.warn('连接断开,3秒后自动重连: ', hostId.value) term.value.write('\r\n连接断开,3秒后自动重连...\r\n') socket.value.emit('reconnect_terminal') }) @@ -170,13 +170,13 @@ const connectIO = () => { socket.value.on('create_fail', (message) => { curStatus.value = CONNECT_FAIL - console.error('n创建失败:', host.value, message) + console.error('n创建失败:', hostId.value, message) term.value.write(`\r\n创建失败: ${ message }\r\n`) }) socket.value.on('connect_fail', (message) => { curStatus.value = CONNECT_FAIL - console.error('连接失败:', host.value, message) + console.error('连接失败:', hostId.value, message) term.value.write(`\r\n连接失败: ${ message }\r\n`) }) }) diff --git a/web/src/views/terminal/index.vue b/web/src/views/terminal/index.vue index 824dfc4..0da3902 100644 --- a/web/src/views/terminal/index.vue +++ b/web/src/views/terminal/index.vue @@ -75,10 +75,10 @@ let isAllConfssh = computed(() => { return hostList.value?.every(item => item.isConfig) }) -function linkTerminal({ id }) { - let targetHost = hostList.value.find(item => item.id === id) - const { host, name } = targetHost - terminalTabs.push({ key: randomStr(16), name, host, status: CONNECTING }) +function linkTerminal(hostInfo) { + let targetHost = hostList.value.find(item => item.id === hostInfo.id) + const { id, host, name } = targetHost + terminalTabs.push({ key: randomStr(16), id, name, host, status: CONNECTING }) } function handleUpdateHost(row) { @@ -110,8 +110,8 @@ onActivated(async () => { const { hostIds } = route.query if (!hostIds) return let targetHosts = hostList.value.filter(item => hostIds.includes(item.id)).map(item => { - const { name, host } = item - return { key: randomStr(16), name, host, status: CONNECTING } + const { id, name, host } = item + return { key: randomStr(16), id, name, host, status: CONNECTING } }) if (!targetHosts || !targetHosts.length) return terminalTabs.push(...targetHosts)