Skip to content

Detect stale GitHub App auth and send users to /setup#155

Merged
stylessh merged 3 commits intomainfrom
stylessh/github-app-reauth-redirect-setup
Apr 18, 2026
Merged

Detect stale GitHub App auth and send users to /setup#155
stylessh merged 3 commits intomainfrom
stylessh/github-app-reauth-redirect-setup

Conversation

@stylessh
Copy link
Copy Markdown
Owner

@stylessh stylessh commented Apr 18, 2026

When GitHub rejects the app user token (for example after permission or credential changes), checkSetupComplete now fails a live GET /user/installations check so protected routes redirect to /setup instead of assuming the DB row is enough.

Installation access token mint errors that indicate re-authorization are surfaced as the same Bad credentials pattern so the error screen can offer Review GitHub access (links to /setup and clears the in-memory protected-route cache). Visiting /setup also clears that cache so returning to the dashboard re-runs the setup check.

Keeps the existing configure access path for Resource not accessible by integration style 403s.

Summary by CodeRabbit

  • New Features

    • Added a reauthorize-GitHub action in error screens with a clear button to guide users to reauthorize access.
    • Setup flow now clears any cached protected-route authentication before proceeding to ensure fresh checks.
  • Bug Fixes

    • Improved detection and messaging for GitHub credential/authorization failures so users receive appropriate reauthorization prompts.

Verify the app user token with GET /user/installations during setup checks.
Normalize installation-token mint failures and common OAuth errors so the
error screen can offer /setup. Clear the protected-route auth cache when
visiting setup or choosing Review GitHub access.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d2cd511d-7734-4784-aa27-f5a0f263c147

📥 Commits

Reviewing files that changed from the base of the PR and between ff9a8bd and 8a62da5.

📒 Files selected for processing (1)
  • apps/dashboard/src/lib/protected-auth-cache.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/src/lib/protected-auth-cache.ts

📝 Walkthrough

Walkthrough

Detects GitHub App credential/authorization failures and introduces reauthorization flow: new error-classification helpers, server-side checks that map such errors to a reauth signal, a protected-route auth cache API, and UI to prompt and initiate GitHub App reauthorization.

Changes

Cohort / File(s) Summary
GitHub auth error detection & handling
apps/dashboard/src/lib/github-auth-errors.ts, apps/dashboard/src/lib/github.server.ts, apps/dashboard/src/lib/github.functions.ts
Added helpers to extract/compact Octokit error messages and decide when reauthorization is required. Wrapped token minting and setup-check calls to classify errors and return false or rethrow based on shouldReauthorizeGitHubApp.
Protected route auth caching
apps/dashboard/src/lib/protected-auth-cache.ts, apps/dashboard/src/routes/_protected.tsx, apps/dashboard/src/routes/setup.tsx
Introduced a browser-guarded protected-route cache API and ProtectedRouteCachedAuth type. Replaced module-scoped route cache with the new API and clear the cache on /setup load.
Dashboard error UI
apps/dashboard/src/components/layouts/dashboard-error-screen.tsx
Extended error discriminant with reauthorize-github-app. Added detection to render a reauthorize button that clears the protected-route cache and navigates to /setup.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant UI as Dashboard Error Screen
    participant Setup as Setup Route
    participant Server as Server Functions
    participant GitHub as GitHub API

    Client->>Server: Request protected resource
    Server->>GitHub: GitHub App call (e.g., GET /user/installations)
    GitHub-->>Server: 401/403/422 or credential error
    Server->>Server: shouldReauthorizeGitHubApp(error)
    alt reauth required
        Server-->>Client: Response indicating reauth required
        Client->>UI: Render reauthorize-github-app action
        Client->>UI: Click "Reauthorize" button
        UI->>UI: clearProtectedRouteCachedAuth()
        UI->>Setup: Navigate to /setup
        Setup->>Server: checkSetupComplete()
        Server->>GitHub: Verify App user install (GET /user/installations)
        GitHub-->>Server: Success
        Server-->>Setup: Setup complete
    else not reauth
        Server-->>Client: Propagate original error
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the key changes and explains why they were made, but does not follow the provided template structure (missing Summary, Changes list, Test Plan, and Screenshots sections). Restructure the description to follow the template with clear Summary, Changes, and Test Plan sections for clarity and consistency.
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: detecting stale GitHub App authentication and redirecting users to /setup for reauthorization.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 stylessh/github-app-reauth-redirect-setup

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

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Apr 18, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
diffkit 8a62da5 Apr 18 2026, 03:18 PM

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/dashboard/src/components/layouts/dashboard-error-screen.tsx (1)

45-73: ⚠️ Potential issue | 🟠 Major

Reauth detection is narrower than canonical auth-error logic.

Line 45 only checks "bad credentials", docs URL, and 401. It misses 403/422 reauthorization signals handled by apps/dashboard/src/lib/github-auth-errors.ts (e.g., suspended/new-permissions/pending-permission cases), so these can be misclassified as "configure-access" at Line 60.

🔧 Suggested alignment patch
 if (
 	lower.includes("bad credentials") ||
 	lower.includes("docs.github.com/rest") ||
-	/\b401\b/.test(lower)
+	/\b401\b/.test(lower) ||
+	(
+		(lower.includes("403") || lower.includes("forbidden")) &&
+		!lower.includes("not accessible by integration") &&
+		(
+			lower.includes("suspended") ||
+			lower.includes("new permissions") ||
+			lower.includes("additional permissions") ||
+			lower.includes("must be granted") ||
+			(lower.includes("permission") && lower.includes("pending"))
+		)
+	) ||
+	(
+		/\b422\b/.test(lower) &&
+		lower.includes("installation") &&
+		(lower.includes("suspend") || lower.includes("permission"))
+	)
 ) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/dashboard/src/components/layouts/dashboard-error-screen.tsx` around
lines 45 - 73, The current reauth detection in dashboard-error-screen.tsx uses
ad-hoc checks (lower.includes("bad credentials"), docs URL, /\b401\b/) which
misses other canonical reauth signals (403/422,
suspended/new-permissions/pending-permission) handled in
apps/dashboard/src/lib/github-auth-errors.ts; replace the manual checks with the
shared helper from that module (import the exported function that detects reauth
cases—e.g., isReauthError or the classifier exported by github-auth-errors.ts)
and use it to decide between returning the LockIcon block with action
"reauthorize-github-app" and the existing "configure-access" block, so LockIcon/
title/ description/ action remain the same but detection is aligned with the
canonical logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/dashboard/src/lib/protected-auth-cache.ts`:
- Around line 21-35: The module-level cache (cachedAuth) is being read/written
during SSR and can leak across requests; wrap all reads and writes so they only
run in the browser by guarding with typeof window !== "undefined": make
getProtectedRouteCachedAuth() return null when window is undefined, make
setProtectedRouteCachedAuth(next) a no-op server-side, and make
clearProtectedRouteCachedAuth() a no-op server-side; keep the existing
cachedAuth variable and function names (cachedAuth, getProtectedRouteCachedAuth,
setProtectedRouteCachedAuth, clearProtectedRouteCachedAuth) so the fixes are
scoped to those symbols.

---

Outside diff comments:
In `@apps/dashboard/src/components/layouts/dashboard-error-screen.tsx`:
- Around line 45-73: The current reauth detection in dashboard-error-screen.tsx
uses ad-hoc checks (lower.includes("bad credentials"), docs URL, /\b401\b/)
which misses other canonical reauth signals (403/422,
suspended/new-permissions/pending-permission) handled in
apps/dashboard/src/lib/github-auth-errors.ts; replace the manual checks with the
shared helper from that module (import the exported function that detects reauth
cases—e.g., isReauthError or the classifier exported by github-auth-errors.ts)
and use it to decide between returning the LockIcon block with action
"reauthorize-github-app" and the existing "configure-access" block, so LockIcon/
title/ description/ action remain the same but detection is aligned with the
canonical logic.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 516c41c5-b81c-4553-a136-73ffd20a027c

📥 Commits

Reviewing files that changed from the base of the PR and between 8979d36 and d5b9cd9.

📒 Files selected for processing (7)
  • apps/dashboard/src/components/layouts/dashboard-error-screen.tsx
  • apps/dashboard/src/lib/github-auth-errors.ts
  • apps/dashboard/src/lib/github.functions.ts
  • apps/dashboard/src/lib/github.server.ts
  • apps/dashboard/src/lib/protected-auth-cache.ts
  • apps/dashboard/src/routes/_protected.tsx
  • apps/dashboard/src/routes/setup.tsx

Comment thread apps/dashboard/src/lib/protected-auth-cache.ts Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 18, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • apps/dashboard/src/lib/protected-auth-cache.ts

Commit: 8a62da538d32d097731920fe7d8b6a5bda4274d2

The changes have been pushed to the stylessh/github-app-reauth-redirect-setup branch.

Time taken: 4m 33s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@stylessh stylessh merged commit a938b10 into main Apr 18, 2026
6 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

Development

Successfully merging this pull request may close these issues.

1 participant