Skip to content

fix(ui): scope last workspace cookie by user#2793

Open
daryllimyt wants to merge 1 commit into
mainfrom
codex/find-issue-with-last-workspace-storage
Open

fix(ui): scope last workspace cookie by user#2793
daryllimyt wants to merge 1 commit into
mainfrom
codex/find-issue-with-last-workspace-storage

Conversation

@daryllimyt

@daryllimyt daryllimyt commented May 30, 2026

Copy link
Copy Markdown
Contributor

Motivation

  • The client-side "last viewed workspace" value was stored in a single shared cookie (__tracecat:workspaces:last-viewed), which could leak a previously selected workspace across different authenticated users in the same browser.
  • The change scopes persisted last-viewed workspace IDs to an authenticated user's ID while preserving the legacy behavior for anonymous callers.

Description

  • Add frontend/src/lib/last-workspace.ts which exposes getLastWorkspaceIdForUser, setLastWorkspaceIdForUser, and clearLastWorkspaceIdForUser, and uses per-user cookie names __tracecat:workspaces:last-viewed:<userId> for authenticated users.
  • Update useWorkspaceManager in frontend/src/lib/hooks.tsx to read the current user via useAuth() and route cookie get/set/clear through the new helpers instead of the shared cookie.
  • Remove direct Cookies usage for the shared key in useWorkspaceManager so workspace persistence is user-scoped.
  • Add regression tests at frontend/tests/last-workspace.test.ts to verify per-user storage, legacy anonymous behavior, and that clearing one user's value does not clear another's.

Testing

  • Ran formatting/type fixes with pnpm -C frontend exec biome check --write src/lib/hooks.tsx src/lib/last-workspace.ts tests/last-workspace.test.ts which completed and autofixed one file. (success)
  • Ran the new unit tests with pnpm -C frontend test -- last-workspace.test.ts and all tests passed (3 passed). (success)
  • Ran TypeScript typecheck with pnpm -C frontend run typecheck which completed without type errors. (success)

Codex Task


Summary by cubic

Scopes the “last viewed workspace” cookie by user to prevent cross-account leakage in the same browser. Keeps the legacy shared cookie for anonymous sessions.

  • Bug Fixes
    • Store last workspace per user via __tracecat:workspaces:last-viewed:<userId>.
    • Add getLastWorkspaceIdForUser, setLastWorkspaceIdForUser, clearLastWorkspaceIdForUser in frontend/src/lib/last-workspace.ts.
    • Update useWorkspaceManager to use useAuth() and the new helpers; remove direct Cookies usage.
    • Preserve __tracecat:workspaces:last-viewed for anonymous users.
    • Add tests in frontend/tests/last-workspace.test.ts for per-user storage, legacy behavior, and scoped clearing.

Written for commit dd8687a. Summary will update on new commits.

Review in cubic

@zeropath-ai

zeropath-ai Bot commented May 30, 2026

Copy link
Copy Markdown

No security or compliance issues detected. Reviewed everything up to dd8687a.

Security Overview
Detected Code Changes
Change Type Relevant files
Refactor ► hooks.tsx
    Refactor workspace ID cookie handling to use user-specific cookies
► last-workspace.ts
    Implement user-specific last workspace cookie logic
Other ► last-workspace.ts
    Add new file for managing last workspace cookies
► last-workspace.test.ts
    Add new test file for last workspace persistence

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files

Confidence score: 3/5

  • There is a concrete regression risk in frontend/src/lib/last-workspace.ts: the !userId check can treat authenticated-but-still-loading users like anonymous users and read/write the legacy shared cookie.
  • Because this is severity 6/10 with fairly strong confidence (7/10) and can affect workspace selection behavior for signed-in sessions, the change carries some user-facing risk until this condition is tightened.
  • Pay close attention to frontend/src/lib/last-workspace.ts - auth-loading vs anonymous state handling may route users to the wrong cookie path.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="frontend/src/lib/last-workspace.ts">

<violation number="1" location="frontend/src/lib/last-workspace.ts:18">
P2: Using `!userId` to select the legacy cookie conflates anonymous and auth-loading states, so authenticated sessions can still hit the shared cookie before user data resolves.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

* previously selected workspace across users.
*/
export function getLastWorkspaceIdForUser(userId?: string): string | undefined {
if (!userId) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Using !userId to select the legacy cookie conflates anonymous and auth-loading states, so authenticated sessions can still hit the shared cookie before user data resolves.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At frontend/src/lib/last-workspace.ts, line 18:

<comment>Using `!userId` to select the legacy cookie conflates anonymous and auth-loading states, so authenticated sessions can still hit the shared cookie before user data resolves.</comment>

<file context>
@@ -0,0 +1,47 @@
+ * previously selected workspace across users.
+ */
+export function getLastWorkspaceIdForUser(userId?: string): string | undefined {
+  if (!userId) {
+    return Cookies.get(LEGACY_LAST_WORKSPACE_COOKIE)
+  }
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant