Skip to content

chore: deep audit hardening across HTTP, WS, auth-mode, i18n, and errors#60

Merged
TheKAdhikari merged 1 commit into
mainfrom
chore/deep-audit-hardening
Jun 28, 2026
Merged

chore: deep audit hardening across HTTP, WS, auth-mode, i18n, and errors#60
TheKAdhikari merged 1 commit into
mainfrom
chore/deep-audit-hardening

Conversation

@TheKAdhikari

Copy link
Copy Markdown
Contributor

Summary

Fixes 30 adversarially-verified findings from a deep multi-dimension audit of the starter (bugs, security, performance, duplication, type-safety, correctness). All quality gates pass: ci:check, type-check, check:deprecated, 170 tests, and production build.

Auth mode (core change)

SAVE_AUTH_TOKENS was a hardcoded false. It now derives from NODE_ENV via an allowlist {development, test}:

  • dev / test → bearer/localStorage tokens
  • all deployed envs → HttpOnly cookies (next build forces NODE_ENV=production, staging included, so staging behaves as prod for the FE)

The secure-storage service now throws if a token write is attempted in a cookie-mode env (defense in depth). Same-site cookie topology is documented in AGENTS.md.

What changed

Critical

  • WebSocket first-subscriber crash — onEvent() ran before the async connect() built the socket. Now buffers subscriptions and flushes on connect.

WebSocket

  • Re-read the bearer token on every (re)connect (was replaying a stale token forever).
  • Tear down both Socket- and Manager-level listeners on disconnect (was leaking).
  • Clear connectedAt on disconnect; zod-validate server-originated payloads.

HTTP

  • Never attach a bearer token to cross-origin requests (both clients).
  • Gate token-store clear() to bearer mode (no-op server-side in cookie mode).
  • Durable refresh-loop guard (was re-arming instantly).
  • Sanitize forwarded cookies; prefer caller-abort over timeout on a tie.
  • Extract shared rotateTokens (de-dup the two refresh adapters), shared runtime helper, dedup CookieResolver, align Result defaults to ApiException, guard getFieldErrors against empty objects, remove dead code.

Logging

  • Broaden redaction to root-level keys, nested keys, and req/res/response headers (pino's * wildcard is not recursive).

i18n / SEO

  • Wire the previously-dead DEFAULT_LOCALE; locale-aware OpenGraph locale; hreflang guard under localePrefix:'never'; single-source SUPPORTED_LOCALES; page-level locale guard.

Error boundaries

  • Localize in-app boundaries, add structured logging, stop rendering raw error.message in production.

Misc

  • Hoist createMiddleware in proxy.ts; min-h-dvh/w-full on the home page.

Test plan

  • yarn ci:check
  • yarn type-check
  • yarn check:deprecated
  • yarn test (170 passing, new tests for WS buffering/teardown, cross-origin guard, refresh-loop block, redaction, runtime)
  • yarn build

Fixes 30 adversarially-verified findings from a deep multi-dimension audit.

Auth mode (core change):
- Derive SAVE_AUTH_TOKENS from NODE_ENV via an allowlist {development,test} →
  bearer/localStorage; all deployed envs (next build forces NODE_ENV=production,
  staging included) → HttpOnly cookies. Add a defense-in-depth throw in the
  secure-storage service so token writes can never run in cookie-mode envs.

WebSocket:
- Fix first-subscriber crash: buffer onEvent subscriptions until connect()
  builds the socket, then flush.
- Re-read the bearer token on every (re)connect via the auth callback form.
- Tear down both Socket- and Manager-level listeners on disconnect.
- Clear connectedAt on disconnect; zod-validate server-originated payloads.

HTTP:
- Never attach a bearer token to a cross-origin request (both clients).
- Gate token-store clear() to bearer mode (no-op server side in cookie mode).
- Make the refresh-loop guard durably block instead of re-arming instantly.
- Sanitize forwarded cookies; classify caller-abort over timeout on a tie.
- Extract shared rotateTokens (de-dup the two refresh adapters), shared
  runtime helper, dedup CookieResolver, align Result defaults to ApiException,
  guard getFieldErrors against empty error objects, remove dead code.

Logging:
- Broaden redaction to root-level keys, nested keys, and req/res/response
  headers (pino's * wildcard is not recursive).

i18n / SEO:
- Wire the previously-dead DEFAULT_LOCALE knob; locale-aware OpenGraph locale;
  hreflang guard under localePrefix:'never'; single-source SUPPORTED_LOCALES;
  page-level locale guard.

Error boundaries:
- Localize the in-app boundaries, add structured logging, and stop rendering
  raw error.message in production.

Misc:
- Hoist createMiddleware in proxy.ts; use min-h-dvh/w-full on the home page.
@TheKAdhikari TheKAdhikari merged commit de8cc8f into main Jun 28, 2026
2 checks passed
@TheKAdhikari TheKAdhikari deleted the chore/deep-audit-hardening branch June 28, 2026 09:04
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