Skip to content

fix: resolve 4 assigned a11y and security issues (#451 #452 #453 #454)#550

Open
oche11207-art wants to merge 1 commit into
MettaChain:mainfrom
oche11207-art:fix/a11y-and-security-issues
Open

fix: resolve 4 assigned a11y and security issues (#451 #452 #453 #454)#550
oche11207-art wants to merge 1 commit into
MettaChain:mainfrom
oche11207-art:fix/a11y-and-security-issues

Conversation

@oche11207-art

@oche11207-art oche11207-art commented Jun 27, 2026

Copy link
Copy Markdown

Summary

This PR addresses all 4 issues currently assigned in the Stellar Wave program.

Issue #453 (P1 - High Priority): PropertyCard nests buttons inside <a>

  • Problem: The entire card was wrapped in a <Link> with nested interactive buttons (cart, favorite, compare, view), causing axe-core nested-interactive violations and broken keyboard semantics.
  • Fix: Changed outer wrapper from <Link> to <article>. Added explicit <Link> elements for the property title and View button. Removed e.preventDefault() / e.stopPropagation() calls that were only needed to suppress parent link navigation.
  • Files: src/components/PropertyCard.tsx, src/components/__tests__/PropertyCard.a11y.test.tsx

Issue #454 (P3): ViewToggle buttons missing accessible name

  • Problem: Buttons had no aria-label, relying only on visible text. In icon-only rendering scenarios (small screens), screen-readers lost the accessible name.
  • Fix: Added aria-label="Grid view" and aria-label="List view" to both buttons. Wrapped visible text in <span> for resilient icon-only CSS targeting.
  • File: src/components/ViewToggle.tsx

Issue #451 (P2): Open redirect / unsafe share URL risk

  • Problem: Share URL construction used raw template strings without validation; property names with newlines or special chars could break share dialogs or be misinterpreted downstream.
  • Fix: Created centralized src/utils/security/shareUrl.ts with:
    • sanitizeDisplayString() - constrains to safe character set, truncates to 200 chars
    • buildPropertyShareUrl() - validates via URL constructor, warns on cross-origin
    • buildTwitterShareUrl(), buildLinkedInShareUrl(), buildEmailShareUrl() - use URL.searchParams for proper encoding
  • Files: src/utils/security/shareUrl.ts (new), src/components/property/ShareButton.tsx, src/components/MortgageCalculator.tsx

Issue #452 (P2): web-vitals & global listeners leak

  • Problem: extensionDetection.ts and earlyErrorSuppression.ts registered global window event listeners and console overrides at module scope with no cleanup, causing listener accumulation across SPA navigations.
  • Fix:
    • Both modules now track registered listeners/overrides in internal arrays and expose cleanup* functions
    • Console overrides are restored on cleanup
    • Created usePerformanceMonitoring React hook that ensures single PerformanceObserver instance per app lifecycle
  • Files: src/utils/extensionDetection.ts, src/utils/earlyErrorSuppression.ts, src/hooks/usePerformanceMonitoring.ts (new)

Verification

  • TypeScript compilation succeeds (pre-existing errors unrelated)
  • PropertyCard a11y tests updated for new DOM structure
  • axe-core violations eliminated (no nested interactive elements)
  • URL construction validated via URL constructor
  • Display strings sanitized before inclusion in share URLs
  • Global listeners trackable and cleanable via lifecycle hooks

closes #451
closes #452
closes #453
closes #454

Issue MettaChain#453 (P1): PropertyCard - remove nested interactive elements
- Replace outer <Link> with <article> to fix nested-interactive violation
- Add explicit <Link> for property title and View button
- Remove stopPropagation calls (no longer needed without parent link)
- Update a11y tests to match new DOM structure

Issue MettaChain#454 (P3): ViewToggle - add accessible names
- Add aria-labels to grid/list buttons for screen-reader support
- Wrap text in <span> for icon-only rendering scenarios

Issue MettaChain#451 (P2): Share URL security
- Create centralized share URL utility with URL validation
- Sanitize display strings to constrained character set
- Use URL constructor to validate all URLs
- Integrate into ShareButton and MortgageCalculator

Issue MettaChain#452 (P2): Global listener leak prevention
- Add cleanup functions for extension event listeners
- Track console overrides for restoration on cleanup
- Create usePerformanceMonitoring hook with lifecycle management
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