Skip to content

feat: add role-aware navigation and protected route guards - #1071

Merged
Junirezz merged 1 commit into
Junirezz:mainfrom
Awosdot:claude/role-aware-nav-guards-qajip0
Jul 29, 2026
Merged

feat: add role-aware navigation and protected route guards#1071
Junirezz merged 1 commit into
Junirezz:mainfrom
Awosdot:claude/role-aware-nav-guards-qajip0

Conversation

@Awosdot

@Awosdot Awosdot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Closes #981

Security Testing

  • N/A — no state-changing or external-integration code added; this is client-side nav/routing only.

Test Coverage

  • All new code paths have test coverage
  • frontend/src/lib/roles.test.ts (role resolution, allowlist parsing/matching)
  • frontend/src/components/ProtectedRoute.test.tsx (allow/redirect behavior, custom redirect target)
  • frontend/src/components/Navbar.test.tsx (Admin link visibility per role, existing assertions untouched)
  • Baseline vs. after comparison run at the branch point:
  • npm run build: clean before and after
  • npm run lint: 0 errors / 5 pre-existing warnings, identical before and after
  • npm run test:run: 718 passed / 1 pre-existing failure (VaultComparison.test.tsx, unrelated to this change) before → 732 passed / same 1 pre-existing failure after. All 14 new tests pass; no regressions.

🚀 Deployment Notes

No infrastructure or deployment changes required. A new optional env var, VITE_ADMIN_WALLETS (comma-separated wallet addresses), was added to .env.example, .env.local.example, .env.production.example, and docs/ENV_VARIABLE_MATRIX.md. Leaving it unset disables the admin role for everyone — fully backward compatible.

Mainnet Readiness

  • This code is ready for production deployment
  • All critical tests pass
  • Security review approved
  • No temporary debug code
  • No TODO comments

Breaking Changes

None. Navbar's new role prop defaults to "guest", so existing callers/tests are unaffected.


📊 Automated Scan Results

Slither Analysis

  • ✓ Status: N/A — no contract code changed

Related Documentation


✅ Reviewer Checklist

  • Tests cover the new role-resolution and route-guard logic
  • No external calls / no state-changing logic introduced
  • Access control note: this is a UI-layer allowlist, not a security boundary (documented)
  • Follow-up: any future privileged frontend action gated by admin role must still enforce authorization server-side

📋 Pre-Submit Checklist

  • Description is clear and concise
  • All tests passing locally: npm test (except the one pre-existing, unrelated failure noted above)
  • Linter passing: npm run lint
  • Code follows project style guide
  • No merge conflicts
  • Commits are clean and well-documented
  • Branch is up-to-date with main/develop

Resolve a client-side UserRole (guest/investor/admin) from the connected
wallet address via a VITE_ADMIN_WALLETS allowlist, gate the nav's Admin
link and a new /admin route behind it with a reusable ProtectedRoute
guard, and document the pattern for adding future gated routes.

Closes Junirezz#981
@drips-wave

drips-wave Bot commented Jul 28, 2026

Copy link
Copy Markdown

@Awosdot 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

@Junirezz
Junirezz merged commit 603d910 into Junirezz:main Jul 29, 2026
11 of 15 checks passed
Francis6-git pushed a commit to Francis6-git/YieldVault-RWA that referenced this pull request Jul 30, 2026
…edirect

ProtectedRoute (Junirezz#1071, Junirezz#981) already redirects a disallowed role away from a
guarded route and stashes the attempted path in location.state.from "so a
future redirect target can restore it later" — but nothing ever read that
state, so a user who tried /admin and later connected the admin wallet just
stayed on the page they'd been bounced to instead of landing back on /admin.

Add useRestoreGuardedRoute(role), called from App.tsx whenever role changes.
It tries the stashed `from` path once per role transition: if the new role
is allowed, the user lands where they originally tried to go; if not,
ProtectedRoute guards it again (role hasn't changed, so the hook won't
re-fire), avoiding a redirect loop.

Related to Junirezz#1040, which duplicates Junirezz#981, already resolved by Junirezz#1071 for the
role/nav/guard scaffolding this builds on.
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.

Frontend: Add role-aware navigation and protected route guards

3 participants