Skip to content

fix: stale client session and cache after the logged-in user is deleted - #42041

Draft
KevLehman wants to merge 1 commit into
developfrom
fix/logout-when-own-user-deleted
Draft

fix: stale client session and cache after the logged-in user is deleted#42041
KevLehman wants to merge 1 commit into
developfrom
fix/logout-when-own-user-deleted

Conversation

@KevLehman

@KevLehman KevLehman commented Sep 3, 2026

Copy link
Copy Markdown
Member

Proposed changes (including videos or screenshots)

Deleting a logged-in user never cleared the session in the browser. The userData stream removed event only dropped the user record from the store, leaving the login token in localStorage, Meteor.userId() set and the cached stores (subscriptions, rooms, ...) populated. Nothing else notices in time: nobody calls logout, and the login-token observe that would close the socket polls every 10s (disable-oplog), well after the user has already logged back in.

Two consequences when logging back in as a recreated user on the same page, both stale cache:

  1. The first login attempt fails with "You must be logged in to do this." because ddpOverREST attaches the deleted user's token from localStorage to the method call.
  2. On retry the login succeeds, the subscriptions cached store loads from the server on a cache miss (token mismatch) and storeMany merges the new records onto the previous session's records still in memory. New subscriptions have new _ids and the same rid, so every auto-joined channel appears twice in the sidebar until a hard refresh.

Changes:

  • client/lib/userData.ts: call clearStoredCredentials() on the own-user removed event, the same dead-session handling already used by RestApiClient, ddpOverREST and startup.ts. Drops the stale token and nulls the connection userId, so the next login goes out unauthenticated and succeeds on the first attempt.
  • client/lib/cachedStores/CachedStore.ts: reset the store before a full <name>/get load. A full load is authoritative, so a cache miss must never merge onto records left by a previous session, whatever path left them there.

Tests:

  • CachedStore.spec.ts (jest): stale record in memory + full load from server keeps only the server records. Failed before the fix.
  • sidebar-after-user-recreation.spec.ts (Playwright): seed a user and a live session via API, delete the user via API, recreate it, log in on the same page without reloading, assert general is listed once. Failed before the fix at the login step; passes in under a second with it (3/3 locally).

Issue(s)

Steps to test or reproduce

  1. Create a user via API and log in with it in a browser.
  2. Delete the user via API. The browser drops to the login page.
  3. Recreate the user via API (same username).
  4. Log in on that same page without reloading.

Before: first login attempt errors, second attempt shows every auto-joined channel twice in the sidebar. After: login succeeds on the first attempt and each channel is listed once.

Further comments

No Meteor internals involved. Accounts.onLogout hooks do not fire on this path, same as the other clearStoredCredentials callers today.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 873370d

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@rocket.chat/meteor Patch
@rocket.chat/core-typings Patch
@rocket.chat/rest-typings Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@dionisio-bot

dionisio-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@coderabbitai

coderabbitai Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.33%. Comparing base (6bbc8a3) to head (873370d).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop   #42041   +/-   ##
========================================
  Coverage    69.32%   69.33%           
========================================
  Files         4287     4287           
  Lines       171470   171471    +1     
  Branches     31117    31108    -9     
========================================
+ Hits        118880   118891   +11     
+ Misses       47411    47400   -11     
- Partials      5179     5180    +1     
Flag Coverage Δ
unit 70.99% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Deleting a logged-in user never cleared the session on the client: the
userData stream 'removed' event only dropped the user record, leaving the
login token in localStorage and the cached stores populated. Logging back
in as a recreated user then failed once (the login call carried the dead
token) and, on retry, merged the new subscriptions onto the stale ones,
duplicating every auto-joined channel in the sidebar until a hard refresh.

Drop the stored credentials on the 'removed' event, and reset the cached
store before a full server load so a cache miss never merges onto records
left by a previous session.
@KevLehman
KevLehman force-pushed the fix/logout-when-own-user-deleted branch from 98c3d1d to 873370d Compare September 3, 2026 18:14
@KevLehman KevLehman changed the title fix: log the client out when its own user is deleted fix: stale client session and cache after the logged-in user is deleted Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant