mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-15 14:19:13 +02:00
fix(workspace): break NoAccessPage redirect loop by clearing stale cookie
The web proxy redirects / to /<lastSlug>/issues based on the last_workspace_slug cookie alone, with no access check. When a user gets evicted from a workspace, the cookie still points at it; clicking "Go to my workspaces" then loops: NoAccessPage -> / -> proxy -> same bad slug -> NoAccessPage. Clear the cookie on mount so the proxy falls through to the landing page, which resolves the correct destination via the workspace list. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,16 @@ describe("NoAccessPage", () => {
|
||||
expect(navigate).toHaveBeenCalledWith("/");
|
||||
});
|
||||
|
||||
it("clears last_workspace_slug cookie on mount so the proxy stops looping us back", () => {
|
||||
document.cookie = "last_workspace_slug=stale; path=/";
|
||||
render(<NoAccessPage />);
|
||||
// Assert empty value, not just absence of "stale" — the proxy reads any
|
||||
// truthy value as a redirect target, so a buggy clear that left e.g.
|
||||
// `last_workspace_slug=other` would still trap users.
|
||||
const value = document.cookie.match(/last_workspace_slug=([^;]*)/)?.[1];
|
||||
expect(value ?? "").toBe("");
|
||||
});
|
||||
|
||||
it("fully logs out on 'Sign in as a different user' instead of just navigating", () => {
|
||||
render(<NoAccessPage />);
|
||||
fireEvent.click(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { Button } from "@multica/ui/components/ui/button";
|
||||
import { paths } from "@multica/core/paths";
|
||||
import { useNavigation } from "../navigation";
|
||||
@@ -15,6 +16,19 @@ import { DragStrip } from "../platform";
|
||||
export function NoAccessPage() {
|
||||
const nav = useNavigation();
|
||||
const logout = useLogout();
|
||||
|
||||
// Clear stale `last_workspace_slug` cookie. The web proxy redirects `/` to
|
||||
// `/<lastSlug>/issues` based on this cookie alone (no access check). When
|
||||
// the cookie points at a workspace the user has just lost access to, the
|
||||
// user gets trapped in a loop: NoAccessPage → click "Go to my workspaces"
|
||||
// → `/` → proxy redirects back to the same bad slug → NoAccessPage.
|
||||
// Clearing the cookie here lets the proxy fall through to the landing page,
|
||||
// which then resolves the correct destination via the workspace list.
|
||||
// No-op outside the browser (desktop renderer also has document, harmless).
|
||||
useEffect(() => {
|
||||
if (typeof document === "undefined") return;
|
||||
document.cookie = "last_workspace_slug=; path=/; max-age=0; SameSite=Lax";
|
||||
}, []);
|
||||
return (
|
||||
<div className="flex min-h-svh flex-col">
|
||||
<DragStrip />
|
||||
|
||||
Reference in New Issue
Block a user