Enforce the permission-name rule at discovery, for every plugin

This commit is contained in:
2026-08-05 13:00:23 +02:00
parent 90cbc47607
commit fb4382be9d
14 changed files with 153 additions and 54 deletions
+11
View File
@@ -5,6 +5,7 @@ import {
definePlugin,
findConflicts,
HOST_API_VERSION,
isValidPermissionName,
isValidPluginId,
parseSemver,
RESERVED_PLUGIN_IDS,
@@ -47,6 +48,16 @@ test("isValidPluginId accepts lowercase/digits/dashes anywhere and rejects every
}
});
test("isValidPermissionName requires <resource>:<action> — a bare word names a role, and roles are groups", () => {
for (const ok of ["users:read", "scheduling:write", "oauth2-clients:read", "team-a:a1_b9", "invoices:approve"]) {
assert.ok(isValidPermissionName(ok), ok);
}
// "admin" is the shape this rule exists to stop: it says who someone is, not what they may do.
for (const bad of ["admin", "", "Users:read", "users:", ":read", "users:read:extra", "a b:read", "-bad:read", "a/b:read", `${"a".repeat(60)}:read`]) {
assert.ok(!isValidPermissionName(bad), bad);
}
});
test("parseSemver follows the semver core, rejecting ranges, prefixes, leading zeros and missing parts", () => {
assert.deepEqual(parseSemver("1.2.3"), { major: 1, minor: 2, patch: 3 });
assert.deepEqual(parseSemver("1.2.3-rc.1+build.5"), { major: 1, minor: 2, patch: 3 }); // prerelease/build tolerated, ignored