mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-05-10 00:52:32 +08:00
Some checks failed
Python Linting / Run Ruff (push) Has been cancelled
Defense-in-depth over GET→POST alone: reject the three CORS-safelisted
simple-form Content-Types (x-www-form-urlencoded, multipart/form-data,
text/plain) on 5 no-body POST handlers (snapshot/save,
manager/queue/{reset,start,update_comfyui}, manager/reboot) to block
<form method=POST> CSRF that bypasses method-only gating. Convert 10 pure
state-changing endpoints (fetch_updates, queue/{update_all,reset,start,
update_comfyui}, snapshot/{remove,restore,save}, comfyui_switch_version,
reboot) from GET to POST and split 5 config endpoints
(db_mode/preview_method/channel_url_list/policy/{component,update}) into
GET(read) + POST(write, JSON body). Emit the in_progress + done event pair
from the /manager/queue/install sync-enable fast-path so client UI
finalizes (previously only queue/start's empty worker done fired, leaving
item.restart unset and the Enable button visible after a successful enable).
Harden js/custom-nodes-manager.js completion path: await onQueueCompleted
with try/catch (surfaces silent turbogrid stale-item throws), replace the
{}.length == 0 no-op empty guard, set install_context before queue/install
to avoid a sync-completion race, wrap classList/updateCell in try/catch.
Resynchronize openapi.yaml with the converted routes (method → post, query
params → requestBody JSON schema, sibling post on 5 split endpoints).
Update 31 JS fetchApi call sites across 7 files; add
tests/test_csrf_content_type_helper.py covering 5 Content-Type cases via
aiohttp TestClient.
Reported-by: XlabAI Team of Tencent Xuanwu Lab
CVSS: 8.1 (AV:N/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:H)
68 lines
2.1 KiB
JavaScript
68 lines
2.1 KiB
JavaScript
import { api } from "../../scripts/api.js";
|
|
import { app } from "../../scripts/app.js";
|
|
import { sleep, customConfirm, customAlert, handle403Response, show_message } from "./common.js";
|
|
|
|
async function tryInstallCustomNode(event) {
|
|
let msg = '-= [ComfyUI Manager] extension installation request =-\n\n';
|
|
msg += `The '${event.detail.sender}' extension requires the installation of the '${event.detail.target.title}' extension. `;
|
|
|
|
if(event.detail.target.installed == 'Disabled') {
|
|
msg += 'However, the extension is currently disabled. Would you like to enable it and reboot?'
|
|
}
|
|
else if(event.detail.target.installed == 'True') {
|
|
msg += 'However, it seems that the extension is in an import-fail state or is not compatible with the current version. Please address this issue.';
|
|
}
|
|
else {
|
|
msg += `Would you like to install it and reboot?`;
|
|
}
|
|
|
|
msg += `\n\nRequest message:\n${event.detail.msg}`;
|
|
|
|
if(event.detail.target.installed == 'True') {
|
|
customAlert(msg);
|
|
return;
|
|
}
|
|
const res = await customConfirm(msg);
|
|
if(res) {
|
|
if(event.detail.target.installed == 'Disabled') {
|
|
const response = await api.fetchApi(`/customnode/toggle_active`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(event.detail.target)
|
|
});
|
|
}
|
|
else {
|
|
await sleep(300);
|
|
app.ui.dialog.show(`Installing... '${event.detail.target.title}'`);
|
|
|
|
const response = await api.fetchApi(`/customnode/install`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(event.detail.target)
|
|
});
|
|
|
|
if(response.status == 403) {
|
|
await handle403Response(response);
|
|
return false;
|
|
}
|
|
else if(response.status == 400) {
|
|
let msg = await res.text();
|
|
show_message(msg);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
let response = await api.fetchApi("/manager/reboot", { method: 'POST' });
|
|
if(response.status == 403) {
|
|
await handle403Response(response);
|
|
return false;
|
|
}
|
|
|
|
await sleep(300);
|
|
|
|
app.ui.dialog.show(`Rebooting...`);
|
|
}
|
|
}
|
|
|
|
api.addEventListener("cm-api-try-install-customnode", tryInstallCustomNode);
|