Skip to content

fix: make prompt=none redirect loop work for api requests#3638

Open
tefkah wants to merge 2 commits into
mainfrom
tfk/fix-reauth
Open

fix: make prompt=none redirect loop work for api requests#3638
tefkah wants to merge 2 commits into
mainfrom
tfk/fix-reauth

Conversation

@tefkah

@tefkah tefkah commented Jun 16, 2026

Copy link
Copy Markdown
Member

Issue(s) Resolved

The recently merged #3627 has a bug that somehow slipped through: while GET requests would automatically invisibly force a reauth loop to kfauth, any api request or POST request wouldnt (because you cant really force a renav in the same way).

This would cause actions such as creating a Pub to fail if your session of 15 minutes expired, and would only allow you to do it again after reloading the page or otherwise navigating.

This PR fixes that in two ways

    1. Turn on rolling sessions. I didnt want to do it initially but it makes sense. Basically if you are doing stuff within the 15 min window your session will get extended.
    1. Standard practice but stupid reauth loop for api requests. Basically, when we get a 401 Session expired from an api request (in apiFetch), we silently spawn a small iframe, do the reauth loop there, then make the request again. This forces the request to succeeed.

This has got me questioning the validatity of this approach, but I will go with it for now to not make the experience very bad.

Test Plan

Screenshots (if applicable)

Optional

Notes/Context/Gotchas

Supporting Docs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes the regression from #3627 where prompt=none silent re-auth worked for browser navigations but not for API/POST requests, leading to failures after the short session expired.

Changes:

  • Enable rolling sessions so activity extends the session cookie expiry.
  • Update silentReauthMiddleware to return 401 { error: 'sessionExpired' } for /api/* (instead of only handling page GET navigations via 302).
  • Add a client-side hidden-iframe renewal flow (apiFetchRaw) that renews on 401 sessionExpired and retries once; wire this into Altcha’s challenge fetch.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
server/server.ts Enables rolling sessions to extend expiry on activity.
server/middleware/silentReauth.ts Returns a structured 401 for API calls so the client can renew/retry.
server/kf/api.ts Adds /auth/renew-done endpoint to signal iframe renewal completion to the parent window.
client/utils/apiFetch.ts Adds apiFetchRaw + hidden-iframe renewal + retry-once behavior.
client/components/Altcha/Altcha.tsx Routes Altcha widget fetches through apiFetchRaw to survive session expiry.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +28 to +31
// ── API requests: tell the frontend to renew ──
if (req.path.startsWith('/api')) {
return res.status(401).json({ error: 'sessionExpired' });
}
Comment thread client/utils/apiFetch.ts
Comment on lines +69 to +77
function rawFetch(path: string, opts?: RequestInit): Promise<Response> {
return fetch(path, {
...opts,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
credentials: 'include',
}).then((response) => {
if (!response.ok) {
return response.json().then((err) => {
if (response.status === 423 && err?.error === 'readOnly') {
window.dispatchEvent(new CustomEvent('pubpub:readOnly'));
}
throw err;
});
Comment on lines +51 to +52
// needs to be done like this, doesnt work when just passing it to altcha-widget
(w as unknown as { customfetch?: typeof apiFetchRaw }).customfetch = apiFetchRaw;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants