Skip to content

feat: External Call History#40658

Open
pierre-lehnen-rc wants to merge 11 commits into
developfrom
wip/external-call-history
Open

feat: External Call History#40658
pierre-lehnen-rc wants to merge 11 commits into
developfrom
wip/external-call-history

Conversation

@pierre-lehnen-rc
Copy link
Copy Markdown
Contributor

@pierre-lehnen-rc pierre-lehnen-rc commented May 22, 2026

Proposed changes (including videos or screenshots)

Issue(s)

DMV-7

Steps to test or reproduce

Further comments

Summary by CodeRabbit

  • New Features

    • External Mitel call-history import, parsing and secure digest-auth retrieval; configurable External Call History settings.
    • Server-backed call history search with pagination, sorting and service registration.
  • Improvements

    • Unified contact model (internal / external / unknown) and streamlined row/contextual UI.
    • Actions (voice call, widgets) shown only when a valid contact number exists.
  • Tests

    • Added unit tests for parsing, conversion, import flows and digest authentication helpers.

Review Change Stack

@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot Bot commented May 22, 2026

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

  • This PR is missing the 'stat: QA assured' label

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 22, 2026

⚠️ No Changeset found

Latest commit: 3bc71c7

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 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e18cc6cd-b6c8-42b6-b87d-0c9eb7f1e5ba

📥 Commits

Reviewing files that changed from the base of the PR and between f4a45c7 and 3bc71c7.

📒 Files selected for processing (1)
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
📜 Recent 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). (5)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: CodeQL-Build
  • GitHub Check: Hacktron Security Check
  • 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/server/services/call-history/mitel/importHistoryForUser.ts
🧠 Learnings (3)
📚 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/server/services/call-history/mitel/importHistoryForUser.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/server/services/call-history/mitel/importHistoryForUser.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/server/services/call-history/mitel/importHistoryForUser.ts
🔇 Additional comments (2)
apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts (2)

20-29: LGTM!


45-53: ⚡ Quick win

Handle rejection on the newPromise.then(resolve) chain

newPromise (from processFetchedHistory(user.uid, result)) is only attached via newPromise.then(resolve), while the surrounding .catch(...) covers the earlier promise in the chain—not newPromise. If processFetchedHistory can reject, this branch can leave the outer promise unsettled after promiseDecided is set.

🔧 Proposed fix
-				newPromise.then(resolve);
+				newPromise
+					.then(resolve)
+					.catch((err) => {
+						logger.error({ msg: 'Unexpected error on external call history processing', err });
+						resolve();
+					});

Walkthrough

This PR adds Mitel external call-history import/parsing and a CallHistoryService (search + optional import), integrates HTTP Digest auth into server-fetch, centralizes call-history contact types with type guards and UI component refactors, and wires new VoIP settings and API/service registration.

Changes

HTTP Digest Authentication

Layer / File(s) Summary
Digest auth type definitions and constants
packages/server-fetch/src/auth/parseDigestHeader.ts, packages/server-fetch/src/constants.ts, packages/server-fetch/src/types.ts
DigestAuthHeader type, digest header parsing, authRequiredStatus constant (401), and ExtendedFetchOptions auth shape.
Digest auth algorithms and response building
packages/server-fetch/src/auth/algorithms.ts, packages/server-fetch/src/auth/buildDigestResponse.ts
MD5 algorithm helper and getHashAlgorithm; buildDigestResponse computes HA1/HA2 and formats Digest Authorization headers.
Authenticated fetch with digest auth retry
packages/server-fetch/src/auth/fetchWithAuthentication.ts, packages/server-fetch/src/index.ts, packages/server-fetch/src/logger.ts
fetchWithAuthentication retries requests on Digest challenges; doFetch integrates retry into serverFetch; logger added for external requests.
Digest auth test fixtures and specs
packages/server-fetch/tests/test-data.ts, packages/server-fetch/tests/buildDigestResponse.spec.ts, packages/server-fetch/tests/fetchWithAuthentication.spec.ts, packages/server-fetch/tests/parseDigestHeader.spec.ts
Test fixtures and parameterized suites covering header parsing, response building, and retry behavior.

Mitel Call History Server Integration

Layer / File(s) Summary
Mitel types and parsing utilities
apps/meteor/server/services/call-history/mitel/definition.ts, apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts, apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts, apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts
MitelConfig/MitelCallItem types; timestamp normalization and parsing; duration parsing; JSON parsing with shape validation.
Mitel call item parsing and conversion
apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts, apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts
Parse raw Mitel fields into MitelCallItem, coerce booleans, parse date/duration; convert parsed items to IMitelCallHistoryItem insertion models with direction/state and transfer/divert handling.
Mitel fetch and import orchestration
apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts, apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts, apps/meteor/server/services/call-history/mitel/importHistoryItems.ts
Fetch Mitel history (uses serverFetch + digest auth), per-user import orchestration with optional timeout handling, and per-item import with logged error handling.
Mitel parsing and conversion tests & fixtures
apps/meteor/server/services/call-history/mitel/parse/test-data.ts, apps/meteor/server/services/call-history/mitel/parse/*.spec.ts
Test data fixtures and Jest specs covering timestamp, duration, JSON, item parsing, and conversion.
Call history logger setup
apps/meteor/server/services/call-history/logger.ts
Dedicated logger instance for call-history operations.

Call History Service and Database Layer

Layer / File(s) Summary
ICallHistoryService interface and core re-exports
packages/core-services/src/types/ICallHistoryService.ts, packages/core-services/src/index.ts
ICallHistoryService with search signature; CallHistory proxied service export added.
CallHistoryService implementation
apps/meteor/server/services/call-history/service.ts
Implements search(uid, filters, pagination) that may trigger Mitel import, selects query type (mitel vs media-call), and returns paginated items/total.
CallHistory model search and import methods
packages/model-typings/src/models/ICallHistoryModel.ts, packages/models/src/models/CallHistory.ts
findAllByUserIdAndSearchFilters for paginated search with regex across contact fields; importHistoryItem upsert for imported items.
Call history item typings including Mitel
packages/core-typings/src/ICallHistoryItem.ts
Adds IMitelCallHistoryItem and extends CallHistoryItem union.

Unified Call History Contact Model (UI)

Layer / File(s) Summary
Contact type definitions and type guards
packages/ui-voip/src/definitions/callHistoryContacts.ts, packages/ui-voip/src/definitions/index.ts, packages/ui-voip/src/index.ts
Centralized InternalCallHistoryContact, ExternalCallHistoryContact, UnknownCallHistoryContact union CallHistoryContact and type guards.
CallHistoryUser selector and subcomponents
packages/ui-voip/src/components/CallHistoryUser.tsx, packages/ui-voip/src/components/CallHistoryInternalUser.tsx, packages/ui-voip/src/components/CallHistoryExternalUser.tsx, packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
CallHistoryUser selects and renders internal/external/unknown contact components; subcomponents updated to accept unified contact shapes.
Table row and contextualbar refactors
packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx, packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx, packages/ui-voip/src/views/CallHistoryContextualbar/index.ts
CallHistoryTableRow generic updated to CallHistoryContact and uses CallHistoryUser; Contextualbar uses centralized contact types and CallHistoryUser.
Storybook update
packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
Story imports and helpers updated to new contact types.
External contact extraction logic
apps/meteor/client/views/mediaCallHistory/MediaCallHistoryExternal.tsx, apps/meteor/client/views/mediaCallHistory/CallHistoryPage.tsx, row components
getExternalContact helper added; CallHistoryPage uses getContact helper; row components updated to use new contact types and conditional action wiring when number is missing.

API and Settings Integration

Layer / File(s) Summary
Call history API endpoint
apps/meteor/app/api/server/v1/call-history.ts
Endpoint delegates search/pagination to CallHistoryService.search and forwards searchTerm/direction/inStates/pagination.
VoIP settings for external call history configuration
apps/meteor/ee/server/settings/voip.ts, packages/i18n/src/locales/en.i18n.json
New VoIP_TeamCollab_ExternalCallHistory settings section with enable flag, host/user/password/timeout and i18n keys.
Service registration and media-call filter
apps/meteor/server/services/startup.ts, apps/meteor/server/services/media-call/service.ts
Registers CallHistoryService at startup; media-call settings watcher excludes ExternalCallHistory settings.
Jest configuration for new tests
apps/meteor/jest.config.ts
Added server test glob for call-history specs.
Server-fetch package cleanup
packages/server-fetch/package.json
Removed unused @rocket.chat/models dependency.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • ggazzo
  • ricardogarim

@pierre-lehnen-rc pierre-lehnen-rc added this to the 8.6.0 milestone May 22, 2026
@pierre-lehnen-rc pierre-lehnen-rc force-pushed the wip/external-call-history branch from cd6fdf2 to 4645ef3 Compare May 22, 2026 18:36
@codecov
Copy link
Copy Markdown

codecov Bot commented May 22, 2026

Codecov Report

❌ Patch coverage is 89.21569% with 88 lines in your changes missing coverage. Please review.
✅ Project coverage is 69.76%. Comparing base (5c8efa7) to head (3bc71c7).
⚠️ Report is 55 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #40658      +/-   ##
===========================================
+ Coverage    69.65%   69.76%   +0.10%     
===========================================
  Files         3326     3358      +32     
  Lines       122681   124054    +1373     
  Branches     21869    22113     +244     
===========================================
+ Hits         85454    86541    +1087     
- Misses       33890    34145     +255     
- Partials      3337     3368      +31     
Flag Coverage Δ
e2e 59.17% <14.28%> (-0.04%) ⬇️
e2e-api 45.46% <7.79%> (-0.90%) ⬇️
unit 70.65% <99.03%> (+0.29%) ⬆️

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.

@pierre-lehnen-rc pierre-lehnen-rc marked this pull request as ready for review May 25, 2026 17:34
@pierre-lehnen-rc pierre-lehnen-rc requested review from a team as code owners May 25, 2026 17:34
@coderabbitai coderabbitai Bot added the type: feature Pull requests that introduces new feature label May 25, 2026
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

9 issues found across 60 files

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

Re-trigger cubic

Comment thread apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts Outdated
Comment thread packages/server-fetch/src/index.ts
Comment thread apps/meteor/server/services/call-history/service.ts
Comment thread packages/server-fetch/src/auth/algorithms.ts
Comment thread packages/server-fetch/src/auth/buildDigestResponse.ts
Comment thread packages/server-fetch/src/auth/fetchWithAuthentication.ts Outdated
Comment thread packages/server-fetch/src/auth/fetchWithAuthentication.ts
Comment thread packages/server-fetch/src/auth/parseDigestHeader.ts Outdated
Comment thread packages/ui-voip/src/components/CallHistoryInternalUser.tsx
@pierre-lehnen-rc pierre-lehnen-rc marked this pull request as draft May 25, 2026 17:47
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: 10

🧹 Nitpick comments (4)
apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts (1)

15-16: ⚡ Quick win

Remove implementation comments in this TS module.

Please remove the inline implementation comment to match repo TS/JS style rules.

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/server/services/call-history/mitel/fetchMitelHistory.ts` around
lines 15 - 16, Remove the inline implementation comment above the
ignoreSsrfValidation property so the module conforms to the TS/JS style rule of
avoiding implementation comments; in the fetchMitelHistory.ts snippet delete the
comment line "// URL can only be configured by users with enough privileges, so
it's fine to skip ssrf validation here" and leave the ignoreSsrfValidation: true
property unchanged.
apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts (1)

3-12: ⚡ Quick win

Remove implementation comments in this TS module.

This file adds several explanatory comments/docblocks in implementation code; repo guidelines ask to avoid code comments in TS/JS implementation.

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

Also applies to: 23-24, 33-34, 38-39

🤖 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/server/services/call-history/mitel/parse/parseMitelTimestamp.ts`
around lines 3 - 12, Remove the explanatory implementation comments/docblocks in
this TS module: delete the top-line commentary and the block explaining Mitel
timestamp format so only code remains; specifically remove the comment lines
around the const minValidLength and the docblock describing the
timestamp/timezone handling (references: minValidLength constant and the
parseMitelTimestamp module), leaving only the actual constant and function
implementation in the file.
apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts (1)

1-3: ⚡ Quick win

Remove implementation comments in this TS module.

Please drop the header comment block to align with repo TS/JS implementation guidelines.

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/server/services/call-history/mitel/parse/parseMitelDuration.ts`
around lines 1 - 3, Remove the top-of-file header comment in the
parseMitelDuration.ts module (the /** Mitel identifies the call duration... */
block); delete that implementation comment so the file contains only code and
any allowed doc/comments outside implementation, and verify there are no other
implementation comments remaining in functions like parseMitelDuration (or
exported helpers) to comply with the repo TS/JS "avoid code comments in the
implementation" guideline.
packages/ui-voip/src/definitions/callHistoryContacts.ts (1)

