Sign out through the proxy when the proxy signed you in

Sign out cleared ipx's cookies and showed its password page, while
Cloudflare Access still vouched for the person: nothing was signed out,
and the page looked like the wrong login. /api/me now says, for someone
the proxy signed in, where to go instead ([web] sign_out_url, which is
/cdn-cgi/access/logout behind Access), and /login sends anyone the proxy
vouches for on to their feeds. The header check both use is one function.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TAC7sLVqfKmY6rsTLXzNgk
This commit is contained in:
2026-09-12 14:10:30 +00:00
parent 9a8a3c696f
commit b94a74ef15
9 changed files with 100 additions and 22 deletions

View File

@@ -793,3 +793,20 @@ test('play in the Files pane plays once, in the player bar', async ({ page }) =>
await expect(page.locator('audio')).toHaveCount(1); // the player bar's, and nothing else
await page.locator('#pclose').click();
});
test('someone the proxy signs in never sees the password page, and signs out through the proxy', async ({ page, browser }) => {
// Signed in with the token, not by the proxy: Sign out stays ipx's own.
expect((await (await page.request.get('/api/me')).json()).sign_out).toBeNull();
const ctx = await browser.newContext({ extraHTTPHeaders: { 'X-Test-User': 'proxied@example.com' } });
const proxied = await ctx.newPage();
// Regression: after Sign out, the password form showed to someone the proxy still vouched for.
await proxied.goto('/login');
await expect(proxied).toHaveURL(/:8791\/$/);
await expect(proxied.locator('#who')).toContainText('proxied@example.com');
expect(await (await proxied.request.get('/api/me')).json())
.toMatchObject({ name: 'proxied@example.com', sign_out: '/signed-out-by-the-proxy' });
await proxied.locator('#signout').click();
await expect(proxied).toHaveURL(/\/signed-out-by-the-proxy$/);
await ctx.close();
});

View File

@@ -37,6 +37,10 @@ enabled = false
enabled = true
bind = "127.0.0.1:8791"
token = "${TOKEN}"
# The proxy path, for tests that send the header themselves: the daemon sees them at 127.0.0.1.
trusted_header = "X-Test-User"
trusted_proxies = ["127.0.0.1"]
sign_out_url = "/signed-out-by-the-proxy"
[feeds.test-show]
url = "http://127.0.0.1:8792/show.xml"