Commit Graph

12 Commits

Author SHA1 Message Date
6ba12cc571 refactor(decnet_web/CanaryTokens): wire hook + bump coverage floor
Final integration step. The page shell is now a thin composition
of useCanaryTokens + the previously-extracted children:

- CanaryTokens.tsx: 1,334 -> 210 LOC. Page owns only the
  pure-UI state (tab, search/state/scope filters, modal
  visibility, drawer selection, local fileDrops log) and the
  thin handlers that translate hook results into confirm/alert
  prompts. Initial parallel fetch + deleteBlob mutation moved
  to useCanaryTokens in the prior commit.
- Modals plug directly into the hook's optimistic helpers
  (prependToken / prependBlob / markTokenRevoked) so the page
  doesn't reach into the data shape.

Coverage floor bumped after the split:

  lines       11 -> 14
  functions   10 -> 13
  branches     8 -> 11
  statements  11 -> 13

Phase 3 final scoreboard: 28 test files, 131 tests, all green.
2026-05-09 05:17:52 -04:00
69f547f75e refactor(decnet_web/CanaryTokens): move FileDropModal + LS helpers
Verbatim move of the file-drop modal (~310 LOC) and its
localStorage glue (FILEDROP_LS_KEY, FileDropEntry type,
loadFileDrops, saveFileDrops) into one file. The list view that
shows these entries lives in the page; the persistence layer
travels with the writer.

- New CanaryTokens/FileDropModal.tsx (modal + LS helpers + entry type)
- FileDropModal.test.tsx covers loadFileDrops empty / round-trip /
  200-row cap / malformed-JSON, plus modal title rendering, the
  bypass-warning banner, and CANCEL -> onClose.
- CanaryTokens.tsx loses the inline modal + LS glue plus the
  now-unused imports (useRef/X/AlertTriangle/useEscapeKey/
  useFocusTrap, plus BTN_PRIMARY/BTN_GHOST/Field that only the
  modals consumed).
2026-05-09 05:13:51 -04:00
b664655dcb refactor(decnet_web/CanaryTokens): move UploadModal out
Verbatim move of the artifact upload modal (~130 LOC) into its
own file. Drop-or-browse picker, server-side-injection warning
banner, and the multipart POST stay unchanged.

- New CanaryTokens/UploadModal.tsx
- UploadModal.test.tsx covers title rendering, empty drop-zone
  hint, server-injection warning banner, UPLOAD-disabled-until-
  file, and CANCEL -> onClose.
2026-05-09 05:11:46 -04:00
e30455551d refactor(decnet_web/CanaryTokens): move CreateTokenModal out
Verbatim move of the canary-token creation modal (~280 LOC) into
its own file. Renamed from CreateModal to CreateTokenModal so the
component name carries scope across the package boundary.

- New CanaryTokens/CreateTokenModal.tsx
- CreateTokenModal.test.tsx covers title rendering, CANCEL ->
  onClose, empty-deckies hint, and the Operator-upload mode
  switch revealing the no-blobs message. useFocusTrap is
  vi.mock'd to avoid jsdom focus shenanigans.
- CanaryTokens.tsx loses the inline modal + its now-unused
  imports (KNOWN_GENERATORS, KIND_OPTIONS, GeneratorName).
2026-05-09 05:10:27 -04:00
a35048b174 refactor(decnet_web/CanaryTokens): extract types + helpers + ui
Foundation for the CanaryTokens split. Types, error/format helpers,
and the inline style + small primitives move out of the page so
the upcoming modal/list extractions can import without reaching
back through CanaryTokens.tsx.

- New CanaryTokens/types.ts (BlobRow, DeckyOption, TopologyOption,
  Scope, KNOWN_GENERATORS / GeneratorName, KIND_OPTIONS, STATE_COLOR)
- New CanaryTokens/helpers.ts (extractError, fmt, fmtBytes)
- New CanaryTokens/ui.tsx (INPUT_STYLE, BTN_PRIMARY, BTN_GHOST,
  Field, Stat)
- CanaryTokens.tsx loses ~110 LOC of inline definitions; behavior
  unchanged.
2026-05-09 05:08:37 -04:00
aa0b22aacb fix(decnet_web/css): sweep rgba colour literals to tokens app-wide
Pre-this-commit, ~80 rgba() literals across 24 files were
hardcoding alert-red, warn-amber, info-cyan, panel-dark, and
white-text-with-alpha shades that bypassed the token cascade.
Net effect in light mode: the .eml/SESSREC drawers, AttackerDetail
verdict pills, MazeNET net-box headers, OPEN/REPLAY action
buttons, threat-intel cards, and all the dim 'whitish' overlays
stayed on their dark-mode hex values, producing the unreadable
panels in the screenshots.

Sweep maps each rgba colour family onto the existing token by
alpha bucket — rgba(13,17,23,*) -> var(--panel),
rgba(255,65,65,*) -> var(--alert)/-tint-10,
rgba(255,170,0,*) and rgba(224,160,64,*) -> var(--warn)/-tint-10,
rgba(0,200,255,*) -> var(--info)/-tint-10,
rgba(255,255,255,*) -> var(--fg-N)/var(--matrix-tint-N) by alpha.

