Files
meshcore-analyzer/test-issue-1409-no-encrypted-flood.js
T
Kpa-clawbot f72b1bd2ca fix(#1409): channels — stop force-enabling 'show encrypted' on every init (#1410)
## What

Delete the unconditional
`localStorage.setItem('channels-show-encrypted', 'true')` call (+
misleading "#1034 PR1: sectioned sidebar" comment) at
`public/channels.js:783-786`. The sectioned-sidebar grouping the comment
referenced was never implemented; in practice the call was
force-flipping the encrypted-visibility gate on every init so an
operator could never turn it off.

## Root cause

`channels.js` init ran:

```js
var showEncrypted = true;
try { localStorage.setItem('channels-show-encrypted', 'true'); } catch (e) {}
```

unconditionally on every load. The `loadChannels()` reader at line ~1563
(`localStorage.getItem('channels-show-encrypted') === 'true'`) then sent
`includeEncrypted=true` on the `/api/channels` call, so the server
returned all 246 encrypted placeholder channels alongside the 19 real
ones — 265 rows flooding the sidebar with no UI control to suppress.

Verified via CDP on staging:
- `localStorage['channels-show-encrypted']` was always `"true"` after
page load.
- `GET /api/channels` → **19** entries (default — encrypted excluded).
- `GET /api/channels?includeEncrypted=true` → **265** entries (246
encrypted).
- Manually `removeItem('channels-show-encrypted')` + reload → list
dropped to 19.

Confirmed the force-set was the only gate driving the flood.

## TDD

- RED commit `a71cecbc` — `test-issue-1409-no-encrypted-flood.js`
source-greps `public/channels.js` for the forbidden literal
`setItem('channels-show-encrypted', 'true')`. Asserts no match. Fails on
master.
- GREEN commit `14281b63` — delete the 2 lines + rewrite comment. Test
passes.

Tests:

```
$ node test-issue-1409-no-encrypted-flood.js
Issue #1409 — no force-enable of channels-show-encrypted
   channels.js does NOT unconditionally setItem(channels-show-encrypted, true)
   channels.js still reads channels-show-encrypted (toggle gate preserved)
2 passed, 0 failed
```

## Manual verification

- After fix, default `localStorage.getItem('channels-show-encrypted')`
is `null` on first load.
- `loadChannels()` reader returns `false`, so `includeEncrypted` is
omitted from the API call → server returns the 19 real channels only.
- Existing reader is preserved, so a future user-facing toggle that
writes the flag will continue to work.

## Out of scope (follow-ups)

- "Show encrypted" header toggle UI — issue acceptance criteria mentions
it as optional; not added here.
- Sectioned-sidebar grouping of encrypted channels (#1034 PR1 design) —
separate issue.
- Cap/collapse behavior when toggle is ON — separate issue.

Fixes #1409

---------

Co-authored-by: openclaw-bot <bot@openclaw.local>
2026-05-26 17:23:02 -07:00

50 lines
2.2 KiB
JavaScript

/* Issue #1409 — channels.js must NOT unconditionally force-enable
* 'channels-show-encrypted' in localStorage on every init.
*
* The bug: channels.js set localStorage.setItem('channels-show-encrypted', 'true')
* unconditionally on init, which made it impossible for an operator to ever
* hide the 246 encrypted-placeholder channels.
*
* Test strategy: source-grep. The file must not contain a
* setItem('channels-show-encrypted', 'true') call anywhere — there is no
* legitimate place to force this on; the only writer should be a future
* user-toggle handler that writes BOTH 'true' and 'false' under a condition.
*/
'use strict';
const fs = require('fs');
const path = require('path');
const assert = require('assert');
let passed = 0, failed = 0;
function test(name, fn) {
try { fn(); passed++; console.log(' \u2705 ' + name); }
catch (e) { failed++; console.log(' \u274c ' + name + ': ' + e.message); }
}
const src = fs.readFileSync(path.join(__dirname, 'public/channels.js'), 'utf8');
console.log('Issue #1409 — no force-enable of channels-show-encrypted');
test('channels.js does NOT unconditionally setItem(channels-show-encrypted, true)', function () {
// Match any whitespace/quote variant of:
// localStorage.setItem('channels-show-encrypted', 'true')
// or with double quotes. A user-toggle handler would set a VARIABLE,
// not the literal string 'true', so this is a safe gate.
var re = /localStorage\s*\.\s*setItem\s*\(\s*['"]channels-show-encrypted['"]\s*,\s*['"]true['"]\s*\)/;
var m = src.match(re);
assert.strictEqual(m, null,
'Found forbidden literal force-set of channels-show-encrypted=true in public/channels.js. ' +
'A user-toggle handler should pass a boolean variable, not the literal string "true".');
});
test('channels.js still reads channels-show-encrypted (toggle gate preserved)', function () {
// We are NOT removing the read path; the reader is still needed so a
// future user toggle works. This sanity-check ensures the fix did not
// also delete the reader.
assert.ok(/getItem\(\s*['"]channels-show-encrypted['"]\s*\)/.test(src),
'Expected getItem(channels-show-encrypted) to still be present');
});
console.log('\n' + passed + ' passed, ' + failed + ' failed');
process.exit(failed > 0 ? 1 : 0);