test: merge device token authz cases

This commit is contained in:
Peter Steinberger
2026-04-17 22:50:55 +01:00
parent 5cf01ac7c1
commit ca34c7cd7b

View File

@@ -128,7 +128,7 @@ async function issuePairingScopedTokenForAdminApprovedDevice(name: string): Prom
}
describe("gateway device.token.rotate/revoke ownership guard (IDOR)", () => {
test("rejects a device-token caller rotating another device's token", async () => {
test("rejects a device-token caller rotating or revoking another device's token", async () => {
const started = await startServer("secret");
const deviceA = await issuePairingScopedTokenForAdminApprovedDevice("idor-device-a");
const deviceB = await issuePairingScopedTokenForAdminApprovedDevice("idor-device-b");
@@ -151,6 +151,16 @@ describe("gateway device.token.rotate/revoke ownership guard (IDOR)", () => {
const pairedB = await getPairedDevice(deviceB.deviceId);
expect(pairedB?.tokens?.operator?.token).toBe(deviceB.pairingToken);
const revoke = await rpcReq(pairingWs, "device.token.revoke", {
deviceId: deviceB.deviceId,
role: "operator",
});
expect(revoke.ok).toBe(false);
expect(revoke.error?.message).toBe("device token revocation denied");
const pairedBAfterRevoke = await getPairedDevice(deviceB.deviceId);
expect(pairedBAfterRevoke?.tokens?.operator?.revokedAtMs).toBeUndefined();
} finally {
pairingWs?.close();
await started.server.close();
@@ -158,9 +168,9 @@ describe("gateway device.token.rotate/revoke ownership guard (IDOR)", () => {
}
});
test("allows an admin-scoped caller to rotate another device's token", async () => {
test("allows an admin-scoped caller to rotate and revoke another device's token", async () => {
const started = await startServerWithClient("secret");
const device = await issuePairingScopedTokenForAdminApprovedDevice("idor-admin-rotate");
const device = await issuePairingScopedTokenForAdminApprovedDevice("idor-admin-rotate-revoke");
try {
await connectOk(started.ws);
@@ -172,48 +182,6 @@ describe("gateway device.token.rotate/revoke ownership guard (IDOR)", () => {
});
expect(rotate.ok).toBe(true);
expect(rotate.payload?.token).toBeTruthy();
} finally {
started.ws.close();
await started.server.close();
started.envSnapshot.restore();
}
});
test("rejects a device-token caller revoking another device's token", async () => {
const started = await startServer("secret");
const deviceA = await issuePairingScopedTokenForAdminApprovedDevice("idor-revoke-a");
const deviceB = await issuePairingScopedTokenForAdminApprovedDevice("idor-revoke-b");
let pairingWs: WebSocket | undefined;
try {
pairingWs = await connectPairingScopedOperator({
port: started.port,
identityPath: deviceA.identityPath,
deviceToken: deviceA.pairingToken,
});
const revoke = await rpcReq(pairingWs, "device.token.revoke", {
deviceId: deviceB.deviceId,
role: "operator",
});
expect(revoke.ok).toBe(false);
expect(revoke.error?.message).toBe("device token revocation denied");
const pairedB = await getPairedDevice(deviceB.deviceId);
expect(pairedB?.tokens?.operator?.revokedAtMs).toBeUndefined();
} finally {
pairingWs?.close();
await started.server.close();
started.envSnapshot.restore();
}
});
test("allows an admin-scoped caller to revoke another device's token", async () => {
const started = await startServerWithClient("secret");
const device = await issuePairingScopedTokenForAdminApprovedDevice("idor-admin-revoke");
try {
await connectOk(started.ws);
const revoke = await rpcReq<{ revokedAtMs?: number }>(started.ws, "device.token.revoke", {
deviceId: device.deviceId,