Files
OmniRoute/tests/unit/access-scopes-infer.test.ts
Diego Rodrigues de Sa e Souza 3c9883bb73 Release v3.8.29 (#4126)
OmniRoute v3.8.29 — 115 commits since v3.8.28. Full CHANGELOG + 41 i18n mirrors. All content quality gates green (build, unit 8/8, vitest 188/188, PR test policy, quality gates extended, docs sync, quality ratchet). Remaining red CI checks are pre-existing release flakes (coverage-shard/integration/node-compat teardown), a new transitive undici advisory in electron devDeps, and a workflow-level CodeQL fail (0 open alerts). VPS-validated by the operator.
2026-06-19 06:49:01 -03:00

49 lines
2.4 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { inferRequiredScope } from "../../src/server/authz/accessScopes.ts";
test("read methods default to read", () => {
assert.equal(inferRequiredScope("GET", "/api/v1/models"), "read");
assert.equal(inferRequiredScope("HEAD", "/api/health"), "read");
assert.equal(inferRequiredScope("OPTIONS", "/api/anything"), "read");
});
test("mutating methods default to write", () => {
assert.equal(inferRequiredScope("POST", "/api/keys"), "write");
assert.equal(inferRequiredScope("PUT", "/api/config"), "write");
assert.equal(inferRequiredScope("PATCH", "/api/combo/x"), "write");
assert.equal(inferRequiredScope("DELETE", "/api/keys/abc"), "write");
});
test("admin-prefix routes require admin for ANY method", () => {
assert.equal(inferRequiredScope("GET", "/api/cli/tokens"), "admin");
assert.equal(inferRequiredScope("POST", "/api/cli/tokens"), "admin");
assert.equal(inferRequiredScope("DELETE", "/api/cli/tokens/tok_1"), "admin");
assert.equal(inferRequiredScope("GET", "/api/oauth/start"), "admin");
assert.equal(inferRequiredScope("POST", "/api/auth/login"), "admin");
assert.equal(inferRequiredScope("POST", "/api/policy"), "admin");
assert.equal(inferRequiredScope("POST", "/api/services/foo/start"), "admin");
});
test("admin-mutation prefixes: GET stays read, mutations become admin", () => {
// providers: status is read, but creating/rotating is admin
assert.equal(inferRequiredScope("GET", "/api/providers/status"), "read");
assert.equal(inferRequiredScope("GET", "/api/providers"), "read");
assert.equal(inferRequiredScope("POST", "/api/providers"), "admin");
assert.equal(inferRequiredScope("DELETE", "/api/providers/openai"), "admin");
// cli-tools/apply writes to the host fs
assert.equal(inferRequiredScope("POST", "/api/cli-tools/apply"), "admin");
});
test("a brand-new mutating route is write by default (not admin)", () => {
assert.equal(inferRequiredScope("POST", "/api/some-future-route"), "write");
assert.equal(inferRequiredScope("GET", "/api/some-future-route"), "read");
});
test("prefix matching does not over-match unrelated paths", () => {
// "/api/authz-inventory" must NOT be caught by the "/api/auth" admin prefix
assert.equal(inferRequiredScope("GET", "/api/authz-inventory"), "read");
// "/api/services" itself and its children are admin, but a lookalike is not
assert.equal(inferRequiredScope("GET", "/api/services-catalog"), "read");
});