chore: web client without Meteor's DDP client

Draft
GG
3h ago
+776-4794

Proposed changes

The Meteor-built web client runs on DDPSDK and REST only, and Meteor's DDP client no longer ships to the browser.

The branch stacks eight commits, each meant to be extracted on its own. The first two are follow-ups to PRs that already merged, and the next three are prerequisites that also work in today's client:

  1. regression: spread and pace the session resume retries (follow-up to #43006)
    • Retries wait a random part of the backoff, so the clients of a server being redeployed don't come back together.
    • The backoff only grows once a retry has actually run.
  2. regression: log out locally when the SAML single logout can't start (follow-up to #42921)
    • Any failure on the way to the identity provider falls back to the local logout instead of leaving the user logged in.
  3. test: drive e2e logins and method calls through the client's own entry points
    • The login helper and the TOTP spec use window.__rocketChatLoginWithToken / __rocketChatCallMethod, which both builds expose, instead of require('meteor/accounts-base') and window.Meteor.callAsync.
  4. fix: only end the session on a 401 that rejects the token
    • The REST client cleared the credentials on any 401 answer to a mutation. Now it only clears them on the authentication middleware's "You must be logged in to do this.", not on endpoint 401s such as rooms.hide for an inaccessible room.
  5. fix: only log out the session a forced logout names
    • A device logout from device management names its session. Every other open session of the user ignores it; a logout with no session still ends all of them.
  6. feat(ddp-client): expose the connection's retry count and next retry time
    • Adds retryCount and nextRetryAt to Connection, so the reconnect countdown can be shown again.
  7. refactor: run the client on DDPSDK and REST only, in the Meteor build too.
    • The modules in vite/native become the client's only implementation: accounts, connection, the DDP codec on npm ejson, the transport flag fixed to DDPSDK, and the storage switch.
    • The native accounts module takes over what accounts-base did:
      • the expired-token check on load;
      • the cross-tab storage poller;
      • a single owner for every login;
      • keeping the session after resume failures that don't refuse the token.
    • client/meteor/overrides/*, minimongo/*, watch.ts and user.ts are deleted.
    • No runtime meteor/* import is left under client/.
  8. chore: keep Meteor's DDP, accounts and mongo packages out of the browser bundle.
    • .meteor/packages applies to every architecture. A new local package, rocketchat:server-runtime, uses and implies the server runtime packages for the server arch only. rocketchat:mongo-config goes first, because it sets the connection options.
    • The browser closure drops from 73 to 29 Meteor packages: no ddp-client, ddp, mongo, minimongo, accounts-base, tracker, reload or autoupdate.
    • No Meteor package code is copied.
    • The new-version notice no longer comes from the autoupdate client. The client subscribes to the same meteor_autoupdate_clientVersions publication through DDPSDK. It fires client_changed when the server serves a different build than the one in __meteor_runtime_config__, so the notice and the dev reload keep working.

Issue(s)

https://rocketchat.atlassian.net/browse/ARCH-2576

Known gaps

  • Desktop app: Rocket.Chat.Electron reads Meteor.userId/user/status/call through window.require. Those no longer exist, so its integrations stop working. This needs an explicit desktop-api contract first.
  • Use_RC_SDK: the setting no longer has any effect on the client. Removing it is a separate breaking change.

Steps to test or reproduce

  • The CI e2e suite exercises login, presence, streams, method calls (including the TOTP spec, driven through the native callMethod), E2EE and SAML on a client with no Meteor DDP client.
  • Tested manually against a copy of a real database:
    • login and logout;
    • sessions across tabs;
    • a server restart with the tab open;
    • a stale token from another instance, which is refused and cleared.

Summary by CodeRabbit

  • New Features

    • Improved sign-in, session restoration, and cross-tab authentication handling.
    • Added smoother SAML identity-provider logout.
    • Improved two-factor authentication during account actions.
    • Added visibility into connection retry attempts and scheduled retry times.
  • Bug Fixes

    • Improved synchronization of authentication state across application and browser sessions.
    • Transient session-resume failures now retry without immediately signing users out.
    • Improved handling of expired, invalid, and refused sessions.