auth-route-protection-checker
Auth Route Protection Checker
To audit and enhance authentication protection across Next.js routes, server components, and API routes, follow these steps systematically.
Step 1: Discover Project Structure
Identify all files that need authentication checks:
-
Use Glob to find all route files:
app/**/page.tsx- Page componentsapp/**/route.ts- API routesapp/**/layout.tsx- Layout componentslib/actions/**/*.ts- Server actions
-
Read middleware configuration:
middleware.ts- Current middleware setupnext.config.js- Route configuration
-
Identify authentication setup:
- Search for auth client files (Supabase, NextAuth, Clerk, etc.)
- Find auth utility functions
Step 2: Analyze Current Protection
For each discovered file, check for existing auth protection:
Check for Authentication Patterns
Use Grep to search for:
- "auth.getUser()"
- "getSession()"
- "currentUser()"
- "requireAuth"
- "redirect.*login"
- "unauthorized"
- "createServerClient"
Identify Protection Gaps
Flag files that:
- Have no auth checks
- Are in protected routes but lack verification
- Accept user input without auth validation
- Perform privileged operations without role checks
Consult references/protection-patterns.md for common patterns.
Step 3: Categorize Routes by Protection Level
Classify routes into security categories:
Public Routes - No auth required:
- Landing pages
- Marketing content
- Public blog posts
- Login/signup pages
Authenticated Routes - Login required:
- User dashboard
- Profile pages
- User-specific data
Role-Protected Routes - Specific roles required:
- Admin panels
- Moderator tools
- Premium features
Action-Protected Routes - Specific permissions required:
- Edit operations
- Delete operations
- Admin actions
Step 4: Generate Protection Report
Create a comprehensive audit report:
# Route Protection Audit Report
Generated: [timestamp]
## Summary
- Total Routes: X
- Protected: Y
- Unprotected: Z
- Needs Review: N
## Unprotected Routes
### Critical (Requires immediate attention)
- [ ] /app/admin/page.tsx - Admin panel with no auth check
- [ ] /app/api/users/delete/route.ts - Delete endpoint unprotected
### High Priority
- [ ] /app/dashboard/page.tsx - User dashboard missing auth
- [ ] /app/api/data/route.ts - API route needs auth
### Medium Priority
- [ ] /app/profile/page.tsx - Profile page needs verification
### Low Priority (Review recommended)
- [ ] /app/about/page.tsx - Consider if auth needed
## Protected Routes
### Properly Protected
- [x] /app/(protected)/settings/page.tsx - Has auth check
- [x] /app/api/auth/logout/route.ts - Auth verified
### Needs Enhancement
- [~] /app/admin/users/page.tsx - Has auth but no role check
- [~] /app/api/posts/route.ts - Auth exists but no rate limiting
Step 5: Generate Protection Code
For each unprotected route, generate appropriate protection code:
Server Component Protection
// app/protected-page/page.tsx
import { createServerClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
export default async function ProtectedPage() {
const supabase = createServerClient()
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
redirect('/login')
}
// Optional: Role check
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
if (profile?.role !== 'admin') {
redirect('/unauthorized')
}
return <div>Protected Content</div>
}
API Route Protection
// app/api/protected/route.ts
import { createServerClient } from '@/lib/supabase/server'
import { NextResponse } from 'next/server'
export async function GET(request: Request) {
const supabase = createServerClient()
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
)
}
// Optional: Role-based access
const userRole = user.user_metadata?.role
if (userRole !== 'admin') {
return NextResponse.json(
{ error: 'Forbidden - Admin access required' },
{ status: 403 }
)
}
// Protected logic here
return NextResponse.json({ data: 'protected data' })
}
Server Action Protection
// lib/actions/admin.ts
'use server'
import { createServerClient } from '@/lib/supabase/server'
import { revalidatePath } from 'next/cache'
export async function deleteUser(userId: string) {
const supabase = createServerClient()
// Auth check
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
throw new Error('Unauthorized')
}
// Role check
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
if (profile?.role !== 'admin') {
throw new Error('Forbidden - Admin access required')
}
// Permission check (optional)
const canDeleteUsers = await checkPermission(user.id, 'users:delete')
if (!canDeleteUsers) {
throw new Error('Insufficient permissions')
}
// Perform action
const { error: deleteError } = await supabase
.from('users')
.delete()
.eq('id', userId)
if (deleteError) throw deleteError
revalidatePath('/admin/users')
}
Middleware Protection
// middleware.ts
import { createServerClient } from '@/lib/supabase/middleware'
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
const response = NextResponse.next()
const supabase = createServerClient(request, response)
const { data: { user } } = await supabase.auth.getUser()
// Protected routes
const protectedRoutes = ['/dashboard', '/profile', '/settings']
const isProtectedRoute = protectedRoutes.some(route =>
request.nextUrl.pathname.startsWith(route)
)
if (isProtectedRoute && !user) {
return NextResponse.redirect(new URL('/login', request.url))
}
// Admin routes
const adminRoutes = ['/admin']
const isAdminRoute = adminRoutes.some(route =>
request.nextUrl.pathname.startsWith(route)
)
if (isAdminRoute) {
if (!user) {
return NextResponse.redirect(new URL('/login', request.url))
}
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
if (profile?.role !== 'admin') {
return NextResponse.redirect(new URL('/unauthorized', request.url))
}
}
return response
}
export const config = {
matcher: [
'/dashboard/:path*',
'/profile/:path*',
'/settings/:path*',
'/admin/:path*',
]
}
Step 6: Generate Helper Functions
Create reusable auth utilities using templates from assets/auth-helpers.ts:
// lib/auth/helpers.ts
import { createServerClient } from '@/lib/supabase/server'
import { redirect } from 'next/navigation'
export async function requireAuth() {
const supabase = createServerClient()
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
redirect('/login')
}
return user
}
export async function requireRole(allowedRoles: string[]) {
const user = await requireAuth()
const supabase = createServerClient()
const { data: profile } = await supabase
.from('profiles')
.select('role')
.eq('id', user.id)
.single()
if (!profile || !allowedRoles.includes(profile.role)) {
redirect('/unauthorized')
}
return { user, role: profile.role }
}
export async function checkPermission(
userId: string,
permission: string
): Promise<boolean> {
const supabase = createServerClient()
const { data } = await supabase
.from('user_permissions')
.select('permission')
.eq('user_id', userId)
.eq('permission', permission)
.single()
return !!data
}
Step 7: Create Testing Suite
Generate tests to verify protection works:
Use templates from assets/auth-tests.ts:
// tests/auth-protection.test.ts
import { describe, it, expect } from 'vitest'
import { GET } from '@/app/api/protected/route'
describe('Route Protection', () => {
it('returns 401 for unauthenticated requests', async () => {
const request = new Request('http://localhost/api/protected')
const response = await GET(request)
expect(response.status).toBe(401)
})
it('returns 403 for unauthorized role', async () => {
// Mock auth with non-admin user
const response = await GET(mockRequestWithUser({ role: 'user' }))
expect(response.status).toBe(403)
})
it('allows access for admin users', async () => {
const response = await GET(mockRequestWithUser({ role: 'admin' }))
expect(response.status).toBe(200)
})
})
Step 8: Generate Documentation
Create documentation for the protection system:
# Authentication & Authorization Guide
## Overview
This application uses [Auth Provider] for authentication and role-based access control.
## Route Protection Levels
### Public Routes
- No authentication required
- Accessible to all visitors
- Examples: /, /about, /login
### Authenticated Routes
- Requires user login
- No specific role needed
- Examples: /dashboard, /profile
### Role-Protected Routes
- Requires specific role(s)
- Examples: /admin (admin role)
### Permission-Protected Routes
- Requires specific permissions
- Granular access control
- Examples: /admin/delete-user (users:delete permission)
## Implementation Patterns
[Include code examples and usage guidelines]
Step 9: Suggest Improvements
Based on the audit, suggest security enhancements:
- Middleware Coverage: Routes missing from middleware config
- Consistent Patterns: Inconsistent auth check implementations
- Error Handling: Better error messages and redirects
- Rate Limiting: API routes needing rate limits
- CSRF Protection: Forms needing CSRF tokens
- Audit Logging: Privileged actions needing logging
Consult references/security-best-practices.md for recommendations.
Implementation Guidelines
Best Practices
- Always check auth on server side, never trust client
- Use middleware for route-based protection
- Add role/permission checks for sensitive operations
- Implement proper error handling and redirects
- Log authentication failures and suspicious activity
- Use HTTPS in production
- Implement rate limiting on auth endpoints
Common Patterns
Consult references/protection-patterns.md for:
- Server component auth checks
- API route protection
- Server action security
- Middleware configuration
- Role-based access control
- Permission-based access control
Output Format
Generate files:
reports/
auth-audit-[timestamp].md
security/
auth-helpers.ts (if missing)
middleware.ts (enhanced version)
tests/
auth-protection.test.ts
docs/
auth-guide.md
Verification Checklist
Before completing:
- All routes categorized by protection level
- Critical unprotected routes identified
- Protection code generated for gaps
- Helper functions created/updated
- Middleware configured correctly
- Tests cover auth scenarios
- Documentation updated
Consulting References
Throughout analysis:
- Consult
references/protection-patterns.mdfor auth patterns - Consult
references/security-best-practices.mdfor guidelines - Use templates from
assets/auth-helpers.ts - Use test templates from
assets/auth-tests.ts
Completion
When finished:
- Display audit report summary
- Highlight critical issues
- Provide generated protection code
- List implementation steps
- Offer to apply fixes or provide guidance
More from hopeoverture/worldbuilding-app-skills
eslint-prettier-husky-config
This skill should be used when setting up code quality tooling with ESLint v9 flat config, Prettier formatting, Husky git hooks, lint-staged pre-commit checks, and GitHub Actions CI lint workflow. Apply when initializing linting, adding code formatting, configuring pre-commit hooks, setting up quality gates, or establishing lint CI checks for Next.js or React projects.
51testing-next-stack
Scaffolds comprehensive testing setup for Next.js applications including Vitest unit tests, React Testing Library component tests, and Playwright E2E flows with accessibility testing via axe-core. This skill should be used when setting up test infrastructure, generating test files, creating test utilities, adding accessibility checks, or configuring testing frameworks for Next.js projects. Trigger terms include setup testing, scaffold tests, vitest, RTL, playwright, e2e tests, component tests, unit tests, accessibility testing, a11y tests, axe-core, test configuration.
38markdown-editor-integrator
This skill should be used when installing and configuring markdown editor functionality using @uiw/react-md-editor. Applies when adding rich text editing, markdown support, WYSIWYG editors, content editing with preview, or text formatting features. Trigger terms include markdown editor, rich text editor, text editor, add markdown, install markdown editor, markdown component, WYSIWYG, content editor, text formatting, editor preview.
27form-generator-rhf-zod
This skill should be used when generating React forms with React Hook Form, Zod validation, and shadcn/ui components. Applies when creating entity forms, character editors, location forms, data entry forms, or any form requiring client and server validation. Trigger terms include create form, generate form, build form, React Hook Form, RHF, Zod validation, form component, entity form, character form, data entry, form schema.
23supabase-auth-ssr-setup
This skill should be used when configuring Supabase Auth for server-side rendering with Next.js App Router, including secure cookie handling, middleware protection, route guards, authentication utilities, and logout flow. Apply when setting up SSR auth, adding protected routes, implementing middleware authentication, configuring secure sessions, or building login/logout flows with Supabase.
18tailwind-shadcn-ui-setup
This skill should be used when setting up, configuring, or initializing Tailwind CSS (v3 or v4) and shadcn/ui for Next.js 16 App Router projects. Configure dark mode, design tokens, base layout with header/sidebar, accessibility defaults, and generate example components. Includes comprehensive setup automation, theme customization, and production-ready patterns. Use when the user requests "setup Tailwind", "configure shadcn/ui", "add dark mode", "initialize design system", or "setup UI framework" for Next.js projects.
17