diff --git a/client/public/version.js b/client/public/version.js index 95ff0d6..b5b23a4 100644 --- a/client/public/version.js +++ b/client/public/version.js @@ -1,5 +1,5 @@ // Maintainer-controlled web client version. // Format: YYYY.MM.DD Rn (example: 2026.02.20 R2) -window.CHGRID_WEB_VERSION = "2026.02.27 R299"; +window.CHGRID_WEB_VERSION = "2026.02.27 R300"; // Optional display timezone for timestamps. Falls back to America/Detroit if unset/invalid. window.CHGRID_TIME_ZONE = "America/Detroit"; diff --git a/client/src/main.ts b/client/src/main.ts index be78d71..9661a78 100644 --- a/client/src/main.ts +++ b/client/src/main.ts @@ -2825,6 +2825,11 @@ function handleAdminRolePermissionListModeInput(code: string, key: string): void audio.sfxUiBlip(); return; } + if (role.name === 'admin') { + updateStatus('Admin role permissions are locked on.'); + audio.sfxUiCancel(); + return; + } const nextPermissions = new Set(role.permissions); if (nextPermissions.has(value)) { nextPermissions.delete(value); diff --git a/server/app/auth_service.py b/server/app/auth_service.py index e15c7d5..8e4dd15 100644 --- a/server/app/auth_service.py +++ b/server/app/auth_service.py @@ -307,6 +307,8 @@ class AuthService: """Replace one role's permission assignment with validated keys.""" normalized_role = self._normalize_role_name(role_name) + if normalized_role == "admin": + raise AuthError("Admin role permissions are locked on.") role_row = self._db_fetchone("SELECT id, name FROM roles WHERE name = ?", (normalized_role,)) if role_row is None: raise AuthError("Role not found.") diff --git a/server/tests/test_auth_service.py b/server/tests/test_auth_service.py index e615fbe..ee840c4 100644 --- a/server/tests/test_auth_service.py +++ b/server/tests/test_auth_service.py @@ -78,3 +78,12 @@ def test_delete_role_rejects_admin_and_user(tmp_path: Path) -> None: service.delete_role("user", "editor") finally: service.close() + + +def test_update_role_permissions_rejects_admin(tmp_path: Path) -> None: + service = make_auth_service(tmp_path) + try: + with pytest.raises(AuthError): + service.update_role_permissions("admin", ["chat.send"]) + finally: + service.close()