Skip to content

In-flight board mutations can repopulate cleared state after logout #3306

Description

@Chris0Jeky

Summary

resetForLogout() generation-gates and aborts board-list/detail reads, then clears all board state. It does not own or invalidate card, column, label, comment, or board mutation requests that were already in flight.

Several mutation paths deliberately treat currentBoard === null as permission to commit into the selected-board collections (the pre-load/test convention). After logout, that same null value means the store was intentionally cleared. A late response can therefore repopulate the previous account's cards, labels, comments, columns, or boards and can emit a toast/error on the login screen or into a later session.

Confirmed shape

  1. A board mutation begins under authenticated session A.
  2. Authentication transitions true→false and resetForLogout() clears the store.
  3. The mutation settles after reset.
  4. Its post-await patch/finally runs without a session-generation guard. Paths that accept a null board write old-session data back into the cleared refs; every path can still write shared loading/error/toast state.

Read cancellation does not cover this because most mutation API calls are not issued with a store-owned abort signal.

Expected design

Introduce one board-store session/mutation epoch owned by resetForLogout():

  • each mutation captures the current epoch before issuing its request;
  • post-await state, toast, error, and loading commits occur only while that epoch is still current;
  • reset synchronously advances the epoch before clearing refs;
  • a stale response may resolve/reject to its original caller, but cannot repopulate or message the logged-out/new session;
  • normal same-session currentBoard === null behavior, if genuinely required, is made explicit rather than doubling as logout authority;
  • server-side effects already accepted before logout are not falsely presented as cancelled or rolled back.

Coordinate with #3305 so a stale mutation cannot clear a newer session's operation-owned loading state.

Acceptance

  • Deferred-promise regressions for create/update/delete across representative board, card, label, and comment paths followed by resetForLogout().
  • Rejection-after-logout produces no stale error/toast in the cleared/new session.
  • Login as a second account before the old response settles cannot receive account-A client state.
  • Existing board list/detail generation, demo-mode, mutation-epoch, and navigation tests remain green.
  • Frontend lint, typecheck, build, full tests, and exact-head hosted CI pass.

Audit provenance

Found during the selected-board async-integrity pass behind #3299, #3301, #3303 and the loading-ownership follow-up #3305. Kept separate from those focused PRs to avoid cross-branch conflicts and to make the session boundary explicit.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority IRelease-blocking or trust-breaking now; release scope still requires milestone membership.bugSomething isn't workingfrontendPrimary implementation impact in Vue/TypeScript UI and client runtime.securityAuthentication, authorization, data protection, abuse prevention, and compliance-related changes.testingTest coverage, harnesses, regression prevention, and verification pipeline work.

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions