Make relay opt-in when pairing devices (#2706)
* feat: make relay opt-in for device pairing * fix(relay): keep pairing state authoritative * fix(relay): refresh pairing state across transports * fix(onboard): honor explicit relay opt-out * fix(relay): surface transport startup failures * fix(pairing): gate offers for older daemons * test(cli): rely on real pairing transport coverage * fix(cli): report live relay without a pid file * fix(relay): synchronize config during daemon startup * fix(relay): preserve mutability for ignored overrides * fix(cli): use reachable daemon for pairing * fix(app): redirect invalid pair device routes * fix(pairing): support remote host device pairing Keep Pair Device host-relative through the existing settings and daemon RPC flow. Route CLI output through an injected adapter so workflow tests do not mutate process globals. * fix(pairing): validate pairing destinations Expose the host-relative Pair Device flow on every supported app platform. Reject a reachable daemon whose identity does not match the requested Paseo home before reading or mutating its pairing state. * fix(pairing): render QR codes across platforms Generate SVG text without DOM or canvas and render it through the existing cross-platform SVG stack. * fix(cli): pair from persisted relay state Allow explicit relay pairing while the daemon is stopped when relay is already enabled in persisted configuration.
This commit is contained in:
@@ -15,7 +15,7 @@ const paseoHome = await mkdtemp(join(tmpdir(), "paseo-onboard-home-"));
|
||||
const port = await getAvailablePort();
|
||||
|
||||
try {
|
||||
console.log("Test 1: `paseo` runs blocking onboarding and prints pairing info");
|
||||
console.log("Test 1: `paseo` runs blocking onboarding without implicit relay pairing");
|
||||
const onboard =
|
||||
await $`PASEO_HOME=${paseoHome} PASEO_LISTEN=127.0.0.1:${port} PASEO_PAIRING_QR=0 npx paseo`.nothrow();
|
||||
|
||||
@@ -24,12 +24,12 @@ try {
|
||||
0,
|
||||
`onboard should succeed:\nstdout:\n${onboard.stdout}\nstderr:\n${onboard.stderr}`,
|
||||
);
|
||||
assert(onboard.stdout.includes("Scan to pair"), "onboard output should include scan header");
|
||||
assert(!onboard.stdout.includes("Scan to pair"), "onboard output should not include scan header");
|
||||
assert(!onboard.stdout.includes("#offer="), "onboard output should not include a pairing offer");
|
||||
assert(
|
||||
onboard.stdout.includes("Pairing link"),
|
||||
"onboard output should include pairing link header",
|
||||
onboard.stdout.includes("Daemon is running with relay off"),
|
||||
"onboard output should explain the direct connection path",
|
||||
);
|
||||
assert(onboard.stdout.includes("#offer="), "onboard output should include pairing offer URL");
|
||||
assert(
|
||||
onboard.stdout.includes("CLI quick reference"),
|
||||
"onboard output should include CLI quick reference",
|
||||
@@ -50,9 +50,28 @@ try {
|
||||
await $`PASEO_HOME=${paseoHome} npx paseo daemon status --home ${paseoHome}`.nothrow();
|
||||
assert.strictEqual(status.exitCode, 0, `daemon status should succeed: ${status.stderr}`);
|
||||
assert(status.stdout.includes("running"), "daemon should be running when onboarding exits");
|
||||
console.log("✓ onboarding prints pairing info and waits for daemon readiness\n");
|
||||
console.log("✓ onboarding keeps relay disabled and waits for daemon readiness\n");
|
||||
|
||||
console.log("Test 2: non-interactive onboarding persists voice disabled config");
|
||||
console.log("Test 2: --no-relay suppresses pairing for an already-running daemon");
|
||||
const enableRelay =
|
||||
await $`PASEO_HOME=${paseoHome} npx paseo daemon pair --home ${paseoHome} --relay`.nothrow();
|
||||
assert.strictEqual(enableRelay.exitCode, 0, `relay enable should succeed: ${enableRelay.stderr}`);
|
||||
assert(enableRelay.stdout.includes("#offer="), "relay enable should produce a pairing offer");
|
||||
|
||||
const noRelayOnboard =
|
||||
await $`PASEO_HOME=${paseoHome} PASEO_LISTEN=127.0.0.1:${port} npx paseo --no-relay`.nothrow();
|
||||
assert.strictEqual(
|
||||
noRelayOnboard.exitCode,
|
||||
0,
|
||||
`--no-relay onboarding should succeed: ${noRelayOnboard.stderr}`,
|
||||
);
|
||||
assert(
|
||||
!noRelayOnboard.stdout.includes("#offer="),
|
||||
"--no-relay onboarding should not include a pairing offer",
|
||||
);
|
||||
console.log("✓ --no-relay suppresses pairing for an already-running daemon\n");
|
||||
|
||||
console.log("Test 3: non-interactive onboarding persists voice disabled config");
|
||||
const configRaw = await readFile(join(paseoHome, "config.json"), "utf-8");
|
||||
const config = JSON.parse(configRaw) as {
|
||||
features?: {
|
||||
|
||||
Reference in New Issue
Block a user