Skip to content

Fix portfolio audit findings and update security dependencies - #38

Merged
Alitleis123 merged 31 commits into
mainfrom
fleet/audit-20261108
Nov 9, 2026
Merged

Alitleis123 merged 31 commits into
mainfrom
fleet/audit-20261108

Conversation

@Alitleis123

@Alitleis123 Alitleis123 commented Nov 9, 2026 •

Copy link
Copy Markdown
Owner

Bug fixes from an audit of the site, the control panel and the ask/ backend, plus a Next.js security update and pull request checks. No new features and no design changes.

Site

  • Galleries opened under the nav bar and the floating Resume, audio and scroll buttons, because <main> is its own stacking context. The close button sat behind the nav, so a click did nothing on desktop and opened the menu on a phone. The gallery now renders into <body>.
  • With Ask open over a gallery, arrow keys typed in Ask flipped the gallery and one Escape closed both. Now only the top dialog reacts.
  • An Ask question sent before the search index loaded got no passages, because ask kept the rank from the render it started in.
  • In the studio, keyboard selection did nothing once the reel had played, and taking over the guided run snapped the projects and roles back to the first entry instead of keeping the one on screen.
  • Studio shortcuts ignored modifier keys, so Alt+Left stepped the reel instead of going Back.
  • The scroll-smooth class on <html> overrode the reduced-motion media query in globals.css.
  • The layout's og:url was / on every page, so shared /studio/ and /galaxy/ cards linked to the chooser.
  • Blocked browser storage no longer crashes the ambient audio or reel mute controls.

Control panel

  • The timeline ruler stepped a fixed 24 hours, so since the Nov 1 clock change it repeated a day and left today off. Day ticks now step by calendar day.
  • Polling could stop at an Ask answer that finished late and miss newer entries behind it. The capped log is now filtered inside Redis, which also sends fewer bytes per poll.
  • A poll that started before a save could land after it and undo the save until the next poll. An answer is now dropped only when a later request has already landed, so slow polls still all apply. Answers merge into what is held when they land, so overlapping polls keep each other's entries, and a sign-out invalidates every poll still in flight.
  • "On the site now" showed someone who had just asked a question as "30m ago". It now uses their latest view or question.
  • Smaller fixes: "Stop counting me" can no longer throw, the counting note refreshes after adding a passkey, Tab reaches the expandable questions in the phone sheet, the median answer time averages the middle pair for an even count, times no longer read "60m ago" at rounding edges, and the icon-only copy button has a label.

Backend

  • /api/visit stored the referring host with no length limit, so one request could add a multi-megabyte entry that every panel load then pulled. It is now cut to 253 characters.
  • A sign-in refused for its origin or ceremony left its challenge usable, despite the comment saying it is spent either way.
  • A pairing code was deleted when the enrollment options went out, so a cancelled Face ID prompt killed it. It is now spent in the same Lua script that stores the passkey, and only if it is still the code the challenge was issued for. One code still enrolls one device, and a failed write leaves it usable.
  • Forgetting a device clipped its id at 200 characters, while WebAuthn allows 1023-byte ids, and a device already gone read as "Keep at least one device". The clip is now 1400 and an already-forgotten device counts as forgotten.
  • Pipeline requests now send Content-Type: application/json. Upstash reads them either way. The Redis stand-in in CI needs it.

Dependencies and checks

  • Next.js and eslint-config-next go from 16.1.1 to 16.4.5 with compatible lockfile updates. npm audit --omit=dev reports zero vulnerabilities. The full audit still lists 13 findings in the TypeScript ESLint and search-index builder chains, which are development-only and need breaking upgrades to fix. agentRules: false stops next dev from writing a rules block into AGENTS.md.
  • A new pull request workflow runs lint, the backend tests, the resume preview render and the static build, matching pages.yml. It starts Redis behind serverless-redis-http, so ask/test/redis.test.js runs the panel's poll script for real. The mock in panel.test.js reimplements that filter in JavaScript, so a broken script used to pass.

Validation

  • npm run lint and npx tsc --noEmit pass.
  • node --test ask/test/*.test.js passes 31 tests locally, with the Redis test skipped without its env vars. In CI it runs too, with none skipped. The new backend tests fail with their fix reverted.
  • redis.test.js also passed against a real Upstash database, and failed against copies with a Lua syntax error and with the 3,000-entry cap removed. The changed DROP and new PAIRED scripts were run on scratch keys in Upstash, including a forced write failure that left the pairing code in place.
  • The panel's refresh ordering was simulated for slow polls, a poll landing after a save, a sign-out before a slow success, and overlapping polls with different entries.
  • Headless Chrome against a local static build checked that the gallery sits above the nav at desktop and phone widths, that arrows typed in Ask leave the gallery alone, that one Escape closes only Ask and a second closes the gallery, that arrows still move the gallery, that keyboard takeover in the studio keeps the current project, that Alt+Left and Ctrl+J are left alone, and that reduced motion jumps instead of scrolling.
  • The ruler fix was compared old against new in America/New_York across the November and March clock changes.

The ask/ backend still needs its separate Vercel deployment after merge. This PR does not deploy it.

Alitleis123 and others added 30 commits November 8, 2026 19:00
@Alitleis123
Alitleis123 merged commit a0708e1 into main Nov 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant