feat(remote): 完善远程桌面认证机制

1. 修复 WebSocket 认证漏洞:WebSocket 连接现在需要认证(支持 URL 参数 password 或 Cookie token)

2. 支持 URL 参数自动登录:HTTP 请求带 ?password=xxx 参数时会自动验证并设置 cookie

3. 主程序添加密码配置:
   - RemoteDevice 类型添加 password 字段
   - ConfigDialog 添加密码输入框
   - 打开远程桌面时传递 password 参数

4. 修复 remote/public/js/app.js:
   - 从 URL 参数获取 password 并传递给 WebSocket 连接
   - 移除错误的 token 当作 password 的代码

5. 添加密码变化检测:修改密码后自动刷新页面重新认证,无需重启 remote 服务

6. 文件传输 API 支持 password 参数
This commit is contained in:
2026-03-09 00:54:48 +08:00
parent 8531d916a3
commit 50cfc8835f
10 changed files with 187 additions and 32 deletions

View File

@@ -1,6 +1,6 @@
import React, { useState, useCallback, useRef, useEffect } from 'react'
import type { FileItem } from '@/lib/api'
import { type RemoteFileItem, uploadFileToRemote, downloadFileFromRemote } from '../../api'
import { type RemoteFileItem, uploadFileToRemote, downloadFileFromRemote, fetchSystemFileContent } from '../../api'
import { type TransferItem } from '../../types'
import { LocalFilePanel } from './LocalFilePanel'
import { RemoteFilePanel } from './RemoteFilePanel'
@@ -9,10 +9,11 @@ import { TransferQueue } from './TransferQueue'
interface FileTransferPageProps {
serverHost: string
port: number
password?: string
onClose: () => void
}
export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost, port, onClose }) => {
export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost, port, password, onClose }) => {
const [localSelected, setLocalSelected] = useState<FileItem | null>(null)
const [remoteSelected, setRemoteSelected] = useState<RemoteFileItem | null>(null)
const [transfers, setTransfers] = useState<TransferItem[]>([])
@@ -38,11 +39,10 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
setTransfers((prev) => [...prev, newTransfer])
try {
const response = await fetch(`/api/files/content?path=${encodeURIComponent(localSelected.path)}`)
const blob = await response.blob()
const blob = await fetchSystemFileContent(localSelected.path)
const file = new File([blob], localSelected.name, { type: blob.type })
await uploadFileToRemote(serverHost, port, file, '', undefined, (progress) => {
await uploadFileToRemote(serverHost, port, file, '', password, (progress) => {
setTransfers((prev) =>
prev.map((t) => (t.id === transferId ? { ...t, progress } : t))
)
@@ -84,7 +84,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
setTransfers((prev) => [...prev, newTransfer])
try {
await downloadFileFromRemote(serverHost, port, remoteSelected.name, '', undefined, (progress) => {
await downloadFileFromRemote(serverHost, port, remoteSelected.name, '', password, (progress) => {
setTransfers((prev) =>
prev.map((t) => (t.id === transferId ? { ...t, progress } : t))
)
@@ -162,6 +162,7 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
<RemoteFilePanel
serverHost={serverHost}
port={port}
password={password}
selectedFile={remoteSelected}
onSelect={setRemoteSelected}
onDownload={handleDownload}
@@ -171,7 +172,8 @@ export const FileTransferPage: React.FC<FileTransferPageProps> = ({ serverHost,
</div>
<div
className="h-2 -my-1 cursor-row-resize hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors relative z-10"
className="cursor-row-resize hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors relative z-10"
style={{ height: 4, marginTop: 0, marginBottom: -4 }}
onMouseDown={handleDragStart}
/>