Skip to content

fix: add auth and validation boundary to notification/preference APIs - #1876

Closed
Shindy-Ship wants to merge 32 commits into
Commitlabs-Org:masterfrom
Shindy-Ship:security/issue-1790-quality-high-improve-notification-api-and
Closed

Shindy-Ship wants to merge 32 commits into
Commitlabs-Org:masterfrom
Shindy-Ship:security/issue-1790-quality-high-improve-notification-api-and

Conversation

@Shindy-Ship

Copy link
Copy Markdown

Overview

This PR enforces a clear authorization and validation boundary for the notification API and user preferences API, addressing the production-quality risk area of notification/preference consistency across sessions and tabs. It defines explicit state, data, authorization, and failure invariants; validates route parameters, wallet identity, network, numeric values, and server responses at the boundary; and ensures ownership and authorization assumptions are checked server-side rather than inferred from client state. Replay, tampering, wrong-network, disconnected-wallet, and malformed-response scenarios are covered with focused automated tests. Design tradeoff: validation and auth logic is centralized in src/lib/validation.ts and src/lib/auth.ts so both route handlers stay thin and consistent. Remaining limitation: anti-replay state is currently per-instance; a shared store would be needed for multi-instance deployments.

Related Issue

Refs #568

Changes

🔐 Authorization & Validation Boundary

  • [ADD] src/lib/validation.ts

    • Centralized request-boundary schemas and guards for notification and preference routes.
    • Validates wallet identity (Stellar public key format), network (pubnet/testnet), numeric values (cursor, limit, timestamps, amounts), and preference payloads.
    • Rejects malformed inputs with typed errors before they reach business logic.
  • [ADD] src/lib/auth.ts

    • Server-side wallet authentication and ownership verification for notification reads/acknowledgements and preference reads/updates.
    • Requires a signed session proof; never infers identity from client-supplied state.
    • Detects disconnected-wallet, replayed, and tampered authorization attempts.
  • [MODIFY] src/app/api/notifications/route.ts

    • Enforces authorization before any sensitive notification read or acknowledgement action.
    • Validates route parameters and request bodies at the boundary; returns consistent error responses for malformed, unauthorized, wrong-network, disconnected-wallet, and replay scenarios.
    • Validates external/server responses before returning them to the client.
  • [MODIFY] src/app/api/user/preferences/route.ts

    • Applies the same boundary validation and ownership enforcement for preference reads and writes.
    • Ensures preference state remains consistent and only the owning wallet can mutate it.
  • [ADD] src/app/api/notifications/route.test.ts

    • Covers success, failure, boundary, retry, and permission behavior for notification reads and acknowledgements.
    • Includes replay, tampering, wrong-network, disconnected-wallet, and malformed-response cases.
  • [ADD] src/app/api/user/preferences/route.test.ts

    • Covers success, failure, boundary, retry, and permission behavior for preference reads and writes.
    • Includes ownership-mismatch and malformed-preference-payload cases.
  • [ADD] src/lib/validation.test.ts

    • Covers malformed route params, invalid wallet identities, wrong-network values, numeric edge cases, and malformed server responses.
  • [ADD] src/lib/auth.test.ts

    • Covers disconnected-wallet, replay, tampered proof, ownership mismatch, and permission-denied scenarios.

Verification Results

npm test -- src/app/api/notifications/route.test.ts src/app/api/user/preferences/route.test.ts src/lib/validation.test.ts src/lib/auth.test.ts
✅ 48/48 passed

Boundary and adversarial checks:
✅ Malformed route parameters rejected
✅ Invalid wallet identity rejected
✅ Wrong-network requests rejected
✅ Disconnected-wallet requests rejected
✅ Replay/tampered auth rejected
✅ Ownership mismatch rejected
✅ Malformed server responses rejected
Acceptance Criteria Status
Defines and enforces relevant invariants for normal and adversarial inputs ✅ Centralized validation + auth boundary with typed failures
Validates route parameters, wallet identity, network, numeric values, and server responses at the boundary ✅ Covered by validation.ts and route handlers
Ownership and authorization checked server-side, not inferred from client state ✅ auth.ts verifies signed session proof
Replay, tampering, wrong-network, disconnected-wallet, malformed-response scenarios covered ✅ Adversarial test cases across all 4 test suites
Automated tests cover success, failure, boundary, retry, and permission behavior ✅ 48 tests across 4 suites
Includes validation commands, design tradeoffs, and limitations ✅ See overview; remaining limitation is per-instance replay state

Closes #1790

@drips-wave

drips-wave Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Shindy-Ship 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

@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

@Shindy-Ship is attempting to deploy a commit to the 1nonly's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Shindy-Ship

Copy link
Copy Markdown
Author

@Commitlabs-Org Hi! This PR is open and ready for review — happy to address any feedback. Thanks!

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.

[Quality][High] Improve notification API and preference consistency: authorization and hostile-input boundary

2 participants