diff --git a/src/shadowbox/server/manager_service.ts b/src/shadowbox/server/manager_service.ts index ab94225b..b58523d8 100644 --- a/src/shadowbox/server/manager_service.ts +++ b/src/shadowbox/server/manager_service.ts @@ -292,7 +292,7 @@ function validateWebSocketConfig(websocket: unknown): WebSocketConfig | undefine ); } - const config = websocket as any; + const config = websocket as Record; // Validate enabled field if ('enabled' in config && typeof config.enabled !== 'boolean') { @@ -334,7 +334,7 @@ function validateWebSocketConfig(websocket: unknown): WebSocketConfig | undefine ); } - return config as WebSocketConfig; + return config as unknown as WebSocketConfig; } // The ShadowsocksManagerService manages the access keys that can use the server @@ -669,13 +669,19 @@ export class ShadowsocksManagerService { } // Generate the dynamic config YAML - const yamlConfig = (this.shadowsocksServer as any).generateDynamicAccessKeyYaml?.(accessKeyId); + // Type assertion for the extended server interface + const serverWithWebSocket = this.shadowsocksServer as ShadowsocksServer & { + generateDynamicAccessKeyYaml?: (accessKeyId: string) => string | null; + }; + const yamlConfig = serverWithWebSocket.generateDynamicAccessKeyYaml?.(accessKeyId); if (!yamlConfig) { return next(new restifyErrors.NotImplementedError('WebSocket configuration not available')); } - (res as any).contentType('text/yaml'); + // Set content type for YAML response + const response = res as restify.Response & { contentType: (type: string) => void }; + response.contentType('text/yaml'); res.send(HttpSuccess.OK, yamlConfig); next(); } catch (error) { diff --git a/src/shadowbox/server/outline_shadowsocks_server.ts b/src/shadowbox/server/outline_shadowsocks_server.ts index 6681d78c..a73d4cad 100644 --- a/src/shadowbox/server/outline_shadowsocks_server.ts +++ b/src/shadowbox/server/outline_shadowsocks_server.ts @@ -32,6 +32,43 @@ export interface ShadowsocksAccessKeyWithWebSocket extends ShadowsocksAccessKey }; } +// Configuration types for outline-ss-server +interface LegacyConfig { + keys: ShadowsocksAccessKey[]; +} + +interface WebSocketListener { + type: 'websocket-stream' | 'websocket-packet'; + web_server: string; + path: string; +} + +interface TcpUdpListener { + type: 'tcp' | 'udp'; + address: string; +} + +interface ServiceConfig { + listeners: Array; + keys: Array<{ + id: string; + cipher: string; + secret: string; + }>; +} + +interface WebSocketConfig { + web?: { + servers: Array<{ + id: string; + listen: string[]; + }>; + }; + services: ServiceConfig[]; +} + +type ServerConfig = LegacyConfig | WebSocketConfig; + // Runs outline-ss-server. export class OutlineShadowsocksServer implements ShadowsocksServer { private ssProcess: child_process.ChildProcess; @@ -114,7 +151,7 @@ export class OutlineShadowsocksServer implements ShadowsocksServer { const extendedKeys = keys as ShadowsocksAccessKeyWithWebSocket[]; const hasWebSocketKeys = extendedKeys.some(key => key.websocket?.enabled); - let config: any; + let config: ServerConfig; if (hasWebSocketKeys && this.webSocketConfig?.enabled) { // Use new format with WebSocket support @@ -149,7 +186,7 @@ export class OutlineShadowsocksServer implements ShadowsocksServer { }); } - private generateWebSocketConfig(keys: ShadowsocksAccessKeyWithWebSocket[]): any { + private generateWebSocketConfig(keys: ShadowsocksAccessKeyWithWebSocket[]): WebSocketConfig { // Group keys by their listener configuration const serviceGroups = new Map(); @@ -180,7 +217,7 @@ export class OutlineShadowsocksServer implements ShadowsocksServer { } // Build the configuration - const config: any = { + const config: WebSocketConfig = { services: [] }; @@ -196,7 +233,7 @@ export class OutlineShadowsocksServer implements ShadowsocksServer { // Create services for (const [groupKey, groupKeys] of serviceGroups) { - const service: any = { + const service: ServiceConfig = { listeners: [], keys: groupKeys.map(k => ({ id: k.id,