diff --git a/src/cli/qr-cli.test.ts b/src/cli/qr-cli.test.ts index 32f01b34d38..c9e42e3c6c7 100644 --- a/src/cli/qr-cli.test.ts +++ b/src/cli/qr-cli.test.ts @@ -118,8 +118,8 @@ describe("registerQrCli", () => { it("uses gateway.remote.url when --remote is set (ignores device-pair publicUrl)", async () => { loadConfig.mockReturnValue({ gateway: { - remote: { url: "wss://remote.example.com:444" }, - auth: { mode: "token", token: "tok" }, + auth: { mode: "token", token: "local-tok" }, + remote: { url: "wss://remote.example.com:444", token: "remote-tok" }, }, plugins: { entries: { @@ -139,7 +139,7 @@ describe("registerQrCli", () => { const expected = encodePairingSetupCode({ url: "wss://remote.example.com:444", - token: "tok", + token: "remote-tok", }); expect(runtime.log).toHaveBeenCalledWith(expected); }); diff --git a/src/cli/qr-cli.ts b/src/cli/qr-cli.ts index aef119aa779..8b0c35cb326 100644 --- a/src/cli/qr-cli.ts +++ b/src/cli/qr-cli.ts @@ -79,6 +79,27 @@ export function registerQrCli(program: Command) { } const wantsRemote = opts.remote === true; + if (wantsRemote && !token && !password) { + const remoteToken = + typeof cfg.gateway?.remote?.token === "string" ? cfg.gateway.remote.token.trim() : ""; + const remotePassword = + typeof cfg.gateway?.remote?.password === "string" + ? cfg.gateway.remote.password.trim() + : ""; + + // In remote mode, prefer the client-side remote credentials. These are expected to match the + // remote gateway's auth settings (gateway.remote.token/password ~= gateway.auth.token/password). + if (remoteToken) { + cfg.gateway.auth.mode = "token"; + cfg.gateway.auth.token = remoteToken; + cfg.gateway.auth.password = undefined; + } else if (remotePassword) { + cfg.gateway.auth.mode = "password"; + cfg.gateway.auth.password = remotePassword; + cfg.gateway.auth.token = undefined; + } + } + if (wantsRemote && !opts.url && !opts.publicUrl) { const tailscaleMode = cfg.gateway?.tailscale?.mode ?? "off"; const remoteUrl = cfg.gateway?.remote?.url;