Skip to content

fix(auth): Remove redundant black sign-in page, redirect to Google#58

Merged
Jose-Gael-Cruz-Lopez merged 2 commits into
mainfrom
fix/signin-skip-black-page-google-redirect
Apr 15, 2026
Merged

fix(auth): Remove redundant black sign-in page, redirect to Google#58
Jose-Gael-Cruz-Lopez merged 2 commits into
mainfrom
fix/signin-skip-black-page-google-redirect

Conversation

@Jose-Gael-Cruz-Lopez

@Jose-Gael-Cruz-Lopez Jose-Gael-Cruz-Lopez commented Apr 15, 2026

Copy link
Copy Markdown
Member

Problem

Users saw an extra black "Welcome back" / Continue with Google screen after or instead of a smooth login, and session checks could hit the wrong path.

Changes

  • Middleware: Unauthenticated visits to /signin or protected routes redirect straight to {API}/api/auth/google (Google OAuth) instead of rendering the old sign-in page.
  • /signin route: Only used when OAuth fails or config is wrong; shows a light error screen with "Try again with Google" (no black full-screen card for the normal path).
  • Session / middleware: Use /api/auth/me consistently (matches FastAPI prefix="/api/auth").
  • Edge case: If NEXT_PUBLIC_API_URL is missing, redirect to /signin?error=google_not_configured to avoid a redirect loop.

Testing

  • npm run build and npm test pass locally.

Notes

Signed-in users hitting /signin are still redirected to dashboard or pending (unchanged behavior).

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Automatic session detection that redirects signed-in users to dashboard or pending approval.
    • Improved sign-in flow with Google redirect handling and safer cancellation logic during background checks.
    • More robust, generalized error messaging on the sign-in page.
  • Bug Fixes

    • Fixed backend session verification endpoint path used for live approval checks.
  • Style

    • Updated sign-in page visuals: backgrounds, spacing, card sizing, and shadow.

- Middleware sends unauthenticated users to /api/auth/google instead of /signin
- /signin only for OAuth errors; light UI, no black Welcome back screen
- Fix auth checks to use /api/auth/me (matches FastAPI router)
- Avoid redirect loop when API URL missing (signin?error=google_not_configured)

Made-with: Cursor
@coderabbitai

coderabbitai Bot commented Apr 15, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 288208fa-8160-4705-a694-70b682f75356

📥 Commits

Reviewing files that changed from the base of the PR and between 6056151 and dcef2f2.

📒 Files selected for processing (1)
  • frontend/src/app/signin/page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/app/signin/page.tsx

📝 Walkthrough

Walkthrough

The PR standardizes the live-approval endpoint from /auth/me to /api/auth/me and adds client + middleware redirect logic to route authenticated users to /dashboard or /pending based on approval status; it also updates the sign-in UI, error handling, and adds Google OAuth redirect helpers.

Changes

Cohort / File(s) Summary
API Endpoint Update
frontend/src/app/api/auth/session/route.ts, frontend/src/middleware.ts, frontend/src/app/signin/page.tsx
Changed live-approval fetch path from ${API_URL}/auth/me to ${API_URL}/api/auth/me used during session verification and redirects.
Sign-In Page Logic & UI
frontend/src/app/signin/page.tsx
Added auto-redirect on mount (reads localStorage.sapling_user, POSTs to /api/auth/session, redirects to /dashboard or /pending), generalized ERROR_COPY handling, updated rendering and styling, and added cancellation guard on unmount.
Middleware Authentication & Routing
frontend/src/middleware.ts
Added googleAuthRedirect and redirectToGoogleOrSignin, implemented redirectIfSignedIn for /signin, refactored protected-route failure handling to use unified redirect logic, extended config.matcher to include /signin, and updated live-approval fetch path to /api/auth/me.

Sequence Diagram

sequenceDiagram
    participant User
    participant Middleware
    participant SignInPage as Sign-In Page
    participant Backend as Backend API

    User->>Middleware: Request /signin
    activate Middleware
    Middleware->>Middleware: Check `sapling_session` cookie
    alt cookie exists
        Middleware->>Backend: GET ${API_URL}/api/auth/me (with timeout)
        activate Backend
        Backend-->>Middleware: { ok / 403 / error }
        deactivate Backend
        alt ok (approved)
            Middleware-->>User: Redirect to /dashboard
        else 403 (pending)
            Middleware-->>User: Redirect to /pending
        else error/timeout
            Middleware-->>User: Redirect to Google or /signin?error=google_not_configured
        end
    else no cookie
        Middleware-->>User: NextResponse.next() (allow /signin)
    end
    deactivate Middleware

    User->>SignInPage: Mounts /signin
    activate SignInPage
    SignInPage->>SignInPage: Read `localStorage.sapling_user`
    alt user id found
        SignInPage->>Backend: POST /api/auth/session (with user_id)
        activate Backend
        Backend-->>SignInPage: { ok / 403 / error }
        deactivate Backend
        alt ok (approved)
            SignInPage-->>User: Redirect to /dashboard
        else 403 (pending)
            SignInPage-->>User: Redirect to /pending
        else error
            SignInPage-->>User: Show error UI with "Try again with Google"
        end
    else no user data
        SignInPage-->>User: Show fallback message / sign-in prompt
    end
    deactivate SignInPage
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐇 I hopped through routes and checks so spry,

Sessions now whisper where users should fly,
Middleware nudges, the backend replies,
Dashboards or pending—no more surprise,
A rabbit’s cheer for redirects gone right ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: removing a redundant black sign-in page and implementing direct Google OAuth redirects in the auth flow.
Description check ✅ Passed The description covers the problem statement, changes made, testing performed, and notes for reviewers, though it does not follow the exact template structure with all prescribed section headings.

✏️ 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 fix/signin-skip-black-page-google-redirect

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

@cloudflare-workers-and-pages

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

Copy link
Copy Markdown

Deploying web with  Cloudflare Pages  Cloudflare Pages

Latest commit: dcef2f2
Status: ✅  Deploy successful!
Preview URL: https://7a6f124a.web-75h.pages.dev
Branch Preview URL: https://fix-signin-skip-black-page-g.web-75h.pages.dev

View logs

@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: 1

🧹 Nitpick comments (1)
frontend/src/middleware.ts (1)

25-50: Consider extracting common fetch-with-timeout logic.

The approval-check fetch pattern (3-second abort timeout, /api/auth/me call, is_approved parsing) appears twice. A shared helper could reduce duplication, though the slightly different return behaviors make this optional.

Also applies to: 82-103

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/middleware.ts` around lines 25 - 50, Extract the duplicated
"approval-check" fetch into a shared helper (e.g., fetchUserApproval or
fetchWithTimeout) and use it from redirectIfSignedIn and the other middleware
function that performs the same `/api/auth/me` check; the helper should accept
userId (and optional timeout), create an AbortController with a 3000ms timeout,
call `${API_URL}/api/auth/me?user_id=${encodeURIComponent(userId)}`, clear the
timeout in a finally, return the parsed JSON (or null/throw on non-ok/failure)
so callers can decide redirect behavior, and preserve existing error-swallowing
behavior in redirectIfSignedIn by returning null on helper failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@frontend/src/app/signin/page.tsx`:
- Around line 27-43: The fetch call in the signin page uses fetch(...).then(...)
without handling rejections, causing unhandled promise rejections on network
errors; update the logic in frontend/src/app/signin/page.tsx (the fetch block
that references cancelled and router.replace) to handle fetch failures by either
appending a .catch(...) to the promise chain that checks cancelled and
handles/logs the error and routes appropriately, or convert the call to
async/await inside the surrounding try/catch so network errors are caught and
handled before using router.replace('/dashboard') or router.replace('/pending').

---

Nitpick comments:
In `@frontend/src/middleware.ts`:
- Around line 25-50: Extract the duplicated "approval-check" fetch into a shared
helper (e.g., fetchUserApproval or fetchWithTimeout) and use it from
redirectIfSignedIn and the other middleware function that performs the same
`/api/auth/me` check; the helper should accept userId (and optional timeout),
create an AbortController with a 3000ms timeout, call
`${API_URL}/api/auth/me?user_id=${encodeURIComponent(userId)}`, clear the
timeout in a finally, return the parsed JSON (or null/throw on non-ok/failure)
so callers can decide redirect behavior, and preserve existing error-swallowing
behavior in redirectIfSignedIn by returning null on helper failure.
🪄 Autofix (Beta)

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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f50d0ac0-c75b-4c30-8b29-dbfb1e73eb3f

📥 Commits

Reviewing files that changed from the base of the PR and between 50721f8 and 6056151.

📒 Files selected for processing (3)
  • frontend/src/app/api/auth/session/route.ts
  • frontend/src/app/signin/page.tsx
  • frontend/src/middleware.ts

Comment thread frontend/src/app/signin/page.tsx
Add .catch() to the fetch chain so network errors don't produce
unhandled promise rejections. Clarify the existing catch comment
to distinguish parse errors from fetch errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Jose-Gael-Cruz-Lopez Jose-Gael-Cruz-Lopez merged commit f28c611 into main Apr 15, 2026
4 of 5 checks passed
@AndresL230 AndresL230 deleted the fix/signin-skip-black-page-google-redirect branch April 19, 2026 00:06
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