Skip to content

fix(hardening): H2 enum-leak & H3 blank-password validation#50

Merged
WolfTasks merged 2 commits into
mainfrom
worktree-hardening-h2-h3
Jul 10, 2026
Merged

fix(hardening): H2 enum-leak & H3 blank-password validation#50
WolfTasks merged 2 commits into
mainfrom
worktree-hardening-h2-h3

Conversation

@WolfTasks

Copy link
Copy Markdown
Owner

Two small backend hardening fixes from the #3 final-review backlog (H2, H3).
Each was prepared as its own spec+plan under docs/superpowers/ and executed TDD.

H2 — Notification-Prefs PUT no longer leaks the enum FQCN

NotificationPreferenceController.update used NotificationType.valueOf(it.type); on an
unknown type the resulting IllegalArgumentException was mapped to 400 but its message
echoed No enum constant com.taskowolf…NotificationType.<X>, leaking the fully qualified
enum name. Now the type is resolved against NotificationType.entries and a controlled
BadRequestException("Unknown notification type: <X>") is thrown on miss. Still HTTP 400;
valid types behave exactly as before. The global IllegalArgumentException handler is left
untouched.

H3 — Reject whitespace-only passwords

ChangePasswordRequest.newPassword and RegisterRequest.password had @Size(min = 8) but
no @NotBlank, so eight spaces passed validation. Added @NotBlank alongside @Size on
both fields. Both endpoints already carry @Valid, so the constraint takes effect
immediately (no controller change). Scope decision: fixed both DTOs for consistency, not
just change-password.

Tests

  • H2: 2 new MockK controller unit tests (asserts no com.taskowolf/No enum constant in the
    message; valid-only path still updates).
  • H3: 4 new direct Bean-Validation unit tests (jakarta.validation.Validator) — blank rejected,
    valid accepted, for both DTOs. No Spring context/JWT needed.
  • Full backend suite green (incl. Postgres testcontainer integration tests).

Specs/plans: docs/superpowers/specs/2026-07-10-h2-* / -h3-* and matching plans/ (on local main).

🤖 Generated with Claude Code

Wolfgang Kozian and others added 2 commits July 10, 2026 23:06
Resolve the notification type against NotificationType.entries and throw a
controlled BadRequestException("Unknown notification type: <X>") on miss,
instead of NotificationType.valueOf(...) whose IllegalArgumentException
message echoed the fully qualified enum name. Still HTTP 400; valid types
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add @notblank alongside @SiZe(min=8) on ChangePasswordRequest.newPassword
and RegisterRequest.password so eight spaces no longer pass validation.
Both endpoints already carry @Valid, so the constraint takes effect
immediately. Covered by direct Bean-Validation unit tests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@WolfTasks WolfTasks merged commit 4a8b966 into main Jul 10, 2026
11 checks passed
@WolfTasks WolfTasks deleted the worktree-hardening-h2-h3 branch July 10, 2026 21:33
WolfTasks pushed a commit that referenced this pull request Jul 10, 2026
H2+H3 merged via PR #50, H1 via PR #51 (both 2026-07-10, squash). All three
hardening items now on main; release still pending (last v1.0.09).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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