feat: 修复 WebSocket 越权与 AI 流 SSRF
This commit is contained in:
+19
-5
@@ -1,17 +1,19 @@
|
||||
import { WS_BASE_URL } from '@env';
|
||||
import { get } from '../api/client';
|
||||
|
||||
export type WSMessageHandler = (data: any) => void;
|
||||
|
||||
class WebSocketManager {
|
||||
private ws: WebSocket | null = null;
|
||||
private token: string | null = null;
|
||||
private ticket: string | null = null;
|
||||
private handlers: Set<WSMessageHandler> = new Set();
|
||||
private reconnectTimer: ReturnType<typeof setTimeout> | null = null;
|
||||
private reconnectAttempts = 0;
|
||||
private maxReconnectAttempts = 10;
|
||||
private isManualClose = false;
|
||||
|
||||
connect(token: string): void {
|
||||
async connect(token: string): Promise<void> {
|
||||
// Close any existing connection before creating a new one
|
||||
if (this.ws) {
|
||||
this.isManualClose = true;
|
||||
@@ -27,14 +29,14 @@ class WebSocketManager {
|
||||
this.reconnectAttempts = 0;
|
||||
this.token = token;
|
||||
this.isManualClose = false;
|
||||
this.doConnect();
|
||||
await this.refreshTicketAndConnect();
|
||||
}
|
||||
|
||||
private doConnect(): void {
|
||||
if (!this.token) return;
|
||||
if (!this.token || !this.ticket) return;
|
||||
|
||||
const wsUrl = (WS_BASE_URL || 'ws://localhost:3000/ws').replace(/\?.*$/, '');
|
||||
const url = `${wsUrl}?token=${encodeURIComponent(this.token)}`;
|
||||
const url = `${wsUrl}?ticket=${encodeURIComponent(this.ticket)}`;
|
||||
|
||||
try {
|
||||
this.ws = new WebSocket(url);
|
||||
@@ -84,11 +86,23 @@ class WebSocketManager {
|
||||
|
||||
this.reconnectTimer = setTimeout(() => {
|
||||
if (!this.isManualClose && this.token) {
|
||||
this.doConnect();
|
||||
this.refreshTicketAndConnect();
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
|
||||
private async refreshTicketAndConnect(): Promise<void> {
|
||||
if (!this.token) return;
|
||||
try {
|
||||
const { ticket } = await get<{ ticket: string }>('/ws/ticket');
|
||||
this.ticket = ticket;
|
||||
this.doConnect();
|
||||
} catch (e) {
|
||||
console.warn('[WS] Failed to fetch ticket:', e);
|
||||
this.scheduleReconnect();
|
||||
}
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
this.isManualClose = true;
|
||||
if (this.reconnectTimer) {
|
||||
|
||||
Reference in New Issue
Block a user