30-35: ⚡ Quick win

Make external/internal guards structural instead of fallback negation.

Line 31 requires a truthy _id; with _id: '', internal contacts are treated as external at Line 35. This weakens runtime narrowing and can route malformed internal data to the wrong renderer.

Proposed change
 export const isInternalCallHistoryContact = (contact: CallHistoryContact): contact is InternalCallHistoryContact => {
-	return '_id' in contact && Boolean(contact._id);
+	return '_id' in contact;
 };
 
 export const isExternalCallHistoryContact = (contact: CallHistoryContact): contact is ExternalCallHistoryContact => {
-	return !isUnknownCallHistoryContact(contact) && !isInternalCallHistoryContact(contact);
+	return !isUnknownCallHistoryContact(contact) && ('number' in contact || 'name' in contact);
 };
🤖 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 `@packages/ui-voip/src/definitions/callHistoryContacts.ts` around lines 30 -
35, The current type-guard uses Boolean(contact._id) which treats {_id: ''} as
not-internal and lets malformed internals fall through; update
isInternalCallHistoryContact to perform a structural check (e.g. '_id' in
contact && typeof contact._id === "string" or contact._id !== undefined) rather
than Boolean coercion, and replace isExternalCallHistoryContact's fallback
negation with an explicit structural guard that checks for the unique field(s)
of ExternalCallHistoryContact (use the actual property name(s) declared on
ExternalCallHistoryContact) so the runtime narrowing is deterministic and does
not rely on negating isUnknown/isInternal.
🤖 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/server/services/call-history/mitel/fetchMitelHistory.ts`:
- Line 7: The endpointUrl construction uses replaceAll('//','/') which corrupts
the protocol (e.g., turns "https://" into "https:/"); instead remove only
trailing slashes from config.host and then join with
"/callHistory/{directoryNumber}" (or use the URL constructor) so the protocol is
preserved. Locate the endpointUrl expression and replace the replaceAll-based
normalization with a safe join that trims trailing slashes from config.host
(reference variables: endpointUrl, config.host, directoryNumber) ensuring the
final URL has exactly one slash between host and path but keeps "https://"
intact.

In `@apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts`:
- Around line 9-11: The current numeric guard (checking typeof value ===
'number' && !Number.isNaN(value)) allows negative and non-finite numbers; update
the check in parseMitelDuration (the branch that returns value) to ensure the
numeric duration is finite and non-negative (e.g., use Number.isFinite(value) &&
value >= 0) and only return the value when that condition passes, otherwise fall
through to the existing fallback handling.

In `@apps/meteor/server/services/call-history/service.ts`:
- Around line 27-33: The external import can cause search() to reject and the
type variable is set incorrectly whenever any external config exists; change the
logic in the block that calls getExternalCallHistorySettings() so you compute a
boolean (e.g., hasFullExternalConfig) using externalHistoryConfig?.host &&
externalHistoryConfig?.username, only await importHistoryForUser(uid,
externalHistoryConfig) when that boolean is true and wrap that call in a
try/catch that logs the error (do not rethrow) to avoid failing list requests,
and set type = hasFullExternalConfig ? 'mitel' : 'media-call' so partial configs
don’t flip the type.

In `@packages/server-fetch/src/auth/algorithms.ts`:
- Line 10: Remove the commented-out registry entry "'SHA-256': SHA256," from the
algorithms registry in packages/server-fetch/src/auth/algorithms.ts so the
implementation contains no inline commented code; locate the registry object
(the algorithm map where other algorithm keys are defined) and delete that
commented line to comply with the project's "no implementation comments" rule.

In `@packages/server-fetch/src/auth/buildDigestResponse.ts`:
- Line 30: Remove the inline implementation comment "// We don't do multiple
auth attempts for the same request, so we don't need to keep track of cnonce
usage" from buildDigestResponse.ts; locate the buildDigestResponse function (or
the surrounding digest builder logic) and delete that comment line so the file
contains no implementation comments per the TS/JS guideline while leaving the
code and any necessary JSDoc or exported documentation unchanged.
- Around line 22-39: The code currently accepts any qop by falling back to
qops[0] and then computes an auth-style response even for non-auth qops; update
the logic in buildDigestResponse (look for qops, qop, and the
responseString/response computation) to explicitly require 'auth' — if qops does
not include 'auth' throw a clear error (e.g., "Unsupported qop") instead of
selecting another value; ensure later construction of responseString and use of
nc/cnonce remains conditional on qop === 'auth' so only the correct auth-style
digest is computed.

In `@packages/server-fetch/src/auth/fetchWithAuthentication.ts`:
- Around line 27-31: The digest URI is built using only url.pathname which omits
query parameters and breaks digest verification; update the calculation of uri
in fetchWithAuthentication.ts (the variable passed into buildDigestResponse) to
include the query string (e.g., combine url.pathname with url.search so queries
like ?a=1 are preserved) before calling buildDigestResponse({ uri, ... }),
ensuring the full request-target (path + query) is used for the digest.

In `@packages/server-fetch/src/auth/parseDigestHeader.ts`:
- Around line 11-13: The current check
authHeader?.toLowerCase().startsWith('digest') incorrectly accepts values like
"digestX"; replace it with an exact auth-scheme token match (e.g. use a regex
test like /^digest\b/i or /^digest\s+/i) to ensure the header begins with the
standalone "Digest" token before parameters; update the condition in
parseDigestHeader (the authHeader validation) to use that regex and keep
throwing Error('Unsupported Auth Schema') when it fails.

In `@packages/server-fetch/src/index.ts`:
- Line 185: Remove the inline implementation comment "// `@ts-expect-error` - This
complained when types were moved to file :/" from the request options block in
packages/server-fetch/src/index.ts; locate the request options / options object
(the variable or parameter used when building the request options) and delete
that comment so the implementation is comment-free, and if TypeScript now
errors, fix the underlying typing (adjust the type import or the options type)
rather than reintroducing an inline explanatory comment.

In
`@packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx`:
- Around line 83-86: The story narrows fixture contacts by casting getContact()
to InternalCallHistoryContact, hiding that getContact returns the broader
CallHistoryContact union; update the story to model the real union instead of
casting—replace the generic usage
CallHistoryTableRowProps<InternalCallHistoryContact> (or the specific variable
typing for results) with CallHistoryTableRowProps<CallHistoryContact> (or remove
the cast on contact and let the compiler infer the union), and ensure getContact
is referenced directly (getContact(index)) so the fixture accurately represents
InternalCallHistoryContact | UnknownCallHistoryContact.

---

Nitpick comments:
In `@apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts`:
- Around line 15-16: Remove the inline implementation comment above the
ignoreSsrfValidation property so the module conforms to the TS/JS style rule of
avoiding implementation comments; in the fetchMitelHistory.ts snippet delete the
comment line "// URL can only be configured by users with enough privileges, so
it's fine to skip ssrf validation here" and leave the ignoreSsrfValidation: true
property unchanged.

In `@apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts`:
- Around line 1-3: Remove the top-of-file header comment in the
parseMitelDuration.ts module (the /** Mitel identifies the call duration... */
block); delete that implementation comment so the file contains only code and
any allowed doc/comments outside implementation, and verify there are no other
implementation comments remaining in functions like parseMitelDuration (or
exported helpers) to comply with the repo TS/JS "avoid code comments in the
implementation" guideline.

In `@apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts`:
- Around line 3-12: Remove the explanatory implementation comments/docblocks in
this TS module: delete the top-line commentary and the block explaining Mitel
timestamp format so only code remains; specifically remove the comment lines
around the const minValidLength and the docblock describing the
timestamp/timezone handling (references: minValidLength constant and the
parseMitelTimestamp module), leaving only the actual constant and function
implementation in the file.

In `@packages/ui-voip/src/definitions/callHistoryContacts.ts`:
- Around line 30-35: The current type-guard uses Boolean(contact._id) which
treats {_id: ''} as not-internal and lets malformed internals fall through;
update isInternalCallHistoryContact to perform a structural check (e.g. '_id' in
contact && typeof contact._id === "string" or contact._id !== undefined) rather
than Boolean coercion, and replace isExternalCallHistoryContact's fallback
negation with an explicit structural guard that checks for the unique field(s)
of ExternalCallHistoryContact (use the actual property name(s) declared on
ExternalCallHistoryContact) so the runtime narrowing is deterministic and does
not rely on negating isUnknown/isInternal.
🪄 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: dfdcba20-931f-422a-b12e-dd0fcfa7a64e

📥 Commits

Reviewing files that changed from the base of the PR and between 9379af4 and b488e73.

⛔ Files ignored due to path filters (2)
  • packages/ui-voip/src/views/CallHistoryContextualbar/__snapshots__/CallHistoryContextualbar.spec.tsx.snap is excluded by !**/*.snap
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (58)
  • apps/meteor/app/api/server/v1/call-history.ts
  • apps/meteor/client/views/mediaCallHistory/CallHistoryPage.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowExternalUser.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowInternalUser.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowUnknownUser.tsx
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryExternal.tsx
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx
  • apps/meteor/ee/server/settings/voip.ts
  • apps/meteor/jest.config.ts
  • apps/meteor/server/services/call-history/logger.ts
  • apps/meteor/server/services/call-history/mitel/definition.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryItems.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts
  • apps/meteor/server/services/call-history/mitel/parse/test-data.ts
  • apps/meteor/server/services/call-history/service.ts
  • apps/meteor/server/services/media-call/service.ts
  • apps/meteor/server/services/startup.ts
  • packages/core-services/src/index.ts
  • packages/core-services/src/types/ICallHistoryService.ts
  • packages/core-typings/src/ICallHistoryItem.ts
  • packages/i18n/src/locales/en.i18n.json
  • packages/model-typings/src/models/ICallHistoryModel.ts
  • packages/models/src/models/CallHistory.ts
  • packages/server-fetch/package.json
  • packages/server-fetch/src/auth/algorithms.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/constants.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/src/logger.ts
  • packages/server-fetch/src/types.ts
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/ui-voip/src/components/CallHistoryExternalUser.tsx
  • packages/ui-voip/src/components/CallHistoryInternalUser.tsx
  • packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
  • packages/ui-voip/src/components/CallHistoryUser.tsx
  • packages/ui-voip/src/definitions/callHistoryContacts.ts
  • packages/ui-voip/src/definitions/index.ts
  • packages/ui-voip/src/index.ts
  • packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx
  • packages/ui-voip/src/views/CallHistoryContextualbar/index.ts
  • packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
💤 Files with no reviewable changes (1)
  • packages/server-fetch/package.json
📜 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). (4)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Hacktron Security Check
  • GitHub Check: 📦 Build Packages
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{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:

  • packages/server-fetch/src/constants.ts
  • packages/server-fetch/src/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowUnknownUser.tsx
  • packages/ui-voip/src/views/CallHistoryContextualbar/index.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/media-call/service.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/definition.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/startup.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/src/types.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • packages/server-fetch/src/auth/algorithms.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/core-services/src/types/ICallHistoryService.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • packages/ui-voip/src/index.ts
  • apps/meteor/ee/server/settings/voip.ts
  • apps/meteor/server/services/call-history/mitel/parse/test-data.ts
  • packages/ui-voip/src/components/CallHistoryInternalUser.tsx
  • packages/ui-voip/src/definitions/callHistoryContacts.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • packages/ui-voip/src/components/CallHistoryUser.tsx
  • apps/meteor/jest.config.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/ui-voip/src/components/CallHistoryExternalUser.tsx
  • packages/ui-voip/src/definitions/index.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryItems.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowExternalUser.tsx
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts
  • apps/meteor/server/services/call-history/service.ts
  • packages/models/src/models/CallHistory.ts
  • packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
  • packages/core-services/src/index.ts
  • packages/core-typings/src/ICallHistoryItem.ts
  • packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryPage.tsx
  • apps/meteor/app/api/server/v1/call-history.ts
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryExternal.tsx
  • packages/model-typings/src/models/ICallHistoryModel.ts
  • packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowInternalUser.tsx
**/*.spec.ts

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

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
🧠 Learnings (11)
📚 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:

  • packages/server-fetch/src/constants.ts
  • packages/server-fetch/src/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/ui-voip/src/views/CallHistoryContextualbar/index.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/media-call/service.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/definition.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/startup.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/src/types.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • packages/server-fetch/src/auth/algorithms.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/core-services/src/types/ICallHistoryService.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • packages/ui-voip/src/index.ts
  • apps/meteor/ee/server/settings/voip.ts
  • apps/meteor/server/services/call-history/mitel/parse/test-data.ts
  • packages/ui-voip/src/definitions/callHistoryContacts.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/jest.config.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/ui-voip/src/definitions/index.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryItems.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts
  • apps/meteor/server/services/call-history/service.ts
  • packages/models/src/models/CallHistory.ts
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
  • packages/core-services/src/index.ts
  • packages/core-typings/src/ICallHistoryItem.ts
  • apps/meteor/app/api/server/v1/call-history.ts
  • packages/model-typings/src/models/ICallHistoryModel.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:

  • packages/server-fetch/src/constants.ts
  • packages/server-fetch/src/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/ui-voip/src/views/CallHistoryContextualbar/index.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/media-call/service.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/definition.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/startup.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/src/types.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • packages/server-fetch/src/auth/algorithms.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/core-services/src/types/ICallHistoryService.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • packages/ui-voip/src/index.ts
  • apps/meteor/ee/server/settings/voip.ts
  • apps/meteor/server/services/call-history/mitel/parse/test-data.ts
  • packages/ui-voip/src/definitions/callHistoryContacts.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/jest.config.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/ui-voip/src/definitions/index.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryItems.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts
  • apps/meteor/server/services/call-history/service.ts
  • packages/models/src/models/CallHistory.ts
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
  • packages/core-services/src/index.ts
  • packages/core-typings/src/ICallHistoryItem.ts
  • apps/meteor/app/api/server/v1/call-history.ts
  • packages/model-typings/src/models/ICallHistoryModel.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:

  • packages/server-fetch/src/constants.ts
  • packages/server-fetch/src/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowUnknownUser.tsx
  • packages/ui-voip/src/views/CallHistoryContextualbar/index.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/media-call/service.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/definition.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/startup.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/src/types.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • packages/server-fetch/src/auth/algorithms.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/core-services/src/types/ICallHistoryService.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • packages/ui-voip/src/index.ts
  • apps/meteor/ee/server/settings/voip.ts
  • apps/meteor/server/services/call-history/mitel/parse/test-data.ts
  • packages/ui-voip/src/components/CallHistoryInternalUser.tsx
  • packages/ui-voip/src/definitions/callHistoryContacts.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • packages/ui-voip/src/components/CallHistoryUser.tsx
  • apps/meteor/jest.config.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/ui-voip/src/components/CallHistoryExternalUser.tsx
  • packages/ui-voip/src/definitions/index.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryItems.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/logger.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowExternalUser.tsx
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts
  • apps/meteor/server/services/call-history/service.ts
  • packages/models/src/models/CallHistory.ts
  • packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
  • packages/core-services/src/index.ts
  • packages/core-typings/src/ICallHistoryItem.ts
  • packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryPage.tsx
  • apps/meteor/app/api/server/v1/call-history.ts
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryExternal.tsx
  • packages/model-typings/src/models/ICallHistoryModel.ts
  • packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowInternalUser.tsx
📚 Learning: 2026-02-24T19:22:48.358Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts:66-67
Timestamp: 2026-02-24T19:22:48.358Z
Learning: In Playwright end-to-end tests (e.g., under apps/meteor/tests/e2e/...), prefer locating elements by translated text (getByText) and ARIA roles (getByRole) over data-qa attributes. If translation values change, update the corresponding test locators accordingly. Never use data-qa locators. This guideline applies to all Playwright e2e test specs in the repository and helps keep tests robust to UI text changes and accessible semantics.

Applied to files:

  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.

Applied to files:

  • apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts
  • packages/server-fetch/tests/parseDigestHeader.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts
  • packages/server-fetch/tests/buildDigestResponse.spec.ts
📚 Learning: 2026-02-26T19:22:29.385Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 38778
File: packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryActions.tsx:40-40
Timestamp: 2026-02-26T19:22:29.385Z
Learning: For TSX files in the UI VOIP package, ensure that when a media session state is 'unavailable', the voiceCall action is excluded from the actions object passed to CallHistoryActions so it does not render in the menu. This filtering should occur upstream (before getItems is called) to avoid tooltips or UI hints for unavailable actions. If there are multiple actions with availability states, implement a centralized helper to filter actions based on session state.

Applied to files:

  • packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
  • packages/ui-voip/src/components/CallHistoryInternalUser.tsx
  • packages/ui-voip/src/components/CallHistoryUser.tsx
  • packages/ui-voip/src/components/CallHistoryExternalUser.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
  • packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx
📚 Learning: 2026-05-05T12:34:29.042Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 40331
File: packages/ui-voip/src/views/MediaCallWidget/OngoingCallWithScreen.tsx:69-69
Timestamp: 2026-05-05T12:34:29.042Z
Learning: In Rocket.Chat’s `packages/ui-voip` UI (e.g., media/call widgets), voice/media calls are only supported in Direct Message (DM) rooms. Rocket.Chat models a DM as a “room” with exactly two participants, so handlers like `onClickDirectMessage` are the correct destination—even when the UI text/element says “Open in room” (e.g., on the shared screen card/`StreamCard`). During review, don’t flag a “DM vs room” mismatch for these cases; they intentionally map to the same destination.

Applied to files:

  • packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
  • packages/ui-voip/src/components/CallHistoryInternalUser.tsx
  • packages/ui-voip/src/components/CallHistoryUser.tsx
  • packages/ui-voip/src/components/CallHistoryExternalUser.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
  • packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx
📚 Learning: 2026-03-27T14:52:56.865Z
Learnt from: dougfabris
Repo: RocketChat/Rocket.Chat PR: 39892
File: apps/meteor/client/views/room/contextualBar/Threads/Thread.tsx:150-155
Timestamp: 2026-03-27T14:52:56.865Z
Learning: In Rocket.Chat, there are two different `ModalBackdrop` components with different prop APIs. During review, confirm the import source: (1) `rocket.chat/fuselage` `ModalBackdrop` uses `ModalBackdropProps` based on `BoxProps` (so it supports `onClick` and other Box/DOM props) and does not have an `onDismiss` prop; (2) `rocket.chat/ui-client` `ModalBackdrop` uses a narrower props interface like `{ children?: ReactNode; onDismiss?: () => void }` and handles Escape keypress and outside mouse-up, and it does not forward arbitrary DOM props such as `onClick`. Flag mismatched props (e.g., `onDismiss` passed to the fuselage component or `onClick` passed to the ui-client component) and ensure the usage matches the correct component being imported.

Applied to files:

  • packages/ui-voip/src/components/CallHistoryUnknownUser.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowUnknownUser.tsx
  • packages/ui-voip/src/components/CallHistoryInternalUser.tsx
  • packages/ui-voip/src/components/CallHistoryUser.tsx
  • packages/ui-voip/src/components/CallHistoryExternalUser.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowExternalUser.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx
  • packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryPage.tsx
  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryExternal.tsx
  • packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx
  • apps/meteor/client/views/mediaCallHistory/CallHistoryRowInternalUser.tsx
📚 Learning: 2025-12-18T15:18:23.819Z
Learnt from: gabriellsh
Repo: RocketChat/Rocket.Chat PR: 37773
File: apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx:24-34
Timestamp: 2025-12-18T15:18:23.819Z
Learning: In apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx, the claim is that internal call history items always have contactId equal to either caller.id or callee.id, so getContact will not produce undefined. Treat this as a file-specific guarantee and avoid adding guards that rely on other data sources in this path. If this invariant holds, you can rely on contact resolution not returning undefined, but consider adding a lightweight runtime assertion or a failing guard when the invariant is violated (e.g., throw or log) to surface unexpected data instead of silently handling undefined. This guideline applies only to this file path and should not be assumed project-wide without verification.

Applied to files:

  • apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx
📚 Learning: 2026-02-23T17:53:06.802Z
Learnt from: ggazzo
Repo: RocketChat/Rocket.Chat PR: 35995
File: apps/meteor/app/api/server/v1/rooms.ts:1107-1112
Timestamp: 2026-02-23T17:53:06.802Z
Learning: During PR reviews that touch endpoint files under apps/meteor/app/api/server/v1, enforce strict scope: if a PR targets a specific endpoint (e.g., rooms.favorite), do not propose changes to unrelated endpoints (e.g., rooms.invite) unless maintainers explicitly request them. Focus feedback on the touched endpoint's behavior, API surface, and related tests; avoid broad cross-endpoint changes in the same PR unless requested.

Applied to files:

  • apps/meteor/app/api/server/v1/call-history.ts
📚 Learning: 2026-02-24T19:09:01.522Z
Learnt from: ahmed-n-abdeltwab
Repo: RocketChat/Rocket.Chat PR: 38974
File: apps/meteor/app/api/server/v1/im.ts:220-221
Timestamp: 2026-02-24T19:09:01.522Z
Learning: In Rocket.Chat OpenAPI migration PRs for endpoints under apps/meteor/app/api/server/v1, avoid introducing logic changes. Only perform scope-tight changes that preserve behavior; style-only cleanups (e.g., removing inline comments) may be deferred to follow-ups to keep the migration PR focused.

Applied to files:

  • apps/meteor/app/api/server/v1/call-history.ts
🧬 Code graph analysis (38)
packages/server-fetch/src/logger.ts (1)
apps/meteor/server/services/call-history/logger.ts (1)
  • logger (3-3)
apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.spec.ts (1)
apps/meteor/server/services/call-history/mitel/parse/test-data.ts (2)
  • validCalls (13-293)
  • invalidCalls (295-354)
apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.spec.ts (2)
apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts (1)
  • parseMitelCallItem (34-47)
apps/meteor/server/services/call-history/mitel/parse/test-data.ts (1)
  • calls (356-356)
apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts (3)
apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts (1)
  • parseMitelCallItem (34-47)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelCallItem (8-23)
apps/meteor/server/services/call-history/logger.ts (1)
  • logger (3-3)
packages/server-fetch/tests/fetchWithAuthentication.spec.ts (2)
packages/server-fetch/src/auth/fetchWithAuthentication.ts (1)
  • fetchWithAuthentication (7-44)
packages/server-fetch/src/auth/buildDigestResponse.ts (1)
  • buildDigestResponse (7-64)
packages/server-fetch/src/auth/buildDigestResponse.ts (3)
packages/server-fetch/src/auth/parseDigestHeader.ts (1)
  • parseDigestHeader (10-36)
packages/server-fetch/src/logger.ts (1)
  • logger (3-3)
packages/server-fetch/src/auth/algorithms.ts (1)
  • getHashAlgorithm (13-15)
apps/meteor/server/services/startup.ts (1)
apps/meteor/server/services/call-history/service.ts (1)
  • CallHistoryService (9-63)
apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.spec.ts (1)
apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts (1)
  • parseMitelDuration (4-24)
packages/server-fetch/src/auth/fetchWithAuthentication.ts (3)
packages/server-fetch/src/auth/buildDigestResponse.ts (1)
  • buildDigestResponse (7-64)
packages/server-fetch/src/logger.ts (1)
  • logger (3-3)
packages/server-fetch/src/types.ts (1)
  • ExtendedFetchOptions (31-31)
packages/server-fetch/tests/parseDigestHeader.spec.ts (2)
packages/server-fetch/src/auth/parseDigestHeader.ts (1)
  • parseDigestHeader (10-36)
packages/server-fetch/tests/test-data.ts (3)
  • validHeaders (1-65)
  • unsupportedHeaders (67-94)
  • invalidHeaders (96-104)
packages/core-services/src/types/ICallHistoryService.ts (1)
packages/core-services/src/index.ts (1)
  • ICallHistoryService (147-147)
apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts (3)
apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts (1)
  • parseMitelJSON (9-25)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelConfig (1-6)
apps/meteor/server/services/call-history/logger.ts (1)
  • logger (3-3)
apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.spec.ts (1)
apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts (2)
  • fixMitelTimestamp (13-20)
  • parseMitelTimestamp (42-60)
apps/meteor/server/services/call-history/mitel/parse/test-data.ts (2)
packages/core-typings/src/ICallHistoryItem.ts (1)
  • IMitelCallHistoryItem (53-72)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelCallItem (8-23)
packages/ui-voip/src/components/CallHistoryInternalUser.tsx (1)
packages/ui-voip/src/definitions/callHistoryContacts.ts (1)
  • InternalCallHistoryContact (11-18)
apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts (2)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelConfig (1-6)
apps/meteor/server/services/call-history/logger.ts (1)
  • logger (3-3)
packages/ui-voip/src/components/CallHistoryUser.tsx (4)
packages/ui-voip/src/definitions/callHistoryContacts.ts (3)
  • CallHistoryContact (24-24)
  • isInternalCallHistoryContact (30-32)
  • isExternalCallHistoryContact (34-36)
packages/ui-voip/src/components/CallHistoryExternalUser.tsx (2)
  • CallHistoryExternalUser (10-29)
  • CallHistoryExternalUserProps (5-8)
packages/ui-voip/src/components/CallHistoryInternalUser.tsx (2)
  • CallHistoryInternalUser (12-34)
  • CallHistoryInternalUserProps (8-10)
packages/ui-voip/src/components/CallHistoryUnknownUser.tsx (1)
  • CallHistoryUnknownUser (4-14)
apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.spec.ts (1)
apps/meteor/server/services/call-history/mitel/parse/parseMitelJSON.ts (1)
  • parseMitelJSON (9-25)
apps/meteor/server/services/call-history/mitel/parse/convertMitelHistoryItem.ts (2)
packages/core-typings/src/ICallHistoryItem.ts (1)
  • IMitelCallHistoryItem (53-72)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelCallItem (8-23)
packages/ui-voip/src/components/CallHistoryExternalUser.tsx (1)
packages/ui-voip/src/definitions/callHistoryContacts.ts (1)
  • ExternalCallHistoryContact (1-9)
apps/meteor/server/services/call-history/mitel/importHistoryItems.ts (3)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelCallItem (8-23)
apps/meteor/server/services/call-history/logger.ts (1)
  • logger (3-3)
packages/core-services/src/index.ts (1)
  • CallHistory (183-183)
packages/server-fetch/src/index.ts (2)
packages/server-fetch/src/auth/fetchWithAuthentication.ts (1)
  • fetchWithAuthentication (7-44)
packages/server-fetch/src/constants.ts (1)
  • authRequiredStatus (47-47)
apps/meteor/server/services/call-history/logger.ts (1)
packages/server-fetch/src/logger.ts (1)
  • logger (3-3)
apps/meteor/server/services/call-history/mitel/parse/parseMitelCallItem.ts (3)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelCallItem (8-23)
apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts (1)
  • parseMitelTimestamp (42-60)
apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts (1)
  • parseMitelDuration (4-24)
apps/meteor/server/services/call-history/mitel/parse/parseMitelTimestamp.ts (1)
apps/meteor/server/services/call-history/logger.ts (1)
  • logger (3-3)
apps/meteor/server/services/call-history/service.ts (5)
apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts (1)
  • importHistoryForUser (69-76)
apps/meteor/server/services/call-history/mitel/definition.ts (1)
  • MitelConfig (1-6)
packages/core-typings/src/ICallHistoryItem.ts (1)
  • CallHistoryItem (74-74)
packages/core-services/src/index.ts (1)
  • CallHistory (183-183)
packages/core-services/src/types/ICallHistoryService.ts (1)
  • ICallHistoryService (3-17)
packages/models/src/models/CallHistory.ts (1)
packages/core-typings/src/ICallHistoryItem.ts (1)
  • CallHistoryItem (74-74)
packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx (2)
packages/ui-voip/src/definitions/callHistoryContacts.ts (4)
  • CallHistoryContact (24-24)
  • InternalCallHistoryContact (11-18)
  • ExternalCallHistoryContact (1-9)
  • UnknownCallHistoryContact (20-22)
packages/ui-voip/src/components/CallHistoryUser.tsx (2)
  • CallHistoryUser (10-20)
  • CallHistoryUserProps (6-8)
packages/server-fetch/tests/buildDigestResponse.spec.ts (2)
packages/server-fetch/src/auth/buildDigestResponse.ts (1)
  • buildDigestResponse (7-64)
packages/server-fetch/tests/test-data.ts (3)
  • unsupportedHeaders (67-94)
  • validHeaders (1-65)
  • invalidHeaders (96-104)
packages/core-services/src/index.ts (2)
packages/core-services/src/lib/proxify.ts (1)
  • proxify (20-22)
packages/core-services/src/types/ICallHistoryService.ts (1)
  • ICallHistoryService (3-17)
packages/ui-voip/src/views/MediaCallHistoryTable/MediaCallHistoryTable.stories.tsx (2)
packages/ui-voip/src/definitions/callHistoryContacts.ts (2)
  • CallHistoryContact (24-24)
  • InternalCallHistoryContact (11-18)
packages/ui-voip/src/views/MediaCallHistoryTable/CallHistoryTableRow.tsx (1)
  • CallHistoryTableRowProps (17-30)
apps/meteor/client/views/mediaCallHistory/MediaCallHistoryInternal.tsx (1)
apps/meteor/client/views/mediaCallHistory/useMediaCallInternalHistoryActions.ts (1)
  • InternalCallHistoryContact (7-14)
apps/meteor/client/views/mediaCallHistory/CallHistoryPage.tsx (1)
packages/ui-voip/src/definitions/callHistoryContacts.ts (3)
  • CallHistoryContact (24-24)
  • isUnknownCallHistoryContact (26-28)
  • isInternalCallHistoryContact (30-32)
apps/meteor/app/api/server/v1/call-history.ts (1)
apps/meteor/server/services/call-history/service.ts (1)
  • CallHistoryService (9-63)
apps/meteor/client/views/mediaCallHistory/MediaCallHistoryExternal.tsx (1)
packages/ui-voip/src/definitions/callHistoryContacts.ts (2)
  • ExternalCallHistoryContact (1-9)
  • UnknownCallHistoryContact (20-22)
packages/model-typings/src/models/ICallHistoryModel.ts (2)
packages/core-typings/src/ICallHistoryItem.ts (1)
  • CallHistoryItem (74-74)
packages/model-typings/src/models/IBaseModel.ts (2)
  • InsertionModel (35-37)
  • FindPaginated (39-42)
packages/ui-voip/src/views/CallHistoryContextualbar/CallHistoryContextualbar.tsx (2)
packages/ui-voip/src/definitions/callHistoryContacts.ts (1)
  • CallHistoryContact (24-24)
packages/ui-voip/src/components/CallHistoryUser.tsx (2)
  • CallHistoryUser (10-20)
  • CallHistoryUserProps (6-8)
apps/meteor/client/views/mediaCallHistory/CallHistoryRowInternalUser.tsx (1)
apps/meteor/client/views/mediaCallHistory/useMediaCallInternalHistoryActions.ts (1)
  • InternalCallHistoryContact (7-14)
🪛 ast-grep (0.42.3)
packages/server-fetch/src/auth/parseDigestHeader.ts

[warning] 38-38: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(${name}="([^"]+)")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

Comment thread apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts Outdated
Comment thread apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts Outdated
Comment thread apps/meteor/server/services/call-history/service.ts
Comment thread packages/server-fetch/src/auth/algorithms.ts Outdated
Comment thread packages/server-fetch/src/auth/buildDigestResponse.ts
Comment thread packages/server-fetch/src/auth/buildDigestResponse.ts
Comment thread packages/server-fetch/src/auth/fetchWithAuthentication.ts Outdated
Comment thread packages/server-fetch/src/auth/parseDigestHeader.ts Outdated
Comment thread packages/server-fetch/src/index.ts
Comment thread apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts Outdated
@hacktron-app
Copy link
Copy Markdown

hacktron-app Bot commented May 25, 2026

🔴 High: Unverified Email Auto-Verification in OAuth Merge

In the addHookToProcessUser method of CustomOAuth, when mergeUsers is enabled and keyField is set to username, the system automatically marks the email address provided by the OAuth identity as verified (verified: true). This logic bypasses the standard email verification workflow, allowing an attacker who can influence the OAuth identity (e.g., via a compromised or malicious OAuth provider, or by registering an account on a trusted provider with a victim's email) to mark an arbitrary email as verified on a user account without out-of-band confirmation. This can lead to account takeover or bypass of security controls that rely on verified email status. Additionally, this operation replaces the entire emails array, potentially removing existing verified emails from the user's account.

Trace
graph TD
    subgraph SG0 ["./Rocket.Chat/apps/meteor/app/custom-oauth/server/custom_oauth_server.js"]
        ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js{{"Defines the CustomOAuth class for handling external OAuth authentication providers."}}
    end
    style SG0 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG1 ["./Rocket.Chat/apps/meteor/app/dolphin/server/lib.ts"]
        ._Rocket.Chat_apps_meteor_app_dolphin_server_lib.ts["Initializes the Dolphin OAuth configuration and registers callbacks."]
    end
    style SG1 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG2 ["./Rocket.Chat/apps/meteor/app/drupal/server/lib.ts"]
        ._Rocket.Chat_apps_meteor_app_drupal_server_lib.ts["Initializes the Drupal OAuth configuration."]
    end
    style SG2 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG3 ["./Rocket.Chat/apps/meteor/app/gitlab/server/lib.ts"]
        ._Rocket.Chat_apps_meteor_app_gitlab_server_lib.ts["Defines the GitLab OAuth configuration and client."]
    end
    style SG3 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG4 ["./Rocket.Chat/apps/meteor/app/message-mark-as-unread/server/logger.ts"]
        ._Rocket.Chat_apps_meteor_app_message-mark-as-unread_server_logger.ts["Initializes and exports a logger instance for the MessageMarkAsUnread module."]
    end
    style SG4 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG5 ["./Rocket.Chat/apps/meteor/app/nextcloud/server/lib.ts"]
        ._Rocket.Chat_apps_meteor_app_nextcloud_server_lib.ts["Module-level setup for Nextcloud OAuth integration."]
    end
    style SG5 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG6 ["./Rocket.Chat/apps/meteor/app/wordpress/server/lib.ts"]
        ._Rocket.Chat_apps_meteor_app_wordpress_server_lib.ts["Initializes WordPress OAuth configuration and sets up settings watchers."]
    end
    style SG6 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG7 ["./Rocket.Chat/apps/meteor/server/lib/oauth/updateOAuthServices.ts"]
        updateOAuthServices["Updates OAuth service configurations based on application settings."]
    end
    style SG7 fill:#2a2a2a,stroke:#444,color:#aaa
    ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js --> ._Rocket.Chat_apps_meteor_app_message-mark-as-unread_server_logger.ts
    ._Rocket.Chat_apps_meteor_app_message-mark-as-unread_server_logger.ts --> ._Rocket.Chat_apps_meteor_app_message-mark-as-unread_server_logger.ts
    updateOAuthServices --> ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js
    ._Rocket.Chat_apps_meteor_app_nextcloud_server_lib.ts --> ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js
    ._Rocket.Chat_apps_meteor_app_wordpress_server_lib.ts --> ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js
    ._Rocket.Chat_apps_meteor_app_dolphin_server_lib.ts --> ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js
    ._Rocket.Chat_apps_meteor_app_drupal_server_lib.ts --> ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js
    ._Rocket.Chat_apps_meteor_app_gitlab_server_lib.ts --> ._Rocket.Chat_apps_meteor_app_custom-oauth_server_custom_oauth_server.js
Loading
Fix with AI

Open in Cursor Open in Claude

Fix the following security vulnerability found by Hacktron.

File: apps/meteor/server/lib/oauth/updateOAuthServices.ts
Severity: high

Vulnerability: Unverified Email Auto-Verification in OAuth Merge

Description:
In the `addHookToProcessUser` method of `CustomOAuth`, when `mergeUsers` is enabled and `keyField` is set to `username`, the system automatically marks the email address provided by the OAuth identity as verified (`verified: true`). This logic bypasses the standard email verification workflow, allowing an attacker who can influence the OAuth identity (e.g., via a compromised or malicious OAuth provider, or by registering an account on a trusted provider with a victim's email) to mark an arbitrary email as verified on a user account without out-of-band confirmation. This can lead to account takeover or bypass of security controls that rely on verified email status. Additionally, this operation replaces the entire `emails` array, potentially removing existing verified emails from the user's account.

Affected Code:
if (this.keyField === 'username' && serviceData.email) {
						updater.set('emails', [{ address: serviceData.email, verified: true }]);
					}

Fix this vulnerability. Only change what's necessary - don't modify unrelated code.

Triage: Reply !fp <reason> (false positive), !valid (confirmed), or !accepted_risk <reason>. Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing. Any other reply is saved as a triage note.

View finding in Hacktron

@hacktron-app
Copy link
Copy Markdown

hacktron-app Bot commented May 25, 2026

🟡 Medium: Resource Exhaustion via Image Processing (Pixel Bomb)

The avatarsOnValidate and uploadsOnValidate methods in FileUpload.ts process user-uploaded images using the sharp library. While the application validates the file size against FileUpload_MaxFileSize, it does not validate the image's pixel dimensions or complexity before passing it to sharp. An attacker can upload a highly compressed image (a "pixel bomb") with a small file size but massive pixel dimensions. When sharp attempts to extract metadata or resize the image, it decompresses the image into memory, leading to excessive CPU and memory consumption. This can result in a Denial of Service (DoS) by exhausting server resources or triggering an Out-Of-Memory (OOM) crash.

Steps to Reproduce
  1. Create a highly compressed PNG image with large dimensions (e.g., 16383x16383 pixels) that is well under the FileUpload_MaxFileSize limit.
  2. Authenticate to the Rocket.Chat instance as a regular user.
  3. Upload the image as an avatar or as a file in a chat room.
  4. Observe the server's memory and CPU usage spike as sharp processes the image. Multiple concurrent uploads can quickly exhaust memory and crash the server.
Trace
graph TD
    subgraph SG0 ["./Rocket.Chat/apps/meteor/app/file-upload/server/config/AmazonS3.ts"]
        ._Rocket.Chat_apps_meteor_app_file-upload_server_config_AmazonS3.ts["Configures Amazon S3 storage stores for uploads, avatars, and user data."]
    end
    style SG0 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG1 ["./Rocket.Chat/apps/meteor/app/file-upload/server/config/FileSystem.ts"]
        ._Rocket.Chat_apps_meteor_app_file-upload_server_config_FileSystem.ts["Configures local file system storage stores for uploads, avatars, and user data."]
    end
    style SG1 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG2 ["./Rocket.Chat/apps/meteor/app/file-upload/server/config/GoogleStorage.ts"]
        ._Rocket.Chat_apps_meteor_app_file-upload_server_config_GoogleStorage.ts["Configures Google Cloud Storage stores for uploads, avatars, and user data."]
    end
    style SG2 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG3 ["./Rocket.Chat/apps/meteor/app/file-upload/server/config/GridFS.ts"]
        ._Rocket.Chat_apps_meteor_app_file-upload_server_config_GridFS.ts["Configures GridFS storage stores and defines file retrieval/copy logic."]
    end
    style SG3 fill:#2a2a2a,stroke:#444,color:#aaa
    subgraph SG4 ["./Rocket.Chat/apps/meteor/app/file-upload/server/lib/FileUpload.ts"]
        ._Rocket.Chat_apps_meteor_app_file-upload_server_lib_FileUpload.ts{{"Initializes file upload settings, handlers, and default configurations."}}
    end
    style SG4 fill:#2a2a2a,stroke:#444,color:#aaa
    ._Rocket.Chat_apps_meteor_app_file-upload_server_config_AmazonS3.ts --> ._Rocket.Chat_apps_meteor_app_file-upload_server_lib_FileUpload.ts
    ._Rocket.Chat_apps_meteor_app_file-upload_server_config_FileSystem.ts --> ._Rocket.Chat_apps_meteor_app_file-upload_server_lib_FileUpload.ts
    ._Rocket.Chat_apps_meteor_app_file-upload_server_config_GoogleStorage.ts --> ._Rocket.Chat_apps_meteor_app_file-upload_server_lib_FileUpload.ts
    ._Rocket.Chat_apps_meteor_app_file-upload_server_config_GridFS.ts --> ._Rocket.Chat_apps_meteor_app_file-upload_server_lib_FileUpload.ts
Loading
Fix with AI

Open in Cursor Open in Claude

Fix the following security vulnerability found by Hacktron.

File: apps/meteor/app/file-upload/server/lib/FileUpload.ts
Severity: medium

Vulnerability: Resource Exhaustion via Image Processing (Pixel Bomb)

Description:
The `avatarsOnValidate` and `uploadsOnValidate` methods in `FileUpload.ts` process user-uploaded images using the `sharp` library. While the application validates the file size against `FileUpload_MaxFileSize`, it does not validate the image's pixel dimensions or complexity before passing it to `sharp`. An attacker can upload a highly compressed image (a "pixel bomb") with a small file size but massive pixel dimensions. When `sharp` attempts to extract metadata or resize the image, it decompresses the image into memory, leading to excessive CPU and memory consumption. This can result in a Denial of Service (DoS) by exhausting server resources or triggering an Out-Of-Memory (OOM) crash.

Proof of Concept:
**Steps to Reproduce**

1. Create a highly compressed PNG image with large dimensions (e.g., 16383x16383 pixels) that is well under the `FileUpload_MaxFileSize` limit.
2. Authenticate to the Rocket.Chat instance as a regular user.
3. Upload the image as an avatar or as a file in a chat room.
4. Observe the server's memory and CPU usage spike as `sharp` processes the image. Multiple concurrent uploads can quickly exhaust memory and crash the server.

Affected Code:
const s = sharp(tempFilePath);
const metadata = await s.metadata();

Fix this vulnerability. Only change what's necessary - don't modify unrelated code.

Triage: Reply !fp <reason> (false positive), !valid (confirmed), or !accepted_risk <reason>. Reason is optional but improves future scans — e.g. !fp internal endpoint, not user-facing. Any other reply is saved as a triage note.

View finding in Hacktron

Copy link
Copy Markdown

@hacktron-app hacktron-app Bot left a comment

Choose a reason for hiding this comment

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

12 issues found across 9 files

Severity Count
🔴 High 7
🟡 Medium 5
Comments Outside Diff (9)

🔴 High: Predictable Federation Authentication Tokens via Public uniqueID

Location: apps/meteor/server/services/federation/Settings.ts:39

The Matrix federation authentication tokens (homeserverToken and applicationServiceToken) are generated using a deterministic SHA-256 hash of the instance's uniqueID. The uniqueID is registered as a public setting (public: true) in createMiscSettings and is accessible to unauthenticated users via the /api/v1/settings.public endpoint. An attacker can obtain the uniqueID and compute the exact tokens used for federation authentication, allowing them to impersonate the homeserver or application service and bypass authentication controls on the federation bridge.

Steps to Reproduce

  1. Send an unauthenticated GET request to the public settings endpoint to retrieve the uniqueID:
    curl -s "http://localhost:3000/api/v1/settings.public?query={\"_id\":\"uniqueID\"}"
  2. Extract the value of the uniqueID from the response.
  3. Compute the homeserverToken by calculating the SHA-256 hash of the string hs_<uniqueID>.
  4. Compute the applicationServiceToken by calculating the SHA-256 hash of the string as_<uniqueID>.
  5. Use the predicted tokens to authenticate against the Matrix federation bridge endpoints.

🔴 High: Insecure Account Linking via OAuth Provider Email Trust

Location: apps/meteor/server/configuration/accounts_meld.js:21-24

The configureAccounts function in accounts_meld.js automatically links OAuth accounts to existing internal user accounts based on the email address provided by the OAuth provider. However, it does not verify that the email address is actually verified by the provider for most supported services (e.g., LinkedIn, GitHub, etc.), except for meteor-developer. If an attacker registers an account on an external OAuth provider using a victim's email address, they can use that OAuth account to log into Rocket.Chat. Rocket.Chat will automatically link the attacker-controlled OAuth account to the victim's existing account, granting the attacker unauthorized access.

Steps to Reproduce

  1. Identify a target user's email address on the Rocket.Chat instance.
  2. Register an account on an enabled OAuth provider (e.g., LinkedIn) using the target's email address.
  3. If the provider allows OAuth login without verifying the email, or if the provider's API returns the unverified email, use it to log into Rocket.Chat.
  4. Rocket.Chat's configureAccounts hook will intercept the login, search for an existing user with that email, and link the OAuth service ID to the victim's account.
  5. The attacker is now logged into the victim's account without needing their password.

🔴 High: IDOR in users.createToken allows unauthorized token generation

Location: apps/meteor/app/api/server/v1/users.ts:584-594

The users.createToken API endpoint is vulnerable to an Insecure Direct Object Reference (IDOR) attack. The endpoint allows any authenticated user to generate an access token for any other user in the system by providing their userId in the request body. The implementation lacks any authorization checks (such as verifying if the caller has permission to manage the target user's tokens), allowing an attacker to generate tokens for arbitrary users.

Steps to Reproduce

  1. Authenticate as a standard user to obtain an X-Auth-Token and X-User-Id.
  2. Identify the userId of a target user (e.g., an administrator or another user).
  3. Send a POST request to /api/v1/users.createToken with the target userId and a chosen secret in the request body.
  4. The API will return an access token for the target user, confirming the unauthorized access.
curl -X POST -H "X-Auth-Token: <your_token>" -H "X-User-Id: <your_userId>" -H "Content-Type: application/json" -d '{"userId": "<target_userId>", "secret": "some_secret"}' <base_url>/api/v1/users.createToken

🔴 High: Unauthorized Spoofing of Room-User Events via Streamer Handler

Location: apps/meteor/server/modules/notifications/notifications.module.ts:106-369

The streamRoomUsers streamer's allowWrite handler in NotificationsModule executes notifyUser for all other room members without validating the event payload. This allows any authenticated user who is a member of a room to trigger arbitrary video-conference or userData events for all other users in that room. This bypasses the validation performed in streamUser.allowWrite (e.g., VideoConf.validateAction), allowing an attacker to spoof video conference invitations, force UI updates, or disrupt sessions. The attacker only needs to be a member of the room to broadcast these spoofed events to all other members.

Steps to Reproduce

  1. Identify a room where the attacker and the victim are both members.
  2. Use a DDP client to call the 'stream-notify-room-users' method.
  3. Pass a crafted event name (e.g., '/video-conference') and malicious arguments.
  4. The server will execute the allowWrite handler, which iterates over all room members (including the victim) and triggers notifyUser for them, effectively spoofing the event.
// Conceptual JavaScript script using a DDP client library to trigger the vulnerability.
// Assuming an authenticated DDP connection.

ddp.call('stream-notify-room-users', ['<roomId>/video-conference', { 
    action: 'call', 
    params: { callId: 'malicious-call-id', uid: '<victim-uid>', rid: '<roomId>' } 
}]);

🟡 Medium: Missing Registration Enabled Check in API Endpoint

Location: apps/meteor/app/api/server/v1/users.ts:584-594

The users.register endpoint is publicly accessible and performs user registration without checking the Accounts_RegistrationForm setting. This allows unauthenticated users to create accounts even when public registration is explicitly disabled by the administrator.

Steps to Reproduce

  1. Identify a Rocket.Chat instance where public registration is disabled (Accounts_RegistrationForm = false).
  2. Send a POST request to /api/v1/users.register with valid user registration data (username, email, password, name).
  3. Observe that the server successfully creates the account despite the registration setting being disabled.
curl -X POST http://<rocket-chat-instance>/api/v1/users.register -H 'Content-Type: application/json' -d '{"username": "attacker", "email": "attacker@example.com", "pass": "password123", "name": "Attacker"}'

🔴 High: Unsanitized input in ImageElement leads to Stored XSS

Location: packages/gazzodown/src/elements/ImageElement.tsx:52-53

The ImageElement component renders the src prop directly into the a tag's href attribute and the img tag's src attribute. While React handles attribute escaping for standard HTML attributes, it does not automatically sanitize URI schemes such as javascript:. If the message parsing pipeline allows javascript: URIs in image or link syntax, an attacker can craft a message that, when rendered, executes arbitrary JavaScript in the victim's browser upon clicking the link or attempting to load the image. The data-title attribute is also populated with the unsanitized src, which could be exploited if other client-side code processes this attribute insecurely.


🟡 Medium: Permissive Cross-Origin Message Handling via Iframe Integration

Location: apps/meteor/client/views/root/hooks/useIframeCommands.ts:40-43

The useIframeCommands hook implements a postMessage listener that processes sensitive client-side commands (e.g., logout, login-with-token, go). When the Iframe_Integration_receive_origin setting is configured as * (which is the default), the application fails to validate the origin of incoming messages. This allows a malicious website, if visited by an authenticated user, to send cross-origin messages to the Rocket.Chat instance, effectively performing unauthorized actions on behalf of the user.

Steps to Reproduce

  1. Ensure the Rocket.Chat instance has Iframe_Integration_receive_enable set to true and Iframe_Integration_receive_origin set to *.
  2. Host a malicious webpage that embeds the Rocket.Chat instance within an iframe.
  3. From the malicious webpage, execute the following JavaScript:
    const iframe = document.querySelector('iframe');
    iframe.contentWindow.postMessage({ externalCommand: 'logout' }, '*');
  4. Observe that the user in the Rocket.Chat iframe is logged out.

🔴 High: Missing Permission Check in users.create Endpoint

Location: apps/meteor/app/api/server/v1/users.ts:584-594

The 'users.create' endpoint is registered with authRequired: true but lacks a permissionsRequired configuration. Furthermore, the action handler does not manually verify if the authenticated user has the 'create-user' permission before calling saveUser. Consequently, any authenticated user can create new users, leading to unauthorized privilege escalation.

Steps to Reproduce

  1. Obtain a valid authentication token for any standard user (non-admin).
  2. Send a POST request to <site-url>/api/v1/users.create with the following headers:
    • X-Auth-Token: <your_token>
    • X-User-Id: <your_user_id>
    • Content-Type: application/json
  3. Provide a JSON body with the required fields: {"email": "newuser@example.com", "password": "password123", "username": "newuser", "name": "New User"}.
  4. The API will successfully create the user, despite the requester not having administrative privileges.

🟡 Medium: Missing 2FA verification on sensitive account deletion action

Location: apps/meteor/app/api/server/v1/users.ts:584-594

The users.deleteOwnAccount endpoint performs a sensitive, destructive action (account deletion) but fails to enforce two-factor authentication (2FA). While the endpoint requires a valid session token, the absence of the twoFactorRequired: true property in the route configuration allows an attacker with a compromised session to delete the account without completing the mandatory 2FA verification steps, even if 2FA is enabled for the user.

Steps to Reproduce

  1. Ensure the Rocket.Chat instance has 2FA enabled for users.
  2. Log in as a user who has 2FA enabled.
  3. Obtain a valid session token (X-Auth-Token) and user ID (X-User-Id).
  4. Send a POST request to the /api/v1/users.deleteOwnAccount endpoint with the user's password in the body.
  5. Observe that the account is deleted successfully without being prompted for or requiring a 2FA code.
curl -X POST http://<your-rocket-chat-instance>/api/v1/users.deleteOwnAccount \
     -H "X-Auth-Token: <valid-session-token>" \
     -H "X-User-Id: <user-id>" \
     -H "Content-Type: application/json" \
     -d '{"password": "<user-password>"}'

View full scan results

@pierre-lehnen-rc pierre-lehnen-rc marked this pull request as ready for review May 25, 2026 20:02
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/server-fetch/src/auth/buildDigestResponse.ts (1)

40-40: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Normalize algorithm casing before the -sess HA1 branch.

Algorithm lookup is case-insensitive, but the -sess check is not. Values like MD5-SESS will compute the wrong HA1 path.

🔧 Suggested fix
-	const ha1 = algorithm.endsWith('-sess') ? hashFn(`${userHash}:${nonce}:${cnonce}`) : userHash;
+	const isSess = algorithm.toLowerCase().endsWith('-sess');
+	const ha1 = isSess ? hashFn(`${userHash}:${nonce}:${cnonce}`) : userHash;
🤖 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 `@packages/server-fetch/src/auth/buildDigestResponse.ts` at line 40, The HA1
branch uses algorithm.endsWith('-sess') case-sensitively, causing wrong paths
for e.g. "MD5-SESS"; normalize algorithm casing first (e.g., let alg =
algorithm.toLowerCase()) and then use alg.endsWith('-sess') when computing ha1
in buildDigestResponse so the hashFn branch
(hashFn(`${userHash}:${nonce}:${cnonce}`)) is executed correctly for session
variants; refer to the ha1 assignment, algorithm, hashFn, userHash, nonce, and
cnonce identifiers when making the change.
♻️ Duplicate comments (4)
packages/server-fetch/src/auth/fetchWithAuthentication.ts (1)

27-31: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Include the query string in digest uri calculation.

Using only pathname breaks digest validation when the request URL contains query parameters.

🔧 Minimal fix
-		const uri = url.pathname;
+		const uri = `${url.pathname}${url.search}`;
🤖 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 `@packages/server-fetch/src/auth/fetchWithAuthentication.ts` around lines 27 -
31, The digest `uri` used when calling buildDigestResponse currently omits the
query string (using only url.pathname), breaking validation for URLs with
parameters; update the code in fetchWithAuthentication so the uri includes the
search/query portion (e.g., uri = url.pathname + url.search or equivalent)
before passing to buildDigestResponse (references: buildDigestResponse,
authResponse, uri variable).
apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts (1)

8-8: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Encode directoryNumber before composing the endpoint URL.

directoryNumber is interpolated raw into the path while SSRF checks are intentionally bypassed, so traversal/query payloads can retarget this credentialed request to unintended Mitel endpoints.

🔧 Minimal fix
-	const separator = config.host.endsWith('/') ? '' : '/';
-	const endpointUrl = `${config.host}${separator}callHistory/${directoryNumber}`;
+	const baseUrl = config.host.endsWith('/') ? config.host : `${config.host}/`;
+	const endpointUrl = new URL(`callHistory/${encodeURIComponent(directoryNumber)}`, baseUrl).toString();
🤖 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/server/services/call-history/mitel/fetchMitelHistory.ts` at line
8, The endpointUrl is built by interpolating directoryNumber raw into the path,
allowing path traversal or query injection; update the code that composes
endpointUrl (the variable named endpointUrl in fetchMitelHistory.ts) to
URL-encode directoryNumber (use encodeURIComponent(directoryNumber) or
equivalent) before building `${config.host}${separator}callHistory/${...}` so
the final path contains a safe, encoded identifier rather than raw user input.
packages/server-fetch/src/auth/parseDigestHeader.ts (1)

