feat: ws链接鉴权增强

This commit is contained in:
chaoszhu
2025-08-20 22:56:49 +08:00
parent 8ec13533e9
commit bea234d8ce
14 changed files with 150 additions and 172 deletions
+15 -12
View File
@@ -16,25 +16,28 @@ module.exports = (httpServer) => {
let connectionCount = 0
serverIo.on('connection', (socket) => {
connectionCount++
consola.success(`docker websocket 已连接 - 当前连接数: ${ connectionCount }`)
let requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
serverIo.on('connection', async (socket) => {
// IP白名单检查
const requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
if (!isAllowedIp(requestIP)) {
socket.emit('ip_forbidden', 'IP地址不在白名单中')
socket.disconnect()
return
}
consola.success('docker websocket 已连接')
// 登录态校验
const { token, uid } = socket.handshake.query
const { success } = await verifyAuthSync(token, uid)
if (!success) {
socket.emit('user_verify_fail')
socket.disconnect()
return
}
connectionCount++
consola.success(`docker websocket 已连接 - 当前连接数: ${ connectionCount }`)
let targetSSHClient = null
let jumpSshClients = []
socket.on('ws_docker', async ({ hostId, token }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
socket.disconnect()
return
}
socket.on('ws_docker', async ({ hostId }) => {
targetSSHClient = new SSHClient()
let { jumpSshClients: dockerJumpSshClients } = await createTerminal(hostId, socket, targetSSHClient, false)
jumpSshClients.push(...dockerJumpSshClients)
+17 -54
View File
@@ -64,27 +64,29 @@ module.exports = (httpServer) => {
let connectionCount = 0
const connectedSockets = new Set() // 跟踪所有连接的socket
transferIo.on('connection', (socket) => {
transferIo.on('connection', async (socket) => {
connectionCount++
connectedSockets.add(socket)
consola.success(`file-transfer websocket 已连接 - 当前连接数: ${ connectionCount }`)
// IP白名单检查
let requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
const requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
if (!isAllowedIp(requestIP)) {
socket.emit('ip_forbidden', 'IP地址不在白名单中')
socket.disconnect()
return
}
// 登录态校验
const { token, uid } = socket.handshake.query
const { success } = await verifyAuthSync(token, uid)
if (!success) {
socket.emit('user_verify_fail')
socket.disconnect()
return
}
// 连接时发送当前所有任务状态
socket.on('get_tasks', async ({ token }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
return
}
socket.on('get_tasks', async () => {
try {
const sortedTasks = await getSortedTasksList()
socket.emit('tasks_list', sortedTasks)
@@ -92,7 +94,7 @@ module.exports = (httpServer) => {
// 检查是否有运行中的任务,如果有则启动定时推送
const runningTasks = sortedTasks.filter(task => task.status === 'running')
if (runningTasks.length > 0) {
startProgressBroadcast(socket, token, requestIP)
startProgressBroadcast(socket)
}
} catch (error) {
socket.emit('error', { message: '获取任务列表失败', error: error.message })
@@ -101,13 +103,6 @@ module.exports = (httpServer) => {
// 启动传输任务
socket.on('start_transfer', async (transferConfig) => {
const { token } = transferConfig
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
return
}
try {
const { createTransferTask = null } = (await decryptAndExecuteAsync(path.join(__dirname, 'plus.js'))) || {}
if (!createTransferTask) throw new Error('Plus功能解锁失败: createTransferTask')
@@ -127,13 +122,7 @@ module.exports = (httpServer) => {
})
// 取消任务
socket.on('cancel_task', async ({ taskId, token }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
return
}
socket.on('cancel_task', async ({ taskId }) => {
try {
await cancelTransferTask(taskId)
socket.emit('task_cancelled', { taskId, message: '任务已取消' })
@@ -143,13 +132,7 @@ module.exports = (httpServer) => {
})
// 重试任务
socket.on('retry_task', async ({ taskId, token }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
return
}
socket.on('retry_task', async ({ taskId }) => {
try {
const task = await fileTransferDB.findOneAsync({ taskId })
if (!task) {
@@ -179,13 +162,7 @@ module.exports = (httpServer) => {
})
// 删除单个任务
socket.on('delete_task', async ({ taskId, token }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
return
}
socket.on('delete_task', async ({ taskId }) => {
try {
const task = await fileTransferDB.findOneAsync({ taskId })
if (!task) {
@@ -211,13 +188,7 @@ module.exports = (httpServer) => {
})
// 清空已完成任务
socket.on('clear_completed_tasks', async ({ token }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
return
}
socket.on('clear_completed_tasks', async () => {
try {
// 删除所有已完成、失败、取消的任务
const result = await fileTransferDB.removeAsync(
@@ -918,7 +889,7 @@ function cleanupRemoteKeyFile(sshClient, keyFile) {
const progressBroadcastTimers = new Map() // socket -> timer
// 启动进度广播
function startProgressBroadcast(socket, token, requestIP) {
function startProgressBroadcast(socket) {
// 如果该socket已经有定时器,先清除
if (progressBroadcastTimers.has(socket)) {
clearInterval(progressBroadcastTimers.get(socket))
@@ -927,14 +898,6 @@ function startProgressBroadcast(socket, token, requestIP) {
// 启动新的定时器,每秒检查并推送运行中任务的进度
const timer = setInterval(async () => {
try {
// 验证token是否仍然有效
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
// token失效,停止广播
stopProgressBroadcast(socket)
return
}
// 检查是否还有运行中的任务
const runningTasks = Array.from(activeTasks.values()).filter(task => task.status === 'running')
if (runningTasks.length === 0) {
+12 -10
View File
@@ -96,14 +96,22 @@ module.exports = (httpServer) => {
origin: '*'
}
})
serverIo.on('connection', (socket) => {
// 前者兼容nginx反代, 后者兼容nodejs自身服务
let requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
serverIo.on('connection', async (socket) => {
// IP白名单检查
const requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
if (!isAllowedIp(requestIP)) {
socket.emit('ip_forbidden', 'IP地址不在白名单中')
socket.disconnect()
return
}
// 登录态校验
const { token, uid } = socket.handshake.query
const { success } = await verifyAuthSync(token, uid)
if (!success) {
socket.emit('user_verify_fail')
socket.disconnect()
return
}
consola.success('onekey-terminal websocket 已连接')
if (isExecuting) {
socket.emit('create_fail', '正在执行中, 请稍后再试')
@@ -111,13 +119,7 @@ module.exports = (httpServer) => {
return
}
isExecuting = true
socket.on('ws_onekey', async ({ hostIds, token, command, timeout }) => {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
socket.disconnect()
return
}
socket.on('ws_onekey', async ({ hostIds, command, timeout }) => {
console.log('onekey command:', command)
const hostList = await hostListDB.findAsync({})
const targetHostsInfo = hostList.filter(item => hostIds.some(id => item._id === id)) || {}
+12 -9
View File
@@ -1327,13 +1327,22 @@ module.exports = (httpServer) => {
origin: '*'
}
})
serverIo.on('connection', (socket) => {
let requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
serverIo.on('connection', async (socket) => {
// IP白名单检查
const requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
if (!isAllowedIp(requestIP)) {
socket.emit('ip_forbidden', 'IP地址不在白名单中')
socket.disconnect()
return
}
// 登录态校验
const { token, uid } = socket.handshake.query
const { success } = await verifyAuthSync(token, uid)
if (!success) {
socket.emit('user_verify_fail')
socket.disconnect()
return
}
let sftpClient = new SFTPClient()
consola.success('sftp-v2 websocket 已连接')
let jumpSshClients = []
@@ -1343,14 +1352,8 @@ module.exports = (httpServer) => {
consola.error('SFTP-v2 Socket连接错误:', err.message)
})
socket.on('ws_sftp', async ({ hostId, token }) => {
socket.on('ws_sftp', async ({ hostId }) => {
try {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
socket.disconnect()
return
}
const targetHostInfo = await hostListDB.findOneAsync({ _id: hostId })
if (!targetHostInfo) throw new Error(`Host with ID ${ hostId } not found`)
+14 -13
View File
@@ -261,27 +261,28 @@ async function createTerminal(hostId, socket, targetSSHClient, isInteractiveShel
function createServerIo(serverIo) {
let connectionCount = 0
serverIo.on('connection', (socket) => {
connectionCount++
consola.success(`terminal websocket 已连接 - 当前连接数: ${ connectionCount }`)
let requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
serverIo.on('connection', async (socket) => {
// IP白名单检查
const requestIP = socket.handshake.headers['x-forwarded-for'] || socket.handshake.address
if (!isAllowedIp(requestIP)) {
socket.emit('ip_forbidden', 'IP地址不在白名单中')
socket.disconnect()
return
}
consola.success('terminal websocket 已连接')
// 登录态校验
const { token, uid } = socket.handshake.query
const { success } = await verifyAuthSync(token, uid)
if (!success) {
socket.emit('user_verify_fail')
socket.disconnect()
return
}
connectionCount++
consola.success(`terminal websocket 已连接 - 当前连接数: ${ connectionCount }`)
let targetSSHClient = null
let jumpSshClients = []
socket.on('ws_terminal', async ({ hostId, token }) => {
socket.on('ws_terminal', async ({ hostId }) => {
try {
const { code } = await verifyAuthSync(token, requestIP)
if (code !== 1) {
socket.emit('token_verify_fail')
socket.disconnect()
return
}
targetSSHClient = new SSHClient()
let result = await createTerminal(hostId, socket, targetSSHClient, true)
+2 -2
View File
@@ -15,13 +15,13 @@ const enumLoginCode = {
const verifyAuthSync = async (token, userId) => {
try {
const { commonKey, user, _id: uid } = await keyDB.findOneAsync({ _id: userId })
if (uid !== userId) return { code: enumLoginCode.ERROR_UID, msg: '用户id校验失败' }
if (uid !== userId) return { code: enumLoginCode.ERROR_UID }
token = await AESDecryptAsync(token)
const { exp } = jwt.verify(token, `${ user }-${ commonKey }`)
if (Date.now() > (exp * 1000)) {
return { code: enumLoginCode.EXPIRES } // 过期
}
return { code: enumLoginCode.SUCCESS } // 验证成功
return { code: enumLoginCode.SUCCESS, success: true } // 验证成功
} catch (err) {
consola.error('用户身份校验失败: ', err.message)
return { code: enumLoginCode.ERROR_TOKEN }
-6
View File
@@ -23,10 +23,4 @@ app.config.globalProperties.$tools = tools
app.config.globalProperties.$http = axios
app.config.globalProperties.$store = useStore()
const serviceURI = import.meta.env.DEV ? process.env.serviceURI : location.origin
app.config.globalProperties.$serviceURI = serviceURI
app.config.globalProperties.$store.$patch({ serviceURI })
console.warn('ISDEV: ', import.meta.env.DEV)
console.warn('serviceURI: ', serviceURI)
app.mount('#app')
+15
View File
@@ -1,6 +1,8 @@
import { reactive } from 'vue'
import JSRsaEncrypt from 'jsencrypt'
import CryptoJS from 'crypto-js'
import socketIo from 'socket.io-client'
import useStore from '../store'
export const EventBus = reactive({})
@@ -175,4 +177,17 @@ export const isValidDate = (dateString) => {
if (!dateString) return false
const date = new Date(dateString)
return !isNaN(date.getTime()) && date instanceof Date
}
const serviceURI = import.meta.env.DEV ? process.env.serviceURI : location.origin
export const generateSocketInstance = (path, query = {}, config = { forceNew: false, reconnection: true, reconnectionAttempts: 3 }) => {
return socketIo(serviceURI, {
path,
query: {
uid: useStore().uid,
token: useStore().token,
...query
},
...config
})
}
+13 -18
View File
@@ -138,15 +138,14 @@
<script setup>
import { ref, computed, onMounted, onUnmounted, getCurrentInstance } from 'vue'
import { List, Setting, ArrowRight, ArrowLeft, Warning } from '@element-plus/icons-vue'
import socketIo from 'socket.io-client'
import { List, Setting, ArrowRight, ArrowLeft } from '@element-plus/icons-vue'
import SftpPanel from '@/components/file-transfer/sftp-panel.vue'
import TransferTaskManager from '@/components/file-transfer/transfer-task-manager.vue'
import { EventBus } from '@/utils'
import { EventBus, generateSocketInstance } from '@/utils'
defineEmits(['exec-script',])
const { proxy: { $store, $message, $serviceURI } } = getCurrentInstance()
const { proxy: { $message, $router } } = getCurrentInstance()
// 传输配置(仅支持Rsync)
const transferOptions = ref({
@@ -174,7 +173,6 @@ const activeTaskCount = computed(() => {
// Socket连接
const socket = ref(null)
const token = computed(() => $store.token)
// 计算属性
const canTransferToRight = computed(() => {
@@ -207,10 +205,7 @@ onUnmounted(() => {
// Socket连接
const initializeSocket = () => {
socket.value = socketIo($serviceURI, {
path: '/file-transfer',
forceNew: true
})
socket.value = generateSocketInstance('/file-transfer')
socket.value.on('connect', () => {
console.log('文件传输WebSocket已连接')
@@ -249,8 +244,9 @@ const initializeSocket = () => {
$message.error(`${ message }: ${ error }`)
})
socket.value.on('token_verify_fail', () => {
$message.error('登录已过期,请重新登录')
socket.value.on('user_verify_fail', () => {
$message.error('登录态校验失败,请重新登录')
$router.push('/login')
})
socket.value.on('task_deleted', ({ message }) => {
@@ -306,8 +302,7 @@ const performTransfer = (fromSide, toSide) => {
})),
targetPath,
method: 'rsync',
options: transferOptions.value,
token: token.value
options: transferOptions.value
}
isTransferring.value = true
@@ -322,29 +317,29 @@ const showTaskManager = () => {
const refreshTasks = () => {
if (socket.value) {
socket.value.emit('get_tasks', { token: token.value })
socket.value.emit('get_tasks')
}
}
const cancelTask = (taskId) => {
socket.value.emit('cancel_task', { taskId, token: token.value })
socket.value.emit('cancel_task', { taskId })
}
const retryTask = (taskId) => {
socket.value.emit('retry_task', { taskId, token: token.value })
socket.value.emit('retry_task', { taskId })
}
const clearCompletedTasks = () => {
// 发送清空请求到后端
if (socket.value) {
socket.value.emit('clear_completed_tasks', { token: token.value })
socket.value.emit('clear_completed_tasks')
}
}
const deleteTask = (taskId) => {
// 发送删除请求到后端
if (socket.value) {
socket.value.emit('delete_task', { taskId, token: token.value })
socket.value.emit('delete_task', { taskId })
}
}
+30 -3
View File
@@ -2,7 +2,7 @@
<div class="login_container">
<div class="login_box">
<div>
<h2>EasyNode</h2>
<h2>EasyNode-{{ version }}</h2>
</div>
<div v-if="notKey">
<el-alert title="Error: 用于加密的公钥获取失败,请尝试重新启动或部署服务" type="error" show-icon />
@@ -83,8 +83,9 @@
<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue'
import { RSAEncrypt } from '@utils/index.js'
import { version } from '../../../package.json'
const { proxy: { $store, $api, $message, $router } } = getCurrentInstance()
const { proxy: { $store, $api, $message, $router, $messageBox } } = getCurrentInstance()
const expireEnum = reactive({
ONE_SESSION: 'one_session',
@@ -96,6 +97,8 @@ const expireTime = ref(expireEnum.CURRENT_DAY)
const loginFormRefs = ref(null)
const notKey = ref(false)
const loading = ref(false)
const isHttps = location.protocol.includes('https')
const notHttpsTips = localStorage.getItem('notHttpsTips') === 'true'
const loginForm = reactive({
loginName: '',
pwd: '',
@@ -134,7 +137,26 @@ const handleLogin = () => {
$store.setJwtToken(token, expireEnum.ONE_SESSION === expireTime.value)
$store.setUser(loginName, uid)
$message.success({ message: msg || 'success', center: true })
$router.push('/')
if (isHttps) return $router.push('/')
if (notHttpsTips) return $router.push('/')
$messageBox.confirm(
'http协议下存在数据劫持风险,外网使用请配置https协议',
'安全提示',
{
confirmButtonText: '我知道了',
cancelButtonText: '不再提示',
type: 'warning',
showCancelButton: true,
cancelButtonClass: 'el-button--info',
confirmButtonClass: 'el-button--warning'
}
)
.catch(() => {
localStorage.setItem('notHttpsTips', 'true')
})
.finally(async () => {
$router.push('/')
})
} finally {
loading.value = false
}
@@ -177,6 +199,11 @@ onMounted(async () => {
margin: 25px;
color: #409eff;
font-size: 25px;
background: linear-gradient(to right, #ffc021, #e4d1a1);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: 600;
}
.footer_btns {
+5 -13
View File
@@ -206,13 +206,9 @@
<script setup>
import { ref, reactive, onMounted, computed, watch, nextTick, getCurrentInstance, onActivated } from 'vue'
import { ArrowDown } from '@element-plus/icons-vue'
import socketIo from 'socket.io-client'
import { useRoute } from 'vue-router'
import { generateSocketInstance } from '@/utils'
const { io } = socketIo
const { proxy: { $api, $notification,$messageBox, $message, $router, $serviceURI, $store, $tools } } = getCurrentInstance()
const route = useRoute()
const { proxy: { $api, $notification,$messageBox, $message, $router, $store, $tools } } = getCurrentInstance()
const loading = ref(false)
const formVisible = ref(false)
@@ -272,11 +268,7 @@ const createExecShell = (hostIds = [], command = 'ls', timeout = 60) => {
loading.value = true
timeRemaining.value = Number(formData.timeout)
let timer = null
socket.value = io($serviceURI, {
path: '/onekey',
forceNew: false,
reconnectionAttempts: 1
})
socket.value = generateSocketInstance('/onekey')
socket.value.on('connect', () => {
timer = setInterval(() => {
timeRemaining.value -= 1
@@ -312,8 +304,8 @@ const createExecShell = (hostIds = [], command = 'ls', timeout = 60) => {
getOnekeyRecord()
})
socket.value.on('token_verify_fail', () => {
$message.error('token验证失败,请重新登录')
socket.value.on('user_verify_fail', () => {
$message.error('登录态校验失败,请重新登录')
$router.push('/login')
})
+4 -12
View File
@@ -213,11 +213,9 @@ import { ref, onMounted, onUnmounted, computed, watch, getCurrentInstance } from
import { VideoPlay, VideoPause, RefreshRight, Delete, MoreFilled } from '@element-plus/icons-vue'
import CodeEdit from '@/components/code-edit/index.vue'
import PlusLimitTip from '@/components/common/PlusLimitTip.vue'
import socketIo from 'socket.io-client'
import { EventBus } from '@/utils'
import { EventBus, generateSocketInstance } from '@/utils'
const { io } = socketIo
const { proxy: { $store, $serviceURI, $message, $messageBox } } = getCurrentInstance()
const { proxy: { $store, $message, $messageBox } } = getCurrentInstance()
const props = defineProps({
hostId: {
@@ -256,7 +254,6 @@ const makeImageRules = ref({
{ required: false, message: '请输入提交说明', trigger: 'blur' },
]
})
const token = computed(() => $store.token)
const hostId = computed(() => props.hostId)
const containerName = computed(() => `${ currentContainer.value?.name }.log(自动刷新)` || '')
const isPlusActive = computed(() => $store.isPlusActive)
@@ -310,16 +307,11 @@ const getStatusType = (status) => {
}
const connectDocker = () => {
socket.value = io($serviceURI, {
path: '/docker',
forceNew: false,
reconnection: false,
reconnectionAttempts: 0
})
socket.value = generateSocketInstance('/docker')
socket.value.on('connect', () => {
console.log('/docker socket已连接:', hostId.value)
loading.value = true
socket.value.emit('ws_docker', { hostId: hostId.value, token: token.value })
socket.value.emit('ws_docker', { hostId: hostId.value })
socket.value.on('docker_containers_data', (data) => {
// console.log('docker_containers_data:', data)
dockerServerErr.value = false
@@ -538,7 +538,7 @@
<script setup>
import { ref, computed, onMounted, onUnmounted, watch, getCurrentInstance, nextTick } from 'vue'
import { ArrowDown, ArrowLeft, Refresh, View, Hide, Edit, ArrowRight, HomeFilled, Check, Close as CloseIcon, Download, Upload, DocumentCopy, Loading, WarningFilled, Star, StarFilled, Delete, SwitchButton } from '@element-plus/icons-vue'
import socketIo from 'socket.io-client'
import { generateSocketInstance } from '@/utils'
import dirIcon from '@/assets/image/system/dir.png'
import linkIcon from '@/assets/image/system/link.png'
import fileIcon from '@/assets/image/system/file.png'
@@ -561,7 +561,7 @@ const props = defineProps({
})
// 组件实例上下文
const { proxy: { $store, $message, $serviceURI, $messageBox } } = getCurrentInstance()
const { proxy: { $message, $messageBox } } = getCurrentInstance()
// 路径 & 隐藏文件显示
const currentPath = ref('/')
@@ -574,7 +574,6 @@ watch(showHidden, (val) => {
// Socket & 列表
const socket = ref(null)
const token = computed(() => $store.token)
const loading = ref(false)
// 连接状态管理
@@ -707,8 +706,6 @@ onUnmounted(() => {
//----------------------------------
const connectSftp = () => {
const { io } = socketIo
// 清理旧的socket连接
if (socket.value) {
socket.value.removeAllListeners()
@@ -720,14 +717,13 @@ const connectSftp = () => {
connectionError.value = ''
loading.value = true
socket.value = io($serviceURI, {
path: '/sftp-v2',
socket.value = generateSocketInstance('/sftp-v2', {
forceNew: true,
reconnectionAttempts: 0 // 禁用socket.io自带的重连,我们自己控制
reconnectionAttempts: 0
})
socket.value.on('connect', () => {
socket.value.emit('ws_sftp', { hostId: props.hostId, token: token.value })
socket.value.emit('ws_sftp', { hostId: props.hostId })
socket.value.on('connect_success', ({ rootList, isRootUser, currentPath: serverCurrentPath }) => {
fileListRaw.value = rootList
+6 -11
View File
@@ -23,20 +23,17 @@ import { FitAddon } from '@xterm/addon-fit'
import { SearchAddon } from '@xterm/addon-search'
// import { SearchBarAddon } from 'xterm-addon-search-bar'
import { WebLinksAddon } from '@xterm/addon-web-links'
import socketIo from 'socket.io-client'
import themeList from 'xterm-theme'
import { terminalStatus } from '@/utils/enum'
import { useContextMenu } from '@/composables/useContextMenu'
import { EventBus, isDockerId, isDockerComposeYml } from '@/utils'
import { EventBus, isDockerId, isDockerComposeYml, generateSocketInstance } from '@/utils'
import useMobileWidth from '@/composables/useMobileWidth'
const { CONNECTING, CONNECT_SUCCESS, CONNECT_FAIL } = terminalStatus
const instance = getCurrentInstance()
const { uid } = instance
const { proxy: { $api, $store, $serviceURI, $notification, $router, $message, $messageBox } } = instance
const { io } = socketIo
const { proxy: { $api, $store, $notification, $router, $message, $messageBox } } = instance
const { isMobileScreen } = useMobileWidth()
@@ -79,7 +76,6 @@ const cursorTheme = {
cursorAccent: '#000000'
}
const token = computed(() => $store.token)
const theme = computed(() => themeList[$store.terminalConfig.themeName])
const fontSize = computed(() => $store.terminalConfig.fontSize)
const background = computed(() => $store.terminalConfig.background)
@@ -153,8 +149,7 @@ const getCommand = async () => {
const connectIO = () => {
curStatus.value = CONNECTING
socket.value = io($serviceURI, {
path: '/terminal',
socket.value = generateSocketInstance('/terminal', {
forceNew: false,
reconnection: false,
reconnectionAttempts: 0
@@ -163,7 +158,7 @@ const connectIO = () => {
console.log('/terminal socket已连接:', hostId.value)
socketConnected.value = true
socket.value.emit('ws_terminal', { hostId: hostId.value, token: token.value })
socket.value.emit('ws_terminal', { hostId: hostId.value })
socket.value.on('terminal_connect_success', () => {
socket.value.on('output', (str) => {
if (props.isSingleWindow && !isPlusActive.value) return
@@ -192,8 +187,8 @@ const connectIO = () => {
emit('ping-data', { host: host.value, time })
})
socket.value.on('token_verify_fail', () => {
$notification({ title: 'Error', message: 'token校验失败,请重新登录', type: 'error' })
socket.value.on('user_verify_fail', () => {
$notification({ title: 'Error', message: '登录态校验失败,请重新登录', type: 'error' })
$router.push('/login')
})