mirror of
https://github.com/Comfy-Org/ComfyUI-Manager.git
synced 2026-05-09 08:32:30 +08:00
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 16 no-body POST handlers (glob + legacy) to block <form method=POST> CSRF that bypasses method-only gating. Move comfyui_switch_version to a JSON body so the preflight requirement applies. Split db_mode/policy/update/channel_url_list into GET(read) + POST(write). Tighten do_fix (high → high+) and gate three previously-ungated config setters at middle. Resynchronize openapi.yaml (27 paths, 30 operations, ComfyUISwitchVersionParams as a shared $ref component). Add E2E harness variants, Playwright config, CSRF/secgate suites, 39-endpoint coverage, and a CHANGELOG. Breaking: legacy per-op POST routes (install/uninstall/fix/disable/update/ reinstall/abort_current) are removed; callers already use queue/batch. Legacy /manager/notice (v1) is removed; /v2/manager/notice is retained. 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)
105 lines
4.7 KiB
Markdown
105 lines
4.7 KiB
Markdown
# Legacy UI — Channel Combo DOM Mapping Note
|
|
|
|
**Date**: 2026-04-20
|
|
**Context**: WI-OO Item 3 follow-up — bloat sweep `dev:ci-022` B8 "Channel dropdown"
|
|
test was title-mismatched (filter `/Cache|Local|Channel/` matched DB combo's
|
|
option text, not the Channel combo itself). This record documents the correct
|
|
DOM locators for any future reactivation.
|
|
**Scope**: Record only. No test code added; no audit impact.
|
|
|
|
---
|
|
|
|
## 1. Source Locations
|
|
|
|
| Artifact | Path | Lines | Role |
|
|
|----------|------|-------|------|
|
|
| Channel combo creation + registration | `comfyui_manager/js/comfyui-manager.js` | 960-986 | Creates the `<select>`, installs title attr, fetches options from API, mounts into the settings panel via `createSettingsCombo` |
|
|
| Settings row wrapper | `comfyui_manager/js/comfyui-gui-builder.js` | 15-27 | Exports `createSettingsCombo(label, content)` that wraps the combo in the label/input row |
|
|
|
|
## 2. DOM Structure
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Tag | `<select>` |
|
|
| Classes | `cm-menu-combo p-select p-component p-inputwrapper p-inputwrapper-filled` |
|
|
| `title` attribute | `"Configure the channel for retrieving data from the Custom Node list (including missing nodes) or the Model list."` (set at L961) |
|
|
| Options source | `/v2/manager/channel_url_list` — populated asynchronously at L963-984 |
|
|
| Option texts | Channel URL names (e.g. `default`, `recent`, custom URLs); NOT the word "Channel" |
|
|
| Label wrapper | `div.setting-item > div.flex.flex-row.items-center.gap-2 > div.form-label.flex.grow.items-center > span.text-muted` with `textContent: "Channel"` (from `createSettingsCombo`) |
|
|
| Render timing | Select element itself: **sync** at menu build time. Options: **async** after `channel_url_list` fetch resolves |
|
|
|
|
## 3. Why the Original `hasText: /Cache|Local|Channel/` Filter Failed
|
|
|
|
The removed test used `hasText` to find the Channel dropdown, but that matcher
|
|
searches the element's rendered text (its `<option>` children's text in the case
|
|
of a `<select>`). The Channel combo's options are channel URL names — they do
|
|
not contain the words `Cache`, `Local`, or `Channel`.
|
|
|
|
In contrast, the DB (datasrc) combo located a few lines above
|
|
(comfyui-manager.js:957, built from `this.datasrc_combo` which seeds options
|
|
`Cache` / `Local` / `Remote`) did contain those literals, so the filter
|
|
silently resolved to the wrong `<select>`. The test asserted visibility, which
|
|
passed against the DB combo, masking the mismatch until WI-OO's audit exposed
|
|
it as B8 title-mismatch bloat.
|
|
|
|
## 4. Stable Selector Candidates
|
|
|
|
Ordered by robustness (most stable first):
|
|
|
|
1. **Title attribute (recommended)** — unique per L961
|
|
```ts
|
|
select[title^="Configure the channel"]
|
|
```
|
|
The leading prefix `Configure the channel` appears nowhere else in the
|
|
managed panel. Safe against minor title copy edits as long as the opening
|
|
phrase is preserved.
|
|
|
|
2. **Label-based scope** — DOM-structure dependent
|
|
```ts
|
|
.setting-item:has(span.text-muted:text-is("Channel")) select
|
|
```
|
|
Works as long as `createSettingsCombo` keeps its current wrapper shape and
|
|
the exact label text `"Channel"`.
|
|
|
|
3. **Class-only** — NOT unique
|
|
Classes `cm-menu-combo p-select ...` are shared with the DB, Update-Policy,
|
|
and Share combos. Using classes alone will match multiple elements and is
|
|
brittle.
|
|
|
|
## 5. Async-Population Note
|
|
|
|
Options for the Channel combo are populated via an async `fetchApi` call to
|
|
`/v2/manager/channel_url_list` at L963. Two testing consequences:
|
|
|
|
- A visibility assertion on the `<select>` resolves immediately — the element
|
|
is appended synchronously at L960 and mounted at L986.
|
|
- An assertion about option count or specific option values MUST wait for the
|
|
fetch to resolve. Use `expect.poll` (or equivalent) with a reasonable
|
|
timeout (≥5s) rather than an immediate `toHaveCount` check.
|
|
|
|
## 6. Proposed Test Skeleton (Reference Only)
|
|
|
|
Not added to any spec — kept here for future activation.
|
|
|
|
```ts
|
|
test('shows Channel dropdown (async-populated)', async ({ page }) => {
|
|
await openManagerMenu(page);
|
|
const dialog = page.locator('#cm-manager-dialog').first();
|
|
const channelCombo = dialog.locator('select[title^="Configure the channel"]');
|
|
await expect(channelCombo).toBeVisible();
|
|
await expect.poll(
|
|
async () => await channelCombo.locator('option').count(),
|
|
{ timeout: 5000 }
|
|
).toBeGreaterThan(0);
|
|
});
|
|
```
|
|
|
|
## 7. Decision
|
|
|
|
Test **not** added. This aligns with the post-bloat-sweep net-removal
|
|
direction established by WI-OO: re-introducing a Channel-dropdown visibility
|
|
test would re-expand the surface the sweep explicitly trimmed. The record is
|
|
preserved here so that, if future coverage expansion prioritizes the settings
|
|
panel, reactivation needs only copy the skeleton above and choose selector
|
|
option 1 from §4.
|