11-11: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use case-insensitive Digest scheme matching.

The current prefix check only accepts exact Digest casing and can reject valid digest challenges from peers that vary scheme casing.

🔧 Suggested fix
-	if (!authHeader.startsWith('Digest ')) {
+	if (!/^\s*digest\s+/i.test(authHeader)) {
 		throw new Error('Unsupported Auth Schema');
 	}
🤖 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 `@packages/server-fetch/src/auth/parseDigestHeader.ts` at line 11, The Digest
scheme check in parseDigestHeader (the authHeader.startsWith('Digest ')
conditional) is currently case-sensitive and should accept any casing; change
the condition to perform a case-insensitive match (e.g., compare a lowercased
prefix or use a case-insensitive regex) so that the Digest scheme is recognized
regardless of header casing while keeping the rest of parseDigestHeader logic
intact.
apps/meteor/server/services/call-history/service.ts (1)

27-33: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Harden external config gating and keep search() resilient to import failures.

Line 29 can reject search() on provider/import errors, and Line 33 still switches to mitel for any truthy config object (including partial credentials). That can break list calls and hide persisted media-call history.

Proposed fix
 		const externalHistoryConfig = this.getExternalCallHistorySettings();
-		if (externalHistoryConfig?.host && externalHistoryConfig.username) {
-			await importHistoryForUser(uid, externalHistoryConfig);
-		}
-
-		// If external history is toggled on, only external entries may be listed
-		const type = externalHistoryConfig ? 'mitel' : 'media-call';
+		const hasExternalHistoryConfig = Boolean(
+			externalHistoryConfig?.host && externalHistoryConfig.username && externalHistoryConfig.password,
+		);
+		if (hasExternalHistoryConfig && externalHistoryConfig) {
+			await importHistoryForUser(uid, externalHistoryConfig).catch(() => undefined);
+		}
+
+		const type = hasExternalHistoryConfig ? 'mitel' : 'media-call';
🤖 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/server/services/call-history/service.ts` around lines 27 - 33,
The external config gating is too permissive and import errors can reject
search(); update the logic in getExternalCallHistorySettings / the caller in
service.ts so you only treat the external provider as enabled when both
externalHistoryConfig.host and externalHistoryConfig.username are present, and
wrap the await importHistoryForUser(uid, externalHistoryConfig) call in a
try/catch that logs the error and continues (do not rethrow) so search() remains
resilient to import failures; ensure the computed type variable is set to
'mitel' only when host+username are valid and falls back to 'media-call'
otherwise.
🧹 Nitpick comments (1)
packages/server-fetch/tests/test-data.ts (1)

93-95: ⚡ Quick win

Remove inline comment from test fixture data.

Keep fixture entries self-describing and comment-free in implementation files.

🔧 Minimal cleanup
-	// Invalid schema
 	{ raw: 'DIGEST realm="api.example.com", nonce="abc123"' },
 	{ raw: 'Digestrealm="api.example.com", nonce="abc123"' },

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 `@packages/server-fetch/tests/test-data.ts` around lines 93 - 95, In
tests/test-data.ts remove the inline comment "// Invalid schema" so the fixture
array remains comment-free; locate the list containing the two objects with raw
values 'DIGEST realm="api.example.com", nonce="abc123"' and
'Digestrealm="api.example.com", nonce="abc123"' and delete the comment line
above them so the fixtures are self-describing and contain only data entries.
🤖 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.

Outside diff comments:
In `@packages/server-fetch/src/auth/buildDigestResponse.ts`:
- Line 40: The HA1 branch uses algorithm.endsWith('-sess') case-sensitively,
causing wrong paths for e.g. "MD5-SESS"; normalize algorithm casing first (e.g.,
let alg = algorithm.toLowerCase()) and then use alg.endsWith('-sess') when
computing ha1 in buildDigestResponse so the hashFn branch
(hashFn(`${userHash}:${nonce}:${cnonce}`)) is executed correctly for session
variants; refer to the ha1 assignment, algorithm, hashFn, userHash, nonce, and
cnonce identifiers when making the change.

---

Duplicate comments:
In `@apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts`:
- Line 8: The endpointUrl is built by interpolating directoryNumber raw into the
path, allowing path traversal or query injection; update the code that composes
endpointUrl (the variable named endpointUrl in fetchMitelHistory.ts) to
URL-encode directoryNumber (use encodeURIComponent(directoryNumber) or
equivalent) before building `${config.host}${separator}callHistory/${...}` so
the final path contains a safe, encoded identifier rather than raw user input.

In `@apps/meteor/server/services/call-history/service.ts`:
- Around line 27-33: The external config gating is too permissive and import
errors can reject search(); update the logic in getExternalCallHistorySettings /
the caller in service.ts so you only treat the external provider as enabled when
both externalHistoryConfig.host and externalHistoryConfig.username are present,
and wrap the await importHistoryForUser(uid, externalHistoryConfig) call in a
try/catch that logs the error and continues (do not rethrow) so search() remains
resilient to import failures; ensure the computed type variable is set to
'mitel' only when host+username are valid and falls back to 'media-call'
otherwise.

In `@packages/server-fetch/src/auth/fetchWithAuthentication.ts`:
- Around line 27-31: The digest `uri` used when calling buildDigestResponse
currently omits the query string (using only url.pathname), breaking validation
for URLs with parameters; update the code in fetchWithAuthentication so the uri
includes the search/query portion (e.g., uri = url.pathname + url.search or
equivalent) before passing to buildDigestResponse (references:
buildDigestResponse, authResponse, uri variable).

In `@packages/server-fetch/src/auth/parseDigestHeader.ts`:
- Line 11: The Digest scheme check in parseDigestHeader (the
authHeader.startsWith('Digest ') conditional) is currently case-sensitive and
should accept any casing; change the condition to perform a case-insensitive
match (e.g., compare a lowercased prefix or use a case-insensitive regex) so
that the Digest scheme is recognized regardless of header casing while keeping
the rest of parseDigestHeader logic intact.

---

Nitpick comments:
In `@packages/server-fetch/tests/test-data.ts`:
- Around line 93-95: In tests/test-data.ts remove the inline comment "// Invalid
schema" so the fixture array remains comment-free; locate the list containing
the two objects with raw values 'DIGEST realm="api.example.com", nonce="abc123"'
and 'Digestrealm="api.example.com", nonce="abc123"' and delete the comment line
above them so the fixtures are self-describing and contain only data entries.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 01abfe1f-a532-447a-b341-bcb633d4b5c0

📥 Commits

Reviewing files that changed from the base of the PR and between b488e73 and 24fa4f7.

📒 Files selected for processing (9)
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/call-history/service.ts
  • packages/server-fetch/src/auth/algorithms.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/tests/test-data.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). (10)
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Hacktron Security Check
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.0 coverage (4/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.0 coverage (2/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.0 coverage (5/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.0 coverage (3/5)
  • GitHub Check: 🔨 Test UI (EE) / MongoDB 8.0 coverage (1/5)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.0 (1/4)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.0 (4/4)
  • GitHub Check: 🔨 Test UI (CE) / MongoDB 8.0 (2/4)
🧰 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:

  • packages/server-fetch/src/auth/algorithms.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/service.ts
🧠 Learnings (3)
📚 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:

  • packages/server-fetch/src/auth/algorithms.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/service.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:

  • packages/server-fetch/src/auth/algorithms.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/service.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:

  • packages/server-fetch/src/auth/algorithms.ts
  • apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/index.ts
  • apps/meteor/server/services/call-history/service.ts
🧬 Code graph analysis (1)
packages/server-fetch/src/index.ts (1)
packages/server-fetch/src/constants.ts (1)
  • authRequiredStatus (47-47)
🔇 Additional comments (5)
packages/server-fetch/src/auth/algorithms.ts (1)

8-9: LGTM!

Also applies to: 13-13

apps/meteor/server/services/call-history/mitel/parse/parseMitelDuration.ts (1)

9-9: LGTM!

packages/server-fetch/src/auth/buildDigestResponse.ts (1)

30-33: LGTM!

packages/server-fetch/tests/test-data.ts (1)

79-82: LGTM!

packages/server-fetch/src/index.ts (1)

122-123: LGTM!

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

7 issues found across 60 files

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

Re-trigger cubic

Comment thread packages/server-fetch/src/index.ts Outdated
Comment thread packages/server-fetch/src/auth/parseDigestHeader.ts Outdated
Comment thread packages/server-fetch/src/auth/parseDigestHeader.ts Outdated
Comment thread apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
Comment thread packages/server-fetch/src/auth/buildDigestResponse.ts Outdated
Comment thread packages/server-fetch/src/index.ts
Copy link
Copy Markdown

@hacktron-app hacktron-app Bot left a comment

Choose a reason for hiding this comment

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

7 issues found across 6 files

Severity Count
🔴 High 5
🟡 Medium 2
Comments Outside Diff (6)

🔴 High: Authentication Bypass via User-Supplied Email in Apple Login Handler

Location: apps/meteor/app/apple/server/loginHandler.ts:32-35

The Apple login handler in Rocket.Chat contains a vulnerability that allows an attacker to take over arbitrary user accounts. The loginHandler.ts script processes the loginRequest object, which is fully controlled by the client. When the handleIdentityToken function parses a valid Apple JWT that does not contain an email claim, the handler falls back to using the email field provided directly in the untrusted loginRequest object.

This unverified email is then passed within the serviceData object to Accounts.updateOrCreateUserFromExternalService, which is overridden in accounts_meld.js. The account merging logic searches for an existing user with this email address and links the attacker's Apple account to the victim's account, granting the attacker unauthorized access to the victim's account.

Steps to Reproduce

  1. Obtain a valid Apple identityToken for an Apple ID that does not share an email address (or for which the email claim is absent).
  2. Identify the email address of a victim user on the target Rocket.Chat instance.
  3. Send a login request to the Rocket.Chat DDP/API login endpoint, providing the valid identityToken and injecting the victim's email address into the email field.
  4. The server will link the attacker's Apple account to the victim's account, allowing the attacker to log in as the victim.
curl -X POST https://your-rocketchat-instance.com/api/v1/login \
  -H "Content-Type: application/json" \
  -d '{
    "serviceName": "apple",
    "identityToken": "YOUR_VALID_APPLE_IDENTITY_TOKEN_WITHOUT_EMAIL",
    "fullName": {"givenName": "Attacker", "familyName": "User"},
    "email": "victim@example.com"
  }'

🔴 High: BOLA in users.delete endpoint

Location: apps/meteor/app/api/server/v1/users.ts:584-594

The 'users.delete' endpoint relies on a global 'delete-user' permission check, which allows any user with this permission to delete any other user, regardless of role hierarchy. This lacks resource-level authorization to prevent a lower-privileged administrator from deleting a higher-privileged or system-critical user account.

Steps to Reproduce

  1. Authenticate as a user with the 'delete-user' permission.
  2. Identify the userId of a target user (e.g., a higher-privileged admin).
  3. Send a POST request to /api/v1/users.delete with the target userId in the body.
  4. The target user will be deleted from the system.
curl -X POST -H "X-Auth-Token: <low_privileged_admin_token>" -H "X-User-Id: <low_privileged_admin_id>" -H "Content-Type: application/json" -d '{"userId": "<target_admin_id>"}' http://<host>/api/v1/users.delete

🔴 High: Unsanitized Image URL leading to Stored XSS in ImageElement

Location: packages/gazzodown/src/elements/ImageElement.tsx:52-53

The ImageElement component in gazzodown renders user-provided image URLs directly into the src attribute of an <img> tag and the href attribute of an <a> tag without any sanitization. An attacker can craft a message containing an image with a javascript: URI (e.g., ![alt](javascript:alert(1))), which will be parsed by the message-parser and rendered by ImageElement. When a user clicks on the image, the JavaScript in the href attribute of the wrapping <a> tag is executed, leading to Stored Cross-Site Scripting (XSS). The message-parser allows javascript: URIs through the MarkdownLinkFilePath grammar rule, and ImageElement fails to utilize the existing sanitizeUrl utility.

Steps to Reproduce

  1. Send a message containing an image syntax with a javascript URI: ![test](javascript:alert(document.domain))
  2. The message parser creates an IMAGE token with the provided src.
  3. ImageElement renders <a href="javascript:alert(document.domain)" ...><img src="javascript:alert(document.domain)" ...></a>.
  4. Clicking the image executes the JavaScript.

🟡 Medium: Unauthorized Event Injection via streamRoomUsers

Location: apps/meteor/server/modules/notifications/notifications.module.ts:106-369

The streamRoomUsers streamer's allowWrite handler performs side effects (notifyUser calls) before returning false. This allows any user in a room to trigger video-conference or userData events for all other users in the room, bypassing the intended authorization checks that would normally apply if the user tried to write directly to streamUser.

Steps to Reproduce

  1. Authenticate as a user who is a member of a room.
  2. Send a DDP message to write to stream-notify-room-users with event name roomId/video-conference and arbitrary payload.
  3. Observe that other users in the room receive the video-conference event on their stream-notify-user subscription.

🔴 High: Account Takeover via Insecure OAuth Account Linking

Location: apps/meteor/server/configuration/accounts_meld.js:21-24

The configureAccounts function in accounts_meld.js automatically links external OAuth accounts to existing local user accounts based on matching email addresses. It implicitly trusts the email address provided by the OAuth service without verifying if the OAuth service has actually validated the email ownership (except for meteor-developer). Furthermore, the intended mitigation (forcing a password reset) is completely bypassed if the target user's email is already marked as verified locally. This allows an attacker who can supply an arbitrary email address via an OAuth provider to silently take over any existing account that has a verified email address.

Steps to Reproduce

  1. Identify a target user with a verified email address on the Rocket.Chat instance (e.g., victim@example.com).
  2. Register an account on a supported OAuth provider (such as a custom OAuth provider or one that allows unverified emails to be returned in the profile) using the target's email address.
  3. Initiate an OAuth login on the Rocket.Chat instance using that provider.
  4. The configureAccounts function will match the email, skip the password reset mitigation (because !_.findWhere(user.emails, { address: serviceData.email, verified: true }) evaluates to false), and link the attacker's OAuth service ID to the target user's account.
  5. The attacker is successfully authenticated as the target user without needing their password.

🔴 High: Improper Authorization in Video Conference Streamer allows Event Spoofing

Location: apps/meteor/server/modules/notifications/notifications.module.ts:106-369

The NotificationsModule.streamUser.allowWrite handler for video-conference events delegates authorization to VideoConf.validateAction. However, validateAction fails to verify that the provided callId actually belongs to the provided rid. An attacker can bypass authorization by providing a rid they have access to, while providing a callId of a video conference in a room they do not have access to. Furthermore, the allowWrite handler does not verify that the target user in the event name (targetUserId/video-conference) matches the caller or the uid parameter. This allows an attacker to spoof video conference events to arbitrary users for arbitrary calls, leading to unauthorized manipulation of video conference states.

Steps to Reproduce

  1. Authenticate as an attacker.
  2. Obtain the callId of an active video conference in a room the attacker does not have access to.
  3. Obtain the rid of a room the attacker does have access to (e.g., their own direct message room).
  4. Connect to the WebSocket endpoint and send the following payload to emit a spoofed event to a victim user:
{
  "msg": "method",
  "method": "stream-notify-user",
  "params": [
    "<victim_user_id>/video-conference",
    {
      "action": "call",
      "params": {
        "callId": "<target_call_id>",
        "uid": "<attacker_user_id>",
        "rid": "<attacker_accessible_rid>"
      }
    }
  ]
}
  1. The server's allowWrite handler will call VideoConf.validateAction, which will return true because the attacker has access to <attacker_accessible_rid>, even though the <target_call_id> belongs to a different room.
  2. The event is successfully emitted to the victim user.

View full scan results

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts (1)

41-45: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Potential unhandled rejection after timeout resolution.

If promiseDecided is already true (timeout fired), newPromise is returned without any rejection handler, so failures in processFetchedHistory can surface as unhandled promise rejections.

Proposed fix
 			.then((result) => {
 				const newPromise = processFetchedHistory(user.uid, result);

 				if (promiseDecided) {
+					void newPromise.catch((err) => {
+						logger.error({ msg: 'Unexpected error on external call history processing', err });
+					});
 					return;
 				}
🤖 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/server/services/call-history/mitel/importHistoryForUser.ts`
around lines 41 - 45, The code creates newPromise via
processFetchedHistory(user.uid, result) but if promiseDecided is already true
the function returns without handling rejections, risking an unhandled
rejection; update the branch that checks promiseDecided to attach a rejection
handler to newPromise (e.g., newPromise.catch(err => processLogger.error(...))
or explicitly void the promise with a no-op catch) so any error from
processFetchedHistory is consumed and logged; reference the variables/process:
promiseDecided, newPromise, and the processFetchedHistory(...) call when making
the change.
🧹 Nitpick comments (1)
packages/server-fetch/src/auth/fetchWithAuthentication.ts (1)

42-47: ⚡ Quick win

Remove inline implementation comments in this block.

This try/catch is already self-explanatory; drop the inline comments to keep the implementation aligned with project conventions.

Proposed diff
 	try {
-		// Consume the body of the old request so it does keep any open sockets
 		response.body?.resume();
 	} catch {
-		// ignore potential errors here
 	}

As per coding guidelines, "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 `@packages/server-fetch/src/auth/fetchWithAuthentication.ts` around lines 42 -
47, In fetchWithAuthentication.ts inside the fetchWithAuthentication function,
remove the inline implementation comments inside the try/catch that calls
response.body?.resume(); so the block becomes a plain try {
response.body?.resume(); } catch { } without the lines "// Consume the body..."
and "// ignore potential errors here"; keep the try/catch behavior intact and
ensure no other surrounding logic or formatting is changed.
🤖 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.

Outside diff comments:
In `@apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts`:
- Around line 41-45: The code creates newPromise via
processFetchedHistory(user.uid, result) but if promiseDecided is already true
the function returns without handling rejections, risking an unhandled
rejection; update the branch that checks promiseDecided to attach a rejection
handler to newPromise (e.g., newPromise.catch(err => processLogger.error(...))
or explicitly void the promise with a no-op catch) so any error from
processFetchedHistory is consumed and logged; reference the variables/process:
promiseDecided, newPromise, and the processFetchedHistory(...) call when making
the change.

---

Nitpick comments:
In `@packages/server-fetch/src/auth/fetchWithAuthentication.ts`:
- Around line 42-47: In fetchWithAuthentication.ts inside the
fetchWithAuthentication function, remove the inline implementation comments
inside the try/catch that calls response.body?.resume(); so the block becomes a
plain try { response.body?.resume(); } catch { } without the lines "// Consume
the body..." and "// ignore potential errors here"; keep the try/catch behavior
intact and ensure no other surrounding logic or formatting is changed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 49559bb5-f121-42af-9df4-06606862e266

📥 Commits

Reviewing files that changed from the base of the PR and between 24fa4f7 and f4a45c7.

📒 Files selected for processing (10)
  • apps/meteor/ee/server/settings/voip.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • packages/i18n/src/locales/en.i18n.json
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • packages/server-fetch/tests/test-data.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/i18n/src/locales/en.i18n.json
📜 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). (5)
  • GitHub Check: 📦 Build Packages
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: CodeQL-Build
  • GitHub Check: Hacktron Security Check
  • GitHub Check: CodeQL-Build
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{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:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/ee/server/settings/voip.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
**/*.spec.ts

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

**/*.spec.ts: Use descriptive test names that clearly communicate expected behavior in Playwright tests
Use .spec.ts extension for test files (e.g., login.spec.ts)

Files:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
🧠 Learnings (5)
📚 Learning: 2026-02-24T19:22:48.358Z
Learnt from: juliajforesti
Repo: RocketChat/Rocket.Chat PR: 38493
File: apps/meteor/tests/e2e/omnichannel/omnichannel-send-pdf-transcript.spec.ts:66-67
Timestamp: 2026-02-24T19:22:48.358Z
Learning: In Playwright end-to-end tests (e.g., under apps/meteor/tests/e2e/...), prefer locating elements by translated text (getByText) and ARIA roles (getByRole) over data-qa attributes. If translation values change, update the corresponding test locators accordingly. Never use data-qa locators. This guideline applies to all Playwright e2e test specs in the repository and helps keep tests robust to UI text changes and accessible semantics.

Applied to files:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.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:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/ee/server/settings/voip.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.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:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/ee/server/settings/voip.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
📚 Learning: 2026-03-06T18:10:15.268Z
Learnt from: tassoevan
Repo: RocketChat/Rocket.Chat PR: 39397
File: packages/gazzodown/src/code/CodeBlock.spec.tsx:47-68
Timestamp: 2026-03-06T18:10:15.268Z
Learning: In tests (especially those using testing-library/dom/jsdom) for Rocket.Chat components, the HTML <code> element has an implicit ARIA role of 'code'. Therefore, screen.getByRole('code') or screen.findByRole('code') will locate <code> elements even without a role attribute. Do not flag findByRole('code') as invalid in reviews; prefer using the implicit role instead of adding role="code" unless necessary for accessibility.

Applied to files:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.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:

  • packages/server-fetch/tests/fetchWithAuthentication.spec.ts
  • packages/server-fetch/src/index.ts
  • packages/server-fetch/src/auth/parseDigestHeader.ts
  • apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts
  • apps/meteor/ee/server/settings/voip.ts
  • packages/server-fetch/src/auth/buildDigestResponse.ts
  • apps/meteor/server/services/call-history/mitel/importHistoryForUser.ts
  • packages/server-fetch/tests/test-data.ts
  • packages/server-fetch/src/auth/fetchWithAuthentication.ts
🔇 Additional comments (10)
packages/server-fetch/src/index.ts (2)

188-188: Inline implementation comment is still present.

This is still open from the previous review and should be removed from implementation code.

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


182-184: LGTM!

Also applies to: 195-195

packages/server-fetch/src/auth/buildDigestResponse.ts (2)

35-35: Implementation comment remains in code.

This was already raised and is still present.

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


40-40: LGTM!

packages/server-fetch/tests/fetchWithAuthentication.spec.ts (1)

81-92: LGTM!

Also applies to: 94-105

packages/server-fetch/src/auth/parseDigestHeader.ts (1)

11-11: LGTM!

Also applies to: 39-39

apps/meteor/server/services/call-history/mitel/fetchMitelHistory.ts (1)

6-15: LGTM!

Also applies to: 45-49

apps/meteor/ee/server/settings/voip.ts (1)

91-91: LGTM!

packages/server-fetch/tests/test-data.ts (1)

38-43: LGTM!

Also applies to: 50-55, 62-73

packages/server-fetch/src/auth/fetchWithAuthentication.ts (1)

27-27: LGTM!

@pierre-lehnen-rc pierre-lehnen-rc modified the milestones: 8.6.0, POC-VOICE May 26, 2026
@rc-layne
Copy link
Copy Markdown

rc-layne Bot commented May 26, 2026

⚠️ Layne — 1 warning(s)

Found 1 issue(s): 1 high.

@julio-rocketchat
Copy link
Copy Markdown
Member

/layne exception-approve LAYNE-d052314b04628fec reason: added justification to code

@rc-layne
Copy link
Copy Markdown

rc-layne Bot commented May 26, 2026

✅ Exception recorded for LAYNE-d052314b04628fec by @julio-rocketchat: "added justification to code". Re-running scan...

@rc-layne
Copy link
Copy Markdown

rc-layne Bot commented May 26, 2026

✅ Exception recorded for LAYNE-d052314b04628fec by @julio-rocketchat: "a justification was added as a comment to the code". Re-running scan...

@coderabbitai coderabbitai Bot removed the type: feature Pull requests that introduces new feature label May 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants