Skip to content

feat: implement 401 and 403 status pages - #223

Merged
naheel0 merged 3 commits into
mainfrom
feat/36-custom-error-status-pages
Aug 8, 2026
Merged

feat: implement 401 and 403 status pages#223
naheel0 merged 3 commits into
mainfrom
feat/36-custom-error-status-pages

Conversation

@naheel0

@naheel0 naheel0 commented Aug 8, 2026

Copy link
Copy Markdown
Member

Closes #36

Adds placeholder 401 (unauthorized) and 403 (forbidden) error pages in the App Router, ready for the now-present GitHub authentication system.

Changes

  • New \src/app/unauthorized.tsx\ — rendered when \unauthorized()\ is called; offers GitHub sign-in.
  • New \src/app/forbidden.tsx\ — rendered when \ orbidden()\ is called.
  • Both match the existing design language of
    ot-found.tsx\ / \error.tsx\ (black bg, gradient headline, terminal panel, responsive CTA buttons).

Notes

  • 404 (
    ot-found.tsx) and 500 (\error.tsx) pages already render correctly with consistent layout.
  • Verified via
    pm run lint, \ sc --noEmit, and a full
    ext build.

@naheel0
naheel0 requested a review from adithyanmkd as a code owner August 8, 2026 16:45
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
readme-gen-ai Ready Ready Preview Aug 8, 2026 4:55pm

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 257de5ce-d10d-4e25-95ad-4ce97f0613d2

📥 Commits

Reviewing files that changed from the base of the PR and between dc11a4a and 6570e06.

📒 Files selected for processing (2)
  • src/app/forbidden.tsx
  • src/app/unauthorized.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/app/forbidden.tsx
  • src/app/unauthorized.tsx

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added a dedicated 403 access-denied page with home and back navigation.
    • Added a dedicated 401 authentication page with GitHub sign-in and home navigation.
    • Both pages provide clear status messaging and verification guidance.

Walkthrough

Adds client-side 401 and 403 status pages with navigation actions and terminal-style diagnostic panels.

Changes

Authentication status pages

Layer / File(s) Summary
Unauthorized authentication page
src/app/unauthorized.tsx
Adds a styled 401 screen with GitHub sign-in, home navigation, and session verification diagnostics.
Forbidden permission page
src/app/forbidden.tsx
Adds a styled 403 screen with home navigation, browser-back behavior, and permission-denied diagnostics.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: adithyanmkd

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: adding 401 Unauthorized and 403 Forbidden status pages.
Description check ✅ Passed The description directly explains the new 401 and 403 pages, their behavior, design consistency, and validation.
Linked Issues check ✅ Passed The changes implement the placeholder 401 and 403 pages requested by issue #36 and support future authentication flows with consistent responsive layouts.
Out of Scope Changes check ✅ Passed The changes are limited to the two status page components and align with issue #36 objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/36-custom-error-status-pages

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/unauthorized.tsx`:
- Around line 42-50: Update the Button/Link composition in
src/app/unauthorized.tsx lines 42-50 and src/app/forbidden.tsx lines 32-40: make
Button use asChild and place the existing Link inside it, preserving the current
href, styling, icon, and label at both sites.
- Line 9: Wire the Unauthorized component in src/app/unauthorized.tsx and the
Forbidden component in src/app/forbidden.tsx into the protected Next.js 16 route
handlers/components: call unauthorized() for missing authentication and
forbidden() for permission failures, and add path coverage proving each
corresponding UI renders. Both cited files require no direct UI changes beyond
preserving their existing components.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ad5fdd6-29c8-43d9-8dc5-8badbf1ad9bd

📥 Commits

Reviewing files that changed from the base of the PR and between ca997ce and dc11a4a.

📒 Files selected for processing (2)
  • src/app/forbidden.tsx
  • src/app/unauthorized.tsx

Comment thread src/app/unauthorized.tsx
import { Home, LogIn, Lock, ShieldQuestion } from "lucide-react";
import { Button } from "@/components/ui/Button";

export default function Unauthorized() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

fd -HI -E node_modules '^next\.config\.(js|mjs|ts)$|^package\.json$' . \
  -x sh -c 'echo "=== $1 ==="; sed -n "1,220p" "$1"' sh {}

rg -n -C 4 --glob '*.{ts,tsx,js,jsx}' \
  '\b(unauthorized|forbidden)\s*\(' src

Repository: BeyteFlow/ReadmeGenAI

Length of output: 1621


🌐 Web query:

Next.js 16 authentication middleware unauthorized forbidden app directory documentation

💡 Result:

In Next.js 16, the middleware.ts file has been deprecated and replaced by proxy.ts [1][2]. This file acts as a centralized request interceptor that runs before your application routes are processed [1][3]. ### Key Authentication Changes in Next.js 16 * Renaming & Runtime: Use the codemod npx @next/codemod@canary middleware-to-proxy to rename middleware.ts to proxy.ts and update the export to proxy [2][4]. Unlike previous versions, proxy.ts now defaults to the Node.js runtime [1][4]. * Architecture Shift: Next.js 16 enforces a "thin proxy" architecture [2]. The proxy.ts file should be limited to optimistic checks (e.g., verifying a session cookie to perform fast redirects) [2][5][6]. It should not perform database lookups or complex cryptographic verification [2][5]. * Security Layers: Because proxy.ts does not protect internal invocations (such as Server Actions or internal server-side fetches), you must perform authoritative authorization within your application logic [7][5][6]. ### Handling Unauthorized and Forbidden States To manage unauthorized or forbidden access within your App Router application, use the dedicated unauthorized() and forbidden() functions [8][9]. * unauthorized() (401): Throws an error to render your unauthorized.js UI [9]. This is best used when a user is not authenticated and needs to be prompted to log in [9]. * forbidden() (403): Throws an error to render your forbidden.js UI [8]. This is best used when a user is authenticated but lacks the specific permissions required for the requested resource [8]. These functions can be invoked in Server Components, Server Actions, and Route Handlers [8][9]. Because they work by throwing an error, they must be called within the render path [8][9]. ### Recommended Pattern 1. Proxy Layer: Use proxy.ts to check for the presence of a session cookie and redirect unauthenticated users to a login page [10][5][6]. 2. Data Access Layer (DAL): Centralize your session verification logic (e.g., verifySession()) in a DAL [11][5]. Use React's cache() function to deduplicate these checks during a single request [11][10][5]. 3. Component/Handler Level: Invoke your verifySession() and check permissions inside your Server Components and Route Handlers, using unauthorized() or forbidden() when requirements are not met [11][10][5][8][9]. This approach ensures that your application is secure regardless of how a route is accessed [5][6].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== tracked file list candidates ==="
git ls-files | rg '(^src/app/(unauthorized|forbidden)\.tsx$|(^src/|test|spec|vitest|package|next\.config|middleware|proxy)\.' || true

echo "=== proxy/middleware/search ==="
rg -n -C 3 --glob '*.{ts,tsx,js,jsx}' '\b(unauthorized|forbidden|verifySession|hasPermission|forbidden\s*\(|unauthorized\s*\()' . || true

Repository: BeyteFlow/ReadmeGenAI

Length of output: 393


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== tracked candidate files ==="
git ls-files | grep -E '(^src/app/(unauthorized|forbidden)\.tsx$|^src/|test|spec|vitest|package\.json|next\.config|middleware|proxy)' || true

echo "=== auth-related symbols ==="
rg -n -C 3 --glob '*.{ts,tsx,js,jsx}' '\b(unauthorized|forbidden|proxy|verifySession|hasPermission)\b' . || true

Repository: BeyteFlow/ReadmeGenAI

Length of output: 1434


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== unauthorized.tsx ==="
cat -n src/app/unauthorized.tsx || true

echo "=== forbidden.tsx ==="
cat -n src/app/forbidden.tsx || true

echo "=== protected route candidates ==="
for f in src/app/generate/\[\ repo\']/page.tsx src/app/docs/page.tsx src/app/generate/page.tsx src/app/examples/page.tsx; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,240p' "$f"
  fi
done

echo "=== Next config/package relevant ==="
sed -n '1,80p' next.config.ts
sed -n '1,120p' package.json

Repository: BeyteFlow/ReadmeGenAI

Length of output: 17208


Wire the 401/403 UI into protected route failures.

src/app/unauthorized.tsx and src/app/forbidden.tsx are only UI components. Call unauthorized() for missing authentication and forbidden() for permission failures in the protected Next.js 16 route handlers/components, and add path coverage so the tests prove each UI renders on the corresponding failure.

📍 Affects 2 files
  • src/app/unauthorized.tsx#L9-L9 (this comment)
  • src/app/forbidden.tsx#L8-L8
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/unauthorized.tsx` at line 9, Wire the Unauthorized component in
src/app/unauthorized.tsx and the Forbidden component in src/app/forbidden.tsx
into the protected Next.js 16 route handlers/components: call unauthorized() for
missing authentication and forbidden() for permission failures, and add path
coverage proving each corresponding UI renders. Both cited files require no
direct UI changes beyond preserving their existing components.

Comment thread src/app/unauthorized.tsx Outdated
@naheel0

naheel0 commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

Regarding the wiring comment: these 401/403 pages are registered Next.js 16 special files (\unauthorized.tsx/ orbidden.tsx) and render whenever \unauthorized()\ / \ orbidden()\ is invoked from a Server Component or Route Handler. There are currently no protected pages in the app — the /generate\ flow intentionally supports anonymous README generation for public repos, so guarding it would break that product flow. The pages are ready to render once an auth-enforced route is introduced. The nested-interactive fix has been pushed.

@naheel0

naheel0 commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@naheel0

naheel0 commented Aug 8, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@naheel0
naheel0 merged commit c70640f into main Aug 8, 2026
7 checks passed
@naheel0
naheel0 deleted the feat/36-custom-error-status-pages branch August 8, 2026 17:37
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.

Custom Status Code Pages Not Fully Implemented in Next.js

1 participant