Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/PVS/analysis/   (PVS Prover Version 6.0.9©)  Datei vom 28.9.2014 mit Größe 1 kB image not shown  

 node-pairing.test.ts

  Interaktion und
PortierbarkeitJAVA
 

import { describe, expect, test } from "vitest";
import { withTempDir } from "../test-helpers/temp-dir.js";
import {
  approveNodePairing,
  getPairedNode,
  listNodePairing,
  requestNodePairing,
  verifyNodeToken,
} from "./node-pairing.js";

async function setupPairedNode(baseDir: string): Promise<string> {
  const request = await requestNodePairing(
    {
      nodeId: "node-1",
      platform: "darwin",
      commands: ["system.run"],
    },
    baseDir,
  );
  await approveNodePairing(
    request.request.requestId,
    { callerScopes: ["operator.pairing""operator.admin"] },
    baseDir,
  );
  const paired = await getPairedNode("node-1", baseDir);
  expect(paired).not.toBeNull();
  if (!paired) {
    throw new Error("expected node to be paired");
  }
  return paired.token;
}

async function withNodePairingDir<T>(run: (baseDir: string) => Promise<T>): Promise<T> {
  return await withTempDir({ prefix: "openclaw-node-pairing-" }, run);
}

describe("node pairing tokens", () => {
  test("reuses existing pending requests for the same node", async () => {
    await withNodePairingDir(async (baseDir) => {
      const first = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
        },
        baseDir,
      );
      const second = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
        },
        baseDir,
      );

      expect(first.created).toBe(true);
      expect(second.created).toBe(false);
      expect(second.request.requestId).toBe(first.request.requestId);
    });
  });

  test("refreshes pending requests with newer commands", async () => {
    await withNodePairingDir(async (baseDir) => {
      const first = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
          commands: ["canvas.snapshot"],
        },
        baseDir,
      );

      const second = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
          displayName: "Updated Node",
          commands: ["canvas.snapshot""system.run"],
        },
        baseDir,
      );
      const third = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
          displayName: "Updated Node",
          commands: ["canvas.snapshot""system.run""system.which"],
        },
        baseDir,
      );

      expect(second.created).toBe(false);
      expect(second.request.requestId).toBe(first.request.requestId);
      expect(third.created).toBe(false);
      expect(third.request.requestId).toBe(second.request.requestId);
      expect(third.request.displayName).toBe("Updated Node");
      expect(third.request.commands).toEqual(["canvas.snapshot""system.run""system.which"]);
    });
  });

  test("generates base64url node tokens with 256-bit entropy output length", async () => {
    await withNodePairingDir(async (baseDir) => {
      const token = await setupPairedNode(baseDir);
      expect(token).toMatch(/^[A-Za-z0-9_-]{43}$/);
      expect(Buffer.from(token, "base64url")).toHaveLength(32);
    });
  });

  test("verifies token and rejects mismatches", async () => {
    await withNodePairingDir(async (baseDir) => {
      const token = await setupPairedNode(baseDir);
      await expect(verifyNodeToken("node-1", token, baseDir)).resolves.toEqual({
        ok: true,
        node: expect.objectContaining({ nodeId: "node-1" }),
      });
      await expect(verifyNodeToken("node-1""x".repeat(token.length), baseDir)).resolves.toEqual({
        ok: false,
      });
    });
  });

  test("treats multibyte same-length token input as mismatch without throwing", async () => {
    await withNodePairingDir(async (baseDir) => {
      const token = await setupPairedNode(baseDir);
      const multibyteToken = "é".repeat(token.length);
      expect(Buffer.from(multibyteToken).length).not.toBe(Buffer.from(token).length);

      await expect(verifyNodeToken("node-1", multibyteToken, baseDir)).resolves.toEqual({
        ok: false,
      });
    });
  });

  test("requires operator.admin to approve system.run node commands", async () => {
    await withNodePairingDir(async (baseDir) => {
      const request = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
          commands: ["system.run"],
        },
        baseDir,
      );

      await expect(
        approveNodePairing(
          request.request.requestId,
          { callerScopes: ["operator.pairing"] },
          baseDir,
        ),
      ).resolves.toEqual({
        status: "forbidden",
        missingScope: "operator.admin",
      });
      await expect(getPairedNode("node-1", baseDir)).resolves.toBeNull();
    });
  });

  test("requires operator.pairing to approve commandless node requests", async () => {
    await withNodePairingDir(async (baseDir) => {
      const request = await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
        },
        baseDir,
      );

      await expect(
        approveNodePairing(request.request.requestId, { callerScopes: [] }, baseDir),
      ).resolves.toEqual({
        status: "forbidden",
        missingScope: "operator.pairing",
      });
      await expect(
        approveNodePairing(
          request.request.requestId,
          { callerScopes: ["operator.pairing"] },
          baseDir,
        ),
      ).resolves.toEqual({
        requestId: request.request.requestId,
        node: expect.objectContaining({
          nodeId: "node-1",
          commands: undefined,
        }),
      });
    });
  });

  test("lists pending requests with precomputed approval scopes", async () => {
    await withNodePairingDir(async (baseDir) => {
      await requestNodePairing(
        {
          nodeId: "node-1",
          platform: "darwin",
          commands: ["canvas.present"],
        },
        baseDir,
      );

      await expect(listNodePairing(baseDir)).resolves.toEqual({
        pending: [
          expect.objectContaining({
            nodeId: "node-1",
            commands: ["canvas.present"],
            requiredApproveScopes: ["operator.pairing""operator.write"],
          }),
        ],
        paired: [],
      });
    });
  });
});

Messung V0.5 in Prozent
C=100 H=100 G=100

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.14Angebot  (Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-09) ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.