56 lines
2.6 KiB
JavaScript
56 lines
2.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
import test from "node:test";
|
|
|
|
const appUrl = new URL("../src/app.mjs", import.meta.url);
|
|
const serverUrl = new URL("../src/server.mjs", import.meta.url);
|
|
const repositoryUrl = new URL("../src/postgres-repository.mjs", import.meta.url);
|
|
const managerComposeUrl = new URL("../../../docker-compose.device-manager.yml", import.meta.url);
|
|
|
|
test("management surface is internal, POST-only and disabled by default", async () => {
|
|
const source = await readFile(appUrl, "utf8");
|
|
|
|
assert.match(source, /managementApiEnabled = false/);
|
|
assert.match(source, /\/internal\/v1\/management\/owner-scopes:ensure/);
|
|
assert.match(source, /\/internal\/v1\/management\/projects:ensure/);
|
|
assert.match(source, /\/internal\/v1\/management\/collections:ensure/);
|
|
assert.match(source, /\/internal\/v1\/management\/project-grants:upsert/);
|
|
assert.match(source, /\/internal\/v1\/management\/device-bindings:ensure/);
|
|
assert.match(source, /\/internal\/v1\/management\/device-configuration-revisions:create/);
|
|
assert.match(source, /request\.method === "POST" && managementCommandKind/);
|
|
assert.doesNotMatch(source, /\/api\/public\/.*management/);
|
|
assert.doesNotMatch(source, /device-commands:(?:plan|confirm|dispatch)/);
|
|
});
|
|
|
|
test("management API is enabled only through a runner-owned file token", async () => {
|
|
const server = await readFile(serverUrl, "utf8");
|
|
const compose = await readFile(managerComposeUrl, "utf8");
|
|
|
|
assert.match(server, /DEVICE_MANAGEMENT_API_ENABLED/);
|
|
assert.match(server, /DEVICE_MANAGEMENT_CORE_TOKEN_FILE/);
|
|
assert.match(compose, /DEVICE_MANAGEMENT_API_ENABLED: "true"/);
|
|
assert.match(
|
|
compose,
|
|
/DEVICE_MANAGEMENT_CORE_TOKEN_FILE: \/run\/nodedc-secrets\/management-core-token/,
|
|
);
|
|
assert.match(
|
|
compose,
|
|
/source: \/volume1\/docker\/nodedc-device-plane\/secrets\/management-core-token/,
|
|
);
|
|
assert.doesNotMatch(compose, /DEVICE_MANAGEMENT_CORE_TOKEN:\s/);
|
|
});
|
|
|
|
test("repository pins idempotency, audit and last-owner checks inside one transaction", async () => {
|
|
const source = await readFile(repositoryUrl, "utf8");
|
|
|
|
assert.match(source, /await client\.query\("begin"\)/);
|
|
assert.match(source, /await client\.query\("commit"\)/);
|
|
assert.match(source, /await client\.query\("rollback"\)/);
|
|
assert.match(source, /device_idempotency_key_conflict/);
|
|
assert.match(source, /device_project_last_owner_required/);
|
|
assert.match(source, /for update of p/);
|
|
assert.match(source, /authorizeManagementReplay/);
|
|
assert.match(source, /insert into device_audit_events/);
|
|
assert.match(source, /update device_management_command_receipts/);
|
|
});
|