mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-07 17:04:42 +00:00
fix(hub): harden relationship boundaries
This commit is contained in:
@@ -91,6 +91,7 @@ export class AgentStorage {
|
||||
private pendingWrites: Map<string, Promise<void>> = new Map();
|
||||
private deleting: Set<string> = new Set();
|
||||
private hubAgentIdsByExecution: Map<string, string> = new Map();
|
||||
private hubExecutionKeysByAgentId: Map<string, string> = new Map();
|
||||
private loaded = false;
|
||||
private baseDir: string;
|
||||
private loadPromise: Promise<StoredAgentRecord[]> | null = null;
|
||||
@@ -260,6 +261,7 @@ export class AgentStorage {
|
||||
this.pathById.clear();
|
||||
this.pathsById.clear();
|
||||
this.hubAgentIdsByExecution.clear();
|
||||
this.hubExecutionKeysByAgentId.clear();
|
||||
|
||||
try {
|
||||
const records = await this.scanDisk();
|
||||
@@ -366,16 +368,23 @@ export class AgentStorage {
|
||||
private indexOwner(record: StoredAgentRecord): void {
|
||||
this.removeOwnerIndex(record.id);
|
||||
if (record.owner?.kind === "hub") {
|
||||
this.hubAgentIdsByExecution.set(hubExecutionKey(record.owner), record.id);
|
||||
const key = hubExecutionKey(record.owner);
|
||||
const previousAgentId = this.hubAgentIdsByExecution.get(key);
|
||||
if (previousAgentId && previousAgentId !== record.id) {
|
||||
this.hubExecutionKeysByAgentId.delete(previousAgentId);
|
||||
}
|
||||
this.hubAgentIdsByExecution.set(key, record.id);
|
||||
this.hubExecutionKeysByAgentId.set(record.id, key);
|
||||
}
|
||||
}
|
||||
|
||||
private removeOwnerIndex(agentId: string): void {
|
||||
for (const [key, indexedAgentId] of this.hubAgentIdsByExecution) {
|
||||
if (indexedAgentId === agentId) {
|
||||
this.hubAgentIdsByExecution.delete(key);
|
||||
}
|
||||
const key = this.hubExecutionKeysByAgentId.get(agentId);
|
||||
if (!key) return;
|
||||
if (this.hubAgentIdsByExecution.get(key) === agentId) {
|
||||
this.hubAgentIdsByExecution.delete(key);
|
||||
}
|
||||
this.hubExecutionKeysByAgentId.delete(agentId);
|
||||
}
|
||||
|
||||
private async waitForPendingWrite(agentId: string): Promise<void> {
|
||||
|
||||
@@ -58,6 +58,7 @@ import type {
|
||||
const execFileAsync = promisify(execFile);
|
||||
const HUB_ORIGIN = "https://hub.test";
|
||||
const SOCKET_URL = "wss://hub.test/daemon";
|
||||
const REPOSITORY_ROOT = path.resolve(import.meta.dirname, "../../../../../..");
|
||||
|
||||
export interface ArchiveWatcher {
|
||||
close(): void;
|
||||
@@ -1013,11 +1014,11 @@ export class HubRelationshipHarness {
|
||||
}
|
||||
|
||||
private async runCli(args: string[]): Promise<Record<string, unknown>> {
|
||||
const entrypoint = path.join(process.cwd(), "packages/cli/src/index.ts");
|
||||
const entrypoint = path.join(REPOSITORY_ROOT, "packages/cli/src/index.ts");
|
||||
const { stdout } = await execFileAsync(
|
||||
process.execPath,
|
||||
["--import", "tsx", entrypoint, ...args, "--host", this.host, "--json"],
|
||||
{ cwd: process.cwd(), env: { ...process.env, NO_COLOR: "1" } },
|
||||
{ cwd: REPOSITORY_ROOT, env: { ...process.env, NO_COLOR: "1" } },
|
||||
);
|
||||
const parsed = JSON.parse(stdout) as unknown;
|
||||
if (Array.isArray(parsed)) return parsed[0] as Record<string, unknown>;
|
||||
|
||||
@@ -188,6 +188,7 @@ function connectClient(
|
||||
) {
|
||||
const ws = createOpenSocket();
|
||||
asInternals<WebSocketServerInternals>(server).sessions.set(ws, {
|
||||
kind: "trusted",
|
||||
session: createSessionWithActivity(activity),
|
||||
clientId: "client-test",
|
||||
appVersion: null,
|
||||
|
||||
@@ -198,6 +198,7 @@ function createOpenSocket() {
|
||||
function connectClient(server: VoiceAssistantWebSocketServer) {
|
||||
const ws = createOpenSocket();
|
||||
asInternals<{ sessions: Map<unknown, unknown> }>(server).sessions.set(ws, {
|
||||
kind: "trusted",
|
||||
session: {
|
||||
getClientActivity: vi.fn(() => null),
|
||||
},
|
||||
|
||||
@@ -2262,7 +2262,7 @@ function toSessionPeer(identity: WebSocketConnectionIdentity): SessionPeer {
|
||||
|
||||
function isLoopbackAddress(address: string): boolean {
|
||||
const normalized = address.toLowerCase();
|
||||
if (normalized === "::1") return true;
|
||||
if (normalized === "::1" || normalized === "0:0:0:0:0:0:0:1") return true;
|
||||
const ipv4 = normalized.startsWith("::ffff:") ? normalized.slice("::ffff:".length) : normalized;
|
||||
return ipv4.startsWith("127.");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user