Skip to content

[FE-02] Enforce auth on admin routes via Next.js middleware - client-only guard is bypassable #270

Description

@Leothosine

Problem

frontend/app/(auth)/layout.tsx and frontend/app/(auth)/admin/layout.tsx are empty wrappers with no authentication check. ProtectedRoute only runs client-side JavaScript. A user who directly navigates to /admin/users receives and renders the full protected page before the client-side auth check can redirect them. Additionally, RoleProtectedPage returns null on a role mismatch instead of redirecting - the user sees a blank screen.

Proposed Solution

  1. Create frontend/middleware.ts intercepting all requests matching /admin/*
  2. Read the JWT from the accessToken cookie, verify it using jose (jwtVerify with JWT_SECRET)
  3. Redirect unauthenticated requests to /login?redirect={originalPath}
  4. Redirect role-violation requests to /admin/dashboard
  5. Change RoleProtectedPage to call router.replace() instead of returning null

Acceptance Criteria

  • Direct browser navigation to /admin/users with no session redirects to /login
  • An expired token in the cookie triggers the redirect (verify exp claim)
  • A staff role token navigating to a super_admin page redirects to /admin/dashboard
  • Middleware matcher config excludes public routes (/api, /_next, /menu, etc.)
  • Middleware latency does not exceed 5ms on average

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions