Skip to content

Hardening audit: identity N+1, PII log scrubbing, dead IsMuted column, dashboard refresh timeout#1300

Merged
iammukeshm merged 5 commits into
mainfrom
audit/fable-hardening
Jun 12, 2026
Merged

Hardening audit: identity N+1, PII log scrubbing, dead IsMuted column, dashboard refresh timeout#1300
iammukeshm merged 5 commits into
mainfrom
audit/fable-hardening

Conversation

@iammukeshm

Copy link
Copy Markdown
Member

What

Output of a full-stack hardening audit (authz/tenant-isolation > performance > clean code > frontend > IaC). Five parallel audit sweeps, every finding re-verified against code before fixing. Headline: no authorization or tenant-isolation issues exist — all historical security fixes re-verified PASS, and a fresh sweep of all 168 endpoints found no gaps.

Fixes

  • perf(identity): GetUserRolesAsync issued one IsInRoleAsync DB round-trip per role (N+1). Now a single GetRolesAsync feeds a case-insensitive set lookup.
  • fix(identity): emails (PII) removed from 3 log message templates (registration, token generation, welcome-email failure) — UserId only.
  • refactor(chat): dead ChannelMember.IsMuted removed end-to-end (domain, EF config, ChannelMemberDto, dashboard client type) + migration DropChannelMemberIsMuted.
    • ⚠️ Deliberate contract change: ChannelMemberDto loses IsMuted. The property was get-only, never set, always serialized false; no consumer read it (verified across both apps and all tests).
    • ⚠️ Schema change: existing DBs need DbMigrator apply (drops chat.ChannelMembers.IsMuted).
  • fix(dashboard): refreshAccessToken now aborts after 30s — a stalled refresh previously hung the shared refresh promise and every queued 401-retry behind it (admin already had this guard). Ticket comment composer passes its body through mutate(arg) (golden rule Advanced User & Role Based Permission Management #9) and gains an aria-label. Chat DM/delete/pin failure toasts now include the ProblemDetails description.
  • chore(admin): unused openapi-typescript devDependency removed.

Verified

  • Backend build 0 warnings (TreatWarningsAsErrors), full suite green: 713/714 integration (1 pre-existing skip) + 964 unit/arch tests, 0 failures
  • Both apps: tsc + vite build + eslint clean; dashboard chat+tickets Playwright 15/15
  • terraform fmt -check + terraform validate clean on app_stack

Deferred (documented, unchanged)

🤖 Generated with Claude Code

iammukeshm and others added 5 commits June 13, 2026 01:47
…lesAsync lookup

GetUserRolesAsync issued one membership query per role in the tenant
(N+1). One GetRolesAsync call now feeds a case-insensitive set lookup,
matching ASP.NET Identity's normalized-name comparison semantics.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lates

PII minimization: user registration, token generation, and welcome-email
failure logs now identify users by the pseudonymous UserId only. The
email previously rode along in three message templates and flowed into
every exported log sink.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ct, and schema

The property was get-only and never set anywhere, so it always
serialized as false: dead weight in the domain, ChannelMemberDto,
the dashboard client type, and a chat.ChannelMembers column. Removed
end-to-end with migration DropChannelMemberIsMuted.

Deliberate contract change: ChannelMemberDto loses a field no consumer
ever read (verified across both React apps and all tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…r chat error toasts

- refreshAccessToken now aborts after the standard 30s timeout; a
  stalled refresh previously hung the shared refreshPromise and every
  queued 401-retry behind it (admin already had this guard).
- Ticket comment composer passes the body through mutate(arg) instead
  of closed-over state (golden rule #9) and gains an aria-label.
- Chat DM/delete/pin failure toasts now include the ProblemDetails
  description instead of a bare generic message.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
No codegen step exists - API types are hand-written per the frontend
conventions. The dependency only created false expectations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@iammukeshm iammukeshm merged commit 8c216ad into main Jun 12, 2026
12 checks 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