Files
homelab-monitor/e2e/tests/oidc-login.spec.ts
T
jhodgkin 294be26500
CI / web (push) Successful in 17s
CI / api (push) Successful in 24s
fix: OIDC callback sent wrong scheme in token exchange redirect_uri
Fastify only sees plain HTTP -- TLS terminates at NPM/Cloudflare
before reaching this process. Building the callback's currentUrl from
req.headers.host with a hardcoded "http://" sent
redirect_uri=http://monitor.jerodrigged.com/... during the token
exchange, which Authentik rejects (logged as generic "invalid_client"
to the client, but its own event log said plainly: "Invalid redirect
URI used by provider"). Fixed by reusing the known-correct
redirectUri's origin and only taking the query string from the actual
request, instead of trying to infer scheme from headers.

Also fixes the Playwright OIDC test's selectors (Authentik's password
field has no <label> association -- placeholder text, not getByLabel).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-12 22:27:39 -06:00

36 lines
1.6 KiB
TypeScript

import { test, expect } from "@playwright/test";
const USERNAME = process.env.OIDC_USERNAME ?? "playwright-test";
const PASSWORD = process.env.OIDC_PASSWORD ?? "";
test("OIDC login via Authentik stays on public domains throughout", async ({ page }) => {
test.skip(!PASSWORD, "OIDC_PASSWORD not set");
await page.goto("/");
const oidcButton = page.getByRole("link", { name: "Sign in with Authentik" });
await expect(oidcButton).toBeVisible();
await oidcButton.click();
// Regression check for the actual bug reported: the authorization endpoint
// must be the public auth.jerodrigged.com, never a LAN IP a browser off the
// LAN can't reach.
await page.waitForURL(/^https:\/\/auth\.jerodrigged\.com\//, { timeout: 10_000 });
expect(page.url()).not.toMatch(/192\.168\./);
await page.getByPlaceholder(/email or username/i).fill(USERNAME);
await page.getByRole("button", { name: /log in|continue|next/i }).click();
// Authentik's password field has no <label> association -- it's identified
// by placeholder text ("Please enter your password"), not an a11y label.
await page.getByPlaceholder(/password/i).fill(PASSWORD);
await page.getByRole("button", { name: /log in|continue|sign in/i }).click();
await page.waitForURL(/^https:\/\/monitor\.jerodrigged\.com\//, { timeout: 15_000 });
expect(page.url()).not.toMatch(/192\.168\./);
await expect(page.locator(".host-card").first()).toBeVisible({ timeout: 15_000 });
await page.getByRole("button", { name: "Sign out" }).click();
await expect(page.getByPlaceholder("Username")).toBeVisible();
});