Skip to content

fix(security): plain 401 for programmatic requests — no browser login dialog over background polls#6128

Merged
delchev merged 1 commit into
masterfrom
fix/no-basic-challenge-for-api-calls
Jul 3, 2026
Merged

fix(security): plain 401 for programmatic requests — no browser login dialog over background polls#6128
delchev merged 1 commit into
masterfrom
fix/no-basic-challenge-for-api-calls

Conversation

@delchev

@delchev delchev commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Problem

An expired session answers every request with 401 + WWW-Authenticate: Basic, so the browser pops its native login dialog before any script sees the response. The generated Harmonia apps poll /services/inbox/tasks every 30 s, so an idle tab surfaces the dialog "out of nowhere" once the 8-hour session lapses (or the server restarts).

Fix

BasicSecurityConfig registers an additional authentication entry point for programmatic requests — Sec-Fetch-Mode present and ≠ navigate (every modern browser stamps fetch/XHR), with X-Requested-With: XMLHttpRequest as the legacy fallback — returning a plain 401 without the Basic challenge. Browser navigations keep the normal Basic/form login flow.

The shared fetch client (application-core api.js) now sends X-Requested-With, and its error catalog already maps 401 to "Your session has ended. Please sign in again." — which the shell now actually gets to display instead of the dialog.

Verified live

request result
Sec-Fetch-Mode: cors, no session 401, no WWW-Authenticate
X-Requested-With: XMLHttpRequest, no session 401, no WWW-Authenticate
Sec-Fetch-Mode: navigate, no session 401 + Basic challenge (login flow intact)
plain curl, no session 401 + Basic challenge
authenticated call 200

🤖 Generated with Claude Code

… dialog over background polls

An expired session answered EVERY request with 401 + WWW-Authenticate:
Basic, so the BROWSER popped its native login dialog before any script saw
the response. The generated Harmonia apps poll the inbox every 30 seconds,
so an idle tab surfaced the dialog "out of nowhere" once the 8h session
lapsed (or the server restarted).

BasicSecurityConfig now registers an additional authentication entry point
for programmatic requests - Sec-Fetch-Mode present and != navigate (every
modern browser stamps fetch/XHR), with X-Requested-With: XMLHttpRequest as
the legacy fallback - returning a plain 401 without the Basic challenge.
Browser navigations keep the normal Basic/form login flow.

The shared fetch client (application-core api.js) now sends
X-Requested-With so the fallback also matches, and its error catalog
already maps 401 to "Your session has ended. Please sign in again." -
which the shell now actually gets to display.

Verified live: 401 without WWW-Authenticate for Sec-Fetch-Mode:cors and
X-Requested-With requests; challenge kept for navigations and plain curl;
authenticated calls unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@delchev delchev force-pushed the fix/no-basic-challenge-for-api-calls branch from 8112eb4 to b8eb155 Compare July 3, 2026 06:54
@delchev delchev merged commit 71745b3 into master Jul 3, 2026
10 of 11 checks passed
@delchev delchev deleted the fix/no-basic-challenge-for-api-calls branch July 3, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant