From c1d2f74bc5c3cea80cca97a15166c8ed2b4bee28 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 23:51:19 +0000 Subject: [PATCH] refactor(test): dedupe gateway auth e2e lockout setup --- src/gateway/server.auth.e2e.test.ts | 121 ++++++++++++---------------- 1 file changed, 53 insertions(+), 68 deletions(-) diff --git a/src/gateway/server.auth.e2e.test.ts b/src/gateway/server.auth.e2e.test.ts index 8064b72f6..91fb4cefc 100644 --- a/src/gateway/server.auth.e2e.test.ts +++ b/src/gateway/server.auth.e2e.test.ts @@ -54,6 +54,53 @@ const openTailscaleWs = async (port: number) => { const originForPort = (port: number) => `http://127.0.0.1:${port}`; +function restoreGatewayToken(prevToken: string | undefined) { + if (prevToken === undefined) { + delete process.env.OPENCLAW_GATEWAY_TOKEN; + } else { + process.env.OPENCLAW_GATEWAY_TOKEN = prevToken; + } +} + +async function startRateLimitedTokenServerWithPairedDeviceToken() { + const { loadOrCreateDeviceIdentity } = await import("../infra/device-identity.js"); + const { approveDevicePairing, getPairedDevice, listDevicePairing } = + await import("../infra/device-pairing.js"); + + testState.gatewayAuth = { + mode: "token", + token: "secret", + rateLimit: { maxAttempts: 1, windowMs: 60_000, lockoutMs: 60_000, exemptLoopback: false }, + // oxlint-disable-next-line typescript/no-explicit-any + } as any; + + const { server, ws, port, prevToken } = await startServerWithClient(); + try { + const initial = await connectReq(ws, { token: "secret" }); + if (!initial.ok) { + const list = await listDevicePairing(); + const pending = list.pending.at(0); + expect(pending?.requestId).toBeDefined(); + if (pending?.requestId) { + await approveDevicePairing(pending.requestId); + } + } + + const identity = loadOrCreateDeviceIdentity(); + const paired = await getPairedDevice(identity.deviceId); + const deviceToken = paired?.tokens?.operator?.token; + expect(deviceToken).toBeDefined(); + + ws.close(); + return { server, port, prevToken, deviceToken: String(deviceToken ?? "") }; + } catch (err) { + ws.close(); + await server.close(); + restoreGatewayToken(prevToken); + throw err; + } +} + describe("gateway server auth/connect", () => { describe("default auth (token)", () => { let server: Awaited>; @@ -693,36 +740,9 @@ describe("gateway server auth/connect", () => { }); test("keeps shared-secret lockout separate from device-token auth", async () => { - const { loadOrCreateDeviceIdentity } = await import("../infra/device-identity.js"); - const { approveDevicePairing, getPairedDevice, listDevicePairing } = - await import("../infra/device-pairing.js"); - testState.gatewayAuth = { - mode: "token", - token: "secret", - rateLimit: { maxAttempts: 1, windowMs: 60_000, lockoutMs: 60_000, exemptLoopback: false }, - // oxlint-disable-next-line typescript/no-explicit-any - } as any; - const prevToken = process.env.OPENCLAW_GATEWAY_TOKEN; - process.env.OPENCLAW_GATEWAY_TOKEN = "secret"; - const port = await getFreePort(); - const server = await startGatewayServer(port); + const { server, port, prevToken, deviceToken } = + await startRateLimitedTokenServerWithPairedDeviceToken(); try { - const ws = await openWs(port); - const initial = await connectReq(ws, { token: "secret" }); - if (!initial.ok) { - const list = await listDevicePairing(); - const pending = list.pending.at(0); - expect(pending?.requestId).toBeDefined(); - if (pending?.requestId) { - await approveDevicePairing(pending.requestId); - } - } - const identity = loadOrCreateDeviceIdentity(); - const paired = await getPairedDevice(identity.deviceId); - const deviceToken = paired?.tokens?.operator?.token; - expect(deviceToken).toBeDefined(); - ws.close(); - const wsBadShared = await openWs(port); const badShared = await connectReq(wsBadShared, { token: "wrong", device: null }); expect(badShared.ok).toBe(false); @@ -740,45 +760,14 @@ describe("gateway server auth/connect", () => { wsDevice.close(); } finally { await server.close(); - if (prevToken === undefined) { - delete process.env.OPENCLAW_GATEWAY_TOKEN; - } else { - process.env.OPENCLAW_GATEWAY_TOKEN = prevToken; - } + restoreGatewayToken(prevToken); } }); test("keeps device-token lockout separate from shared-secret auth", async () => { - const { loadOrCreateDeviceIdentity } = await import("../infra/device-identity.js"); - const { approveDevicePairing, getPairedDevice, listDevicePairing } = - await import("../infra/device-pairing.js"); - testState.gatewayAuth = { - mode: "token", - token: "secret", - rateLimit: { maxAttempts: 1, windowMs: 60_000, lockoutMs: 60_000, exemptLoopback: false }, - // oxlint-disable-next-line typescript/no-explicit-any - } as any; - const prevToken = process.env.OPENCLAW_GATEWAY_TOKEN; - process.env.OPENCLAW_GATEWAY_TOKEN = "secret"; - const port = await getFreePort(); - const server = await startGatewayServer(port); + const { server, port, prevToken, deviceToken } = + await startRateLimitedTokenServerWithPairedDeviceToken(); try { - const ws = await openWs(port); - const initial = await connectReq(ws, { token: "secret" }); - if (!initial.ok) { - const list = await listDevicePairing(); - const pending = list.pending.at(0); - expect(pending?.requestId).toBeDefined(); - if (pending?.requestId) { - await approveDevicePairing(pending.requestId); - } - } - const identity = loadOrCreateDeviceIdentity(); - const paired = await getPairedDevice(identity.deviceId); - const deviceToken = paired?.tokens?.operator?.token; - expect(deviceToken).toBeDefined(); - ws.close(); - const wsBadDevice = await openWs(port); const badDevice = await connectReq(wsBadDevice, { token: "wrong" }); expect(badDevice.ok).toBe(false); @@ -802,11 +791,7 @@ describe("gateway server auth/connect", () => { wsDeviceReal.close(); } finally { await server.close(); - if (prevToken === undefined) { - delete process.env.OPENCLAW_GATEWAY_TOKEN; - } else { - process.env.OPENCLAW_GATEWAY_TOKEN = prevToken; - } + restoreGatewayToken(prevToken); } });