refactor(test): dedupe gateway auth e2e lockout setup
This commit is contained in:
@@ -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<ReturnType<typeof startGatewayServer>>;
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user