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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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-LopezJose-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

coderabbitaiBot 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 nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring 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 nameStatusExplanation
Title check✅ PassedThe 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✅ PassedThe 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-pagesBot 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

@coderabbitaicoderabbitaiBot 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 threadfrontend/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 mainApr 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 freeto 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

@Jose-Gael-Cruz-Lopez