VERDICT_TONE in AttackerDetail (MALICIOUS/SUSPICIOUS/BENIGN/
NO SIGNAL) was the worst offender — string literals
'#ff4d4d'/'#ffae42'/'#5fd07a'/rgba(255,255,255,0.4) baked into
inline JS styles. Now resolves at render time via var(--alert)/
var(--warn)/var(--ok)/var(--fg-4).

New tokens in :root:
 - --bg-color (alias of --bg) — drawers used this name with
   #0d1117 fallback that fired in every browser because nothing
   defined --bg-color. Adding the alias makes drawers re-tone.
 - --info / --info-tint-10 / --info-tint-30 — REPLAY buttons and
   any future neutral-secondary use.
 - --ok — semantic alias for 'verified good' (matrix in dark,
   emerald in light) so BENIGN pills stay readable across themes.

Login.css left intentionally — pre-auth surface, not themed.
2026-05-09 03:48:05 -04:00
57fecb8071 refactor(frontend): ApiError interface, tempIdSuffix rename, NET_GRID constants, extract onPaletteDrop handlers
ApiError: defined once in utils/api.ts, replaces 9 ad-hoc anonymous casts
across MazeNET, Inspector, DeckyFleet, SwarmHosts, Webhooks, PersonaGeneration,
ServiceConfigFields, CanaryTokens.

hex4 renamed to tempIdSuffix — the name now matches the comment that already
explained its purpose.

NET_GRID_{W,H,GAP,COLS} extracted from inline magic numbers to module-level
constants in MazeNET.tsx.

onPaletteDrop (130-line useCallback) split into three module-level handlers
(_dropNetwork, _dropArchetype, _dropService); the callback becomes a 10-line
router.
2026-04-30 22:14:20 -04:00
fbc9877ef2 fix(ui): follow-up polish — icons, dashboard bar, filter redesign, bounty/creds sort
- Dashboard: fix invisible bar at bottom of LIVE FEED by constraining
  max-height on the section instead of the inner container; same fix
  for side panels
- Page icons: add violet-accent icon beside h1 on all 9 missing pages
  (CanaryTokens, RealismConfig, SyntheticFiles, PersonaGeneration,
  Attackers, Webhooks, LiveLogs, Topologies, DecoyFleet)
- Attackers filter chips: replace ad-hoc chip buttons with seg-group
  tabs (ALL / ACTIVE N / PASSIVE N / INACTIVE N) matching Credential
  Vault style; country chips use same seg-group treatment
- Credential Vault: add sortable headers to REUSE tab (LAST SEEN,
  PRINCIPAL, KIND, TARGETS, ATTEMPTS); reuses same SortTh pattern
- Bounty: remove CREDENTIALS and PAYLOADS tabs; keep ALL, ARTIFACTS,
  FINGERPRINTS; add EMAIL (artifact subtype, filtered client-side)
2026-04-30 00:20:25 -04:00
463877b8fc fix(ui): hit /topologies/ with trailing slash to keep bearer
FastAPI's redirect_slashes=True 307s /topologies → /topologies/, and
the browser drops Authorization on the redirected URL — the topology
picker in the canary create modal was landing as 401 even for admins.
Hit the canonical (trailing-slash) path so the request resolves on the
first hop.
2026-04-28 23:18:39 -04:00
4287e94deb feat(ui): file drops tab on CanaryTokens
CanaryTokens.tsx grows a third tab — File drops — alongside Tokens
and Blobs.  The page now covers every 'admin landed bytes on a decky'
operation in one place.

FileDropModal mirrors the canary CreateModal's shape: Fleet/MazeNET
toggle, topology+decky picker, absolute-path validation matching the
backend (DeckyFileDropRequest rejects relative + ..-traversal), mode
+ mtime offset inputs, and a -1w preset for backdating.  FileReader →
data URL → strip prefix → POST /api/v1/deckies/files.

The list is local-only (localStorage, capped at 200 entries).  W2's
backend doesn't persist drops by design — the endpoint is for staging
payloads, not as an audit trail.  CLEAR LIST button on the tab; no
DELETE button on rows since the local entry doesn't track whether the
file is still there (an attacker may have moved it).

Alt+D shortcut joins Alt+C; alt-key only per the Linux-meta-key rule.
2026-04-28 23:06:53 -04:00
c942d4d333 feat(ui): scope canary tokens to MazeNET topology deckies
CanaryTokens.tsx grows a Fleet/MazeNET toggle in the create modal.  In
topology mode we hydrate /topologies?status=active for the topology
picker, then GET /topologies/{id} on selection to repopulate the decky
picker — topology deckies have a different shape than fleet's /deckies
endpoint.

The tokens table gains a SCOPE column (chip: 'fleet' / 'topology'),
and a third filter dropdown alongside state.  The drawer's metadata
section shows a Scope row with a clickable jump-link back to the
MazeNET view at the right topology.

CanaryTokenRow grows a topology_id field so the drawer/list can
discriminate without re-fetching.
2026-04-28 23:04:13 -04:00
862e4dbb31 merge: testing → main (reconcile 2-week divergence) 2026-04-28 18:36:00 -04:00