chore: deep audit hardening across HTTP, WS, auth-mode, i18n, and errors#60
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_TOKENSwas a hardcodedfalse. It now derives fromNODE_ENVvia an allowlist{development, test}:next buildforcesNODE_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
onEvent()ran before the asyncconnect()built the socket. Now buffers subscriptions and flushes on connect.WebSocket
connectedAton disconnect; zod-validate server-originated payloads.HTTP
clear()to bearer mode (no-op server-side in cookie mode).rotateTokens(de-dup the two refresh adapters), shared runtime helper, dedupCookieResolver, alignResultdefaults toApiException, guardgetFieldErrorsagainst empty objects, remove dead code.Logging
req/res/responseheaders (pino's*wildcard is not recursive).i18n / SEO
DEFAULT_LOCALE; locale-aware OpenGraph locale; hreflang guard underlocalePrefix:'never'; single-sourceSUPPORTED_LOCALES; page-level locale guard.Error boundaries
error.messagein production.Misc
createMiddlewareinproxy.ts;min-h-dvh/w-fullon the home page.Test plan
yarn ci:checkyarn type-checkyarn check:deprecatedyarn test(170 passing, new tests for WS buffering/teardown, cross-origin guard, refresh-loop block, redaction, runtime)yarn build