Relay pairing offer v2 (E2EE) + host connections

This commit is contained in:
Mohamed Boudra
2026-02-04 22:53:00 +07:00
parent 9ce4ad9758
commit 0218729316
59 changed files with 2022 additions and 1547 deletions
+28 -99
View File
@@ -15,23 +15,32 @@ test('new agent auto-selects the previous host', async ({ page }) => {
test('new agent respects serverId in the URL', async ({ page }) => {
const daemonPort = process.env.E2E_DAEMON_PORT;
const serverId = process.env.E2E_SERVER_ID;
if (!daemonPort) {
throw new Error('E2E_DAEMON_PORT is not set (expected from globalSetup).');
}
if (!serverId) {
throw new Error('E2E_SERVER_ID is not set (expected from globalSetup).');
}
// Ensure this test's storage is deterministic even under parallel load.
const nowIso = new Date().toISOString();
const testDaemon = {
id: 'e2e-test-daemon',
serverId,
label: 'localhost',
endpoints: [`127.0.0.1:${daemonPort}`],
relay: null,
metadata: null,
connections: [
{
id: `direct:127.0.0.1:${daemonPort}`,
type: 'direct',
endpoint: `127.0.0.1:${daemonPort}`,
},
],
preferredConnectionId: `direct:127.0.0.1:${daemonPort}`,
createdAt: nowIso,
updatedAt: nowIso,
};
const createAgentPreferences = {
serverId: testDaemon.id,
serverId: testDaemon.serverId,
provider: 'claude',
providerPreferences: {
claude: { model: 'haiku' },
@@ -53,19 +62,7 @@ test('new agent respects serverId in the URL', async ({ page }) => {
await page.reload();
await expect(page.getByText('Online', { exact: true }).first()).toBeVisible({ timeout: 20000 });
const seededDaemonId = await page.evaluate(() => {
const raw = localStorage.getItem('@paseo:daemon-registry');
if (!raw) return null;
const parsed = JSON.parse(raw) as any[];
return Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0]?.id === 'string'
? (parsed[0].id as string)
: null;
});
if (!seededDaemonId) {
throw new Error('Expected daemon registry to contain a seeded daemon id.');
}
await page.goto(`/?serverId=${encodeURIComponent(seededDaemonId)}`);
await page.goto(`/?serverId=${encodeURIComponent(serverId)}`);
await expect(page.getByText('New agent', { exact: true }).first()).toBeVisible();
const input = page.getByRole('textbox', { name: 'Message agent...' });
@@ -74,17 +71,26 @@ test('new agent respects serverId in the URL', async ({ page }) => {
test('new agent auto-selects first online host when no preference is stored', async ({ page }) => {
const daemonPort = process.env.E2E_DAEMON_PORT;
const serverId = process.env.E2E_SERVER_ID;
if (!daemonPort) {
throw new Error('E2E_DAEMON_PORT is not set (expected from globalSetup).');
}
if (!serverId) {
throw new Error('E2E_SERVER_ID is not set (expected from globalSetup).');
}
const nowIso = new Date().toISOString();
const testDaemon = {
id: 'e2e-test-daemon',
serverId,
label: 'localhost',
endpoints: [`127.0.0.1:${daemonPort}`],
relay: null,
metadata: null,
connections: [
{
id: `direct:127.0.0.1:${daemonPort}`,
type: 'direct',
endpoint: `127.0.0.1:${daemonPort}`,
},
],
preferredConnectionId: `direct:127.0.0.1:${daemonPort}`,
createdAt: nowIso,
updatedAt: nowIso,
};
@@ -110,80 +116,3 @@ test('new agent auto-selects first online host when no preference is stored', as
const input = page.getByRole('textbox', { name: 'Message agent...' });
await expect(input).toBeEditable({ timeout: 30000 });
});
test('adopts daemon-provided serverId for legacy host ids', async ({ page }) => {
const daemonPort = process.env.E2E_DAEMON_PORT;
if (!daemonPort) {
throw new Error('E2E_DAEMON_PORT is not set (expected from globalSetup).');
}
const nowIso = new Date().toISOString();
const legacyId = 'legacy-daemon-id';
const daemon = {
id: legacyId,
label: 'localhost',
endpoints: [`127.0.0.1:${daemonPort}`],
relay: null,
metadata: null,
createdAt: nowIso,
updatedAt: nowIso,
};
await page.goto('/settings');
await page.evaluate(
({ daemon, legacyId }) => {
const nonce = localStorage.getItem('@paseo:e2e-seed-nonce') ?? '1';
localStorage.setItem('@paseo:e2e-disable-default-seed-once', nonce);
localStorage.setItem('@paseo:daemon-registry', JSON.stringify([daemon]));
localStorage.setItem(
'@paseo:create-agent-preferences',
JSON.stringify({
serverId: legacyId,
provider: 'claude',
providerPreferences: {
claude: { model: 'haiku' },
codex: { model: 'gpt-5.1-codex-mini' },
},
})
);
localStorage.removeItem('@paseo:settings');
},
{ daemon, legacyId }
);
await page.reload();
await expect(page.getByText('Online', { exact: true }).first()).toBeVisible({ timeout: 20000 });
// Wait for server_info handshake to rekey registry + preferences.
await page.waitForFunction(
() => {
const raw = localStorage.getItem('@paseo:daemon-registry');
const prefsRaw = localStorage.getItem('@paseo:create-agent-preferences');
if (!raw || !prefsRaw) return false;
const registry = JSON.parse(raw);
const prefs = JSON.parse(prefsRaw);
if (!Array.isArray(registry) || registry.length !== 1) return false;
if (registry[0]?.id !== 'e2e-test-daemon') return false;
if (prefs?.serverId !== 'e2e-test-daemon') return false;
const legacyIds = registry[0]?.metadata?.legacyIds;
return Array.isArray(legacyIds) && legacyIds.includes('legacy-daemon-id');
},
{ timeout: 20000 }
);
const snapshot = await page.evaluate(() => {
const raw = localStorage.getItem('@paseo:daemon-registry');
const prefsRaw = localStorage.getItem('@paseo:create-agent-preferences');
return { raw, prefsRaw };
});
if (!snapshot.raw || !snapshot.prefsRaw) {
throw new Error('Expected registry + preferences to be present after rekey.');
}
const registry = JSON.parse(snapshot.raw) as any[];
expect(registry[0].id).toBe('e2e-test-daemon');
expect(registry[0].metadata.legacyIds).toContain('legacy-daemon-id');
const prefs = JSON.parse(snapshot.prefsRaw) as any;
expect(prefs.serverId).toBe('e2e-test-daemon');
});