Skip to content

feat: password-reset rate limiting, ARIA labels, form label associations, keyboard navigation#830

Merged
Mystery-CLI merged 1 commit into
Ethereal-Future:mainfrom
jasmine874:feat/issues-735-736-737-738
Jun 28, 2026
Merged

feat: password-reset rate limiting, ARIA labels, form label associations, keyboard navigation#830
Mystery-CLI merged 1 commit into
Ethereal-Future:mainfrom
jasmine874:feat/issues-735-736-737-738

Conversation

@jasmine874

Copy link
Copy Markdown
Contributor

Summary

  • Closes Add rate limiting to password-reset endpoint #735 — Added POST /auth/password-reset with per-IP (10 req/hr) and per-email (3 req/hr) rate limits, a 200ms minimum response delay to prevent timing-based enumeration, previous-token invalidation, 15-min token TTL, and an identical response body regardless of whether the email is registered. Also adds /auth/password-reset/confirm to complete the flow.
  • Closes Add ARIA labels to all icon-only buttons #736 — Added aria-label to the icon-only ✕ remove-contact button in AddressBook.jsx. Confirmed all other icon-only buttons (QR close, copy, notification bell, settings gear) already carried labels.
  • Closes Ensure all form fields have associated label elements #737 — Updated FormField.jsx to use React useId + cloneElement to automatically inject id into child inputs and wire htmlFor on the wrapping <label>, fixing label associations for every FormField usage (KYCForm, NotificationPreferences, etc.). Also added explicit id/aria-label to all unlabeled inputs in AdvancedSearch, AddressBook, and the account-label edit field in AccountDashboardPage.
  • Closes Add keyboard navigation to SearchableSelect component #738 — Rewrote SearchableSelect.jsx with the ARIA combobox pattern: role="combobox", aria-expanded, aria-controls, aria-activedescendant, role="listbox", role="option". Keyboard support: ArrowDown/ArrowUp to move highlight, Home/End for first/last, Enter to select, Escape to dismiss, Tab to close. Visual highlight tracks active index.

Test plan

  • POST /auth/password-reset with the same email 4+ times within an hour returns 429 after the 3rd call, but the response body matches the success body
  • 11+ requests from the same IP within an hour result in 429
  • Timing: even for unknown emails the response takes ≥200ms
  • FormField-wrapped inputs are announced with their label in a screen reader or axe audit
  • SearchableSelect can be fully operated with keyboard alone (open → navigate → select → close)
  • AddressBook remove buttons announce "Remove [name]" to a screen reader

🤖 Generated with Claude Code

… keyboard nav

- Issue 735: Add POST /auth/password-reset with per-IP (10/hr) and per-email (3/hr) rate limiting, 200ms minimum delay to prevent timing enumeration, token invalidation and 15-min TTL, identical response for registered/unregistered emails. Adds /auth/password-reset/confirm endpoint.
- Issue 736: Add aria-label to icon-only ✕ remove-contact button in AddressBook.
- Issue 737: Fix FormField to auto-associate <label htmlFor> with child input using useId + cloneElement; add explicit id/aria-label to all unlabeled inputs in AdvancedSearch, AddressBook, and AccountDashboardPage.
- Issue 738: Implement ARIA combobox keyboard navigation in SearchableSelect — ArrowDown/Up/Home/End/Enter/Escape/Tab, aria-expanded, aria-controls, aria-activedescendant, role=listbox/option, visual highlight tracking.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

@jasmine874 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Mystery-CLI Mystery-CLI merged commit 0c26c0f into Ethereal-Future:main Jun 28, 2026
13 of 39 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

2 participants