'use strict'; const crypto = require('crypto'); const { v4: uuidv4 } = require('uuid'); // ─── 常量 ─── const HANDSHAKE_EXPIRE_MS = 5 * 60 * 1000; // 5分钟 const HEARTBEAT_INTERVAL_MS = 30 * 1000; // 30秒 const CONNECTION_EXPIRE_MS = 24 * 60 * 60 * 1000; // 24小时 // ─── 内存存储 ─── const pendingHandshakes = new Map(); // handshakeId → { initiatorId, targetId, createdAt, tempKey } const activeConnections = new Map(); // connectionId → { initiatorId, targetId, createdAt, lastHeartbeat, sharedKey } /** * 初始化握手 * @param {string} initiatorId - 发起方Agent ID * @param {string} targetId - 目标Agent ID * @param {string} token - 会话token * @returns {{handshakeId: string, tempKey: string, expiresAt: string}} */ function initiateHandshake(initiatorId, targetId, token) { if (!initiatorId || !targetId || !token) { throw new Error('缺少必要参数'); } // 验证会话token // TODO: 集成现有会话验证系统 const handshakeId = uuidv4(); const tempKey = crypto.randomBytes(32).toString('hex'); const expiresAt = Date.now() + HANDSHAKE_EXPIRE_MS; pendingHandshakes.set(handshakeId, { initiatorId, targetId, tempKey, createdAt: Date.now(), expiresAt }); return { handshakeId, tempKey, expiresAt: new Date(expiresAt).toISOString() }; } /** * 完成握手 * @param {string} handshakeId - 握手ID * @param {string} targetId - 目标Agent ID * @param {string} targetKey - 目标Agent临时密钥 * @param {string} token - 会话token * @returns {{connectionId: string, sharedKey: string, expiresAt: string}} */ function completeHandshake(handshakeId, targetId, targetKey, token) { if (!handshakeId || !targetId || !targetKey || !token) { throw new Error('缺少必要参数'); } const handshake = pendingHandshakes.get(handshakeId); if (!handshake) { throw new Error('无效的握手ID'); } if (Date.now() > handshake.expiresAt) { pendingHandshakes.delete(handshakeId); throw new Error('握手已过期'); } if (handshake.targetId !== targetId) { throw new Error('目标Agent不匹配'); } // 验证临时密钥 if (handshake.tempKey !== targetKey) { throw new Error('无效的临时密钥'); } // 生成共享密钥 const connectionId = uuidv4(); const sharedKey = crypto.randomBytes(32).toString('hex'); const expiresAt = Date.now() + CONNECTION_EXPIRE_MS; activeConnections.set(connectionId, { initiatorId: handshake.initiatorId, targetId: handshake.targetId, sharedKey, createdAt: Date.now(), lastHeartbeat: Date.now(), expiresAt }); // 清理握手 pendingHandshakes.delete(handshakeId); return { connectionId, sharedKey, expiresAt: new Date(expiresAt).toISOString() }; } /** * 心跳检测 * @param {string} connectionId - 连接ID * @param {string} token - 会话token * @returns {{alive: boolean, expiresAt: string}} */ function heartbeat(connectionId, token) { if (!connectionId || !token) { throw new Error('缺少必要参数'); } const connection = activeConnections.get(connectionId); if (!connection) { throw new Error('无效的连接ID'); } if (Date.now() > connection.expiresAt) { activeConnections.delete(connectionId); throw new Error('连接已过期'); } connection.lastHeartbeat = Date.now(); return { alive: true, expiresAt: new Date(connection.expiresAt).toISOString() }; } /** * 断开连接 * @param {string} connectionId - 连接ID * @param {string} token - 会话token * @returns {{success: boolean}} */ function disconnect(connectionId, token) { if (!connectionId || !token) { throw new Error('缺少必要参数'); } activeConnections.delete(connectionId); return { success: true }; } /** * 验证连接 * @param {string} connectionId - 连接ID * @param {string} sharedKey - 共享密钥 * @returns {{valid: boolean, initiatorId?: string, targetId?: string}} */ function validateConnection(connectionId, sharedKey) { if (!connectionId || !sharedKey) { return { valid: false }; } const connection = activeConnections.get(connectionId); if (!connection) { return { valid: false }; } if (Date.now() > connection.expiresAt) { activeConnections.delete(connectionId); return { valid: false }; } if (connection.sharedKey !== sharedKey) { return { valid: false }; } return { valid: true, initiatorId: connection.initiatorId, targetId: connection.targetId }; } module.exports = { initiateHandshake, completeHandshake, heartbeat, disconnect, validateConnection };