Skip to content

Commit ab2231a

Browse files
committed
fix(ui): prevent logout redirect loop
1 parent b67cf5b commit ab2231a

5 files changed

Lines changed: 36 additions & 28 deletions

File tree

.github/assets/fitz-logo.png

1.22 MB
Loading

ui/src/adapters/client.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ const requestHeaders: Middleware = (context, next) => {
2525

2626
const redirectUnauthenticated: Middleware = async (context, next) => {
2727
const result = await next(context);
28+
const requestPath = new URL(context.request.url).pathname;
2829

2930
if (
3031
result.status === 401 &&
32+
requestPath !== "/api/v1/session" &&
3133
typeof window !== "undefined" &&
3234
!window.location.pathname.startsWith("/login")
3335
) {

ui/tests/e2e/login.spec.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
import { expect, test } from "@playwright/test";
2-
import { mockAdminFeatures } from "./shell/api-fixtures";
3-
4-
async function mockCredentialLogin(page: import("@playwright/test").Page) {
5-
await page.route("**/api/v1/features", async (route) => {
6-
await route.fulfill({
7-
json: {
8-
admin_auth_required: true,
9-
admin_auth_mode: "password",
10-
route_families: ["1"],
11-
route_families_wildcard: false,
12-
},
13-
});
14-
});
15-
16-
await page.route("**/api/v1/session", async (route) => {
17-
await route.fulfill({ status: 401, json: { error: "unauthenticated" } });
18-
});
19-
}
2+
import { mockAdminFeatures, mockCredentialLogin, mockPendingLogout } from "./shell/api-fixtures";
203

214
test("should_center_the_credential_form_in_the_full_viewport", async ({ page }) => {
225
// Arrange
@@ -93,14 +76,7 @@ test("renders truthful open-access state when authentication is disabled", async
9376

9477
test("should_show_logout_progress_while_the_session_is_cleared", async ({ page }) => {
9578
// Arrange
96-
await mockCredentialLogin(page);
97-
await page.route("**/api/v1/session", async (route) => {
98-
if (route.request().method() === "DELETE") {
99-
await new Promise<void>(() => {});
100-
return;
101-
}
102-
await route.fallback();
103-
});
79+
await mockPendingLogout(page);
10480
await page.goto("/logout");
10581
await expect(page.getByRole("heading", { level: 1, name: "Signing out" })).toBeVisible();
10682
const viewport = page.viewportSize();

ui/tests/e2e/shell/api-fixtures.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,35 @@ export async function mockAdminFeatures(page: Page) {
4545
});
4646
}
4747

48+
export async function mockCredentialLogin(page: Page) {
49+
await page.route("**/api/v1/features", async (route) => {
50+
await route.fulfill({
51+
json: {
52+
admin_auth_required: true,
53+
admin_auth_mode: "password",
54+
route_families: ["1"],
55+
route_families_wildcard: false,
56+
},
57+
});
58+
});
59+
60+
await page.route("**/api/v1/session", async (route) => {
61+
await route.fulfill({ status: 401, json: { error: "unauthenticated" } });
62+
});
63+
}
64+
65+
export async function mockPendingLogout(page: Page) {
66+
await mockCredentialLogin(page);
67+
await page.route("**/api/v1/session", async (route) => {
68+
if (route.request().method() === "DELETE") {
69+
await new Promise<void>(() => {});
70+
return;
71+
}
72+
73+
await route.fallback();
74+
});
75+
}
76+
4877
export const topologyApiPayload: MessagingTopology = {
4978
broker: {
5079
connections: topologyOverview.broker.connections,

ui/tests/e2e/shell/chrome.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
mockDomainOverviewApis,
55
mockHomeRouteApis,
66
mockMetricsApi,
7+
mockPendingLogout,
78
mockSessionsApi,
89
sessionsWithData,
910
} from "./api-fixtures";
@@ -520,8 +521,8 @@ export const sprint16Routes: RouteScenario[] = [
520521
{
521522
path: "/logout",
522523
shell: "auth",
523-
setup: (page) => mockHomeRouteApis(page),
524-
title: "Sign out",
524+
setup: (page) => mockPendingLogout(page),
525+
title: "Signing out",
525526
},
526527
{
527528
path: "/admin/1/rpc/default/ops/primary/GetStatus",

0 commit comments

Comments
 (0)