mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-10-13 18:22:49 +03:00
Return to the requested URL after logging in (#24637)
When an unauthenticated user opens a deep link, carry the requested path through the login page in a redirect query param and return to it after a successful login instead of always going to the home page. Only same-origin targets are honored. Claude-Session: https://claude.ai/code/session_011CFGjgYURSRTpXBaxp1Dq7 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
135a95d8f2
commit
e7164882f5
@@ -6,9 +6,9 @@
|
||||
* viewer nav restrictions; all-routes smoke.
|
||||
*/
|
||||
|
||||
import { test, expect } from "../fixtures/frigate-test";
|
||||
import { test, expect, type FrigateApp } from "../fixtures/frigate-test";
|
||||
import { systemTab } from "../helpers/system-tabs";
|
||||
import { viewerProfile } from "../fixtures/mock-data/profile";
|
||||
import { adminProfile, viewerProfile } from "../fixtures/mock-data/profile";
|
||||
|
||||
test.describe("Auth — admin access @high", () => {
|
||||
test("admin /system renders general tab", async ({ frigateApp }) => {
|
||||
@@ -109,3 +109,71 @@ test.describe("Auth — all routes smoke @high @mobile", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Auth: login redirect @high", () => {
|
||||
// 401 on /profile is how the app learns that a login is required
|
||||
test.use({ expectedErrors: [/401/] });
|
||||
|
||||
async function requireLogin(frigateApp: FrigateApp) {
|
||||
let loggedIn = false;
|
||||
await frigateApp.page.route("**/api/profile", (route) =>
|
||||
loggedIn
|
||||
? route.fulfill({ json: adminProfile() })
|
||||
: route.fulfill({ status: 401, body: "" }),
|
||||
);
|
||||
await frigateApp.page.route("**/api/login", (route) => {
|
||||
loggedIn = true;
|
||||
return route.fulfill({ json: {} });
|
||||
});
|
||||
await frigateApp.page.route("**/api/auth/first_time_login", (route) =>
|
||||
route.fulfill({ json: { admin_first_time_login: false } }),
|
||||
);
|
||||
}
|
||||
|
||||
async function logIn(frigateApp: FrigateApp) {
|
||||
await frigateApp.page.getByLabel("Username").fill("admin");
|
||||
await frigateApp.page.getByLabel("Password").fill("password");
|
||||
await frigateApp.page.getByRole("button", { name: "Login" }).click();
|
||||
}
|
||||
|
||||
test("returns to the requested url after logging in", async ({
|
||||
frigateApp,
|
||||
}) => {
|
||||
await requireLogin(frigateApp);
|
||||
await frigateApp.page.goto("/explore?labels=person");
|
||||
await expect(frigateApp.page).toHaveURL(
|
||||
`/login?redirect=${encodeURIComponent("/explore?labels=person")}`,
|
||||
);
|
||||
|
||||
await logIn(frigateApp);
|
||||
await expect(frigateApp.page).toHaveURL("/explore?labels=person");
|
||||
await expect(frigateApp.page.locator("#pageRoot")).toBeVisible({
|
||||
timeout: 10_000,
|
||||
});
|
||||
});
|
||||
|
||||
test("goes home after logging in from the home page", async ({
|
||||
frigateApp,
|
||||
}) => {
|
||||
await requireLogin(frigateApp);
|
||||
await frigateApp.page.goto("/");
|
||||
await expect(frigateApp.page).toHaveURL("/login");
|
||||
|
||||
await logIn(frigateApp);
|
||||
await expect(frigateApp.page).toHaveURL("/");
|
||||
});
|
||||
|
||||
for (const target of ["https://example.com/", "//example.com/"]) {
|
||||
test(`ignores a redirect to another site (${target})`, async ({
|
||||
frigateApp,
|
||||
}) => {
|
||||
await requireLogin(frigateApp);
|
||||
await frigateApp.page.goto(
|
||||
`/login?redirect=${encodeURIComponent(target)}`,
|
||||
);
|
||||
|
||||
await logIn(frigateApp);
|
||||
await expect(frigateApp.page).toHaveURL("/");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user