Skip to content

refactor(client): drop residual Accounts.* usages from 3 client files#40480

Merged
ggazzo merged 5 commits into
developfrom
refactor/accounts-misc-cleanup
May 13, 2026
Merged

refactor(client): drop residual Accounts.* usages from 3 client files#40480
ggazzo merged 5 commits into
developfrom
refactor/accounts-misc-cleanup

Conversation

@ggazzo
Copy link
Copy Markdown
Member

@ggazzo ggazzo commented May 11, 2026

Summary

Three small follow-ups to the Meteor → SDK migration that don't fit any larger cluster:

  • CachedStore.getToken() reads the stored login token via getStoredItem(STORAGE_KEYS.LOGIN_TOKEN) from the SDK storage helper (added in refactor(client): replace Accounts.storageLocation with SDK storage helper #40479) instead of Accounts._storedLoginToken(). The meteor/accounts-base import is no longer needed in this file.
  • Define a local LoginCancelledError class at apps/meteor/client/meteor/login/LoginCancelledError.ts with the same numericError (0x8acdc2f) and Error-subclass shape as Meteor's Accounts.LoginCancelledError. The OAuth login flow checks Meteor.Error.error === LoginCancelledError.numericError to detect server-issued cancellations, so the constant has to match. Replace the 3 Accounts.LoginCancelledError references in oauth.ts with the new class.
  • Accounts.verifyEmail in meteor/startup/accounts.ts becomes await sdk.call('verifyEmail', token) wrapped in async/await with the same error-toast flow. Register verifyEmail on @rocket.chat/ddp-client's ServerMethods via module augmentation since it's a Meteor built-in (accounts-password) and isn't otherwise typed. Drops the meteor/accounts-base import from this file.

No behaviour change.

Test plan

  • tsc --noEmit on apps/meteor is clean (no regressions in the changed files)
  • yarn eslint on the 4 changed files: 0 errors
  • Manual: log out and back in, observe that the private cached stores (subscriptions/permissions/public-settings) reload — confirms CachedStore.getToken() still returns the stored token.
  • Manual: trigger an OAuth login (e.g. Google) and cancel the popup; the login flow should surface a cancellation error and not crash.
  • Manual: complete the email verification flow (/verify-email/<token>); on success the toast appears and afterVerifyEmail server method fires; on a bad token the error toast appears.

Summary by CodeRabbit

  • Refactor
    • Login token now reads from local cached storage for more reliable auth.
    • Reconnection handling moved to direct connection events for more robust reconnect/resync behavior; reduced use of legacy reactive autoruns.
  • Bug Fixes
    • OAuth cancellation consistently surfaces a dedicated cancellation error.
  • User Experience
    • Email verification runs via typed call, waits for readiness, and shows clear success/error toasts.

Review Change Stack

Task: ARCH-2134

Three small follow-ups to the Meteor → SDK migration that don't fit any
larger cluster:

- CachedStore.getToken() reads the stored login token via getStoredItem from
  the SDK storage helper instead of Accounts._storedLoginToken(); the
  meteor/accounts-base import is no longer needed in this file.
- Define a local LoginCancelledError class with the same numericError
  (0x8acdc2f) and Error shape as Meteor's Accounts.LoginCancelledError. The
  OAuth login flow checks Meteor.Error.error against that numericError to
  detect server-issued cancellations, so the constant has to match. Replace
  the 3 Accounts.LoginCancelledError references in oauth.ts with the new
  class.
- Replace Accounts.verifyEmail(token, callback) with sdk.call('verifyEmail',
  token) wrapped in async/await. Register the method on @rocket.chat/ddp-client
  via module augmentation since verifyEmail is a Meteor built-in
  (accounts-password) and isn't otherwise typed. Drops the
  meteor/accounts-base import from startup/accounts.ts.

No behaviour change.
@ggazzo ggazzo requested a review from a team as a code owner May 11, 2026 20:19
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented May 11, 2026

Looks like this PR is ready to merge! 🎉
If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 11, 2026

⚠️ No Changeset found

Latest commit: 584aa0e

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 11, 2026

Walkthrough

This PR decouples the client from Meteor's Accounts module by introducing a custom LoginCancelledError class, migrating email verification to async SDK calls, and switching token retrieval to local storage.

Changes

Meteor Accounts Decoupling

Layer / File(s) Summary
Custom Login Cancelled Error
apps/meteor/client/meteor/login/LoginCancelledError.ts
New LoginCancelledError class extends Error with static numericError identifier and overrides name to 'Accounts.LoginCancelledError'.
OAuth Error Conversion
apps/meteor/client/meteor/login/oauth.ts
convertError detects cancellation via LoginCancelledError.numericError and returns new LoginCancelledError(error.reason) for cancellation cases; other errors pass through unchanged.
Email Verification Migration
apps/meteor/client/meteor/startup/accounts.ts
Email verification handler refactored from callback-based Accounts.verifyEmail to async sdk.call('verifyEmail', token) with a TypeScript module augmentation declaring ServerMethods.verifyEmail.
Token Retrieval
apps/meteor/client/lib/cachedStores/CachedStore.ts
PrivateCachedStore.getToken() now retrieves login token with getStoredItem(STORAGE_KEYS.LOGIN_TOKEN) and removes the Accounts import.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant DdpSdk as DdpSdk
  participant Server
  participant MainApp as MainApp
  participant UI
  Client->>DdpSdk: onEmailVerificationLink(token)
  DdpSdk->>Server: call('verifyEmail', token)
  Server-->>DdpSdk: verification result
  DdpSdk-->>Client: result
  Client->>MainApp: whenMainReady()
  Client->>UI: afterVerifyEmail / show success or error toast
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • tassoevan
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main objective: removing residual Accounts.* API usages from three client files (CachedStore, oauth.ts, accounts.ts), which aligns with the primary changes across the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • ARCH-2134: Request failed with status code 401

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/meteor/client/meteor/startup/accounts.ts (1)

5-9: ⚡ Quick win

Remove inline implementation comments in this TS file.

Please drop the explanatory comments (including the eslint-disable comment) here and keep only the augmentation code itself.

As per coding guidelines: “**/*.{ts,tsx,js}: … Avoid code comments in the implementation”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/meteor/client/meteor/startup/accounts.ts` around lines 5 - 9, Remove the
inline explanatory comments and the eslint-disable comment from the TypeScript
module augmentation so only the augmentation remains; specifically edit the
declare module '@rocket.chat/ddp-client' block and its interface ServerMethods
to keep only the TypeScript declarations (no comments or eslint directives)
while leaving the declaration code intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/meteor/client/meteor/login/LoginCancelledError.ts`:
- Around line 1-3: Remove the top-of-file implementation comment block (the
three comment lines preceding the code) so the file conforms to the repo TS
guideline; leave the exported LoginCancelledError symbol and its implementation
unchanged (i.e., delete the comment that says it mirrors Meteor's
Accounts.LoginCancelledError but do not modify the LoginCancelledError class or
its export).

In `@apps/meteor/client/meteor/startup/accounts.ts`:
- Around line 59-61: The toast is currently passing the raw caught value (error)
to dispatchToastMessage which can be an object; normalize it into a
user-friendly string first (e.g., const msg = error?.message || String(error ||
'An error occurred')) and then call dispatchToastMessage({ type: 'error',
message: msg }); update the code in the block that runs after await
whenMainReady() where dispatchToastMessage(...) is called (and keep the existing
throw new Meteor.Error('verify-email', 'E-mail not verified') behavior).

---

Nitpick comments:
In `@apps/meteor/client/meteor/startup/accounts.ts`:
- Around line 5-9: Remove the inline explanatory comments and the eslint-disable
comment from the TypeScript module augmentation so only the augmentation
remains; specifically edit the declare module '@rocket.chat/ddp-client' block
and its interface ServerMethods to keep only the TypeScript declarations (no
comments or eslint directives) while leaving the declaration code intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 51d3e5d7-430d-4c65-85cc-ec602c8a9bc5

📥 Commits

Reviewing files that changed from the base of the PR and between 1acd37a and 23b7097.

📒 Files selected for processing (4)
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/meteor/login/LoginCancelledError.ts
  • apps/meteor/client/meteor/login/oauth.ts
  • apps/meteor/client/meteor/startup/accounts.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/meteor/login/LoginCancelledError.ts
  • apps/meteor/client/meteor/startup/accounts.ts
  • apps/meteor/client/meteor/login/oauth.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
🧠 Learnings (4)
📚 Learning: 2026-02-10T16:32:42.586Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Applied to files:

  • apps/meteor/client/meteor/login/LoginCancelledError.ts
  • apps/meteor/client/meteor/startup/accounts.ts
  • apps/meteor/client/meteor/login/oauth.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/client/meteor/login/LoginCancelledError.ts
  • apps/meteor/client/meteor/startup/accounts.ts
  • apps/meteor/client/meteor/login/oauth.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/client/meteor/login/LoginCancelledError.ts
  • apps/meteor/client/meteor/startup/accounts.ts
  • apps/meteor/client/meteor/login/oauth.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.

Applied to files:

  • apps/meteor/client/meteor/login/LoginCancelledError.ts
  • apps/meteor/client/meteor/startup/accounts.ts
  • apps/meteor/client/meteor/login/oauth.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
🔇 Additional comments (4)
apps/meteor/client/lib/cachedStores/CachedStore.ts (2)

16-16: Import migration looks correct.

This switch cleanly centralizes token access through the SDK storage helper and supports the Accounts decoupling goal.


383-385: Token source change in getToken() is sound.

Using STORAGE_KEYS.LOGIN_TOKEN here preserves the existing cache token guard behavior while removing the residual Accounts.* dependency.

apps/meteor/client/meteor/login/LoginCancelledError.ts (1)

4-11: Error-shape compatibility looks good.

numericError, name, and constructor behavior preserve cancellation mapping as intended.

apps/meteor/client/meteor/login/oauth.ts (1)

5-5: Cancellation conversion refactor is clean and type-safe.

The LoginCancelledError guard + return type update is consistent and preserves prior behavior without Accounts.LoginCancelledError coupling.

Also applies to: 11-11, 13-13, 15-15

Comment thread apps/meteor/client/meteor/login/LoginCancelledError.ts
Comment on lines +59 to +61
await whenMainReady();
dispatchToastMessage({ type: 'error', message: error });
throw new Meteor.Error('verify-email', 'E-mail not verified');
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot May 11, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Normalize caught errors before sending toast message.

message: error can surface non-user-friendly output when the thrown value is an object. Convert it to a string message before dispatching the toast.

Proposed fix
 	} catch (error) {
 		await whenMainReady();
-		dispatchToastMessage({ type: 'error', message: error });
+		const message =
+			error instanceof Meteor.Error
+				? error.reason || error.message
+				: error instanceof Error
+					? error.message
+					: t('E-mail_not_verified');
+		dispatchToastMessage({ type: 'error', message });
 		throw new Meteor.Error('verify-email', 'E-mail not verified');
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
await whenMainReady();
dispatchToastMessage({ type: 'error', message: error });
throw new Meteor.Error('verify-email', 'E-mail not verified');
} catch (error) {
await whenMainReady();
const message =
error instanceof Meteor.Error
? error.reason || error.message
: error instanceof Error
? error.message
: t('E-mail_not_verified');
dispatchToastMessage({ type: 'error', message });
throw new Meteor.Error('verify-email', 'E-mail not verified');
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/meteor/client/meteor/startup/accounts.ts` around lines 59 - 61, The
toast is currently passing the raw caught value (error) to dispatchToastMessage
which can be an object; normalize it into a user-friendly string first (e.g.,
const msg = error?.message || String(error || 'An error occurred')) and then
call dispatchToastMessage({ type: 'error', message: msg }); update the code in
the block that runs after await whenMainReady() where dispatchToastMessage(...)
is called (and keep the existing throw new Meteor.Error('verify-email', 'E-mail
not verified') behavior).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

dispatchToastMessage implementation was built for handling error objects whenever type is 'error'.

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.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
ast-grep --pattern 'const dispatchToastMessage = $_' 
rg -n "dispatchToastMessage" --type=ts -C5 -g "!*.test.*" -g "!*.spec.*" | grep -A10 "type.*error\|error.*type\|message.*error" | head -60
fd "toast" --type=f -e ts | head -20

Length of output: 37850


🏁 Script executed:

#!/bin/bash
cat apps/meteor/client/lib/toast.ts
echo "---"
cat packages/ui-contexts/src/ToastMessagesContext.ts

Length of output: 1232


@tassoevan, you're absolutely right — the type definition confirms it. The ToastMessagePayload for type: 'error' explicitly declares message: unknown, meaning dispatchToastMessage is intentionally designed to accept raw error objects in the error case. My suggestion to normalize the error was unnecessary. Apologies for the noise!


✏️ Learnings added
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 40480
File: apps/meteor/client/meteor/startup/accounts.ts:59-61
Timestamp: 2026-05-11T20:30:35.265Z
Learning: In RocketChat/Rocket.Chat, `dispatchToastMessage` (defined in `apps/meteor/client/lib/toast.ts`) accepts `message: unknown` when `type` is `'error'`, so it intentionally handles raw error objects directly. Do not suggest normalizing caught errors before passing them to `dispatchToastMessage({ type: 'error', message: error })` — no manual conversion to string or `error.message` extraction is needed.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.

Comment thread apps/meteor/client/meteor/login/LoginCancelledError.ts Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented May 11, 2026

Codecov Report

❌ Patch coverage is 8.88889% with 41 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.59%. Comparing base (1acd37a) to head (584aa0e).
⚠️ Report is 18 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #40480      +/-   ##
===========================================
- Coverage    69.63%   69.59%   -0.05%     
===========================================
  Files         3318     3321       +3     
  Lines       121981   122507     +526     
  Branches     21813    21876      +63     
===========================================
+ Hits         84947    85259     +312     
- Misses       33701    33924     +223     
+ Partials      3333     3324       -9     
Flag Coverage Δ
unit 70.35% <0.00%> (-0.08%) ⬇️

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.

@ggazzo ggazzo added this to the 8.5.0 milestone May 11, 2026
- Move all imports above the `declare module` block in
  meteor/startup/accounts.ts (import/order + import/first).
- Add the blank line lines-between-class-members expects between
  numericError and the override name field on LoginCancelledError.
@ggazzo
Copy link
Copy Markdown
Member Author

ggazzo commented May 11, 2026

/jira ARCH-2116

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/sdk-tracker-easy-autoruns.md:
- Line 5: The changeset text incorrectly claims the bridge subscribes to
'connected' when the implementation in meteorBackedSdk (the connection-status
bridge that attaches to Meteor.connection._stream) deliberately only registers
'reset' and 'disconnect' because stream.on('connected', …) is invalid; update
the changeset wording to list only 'reset' and 'disconnect' (and/or explicitly
state that 'connected' is omitted and why) so it matches the implementation and
prevents future maintainers from re-adding a 'connected' listener.

In `@apps/meteor/client/lib/cachedStores/CachedStore.ts`:
- Around line 317-329: The reconnection listener stored in
reconnectionUnsubscribe is not being removed when the store is released,
allowing trySync() to be called after teardown; in the release() method
(alongside where listenerUnsubscriber is cleaned up) call
reconnectionUnsubscribe?.() and set reconnectionUnsubscribe = undefined (and do
the same cleanup wherever release logic exists, e.g., the other release path
referenced around the second occurrence) so the on('connection') handler is
unsubscribed and cannot trigger trySync() after release.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a549c9cc-65a4-43f2-877e-f092da07ad61

📥 Commits

Reviewing files that changed from the base of the PR and between 1de1b8f and a4f65fd.

📒 Files selected for processing (12)
  • .changeset/sdk-tracker-easy-autoruns.md
  • apps/meteor/app/ui-message/client/messageBox/createComposerAPI.ts
  • apps/meteor/app/utils/client/lib/SDKClient.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/client/providers/AuthenticationProvider/AuthenticationProvider.tsx
  • apps/meteor/definition/externals/meteor/meteor.d.ts
✅ Files skipped from review due to trivial changes (1)
  • apps/meteor/client/providers/AuthenticationProvider/AuthenticationProvider.tsx
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/playwright.mdc)

**/*.{ts,tsx,js}: Write concise, technical TypeScript/JavaScript with accurate typing in Playwright tests
Avoid code comments in the implementation

Files:

  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/app/ui-message/client/messageBox/createComposerAPI.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/definition/externals/meteor/meteor.d.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/app/utils/client/lib/SDKClient.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
🧠 Learnings (6)
📚 Learning: 2026-02-10T16:32:42.586Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 38528
File: apps/meteor/client/startup/roles.ts:14-14
Timestamp: 2026-02-10T16:32:42.586Z
Learning: In Rocket.Chat's Meteor client code, DDP streams use EJSON and Date fields arrive as Date objects; do not manually construct new Date() in stream handlers (for example, in sdk.stream()). Only REST API responses return plain JSON where dates are strings, so implement explicit conversion there if needed. Apply this guidance to all TypeScript files under apps/meteor/client to ensure consistent date handling in DDP streams and REST responses.

Applied to files:

  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
📚 Learning: 2026-05-11T20:30:35.265Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 40480
File: apps/meteor/client/meteor/startup/accounts.ts:59-61
Timestamp: 2026-05-11T20:30:35.265Z
Learning: In Rocket.Chat’s Meteor client code, when calling `dispatchToastMessage` with `{ type: 'error' }`, pass the raw caught error object as `message` without manual normalization. `dispatchToastMessage` is designed to accept `message: unknown` for error toasts, so avoid converting errors to strings (e.g., `String(error)`) or extracting `error.message` before passing them.

Applied to files:

  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In the Rocket.Chat repository, do not reference Biome lint rules in code review feedback. Biome is not used even if biome.json exists; only reference Biome rules if there is explicit, project-wide usage documented. For TypeScript files, review lint implications without Biome guidance unless the project enables Biome rules.

Applied to files:

  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/app/ui-message/client/messageBox/createComposerAPI.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/definition/externals/meteor/meteor.d.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/app/utils/client/lib/SDKClient.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
📚 Learning: 2026-02-26T19:25:44.063Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/providers/useMediaSession.ts:192-192
Timestamp: 2026-02-26T19:25:44.063Z
Learning: In this repository (RocketChat/Rocket.Chat), Biome lint rules are not used even if a biome.json exists. When reviewing TypeScript files (e.g., packages/ui-voip/src/providers/useMediaSession.ts), ensure lint suggestions do not reference Biome-specific rules. Rely on general ESLint/TypeScript lint rules and project conventions instead.

Applied to files:

  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/app/ui-message/client/messageBox/createComposerAPI.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/definition/externals/meteor/meteor.d.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/app/utils/client/lib/SDKClient.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
📚 Learning: 2026-05-06T12:21:44.083Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 40256
File: apps/meteor/client/components/CreateDiscussion/CreateDiscussion.tsx:121-149
Timestamp: 2026-05-06T12:21:44.083Z
Learning: Field wrappers in rocket.chat/fuselage-forms (Field, FieldLabel, FieldRow, FieldError, FieldHint) auto-create htmlFor/id associations, aria-describedby, and role="alert" for errors. Do not manually set htmlFor, id, aria-describedby, or role attributes when using these wrappers. This automatic wiring does not apply to plain rocket.chat/fuselage components, which require explicit ID wiring per the accessibility docs. In code reviews, prefer using fuselage-forms wrappers for form fields and verify there is no unnecessary manual ID/aria wiring in files that use these wrappers. If a component uses plain fuselage components, ensure proper id wiring as per docs.

Applied to files:

  • apps/meteor/client/meteor/overrides/killMeteorStream.ts
  • apps/meteor/client/lib/sdk/ddpSdk.ts
  • apps/meteor/client/meteor/overrides/subscribeViaSDK.ts
  • apps/meteor/app/ui-message/client/messageBox/createComposerAPI.ts
  • apps/meteor/client/lib/cachedStores/CachedStore.ts
  • apps/meteor/client/lib/streamer/streamer.ts
  • apps/meteor/definition/externals/meteor/meteor.d.ts
  • apps/meteor/client/lib/sdk/meteorBackedSdk.ts
  • apps/meteor/app/utils/client/lib/SDKClient.ts
  • apps/meteor/client/meteor/overrides/stubMeteorStream.ts
📚 Learning: 2026-03-16T21:50:37.589Z
Learnt from: amitb0ra
Repo: RocketChat/Rocket.Chat PR: 39676
File: .changeset/migrate-users-register-openapi.md:3-3
Timestamp: 2026-03-16T21:50:37.589Z
Learning: For changes related to OpenAPI migrations in Rocket.Chat/OpenAPI, when removing endpoint types and validators from rocket.chat/rest-typings (e.g., UserRegisterParamsPOST, /v1/users.register) document this as a minor changeset (not breaking) per RocketChat/Rocket.Chat-Open-API#150 Rule 7. Note that the endpoint type is re-exposed via a module augmentation .d.ts in the consuming package (e.g., packages/web-ui-registration/src/users-register.d.ts). In reviews, ensure the changeset clearly states: this is a non-breaking change, the major version should not be bumped, and the changeset reflects a minor version bump. Do not treat this as a breaking change during OpenAPI migrations.

Applied to files:

  • .changeset/sdk-tracker-easy-autoruns.md
🔇 Additional comments (10)
apps/meteor/client/lib/cachedStores/CachedStore.ts (1)

15-15: LGTM!

Also applies to: 382-383

apps/meteor/app/utils/client/lib/SDKClient.ts (1)

201-201: LGTM!

Also applies to: 269-269, 302-303

apps/meteor/client/lib/streamer/streamer.ts (1)

24-31: LGTM!

Also applies to: 51-51, 80-80, 112-112

apps/meteor/client/meteor/overrides/killMeteorStream.ts (1)

33-33: LGTM!

apps/meteor/client/meteor/overrides/stubMeteorStream.ts (1)

34-34: LGTM!

Also applies to: 36-36, 51-51, 53-53, 55-55, 64-64, 71-71

apps/meteor/client/meteor/overrides/subscribeViaSDK.ts (1)

48-48: LGTM!

Also applies to: 64-64

apps/meteor/client/lib/sdk/ddpSdk.ts (1)

146-146: LGTM!

apps/meteor/definition/externals/meteor/meteor.d.ts (1)

67-102: LGTM!

Also applies to: 110-114, 117-117, 148-148

apps/meteor/client/lib/sdk/meteorBackedSdk.ts (1)

29-57: LGTM!

Also applies to: 78-87, 111-111

apps/meteor/app/ui-message/client/messageBox/createComposerAPI.ts (1)

10-10: LGTM!

Also applies to: 198-217, 222-222

Comment thread .changeset/sdk-tracker-easy-autoruns.md Outdated
Comment on lines +317 to 329
this.reconnectionUnsubscribe?.();
const sdk = getDdpSdk();
let wentOffline = sdk.connection.status !== 'connected';
this.reconnectionUnsubscribe = sdk.connection.on('connection', () => {
if (sdk.connection.status !== 'connected') {
wentOffline = true;
return;
}

if (status === 'connected' && wentOffline) {
if (wentOffline) {
wentOffline = false;
this.trySync();
}
});
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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Unsubscribe the reconnection handler during release.

This listener survives release(), so logout can still leave the private store reacting to later connection changes and calling trySync() after it was torn down. Please clean up reconnectionUnsubscribe alongside listenerUnsubscriber.

Proposed fix
 async release() {
 	if (this.initializationPromise) {
 		await this.initializationPromise;
 	}

 	this.listenerUnsubscriber?.();
+	this.reconnectionUnsubscribe?.();
+	this.reconnectionUnsubscribe = undefined;
 	this.setReady(false);
 }

Also applies to: 364-364

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/meteor/client/lib/cachedStores/CachedStore.ts` around lines 317 - 329,
The reconnection listener stored in reconnectionUnsubscribe is not being removed
when the store is released, allowing trySync() to be called after teardown; in
the release() method (alongside where listenerUnsubscriber is cleaned up) call
reconnectionUnsubscribe?.() and set reconnectionUnsubscribe = undefined (and do
the same cleanup wherever release logic exists, e.g., the other release path
referenced around the second occurrence) so the on('connection') handler is
unsubscribed and cannot trigger trySync() after release.

@ggazzo ggazzo added the stat: QA assured Means it has been tested and approved by a company insider label May 13, 2026
@dionisio-bot dionisio-bot Bot added the stat: ready to merge PR tested and approved waiting for merge label May 13, 2026
@ggazzo ggazzo merged commit 0ae9ab0 into develop May 13, 2026
44 of 47 checks passed
@ggazzo ggazzo deleted the refactor/accounts-misc-cleanup branch May 13, 2026 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stat: QA assured Means it has been tested and approved by a company insider stat: ready to merge PR tested and approved waiting for merge type: chore

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants