Guard other plugins like ComfyUI Manager; hide Pixaroma's workflow browser

Plugin button groups in the top bar are hidden without the manager
permission, and rgthree-comfy / Crystools server-wide settings need it too.
Pixaroma's workflow browser (which lists every folder from disk) is hidden
with the other workflow browsers and its routes are admin-only.
This commit is contained in:
Edouard Durand
2026-09-27 00:54:21 +00:00
parent e123dc9279
commit 27e4fd37f1
8 changed files with 85 additions and 3 deletions
+7
View File
@@ -1,5 +1,12 @@
# Changelog
## Unreleased
### Changed
- Other plugins' top-bar buttons (rgthree-comfy, Crystools...) are hidden without the *Manager* permission, like ComfyUI Manager's. Their settings kept on the server, which apply to everyone, need *Manager* too
- Pixaroma's Workflows panel is hidden along with ComfyUI's Workflows and Apps tabs (admin setting now called *Hide other workflow browsers*), and its shortcut opens Files. Its server routes are refused to everyone but admins: they read the workflows folder straight from disk, private folders included
## 1.2.3 (2026-09-27)
### Fixed
+1 -1
View File
@@ -7,7 +7,7 @@
| *(none)*, a viewer | Watch shared workflows, chat, follow people, open snapshots as private copies |
| **Edit** | Change shared workflows, save or rename workflow files, take and restore snapshots, upload files |
| **Queue** | Queue prompts, stop or remove your own runs, free memory. Stopping or removing someone else's, or clearing the queue, needs *Admin* |
| **Manager** | Open ComfyUI Manager: install, update or remove custom nodes and models, snapshots, restart |
| **Manager** | Open ComfyUI Manager: install, update or remove custom nodes and models, snapshots, restart. Also other plugins' top-bar buttons and their server-wide settings (rgthree-comfy, Crystools) |
| **Admin** | Everything, plus deleting workflow files, accounts and server settings |
Queueing, uploads, and saving or deleting workflow files are checked by the server too, when *Enforce permissions on the ComfyUI API* is on (the default). A viewer cannot get around it with a script.
+1 -1
View File
@@ -27,7 +27,7 @@ Admins change these under **Admin → Server settings**. They are stored in `rig
| `guest_permissions` | `{"edit": false, "queue": false}` | What guests may do |
| `broadcast_execution` | `true` | Send progress and previews to everyone, not only whoever queued |
| `hide_comfy_account` | `false` | Hide ComfyUI's Comfy.org sign-in button and dialog |
| `hide_comfy_file_tabs` | `true` | Hide ComfyUI's own Workflows and Apps sidebar tabs; RigShare's Files tab replaces them and their shortcuts open it |
| `hide_comfy_file_tabs` | `true` | Hide other workflow browsers: ComfyUI's Workflows and Apps sidebar tabs and Pixaroma's Workflows panel. RigShare's Files tab replaces them and their shortcuts open it |
| `hide_api_templates` | `false` | Remove templates that need paid API nodes from the template browser |
| `api_protection.enabled` | `true` | Server-side checks on queue, interrupt, free and upload calls |
| `api_protection.trusted_ips` | `["127.0.0.1", "::1"]` | Addresses or networks that skip login and checks |
+16
View File
@@ -33,6 +33,17 @@ LOGIN_WATCH = """<script id="rigshare-login-watch">(() => {
};
})();</script>"""
# Other plugins' server routes RigShare guards: (method or None, path prefix,
# permission, why). Settings they keep on the server apply to everyone, like
# ComfyUI Manager, so they need the same "manager" permission; Pixaroma's workflow
# browser reads the workflows folder straight from disk, private folders included.
PLUGIN_RULES = [
("POST", "/rgthree/api/", "manager", "changing rgthree-comfy's settings needs the 'manager' permission"),
("POST", "/crystools/", "manager", "changing Crystools' settings needs the 'manager' permission"),
(None, "/pixaroma/api/workflows", "admin",
"Pixaroma's workflow browser shows every folder, private ones included; use RigShare's Files tab"),
]
# (method, path) prefixes that need a permission when api_protection is on.
PROTECTED = [
("POST", "/prompt", "queue"),
@@ -798,6 +809,11 @@ def setup(server, store, hub):
"details": "", "extra_info": {}}, "node_errors": {}},
status=403)
break
for method, prefix, need, why in PLUGIN_RULES:
if (method is None or request.method == method) and api_path(request).startswith(prefix):
if not trusted(request.remote or "") and not perms_for(request).get(need) and not perms_for(request).get("admin"):
return web.json_response({"error": f"RigShare: {why}"}, status=403)
break
refusal = await check_queue_ownership(request)
if refusal:
return web.json_response({"error": f"RigShare: {refusal}"}, status=403)
+33
View File
@@ -546,3 +546,36 @@ def test_file_changes_reach_who_can_see_them(run):
assert await changed(b), "moves"
await a.close(); await b.close()
run(scenario())
def test_other_plugins_server_routes(run):
async def scenario():
async def ok(request):
from aiohttp import web
return web.json_response({"ok": True})
def routes(app):
for path in ("/rgthree/api/config", "/crystools/monitor/switch", "/pixaroma/api/workflows/index",
"/pixaroma/api/workflows/folder", "/pixaroma/api/fonts/list"):
app.router.add_route("*", path, ok)
async with rig_server(setup=routes) as rig:
admin = await rig.setup_admin()
alice = await rig.add_user("alice", edit=True, queue=True)
manager = await rig.add_user("mgr", manager=True)
h = rig.http
async def status(method, path, who):
return (await h.request(method, rig.url(path), headers=who)).status
# Server-wide plugin settings: like ComfyUI Manager.
assert await status("POST", "/rgthree/api/config", alice) == 403
assert await status("POST", "/crystools/monitor/switch", alice) == 403
assert await status("POST", "/rgthree/api/config", manager) == 200
assert await status("GET", "/rgthree/api/config", alice) == 200, "reading is fine"
# Pixaroma's workflow browser reads every folder from disk: admins only.
assert await status("GET", "/pixaroma/api/workflows/index", alice) == 403
assert await status("POST", "/pixaroma/api/workflows/folder", manager) == 403
assert await status("GET", "/pixaroma/api/workflows/index", admin) == 200
assert await status("GET", "/pixaroma/api/fonts/list", alice) == 200, "the rest of Pixaroma works"
run(scenario())
+22
View File
@@ -89,6 +89,19 @@ function installManagerGuard(client) {
client.on("self", apply);
client.on("status", apply);
setTimeout(apply, 2000); // Manager registers its commands during setup
// Other plugins put their buttons in the same place as ComfyUI Manager (just
// before ComfyUI's settings group in the top bar): tag them so they are hidden
// the same way without the "manager" permission. Their server-side settings
// are guarded too (PLUGIN_RULES on the server).
const tagPluginButtons = () => {
const settings = app.menu?.settingsGroup?.element;
const bar = settings?.parentElement;
if (!bar) return;
for (const group of bar.children) {
if (group !== settings && group.classList.contains("comfyui-button-group")) group.classList.add("rs-plugin-bar");
}
};
setInterval(tagPluginButtons, 1000);
}
// Comfy.org account: hide the top-bar sign-in button and refuse the sign-in
@@ -139,6 +152,15 @@ function installFileTabsGuard(client) {
const apply = () => {
if (!client.server) return; // wait for the server's settings
const hide = hidden();
document.body.classList.toggle("rs-hide-file-browsers", hide);
// Pixaroma's workflow browser lists every folder from disk, private ones
// included (the server refuses it to non-admins): its shortcut opens Files.
const pix = (manager()?.command?.commands ?? []).find((c) => c.id === "Pixaroma.OpenWorkflowBrowser");
if (pix && !pix.__rigshare) {
const original = pix.function;
pix.function = (...args) => (hidden() ? openFiles() : original(...args));
pix.__rigshare = true;
}
for (const id of COMFY_FILE_TABS) {
const tab = tabs().find((t) => t.id === id);
// Open workflow tabs can be shown in the Workflows sidebar tab: keep it then.
+1 -1
View File
@@ -866,7 +866,7 @@ export class RigSharePanel {
line(f.broadcast, "Share execution progress", "Everyone sees progress and previews, not only whoever queued"),
line(f.protect, "Enforce permissions on the ComfyUI API", "Blocks queueing, interrupting and uploads for users without permission"),
line(f.hideAccount, "Hide the Comfy.org account login", "Removes ComfyUI's own sign-in button and dialog (used for paid API nodes)"),
line(f.hideFileTabs, "Hide ComfyUI's Workflows and Apps tabs", "RigShare's Files tab replaces them. Their shortcuts open Files instead"),
line(f.hideFileTabs, "Hide other workflow browsers", "ComfyUI's Workflows and Apps tabs, and Pixaroma's Workflows panel: RigShare's Files tab replaces them and their shortcuts open Files"),
line(f.hideApiTemplates, "Hide API templates", "Removes templates that need paid API nodes from the template browser"),
h("label", { class: "rs-label" }, "Trusted IPs / networks (skip login and checks)"), f.trusted,
h("div", { class: "rs-row" }, h("label", { class: "rs-label rs-grow" }, "Auto snapshot every (min, 0 = off)"), f.interval),
+4
View File
@@ -107,6 +107,10 @@ code { font-family: ui-monospace, monospace; font-size: 11px; background: var(--
/* Comfy.org account sign-in hidden by the admin */
body.rs-hide-comfy-account [data-testid="login-button"],
body.rs-hide-comfy-account [data-testid="login-button-popover"] { display: none !important; }
/* Other plugins' top-bar buttons (rgthree-comfy, Crystools...) hidden like ComfyUI Manager */
body.rs-no-manager .rs-plugin-bar { display: none !important; }
/* Pixaroma's workflow browser button: RigShare's Files tab replaces it */
body.rs-hide-file-browsers .pixwb-group-btn { display: none !important; }
/* ComfyUI Manager hidden for accounts without the "manager" permission */
body.rs-no-manager .comfyui-button-group:has(> [title="ComfyUI Manager"]),
body.rs-no-manager [title="ComfyUI Manager"],