Skip to content

feat: refresh token rotation, admin scopes, Redis cache, history a11y#277

Merged
robertocarlous merged 1 commit into
Neurowealth:mainfrom
Uyoxy:feat/auth-cache-a11y-issues-213-214-215-352
Jun 29, 2026
Merged

feat: refresh token rotation, admin scopes, Redis cache, history a11y#277
robertocarlous merged 1 commit into
Neurowealth:mainfrom
Uyoxy:feat/auth-cache-a11y-issues-213-214-215-352

Conversation

@Uyoxy

@Uyoxy Uyoxy commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

#214 – Add refresh token rotation for JWT sessions

  • Issue short-lived access tokens (15 min) + long-lived refresh tokens (7 days)
  • Store refresh token hash in Session table (bcrypt, single-use)
  • POST /api/auth/refresh rotates pair; old token invalidated immediately
  • Logout deletes session row, nullifying the refresh token hash
  • Prisma migration: refreshTokenHash, refreshTokenExpiresAt on sessions
  • REFRESH_TOKEN_SECRET + REFRESH_TOKEN_TTL documented in .env.example

#215 – Add per-key permission scoping for admin API keys

  • ADMIN_SCOPES enum: read | write | wallet | agent | super
  • requireAdminScope(scope) middleware factory; super implicitly grants all
  • Scope-mismatch failures written to AdminAuditLog with route + reason
  • 403 response includes human-readable reason field
  • validateScopesInput() for use in key-creation endpoint

#213 – Add Redis caching layer for protocol rates and portfolio snapshots

  • ioredis client initialised in src/config/redis.ts, exported app-wide
  • Protocol rates cached per network with configurable TTL (default 60 s)
  • Portfolio snapshots cached per user; invalidatePortfolioSnapshot() for deposit/withdraw mutations
  • cache_hits_total + cache_misses_total Prometheus counters on /metrics
  • REDIS_URL + TTL vars documented in .env.example

#352 – Improve transaction history filter and pagination accessibility

  • FilterBar: all controls have explicit / htmlFor, fieldset+legend for date range, aria-disabled on loading, logical tab order
  • Pagination: aria-live='polite' region announces page N of M on change, aria-current='page', aria-label on every button, disabled at boundaries
  • useTransactionFilters: resets page to 1 on any filter change
  • history/page.tsx: aria-busy results region, accessible table (scope, caption), role='alert' for errors, role='status' for loading/empty

Closes #214
Closes #215
Closes #213
Closes #352

Neurowealth#214 – Add refresh token rotation for JWT sessions
- Issue short-lived access tokens (15 min) + long-lived refresh tokens (7 days)
- Store refresh token hash in Session table (bcrypt, single-use)
- POST /api/auth/refresh rotates pair; old token invalidated immediately
- Logout deletes session row, nullifying the refresh token hash
- Prisma migration: refreshTokenHash, refreshTokenExpiresAt on sessions
- REFRESH_TOKEN_SECRET + REFRESH_TOKEN_TTL documented in .env.example

Neurowealth#215 – Add per-key permission scoping for admin API keys
- ADMIN_SCOPES enum: read | write | wallet | agent | super
- requireAdminScope(scope) middleware factory; super implicitly grants all
- Scope-mismatch failures written to AdminAuditLog with route + reason
- 403 response includes human-readable reason field
- validateScopesInput() for use in key-creation endpoint

Neurowealth#213 – Add Redis caching layer for protocol rates and portfolio snapshots
- ioredis client initialised in src/config/redis.ts, exported app-wide
- Protocol rates cached per network with configurable TTL (default 60 s)
- Portfolio snapshots cached per user; invalidatePortfolioSnapshot() for
  deposit/withdraw mutations
- cache_hits_total + cache_misses_total Prometheus counters on /metrics
- REDIS_URL + TTL vars documented in .env.example

#352 – Improve transaction history filter and pagination accessibility
- FilterBar: all controls have explicit <label> / htmlFor, fieldset+legend
  for date range, aria-disabled on loading, logical tab order
- Pagination: aria-live='polite' region announces page N of M on change,
  aria-current='page', aria-label on every button, disabled at boundaries
- useTransactionFilters: resets page to 1 on any filter change
- history/page.tsx: aria-busy results region, accessible table (scope,
  caption), role='alert' for errors, role='status' for loading/empty

Closes Neurowealth#214
Closes Neurowealth#215
Closes Neurowealth#213
Closes #352
@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

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

@robertocarlous robertocarlous merged commit 571f0fb into Neurowealth:main Jun 29, 2026
1 of 5 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