Summary
A user reports seeing a blank page after completing the OAuth login flow on lbc-2026.interactiveliterature.org. The symptom: clicking "Sign In" redirects to neilhosting.net, which redirects back to /oauth/callback, but the page never shows content — just hangs blank or briefly shows a spinner and then goes blank.
Nat confirmed this could not be reproduced locally (Firefox and Chrome both worked for him), but the user sees it in both Chrome and Edge.
Evidence
HAR file and JS console screenshot were captured during a failing login attempt.
Console errors
POST /oauth_session/refresh 401 — twice, from authenticationManager.performRefresh
No HydrateFallback element provided to render during initial hydration — React Router warning
Cookie-backed refresh failed; clearing in-memory access token Error: /oauth_session/refresh failed: HTTP 401
HAR analysis
- No
/oauth_session/exchange call in the captured requests (87 entries total)
- Two 401s from
/oauth_session/refresh, both with empty request cookies
- One successful
200 POST /graphql with currentUser: null
- The exchange call would be entry 88+ — it likely happens after the HAR was saved, just before
window.location.href navigates away
Root cause: CloudFront stripping the __Host-intercode_refresh cookie
This was diagnosed and fixed in commit 7b56892 (June 2):
The __Host-intercode_refresh HttpOnly cookie set by /oauth_session/exchange was never reaching the Rails server on subsequent /oauth_session/refresh calls because the CloudFront origin request policy for all dynamic routes uses cookie_behavior = "none", which strips every browser cookie before forwarding to the origin.
The fix adds a new forward_host_with_refresh_cookie CloudFront origin request policy and a dedicated ordered_cache_behavior for /oauth_session/* that whitelists the refresh cookie.
Diagnostic logging added in the same commit was removed in f2fc192 after confirming refresh_token_present=true in production — so the server side is generating the cookie correctly. The Terraform infrastructure fix is the only change needed.
What happens to the user
- Login flow runs,
/oauth_session/exchange succeeds, cookie is set in the browser
window.location.href navigates to returnPath (usually /)
- New page load:
bootstrapFromCookie() calls POST /oauth_session/refresh
- CloudFront strips the
__Host-intercode_refresh cookie before forwarding to Rails
- Rails sees no cookie → 401 → user is not authenticated
- Convention home page renders without authentication (or if there's a redirect loop back to sign-in, the user lands back at
/oauth/callback with a new OAuth code)
The blank page
The page going blank is the brief transition between navigating away from /oauth/callback (after exchange) and the new page loading. The inline CSS spinner added in aebc7fa (June 3) is what the user sees "very briefly" before going blank.
The "No HydrateFallback" warning is expected: RouterProvider renders null during initialization and RouterLoadingOverlay (also from aebc7fa) bridges this gap as a sibling component, but doesn't suppress React Router's internal console warning.
Action required
- Apply the Terraform changes from 7b56892 — run
terraform apply for the CloudFront module so the new ordered_cache_behavior for /oauth_session/* with cookie whitelisting goes live
- Verify the fix by checking that a login flow results in
bootstrapFromCookie returning a valid token (no 401 from /oauth_session/refresh after the exchange)
Secondary: OAuthCallback fallback when login flow data is missing
If a user navigates directly to /oauth/callback?code=... (e.g., from a bookmark, or after sessionStorage is cleared), currentLoginFlowData is null and handleOauthCallback throws "No current login flow found". The error UI renders — but if the user clicks Sign In again from that error page and the new OAuth flow completes, they may end up in a slightly confusing state.
Consider: when currentLoginFlowData is null in handleOauthCallback, automatically call initiateAuthentication to restart the flow instead of (or in addition to) showing the error.
Files involved
terraform/modules/cloudfront_intercode/main.tf — Terraform fix (committed, needs deploy)
app/javascript/Authentication/authenticationManager.ts — handleOauthCallback, bootstrapFromCookie, performRefresh
app/javascript/Authentication/OAuthCallback.tsx — renders during callback, calls handleOauthCallback
app/controllers/oauth_sessions_controller.rb — Rails endpoints for exchange/refresh/sign-out
Summary
A user reports seeing a blank page after completing the OAuth login flow on lbc-2026.interactiveliterature.org. The symptom: clicking "Sign In" redirects to neilhosting.net, which redirects back to
/oauth/callback, but the page never shows content — just hangs blank or briefly shows a spinner and then goes blank.Nat confirmed this could not be reproduced locally (Firefox and Chrome both worked for him), but the user sees it in both Chrome and Edge.
Evidence
HAR file and JS console screenshot were captured during a failing login attempt.
Console errors
POST /oauth_session/refresh 401— twice, fromauthenticationManager.performRefreshNo HydrateFallback element provided to render during initial hydration— React Router warningCookie-backed refresh failed; clearing in-memory access token Error: /oauth_session/refresh failed: HTTP 401HAR analysis
/oauth_session/exchangecall in the captured requests (87 entries total)/oauth_session/refresh, both with empty request cookies200 POST /graphqlwithcurrentUser: nullwindow.location.hrefnavigates awayRoot cause: CloudFront stripping the
__Host-intercode_refreshcookieThis was diagnosed and fixed in commit 7b56892 (June 2):
The fix adds a new
forward_host_with_refresh_cookieCloudFront origin request policy and a dedicatedordered_cache_behaviorfor/oauth_session/*that whitelists the refresh cookie.Diagnostic logging added in the same commit was removed in f2fc192 after confirming
refresh_token_present=truein production — so the server side is generating the cookie correctly. The Terraform infrastructure fix is the only change needed.What happens to the user
/oauth_session/exchangesucceeds, cookie is set in the browserwindow.location.hrefnavigates toreturnPath(usually/)bootstrapFromCookie()callsPOST /oauth_session/refresh__Host-intercode_refreshcookie before forwarding to Rails/oauth/callbackwith a new OAuth code)The blank page
The page going blank is the brief transition between navigating away from
/oauth/callback(after exchange) and the new page loading. The inline CSS spinner added in aebc7fa (June 3) is what the user sees "very briefly" before going blank.The "No HydrateFallback" warning is expected:
RouterProviderrenders null during initialization andRouterLoadingOverlay(also from aebc7fa) bridges this gap as a sibling component, but doesn't suppress React Router's internal console warning.Action required
terraform applyfor the CloudFront module so the newordered_cache_behaviorfor/oauth_session/*with cookie whitelisting goes livebootstrapFromCookiereturning a valid token (no 401 from/oauth_session/refreshafter the exchange)Secondary: OAuthCallback fallback when login flow data is missing
If a user navigates directly to
/oauth/callback?code=...(e.g., from a bookmark, or after sessionStorage is cleared),currentLoginFlowDatais null andhandleOauthCallbackthrows "No current login flow found". The error UI renders — but if the user clicks Sign In again from that error page and the new OAuth flow completes, they may end up in a slightly confusing state.Consider: when
currentLoginFlowDatais null inhandleOauthCallback, automatically callinitiateAuthenticationto restart the flow instead of (or in addition to) showing the error.Files involved
terraform/modules/cloudfront_intercode/main.tf— Terraform fix (committed, needs deploy)app/javascript/Authentication/authenticationManager.ts—handleOauthCallback,bootstrapFromCookie,performRefreshapp/javascript/Authentication/OAuthCallback.tsx— renders during callback, callshandleOauthCallbackapp/controllers/oauth_sessions_controller.rb— Rails endpoints for exchange/refresh/sign-out