Skip to content

chore: ddp client#6800

Open
Rohit3523 wants to merge 237 commits into
developfrom
feat-ddp-client
Open

chore: ddp client#6800
Rohit3523 wants to merge 237 commits into
developfrom
feat-ddp-client

Conversation

@Rohit3523

@Rohit3523 Rohit3523 commented Nov 14, 2025

Copy link
Copy Markdown
Member

Proposed changes

Migrate from legacy @rocket.chat/sdk to @rocket.chat/ddp-client, standardize REST API paths to explicit /v1/ prefixes, centralize header management via SDK, fix critical subscription lifecycle race conditions, and improve error handling across subscription and authentication flows.

Issue(s)

Related: https://rocketchat.atlassian.net/browse/CORE-1579

How to test or reproduce

1. Connection lifecycle

  • Cold start → verify the app connects to the server and all room subscriptions load
  • Background the app for 30 s → foreground it → verify the WebSocket reconnects and no messages were missed (check room badge counts match)
  • Toggle airplane mode while in a room → turn it off → verify the app reconnects and queued messages deliver without a manual refresh
  • Switch servers (Settings → Add server or switch workspace) → verify subscriptions for the old server are torn down and the new server's rooms load cleanly

2. Authentication

  • Login with username + password → full login flow completes, rooms load
  • Login with a 2FA-enabled account → 2FA challenge appears, token accepted, rooms load
  • Logout → verify the DDP session is closed, Redux state is cleared, and you land on the login screen with no leftover subscriptions (check network tab: no lingering WebSocket frames)
  • Kill and reopen the app while logged in → auto-resume from stored token, no re-login prompt

3. Real-time messages & room subscriptions

  • Send a message from a web browser → verify it appears in real-time on the device
  • Receive a message in a room you're not viewing → verify unread badge increments on the room list
  • Reply in a thread from another client → verify the thread count updates on the parent message

4. File operations & headers

  • Upload a user avatar (Profile → Edit → Avatar) → open a network inspector (e.g., Proxyman / Charles) and confirm the request includes Authorization and User-Agent headers
  • Send an image/file in a chat room → confirm auth headers and User-Agent are present, and the file renders correctly in the message list
  • Cancel an in-progress file upload → verify no zombie upload appears in the room

5. Omnichannel (requires an agent account)

  • Log in as an omnichannel agent → department queue updates are received and displayed in real-time
  • Switch to another workspace and back → queue subscriptions re-establish without a manual refresh
  • Logout then log back in → queue updates resume correctly (this was the critical regression fixed in this PR)

6. Autocomplete

  • Type /preview in the message composer → a loading indicator appears; it clears on both success and failure (not stuck indefinitely)
  • Type /nonexistent-command → loading indicator still clears (error path)
  • Type @ → user suggestion list appears; selecting a user inserts the mention and clears the list

7. REST API path correctness

  • Perform several operations (send message, mark room as read, search for a user, invite to channel) → open network inspector and verify all REST calls return 2xx, no unexpected 404s
  • Confirm channels, groups, and DMs all load their message history

8. End-to-end encryption

  • Open a room with E2E encryption enabled → send a message → verify it is shown as encrypted in transit and decrypted on both ends
  • Log out and back in → verify E2E keys are re-established and old encrypted messages still decrypt

9. Video conferencing

  • Start a Jitsi call from a room → call initiates and the join button appears for other participants
  • Join an active call via the video conference block in the message list

10. Error / edge-case handling

  • Simulate a malformed server response (e.g., temporarily point to a non-RC server) → app should not crash; it should show a connection error
  • Kill the server mid-upload → verify the app surfaces an error and does not silently swallow it

Screenshots

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Related PRs in core repo

Summary by CodeRabbit

  • New Features
    • Added support for REST v1 authentication, chat synchronization, message sending, presence, team management, commands, and push-token operations.
    • Improved compatibility with newer server versions across messaging, rooms, media calls, file uploads, and omnichannel features.
  • Bug Fixes
    • Improved reconnection and connection health handling, including safer recovery from interrupted sessions.
    • Fixed loading indicators, incoming/video call requests, user preferences, message history, and encryption edge cases.
  • Tests
    • Expanded coverage for authentication, networking, subscriptions, uploads, omnichannel queues, and connection recovery.

Summary by CodeRabbit

  • New Features

    • Added support for versioned REST API routes across messaging, rooms, users, notifications, media, authentication, and omnichannel features.
    • Improved login, logout, Basic Auth, two-factor authentication, and per-server credential handling.
    • Added connection health checks and more reliable automatic reconnection.
    • Added support for chat synchronization, command listing, presence updates, team actions, and push-token removal.
  • Bug Fixes

    • Improved subscription cleanup, server switching, message loading, media uploads, and incoming call handling.
    • Prevented authentication headers from being sent to unrelated domains.
    • Improved error handling when encryption, settings, or connection requests fail.

@coderabbitai

coderabbitai Bot commented Nov 14, 2025

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The PR migrates the mobile client from the legacy SDK toward DDPSDK, standardizes REST requests and contracts on /v1, updates connection and subscription lifecycles, centralizes authentication headers, and expands regression coverage across these flows.

Changes

DDPSDK and REST v1 migration

Layer / File(s) Summary
REST contracts and route migration
app/definitions/rest/v1/*, app/lib/services/restApi.ts, app/lib/methods/*
Adds and adjusts REST v1 endpoint typings and migrates callers to versioned routes, including messaging, rooms, teams, livechat, users, push tokens, E2E, and media APIs.
DDPSDK service and REST transport
app/lib/services/sdk.ts, app/lib/services/connect.ts, app/lib/services/logout.ts, package.json, patches/*
Replaces legacy SDK integration with DDPSDK, adds REST error normalization, TOTP retry handling, server-scoped headers, method-call routing, logout cleanup, and connection probing/reopening.
Connection lifecycle and subscriptions
app/lib/methods/subscriptions/*, app/ee/omnichannel/lib/subscriptions/*, app/lib/services/voip/*
Moves stream handling to collection and connection-status APIs, tracks subscription teardown handles, guards stale inquiry subscriptions, and updates room reconnection behavior.
Header and upload integration
app/lib/methods/helpers/*, app/lib/methods/sendFileMessage/*, app/lib/methods/uploadAvatar/*, app/containers/Avatar/*
Centralizes default and authentication headers, strips session headers from cross-origin requests, and removes direct user credential passing from upload flows.
Regression coverage and dependent flows
app/lib/services/*.test.ts, app/lib/methods/**/*.test.ts, app/sagas/*, app/views/*, app/containers/*
Updates and adds tests for SDK, connection, REST, subscriptions, uploads, logout, settings, omnichannel routing, server selection, and related UI state handling.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested reviewers: diegolmello

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and clearly points to the DDP client migration at the center of this PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • CORE-1579: Request failed with status code 401

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

❤️ Share

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

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat 4.75.0.109358

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat 4.75.0.109384

@Rohit3523

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (6)
app/sagas/videoConf.ts (1)

182-196: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

videoConfResponse.success still doesn't exist on the response type — and the failure branch was removed.

Per earlier review (unresolved), /v1/video-conference.start returns { data: ... } with no success field, so this condition is always falsy and the success path never runs. Previously there was at least a failure branch that reset setCalling/hid the action sheet; that branch has now been removed entirely, so on this (always-taken) falsy path nothing happens — no state reset, no action-sheet dismissal, no error shown. The call UI can get stuck indefinitely with no feedback, since this isn't an exception path that the surrounding catch would handle. This directly matches the maintainer's unaddressed question about the removed logic.

🐛 Suggested fix
-			if (videoConfResponse.success) {
+			if (videoConfResponse.data) {
 				...
+			} else {
+				yield put(setCalling(false));
+				yield call(hideActionSheetRef);
+				showErrorAlert(i18n.t('error-init-video-conf'));
 			}
🤖 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 `@app/sagas/videoConf.ts` around lines 182 - 196, Update the response handling
in the video conference saga around videoConfResponse so it does not depend on
the nonexistent success field; treat the presence of the returned data as the
success condition. Restore an explicit failure path that resets setCalling,
hides the action sheet via hideActionSheetRef, and shows the existing
initialization error when the response lacks valid data, while preserving the
direct-call and join behavior for successful responses.
app/sagas/deepLinking.js (1)

162-164: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not treat a matching server URL as an active connection.

sdk.server can already equal server before DDP connects. In that state this skips LOGIN.SUCCESS and opens the share-extension flow without an authenticated connection. Require authenticated/connected state, as selectServer now does, before skipping the wait.

🤖 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 `@app/sagas/deepLinking.js` around lines 162 - 164, Update the deep-linking
wait condition around sdk.server so a matching server URL only skips
LOGIN.SUCCESS when the SDK is actually authenticated and connected, reusing the
same state criteria established by selectServer; otherwise continue waiting for
types.LOGIN.SUCCESS.
app/lib/methods/sendFileMessage/sendFileMessage.ts (1)

59-62: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore session credentials for same-origin authenticated requests.

DDPSDK.sdk.getHeaders() does not supply X-Auth-Token or X-User-Id. The upload now sends unauthenticated requests, while these tests mock an impossible header shape and therefore mask the regression. Source session credentials from sdk.currentLogin for same-origin requests, and retain stripping for cross-origin URLs.

  • app/lib/methods/sendFileMessage/sendFileMessage.ts#L59-L62: merge same-origin session credentials into the upload headers.
  • app/lib/methods/helpers/getAuthHeaders.test.ts#L2-L7: mock sdk.currentLogin separately from default SDK headers.
  • app/lib/methods/helpers/fetch.test.ts#L70-L103: model default headers and session credentials separately in same-origin and cross-origin tests.
🤖 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 `@app/lib/methods/sendFileMessage/sendFileMessage.ts` around lines 59 - 62, The
upload headers in sendFileMessage must merge X-Auth-Token and X-User-Id from
sdk.currentLogin for same-origin requests while preserving credential stripping
for cross-origin URLs. Update app/lib/methods/sendFileMessage/sendFileMessage.ts
lines 59-62 accordingly; in app/lib/methods/helpers/getAuthHeaders.test.ts lines
2-7 mock currentLogin separately from default SDK headers; and in
app/lib/methods/helpers/fetch.test.ts lines 70-103 model those sources
separately in both same-origin and cross-origin cases.
app/views/ThreadMessagesView/index.tsx (1)

347-361: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Failure path permanently disables pagination — echoes the unresolved reviewer question.

Setting end: true in both the new else branch (unsuccessful result.success) and the existing catch block means any transient failure (timeout, flaky network) permanently blocks further loads: the guard if (end || loading || !this.mounted) return; at the top of load will short-circuit forever, since nothing ever resets end back to false. This mirrors the still-unanswered why? raised by diegolmello on these exact lines in a previous review.

Consider only resetting loading on failure (letting a future onEndReached retry) or adding an explicit retry/backoff instead of a permanent end: true.

🐛 Possible fix
			} else {
-				this.setState({ loading: false, end: true });
+				// Don't permanently stop pagination on a failed request; allow retry on next onEndReached.
+				this.setState({ loading: false });
			}
		} catch (e) {
			log(e);
-			this.setState({ loading: false, end: true });
+			this.setState({ loading: false });
		}
🤖 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 `@app/views/ThreadMessagesView/index.tsx` around lines 347 - 361, Update the
failure paths in the load method so unsuccessful results and caught errors clear
loading without permanently setting end to true, allowing a later onEndReached
call to retry. Preserve end updates for successful pagination responses and the
existing guard behavior.
app/lib/methods/getSettings.ts (1)

165-179: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Intentional AbortSignal cancellations are logged as errors.

Now that getSettings accepts a cancellation signal, an aborted fetch throws an AbortError that falls into the same catch (e) { log(e); } as genuine failures. If log reports to crash/error tracking, intentional cancellations (unmount, server switch) will show up as noise alongside real failures.

🛡️ Possible fix
	} catch (e) {
+		if ((e as Error)?.name === 'AbortError') {
+			return;
+		}
		log(e);
	}
🤖 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 `@app/lib/methods/getSettings.ts` around lines 165 - 179, Update the error
handling in getSettings so AbortError exceptions caused by the provided
cancellation signal are ignored, while genuine fetch or parsing failures
continue through the existing log(e) path. Use the existing signal and catch
block to distinguish intentional aborts without changing successful pagination
behavior.
app/ee/omnichannel/lib/index.test.ts (1)

158-183: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Stop the previous inquiry subscription before creating a replacement.

subscribeInquiry() replaces this.inquirySub with the new subscription, but the old stop handle is dropped unless the app dispatches INQUIRY_UNSUBSCRIBE between subscribe events. This test exercises that scenario and now expects the stale subscription’s firstStop to remain silent, leaving it orphaned indefinitely. Call this.inquirySub?.stop() before assigning the new subscription.

🤖 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 `@app/ee/omnichannel/lib/index.test.ts` around lines 158 - 183, Update the
INQUIRY_SUBSCRIBE handling in subscribeInquiry to call this.inquirySub?.stop()
before creating and assigning the replacement subscription. Preserve the
existing behavior for the initial subscription and ensure each subsequent
subscribe event stops the previous handle before mockSubscribeInquiry runs.
🤖 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 `@app/lib/methods/helpers/getAuthHeaders.test.ts`:
- Around line 13-45: Explicitly annotate all affected callbacks: use void
returns for describe, it, test, and beforeEach callbacks in
app/lib/methods/helpers/getAuthHeaders.test.ts (anchor, lines 13-45) and
app/lib/methods/helpers/isSameOrigin.test.ts (lines 3-32); use Promise<void> for
async test callbacks and void for synchronous callbacks in
app/lib/methods/helpers/fetch.test.ts (lines 70-119). In
app/sagas/selectServer.ts, annotate the state parameter for the selector
callbacks at lines 141 and 191 with the appropriate state type.

In `@app/lib/methods/helpers/isSameOrigin.test.ts`:
- Around line 21-23: Correct the test description in the “origin is undefined”
case to state that it returns false, matching the existing isSameOrigin
assertion; leave the test logic unchanged.

In `@app/lib/services/connect.ts`:
- Around line 45-47: Update the same-server early return in connect() to require
successful SDK initialization, not merely sdk.server equality. Track or reuse
the finalized initialization state, such as sdk.current?.connection.status, so
retries after loadBasicAuth() or handleTwoFactorChallenge() failures perform
disconnect and reinitialization.

In `@app/lib/services/sdk.ts`:
- Around line 291-296: Update callMethod to capture the result of
ensureInitialized() in a local variable and use that variable for the
client.callAsyncWithOptions invocation. Preserve the existing method, params,
and optional two-factor code arguments while avoiding direct access to the
potentially undefined this.current property.

---

Outside diff comments:
In `@app/ee/omnichannel/lib/index.test.ts`:
- Around line 158-183: Update the INQUIRY_SUBSCRIBE handling in subscribeInquiry
to call this.inquirySub?.stop() before creating and assigning the replacement
subscription. Preserve the existing behavior for the initial subscription and
ensure each subsequent subscribe event stops the previous handle before
mockSubscribeInquiry runs.

In `@app/lib/methods/getSettings.ts`:
- Around line 165-179: Update the error handling in getSettings so AbortError
exceptions caused by the provided cancellation signal are ignored, while genuine
fetch or parsing failures continue through the existing log(e) path. Use the
existing signal and catch block to distinguish intentional aborts without
changing successful pagination behavior.

In `@app/lib/methods/sendFileMessage/sendFileMessage.ts`:
- Around line 59-62: The upload headers in sendFileMessage must merge
X-Auth-Token and X-User-Id from sdk.currentLogin for same-origin requests while
preserving credential stripping for cross-origin URLs. Update
app/lib/methods/sendFileMessage/sendFileMessage.ts lines 59-62 accordingly; in
app/lib/methods/helpers/getAuthHeaders.test.ts lines 2-7 mock currentLogin
separately from default SDK headers; and in
app/lib/methods/helpers/fetch.test.ts lines 70-103 model those sources
separately in both same-origin and cross-origin cases.

In `@app/sagas/deepLinking.js`:
- Around line 162-164: Update the deep-linking wait condition around sdk.server
so a matching server URL only skips LOGIN.SUCCESS when the SDK is actually
authenticated and connected, reusing the same state criteria established by
selectServer; otherwise continue waiting for types.LOGIN.SUCCESS.

In `@app/sagas/videoConf.ts`:
- Around line 182-196: Update the response handling in the video conference saga
around videoConfResponse so it does not depend on the nonexistent success field;
treat the presence of the returned data as the success condition. Restore an
explicit failure path that resets setCalling, hides the action sheet via
hideActionSheetRef, and shows the existing initialization error when the
response lacks valid data, while preserving the direct-call and join behavior
for successful responses.

In `@app/views/ThreadMessagesView/index.tsx`:
- Around line 347-361: Update the failure paths in the load method so
unsuccessful results and caught errors clear loading without permanently setting
end to true, allowing a later onEndReached call to retry. Preserve end updates
for successful pagination responses and the existing guard behavior.
🪄 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 Plus

Run ID: ce0c89f2-7766-4248-bc6f-7d40c2bbf8d7

📥 Commits

Reviewing files that changed from the base of the PR and between 187b02e and dcc7534.

⛔ Files ignored due to path filters (4)
  • app/containers/message/components/__tests__/__snapshots__/Message.test.tsx.snap is excluded by !**/*.snap
  • app/containers/message/components/stories/__tests__/__snapshots__/leaves.test.tsx.snap is excluded by !**/*.snap
  • app/views/RoomView/LoadMore/__snapshots__/LoadMore.test.tsx.snap is excluded by !**/*.snap
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (39)
  • app/containers/Avatar/Avatar.tsx
  • app/containers/MessageComposer/MessageComposer.test.tsx
  • app/containers/MessageComposer/MessageComposer.tsx
  • app/definitions/rest/v1/auth.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/ee/omnichannel/lib/index.ts
  • app/ee/omnichannel/lib/subscriptions/inquiry.test.ts
  • app/ee/omnichannel/lib/subscriptions/inquiry.ts
  • app/lib/methods/actions.test.ts
  • app/lib/methods/actions.ts
  • app/lib/methods/getSettings.ts
  • app/lib/methods/helpers/fetch.test.ts
  • app/lib/methods/helpers/fetch.ts
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/lib/methods/helpers/getAuthHeaders.ts
  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/lib/methods/helpers/isSameOrigin.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/methods/subscriptions/room.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/connect.ts
  • app/lib/services/restApi.test.ts
  • app/lib/services/restApi.ts
  • app/lib/services/sdk.test.ts
  • app/lib/services/sdk.ts
  • app/sagas/deepLinking.js
  • app/sagas/selectServer.ts
  • app/sagas/videoConf.ts
  • app/views/NewServerView/methods/basicAuth.ts
  • app/views/SearchMessagesView/index.tsx
  • app/views/ShareView/index.tsx
  • app/views/ThreadMessagesView/index.tsx
  • app/views/UserNotificationPreferencesView/index.tsx
  • jest.config.js
  • package.json
  • patches/@rocket.chat+api-client+0.2.56.patch
🚧 Files skipped from review as they are similar to previous changes (13)
  • app/containers/Avatar/Avatar.tsx
  • jest.config.js
  • app/lib/methods/actions.test.ts
  • app/views/SearchMessagesView/index.tsx
  • app/definitions/rest/v1/auth.ts
  • app/containers/MessageComposer/MessageComposer.tsx
  • app/containers/MessageComposer/MessageComposer.test.tsx
  • package.json
  • app/ee/omnichannel/lib/subscriptions/inquiry.test.ts
  • app/views/UserNotificationPreferencesView/index.tsx
  • app/ee/omnichannel/lib/index.ts
  • app/ee/omnichannel/lib/subscriptions/inquiry.ts
  • app/lib/services/restApi.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: E2E Build Android / android-build
  • GitHub Check: E2E Build iOS / ios-build
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/lib/methods/helpers/getAuthHeaders.ts
  • app/views/NewServerView/methods/basicAuth.ts
  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/sagas/deepLinking.js
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/views/ThreadMessagesView/index.tsx
  • app/views/ShareView/index.tsx
  • app/lib/methods/helpers/fetch.test.ts
  • app/lib/methods/helpers/isSameOrigin.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/lib/methods/actions.ts
  • app/sagas/selectServer.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/methods/getSettings.ts
  • app/sagas/videoConf.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/services/restApi.test.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/methods/helpers/fetch.ts
  • app/lib/methods/subscriptions/room.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/sdk.test.ts
  • app/lib/services/sdk.ts
  • app/lib/services/connect.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

Use TypeScript strict mode; resolve application imports relative to the app/ base URL.

Files:

  • app/lib/methods/helpers/getAuthHeaders.ts
  • app/views/NewServerView/methods/basicAuth.ts
  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/views/ThreadMessagesView/index.tsx
  • app/views/ShareView/index.tsx
  • app/lib/methods/helpers/fetch.test.ts
  • app/lib/methods/helpers/isSameOrigin.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/lib/methods/actions.ts
  • app/sagas/selectServer.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/methods/getSettings.ts
  • app/sagas/videoConf.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/services/restApi.test.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/methods/helpers/fetch.ts
  • app/lib/methods/subscriptions/room.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/sdk.test.ts
  • app/lib/services/sdk.ts
  • app/lib/services/connect.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Follow the repository Prettier style: tabs, single quotes, 130-character width, no trailing commas, omitted arrow-function parentheses where allowed, and same-line brackets.

Files:

  • app/lib/methods/helpers/getAuthHeaders.ts
  • app/views/NewServerView/methods/basicAuth.ts
  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/sagas/deepLinking.js
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/views/ThreadMessagesView/index.tsx
  • app/views/ShareView/index.tsx
  • app/lib/methods/helpers/fetch.test.ts
  • app/lib/methods/helpers/isSameOrigin.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/lib/methods/actions.ts
  • app/sagas/selectServer.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/methods/getSettings.ts
  • app/sagas/videoConf.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/services/restApi.test.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/methods/helpers/fetch.ts
  • app/lib/methods/subscriptions/room.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/sdk.test.ts
  • app/lib/services/sdk.ts
  • app/lib/services/connect.ts
**/*.test.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Run Jest tests with TZ=UTC to ensure deterministic timezone-dependent test behavior.

Files:

  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/lib/methods/helpers/fetch.test.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/services/restApi.test.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/sdk.test.ts
app/ee/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Keep enterprise Omnichannel and livechat functionality in the enterprise layer.

Files:

  • app/ee/omnichannel/lib/index.test.ts
app/sagas/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use sagas for side effects such as initialization, authentication, rooms, messages, encryption, deep linking, and video conferencing.

Files:

  • app/sagas/selectServer.ts
  • app/sagas/videoConf.ts
app/sagas/videoConf.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Implement VideoConf as a server-managed Jitsi feature using Redux actions, reducers, and sagas; keep it separate from VoIP.

Files:

  • app/sagas/videoConf.ts
app/lib/services/{sdk,restApi,connect}.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use the SDK service for WebSocket subscriptions, the REST API service for HTTP requests via fetch, and the connect service for server connection management.

Files:

  • app/lib/services/sdk.ts
  • app/lib/services/connect.ts
🧠 Learnings (6)
📚 Learning: 2026-04-30T17:07:51.020Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7274
File: app/lib/services/voip/MediaCallEvents.ts:0-0
Timestamp: 2026-04-30T17:07:51.020Z
Learning: In this Rocket.Chat React Native codebase, the ESLint rule `no-void: error` is enforced. When you see a promise returned from an async call that is not awaited (a “floating promise”), do not silence it with the `void somePromise()` pattern. Instead, handle the promise explicitly by attaching `.catch(...)` (or otherwise awaiting/handling the error) so unhandled-rejection risks are addressed in a way that satisfies the existing ESLint configuration.

Applied to files:

  • app/lib/methods/helpers/getAuthHeaders.ts
  • app/views/NewServerView/methods/basicAuth.ts
  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/views/ThreadMessagesView/index.tsx
  • app/views/ShareView/index.tsx
  • app/lib/methods/helpers/fetch.test.ts
  • app/lib/methods/helpers/isSameOrigin.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/lib/methods/actions.ts
  • app/sagas/selectServer.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/methods/getSettings.ts
  • app/sagas/videoConf.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/services/restApi.test.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/methods/helpers/fetch.ts
  • app/lib/methods/subscriptions/room.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/sdk.test.ts
  • app/lib/services/sdk.ts
  • app/lib/services/connect.ts
📚 Learning: 2026-06-25T18:37:25.526Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7434
File: app/views/ScreenLockConfigView.test.tsx:16-22
Timestamp: 2026-06-25T18:37:25.526Z
Learning: In Rocket.Chat ReactNative tests that mock selectors for `useAppSelector`, don’t require the mocked selector input to be typed as `IApplicationState` when the fixture only includes a partial Redux state slice (e.g., only `server` and `settings`). Requiring the full `IApplicationState` type in that scenario forces unsafe `as IApplicationState` casts and undermines type-safety. For these narrowly scoped selector-mock fixtures, use a less strict type (e.g., `any`) to keep the mock focused on the slice under test.

Applied to files:

  • app/lib/methods/helpers/isSameOrigin.test.ts
  • app/lib/methods/helpers/getAuthHeaders.test.ts
  • app/lib/methods/helpers/fetch.test.ts
  • app/ee/omnichannel/lib/index.test.ts
  • app/lib/services/__tests__/ddpConnectionPatch.test.ts
  • app/lib/methods/sendFileMessage/sendFileMessage.test.ts
  • app/lib/services/restApi.test.ts
  • app/lib/methods/subscriptions/room.test.ts
  • app/lib/services/connect.test.ts
  • app/lib/services/sdk.test.ts
📚 Learning: 2026-05-07T13:19:52.152Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7304
File: app/sagas/deepLinking.js:237-243
Timestamp: 2026-05-07T13:19:52.152Z
Learning: In this codebase’s Redux-Saga usage, remember that `yield put(action)` dispatches through the Redux store synchronously, and any saga(s) that synchronously react via action listeners (and synchronous `put` chains) will run to completion before the calling saga resumes at its next `yield`. As a result, within a single saga there is no scheduler interleaving between a `yield select(...)` and a subsequent `yield take(...)` at the next `yield` point, so a check-then-take pattern like `const state = yield select(...); if (state !== TARGET) { yield take(a => a.type === TARGET); }` is safe from TOCTOU races under the synchronous `put`/take model described above.

Applied to files:

  • app/sagas/deepLinking.js
📚 Learning: 2026-06-24T22:58:43.390Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7157
File: app/views/MessagesView/index.tsx:392-392
Timestamp: 2026-06-24T22:58:43.390Z
Learning: When wrapping a React Native component (e.g., via `withSafeAreaInsets`) ensure `hoistNonReactStatics` is only required if the wrapped component actually defines static properties/methods that consumers rely on. If the component has no statics (as in `app/views/MessagesView/index.tsx`), you can omit `hoistNonReactStatics` for this case.

Applied to files:

  • app/views/ThreadMessagesView/index.tsx
  • app/views/ShareView/index.tsx
📚 Learning: 2026-06-25T18:37:44.793Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7434
File: app/views/ScreenLockConfigView.tsx:101-141
Timestamp: 2026-06-25T18:37:44.793Z
Learning: In the Rocket.Chat React Native codebase, do not treat passing an `async` function directly to an event prop in React/React Native UI components (e.g., `onPress={async () => ...}` in TSX) as a “floating promises” CI-blocking lint issue—this repo does not enable the ESLint `no-floating-promises` rule (while `no-void` is enforced). Only raise robustness follow-ups when there are genuinely unhandled promise paths (e.g., fire-and-forget calls like `save()` that return a Promise that is neither awaited nor handled), and prefer making sure failure paths are explicitly handled/reported rather than blocking on lint-style floating-promise concerns.

Applied to files:

  • app/views/ThreadMessagesView/index.tsx
  • app/views/ShareView/index.tsx
📚 Learning: 2026-05-05T21:08:33.177Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7298
File: patches/@rocket.chat+sdk+1.3.3-mobile.patch:79-79
Timestamp: 2026-05-05T21:08:33.177Z
Learning: In the RocketChat/Rocket.Chat.ReactNative repo, for patches under patches/*.patch (especially those touching rocket.chat/sdk), remember that the patching sandbox's node_modules reflects the pre-patch state. Grepping node_modules for symbols (e.g., userDisconnectCloseCode = 4000 in node_modules/rocket.chat/sdk/lib/drivers/ddp.ts) can yield false positives. Review patches by inspecting the diff and applying it to a fresh copy of the SDK or diffing against the SDK source, rather than relying on node_modules. Ensure the patch actually introduces/updates symbols in the SDK source and run the test suite to validate behavior after applying the patch.

Applied to files:

  • patches/@rocket.chat+api-client+0.2.56.patch
🪛 GitHub Check: ESLint and Test / run-eslint-and-test
app/lib/services/sdk.ts

[failure] 295-295:
Object is possibly 'undefined'.

🔇 Additional comments (29)
patches/@rocket.chat+api-client+0.2.56.patch (2)

1-30: LGTM!


7-8: 🎯 Functional Correctness

No change needed for the buildFormData argument-order swap.

buildFormData(data, formData = new FormData(), parentKey) matches the new call sites, so delete() can pass a single params argument safely.

			> Likely an incorrect or invalid review comment.
app/lib/services/sdk.ts (4)

173-217: 🎯 Functional Correctness

Verify 2FA header retry actually resolves the challenge for the REST-wrapped method-call path.

On retry, post() attaches x-2fa-code/x-2fa-method as HTTP headers (lines 207-210) for both plain REST endpoints and the /v1/method.call/... wrapper (isMethodCall). For the wrapped-method-call path, the DDP method's own arguments live inside the JSON message body, and 2FA for direct DDP calls is passed as an extra method argument (see callMethod's ...(code ? [code] : [])), not a header. It's unclear whether the server's generic 2FA check also honors headers for this specific wrapped endpoint, or whether the retry needs to re-encode the code into the message payload instead — resending the same unchanged params/message with just new headers could repeat the same totp-required/totp-invalid failure.

Per the PR's own review thread, this is flagged as a still-open concern ("REST method-call 2FA retries may collect a code but resend without including it"), not confirmed as resolved.


60-137: LGTM! Server-switch guards in login(), try/catch/finally with a bounded timeout in logout(), and the initialize()/ensureInitialized()/setBasicAuth() reworks all address the previously-flagged issues (stale headers across server switches, cross-server credential leakage on login, logout not clearing auth headers on failure).

Also applies to: 254-285, 432-454


139-159: LGTM! get()/delete() now correctly attach this.headers, and methodCallWrapper()'s REST/WS routing and Date→EJSON handling match the documented/tested behavior.

Also applies to: 221-241, 312-329


331-415: LGTM! subscribe() now fails fast via ensureInitialized() instead of silently returning undefined, and subscribeNotifyUser()/subscribeRoom() implementations look consistent with the covering tests.

app/lib/methods/helpers/fetch.ts (1)

17-31: LGTM! This correctly resolves the prior header-merge-order and cross-origin token-leak issues raised in earlier reviews: caller headers can override SDK defaults for same-origin requests, while X-Auth-Token/X-User-Id are stripped for cross-origin requests even if explicitly supplied by the caller, matching fetch.test.ts.

app/lib/methods/helpers/getAuthHeaders.ts (1)

9-17: LGTM!

app/lib/methods/helpers/isSameOrigin.ts (1)

1-17: LGTM! The trailing-slash normalization before startsWith correctly prevents false positives between sibling subpath deployments (e.g. /workspace-a vs /workspace-a-extra).

app/lib/methods/sendFileMessage/sendFileMessage.test.ts (1)

68-212: LGTM! Solid coverage of the V1/V2 routing, header composition, and encrypted multipart payload behavior introduced by the SDK header centralization.

app/views/ShareView/index.tsx (2)

81-92: LGTM! The migration from local selectedMessages/action state to a scoped messageActionStore (limited to the kind === 'quote' flow) is internally consistent, and lifecycle cleanup (componentWillUnmount, onRemoveQuoteMessage) correctly derives from the store.

Also applies to: 123-127, 242-242, 269-272, 385-387, 395-403


278-295: 🗄️ Data Integrity & Integration

No change needed. sendAttachments delegates to sendFileMessage, whose signature does not take a user field, while sendMessage still constructs the local message author from the passed user.

app/lib/methods/actions.ts (1)

131-138: 🔒 Security & Privacy

No change needed.

fetch is imported from app/lib/methods/helpers/fetch, and that helper merges the SDK auth headers for same-origin requests before calling the native fetch.

app/lib/methods/sendFileMessage/sendFileMessage.ts (1)

4-4: LGTM!

Also applies to: 16-25

app/lib/methods/helpers/isSameOrigin.test.ts (1)

4-19: LGTM!

Also applies to: 25-31

app/lib/methods/helpers/fetch.test.ts (1)

5-5: LGTM!

Also applies to: 106-119

app/views/NewServerView/methods/basicAuth.ts (1)

13-13: LGTM!

app/sagas/deepLinking.js (1)

239-239: LGTM!

Also applies to: 342-342

app/lib/methods/helpers/getAuthHeaders.test.ts (1)

1-45: 📐 Maintainability & Code Quality

Jest test suites are already run with TZ=UTC.

package.json defines test and test-update as TZ=UTC jest, and CI uses pnpm test --runInBand, so no change is needed.

app/lib/methods/getSettings.ts (1)

160-163: 🎯 Functional Correctness

Confirm getSettings targets the correct server when adding a new workspace.

This still relies on reduxStore.getState().server for both server and serverVersion, the same concern diegolmello raised previously and left unresolved: when a new workspace is being added, does this correctly resolve to the new server being connected to, or could it read stale/previous-session state from the store?

app/lib/methods/subscriptions/room.test.ts (1)

8-10: LGTM!

Also applies to: 19-20, 153-172, 223-233, 235-257, 269-271, 306-347

app/lib/services/sdk.test.ts (1)

158-167: LGTM!

Also applies to: 239-240, 291-325, 370-382, 602-645, 854-866, 900-928

app/lib/services/connect.test.ts (2)

1174-1208: 🎯 Functional Correctness

getWebsocketInfo now fails on any probe error, not just an explicit websocket-disabled response.

These tests confirm that for any error other than one containing '400', getWebsocketInfo returns { success: false, message: <raw error> } (see the "falls back to the error message for non-400 failures" case). This matches a previously raised concern: a transient network/DNS blip during this probe will now cause the add-server flow to reject a valid server URL as Invalid_URL, not just a server that explicitly disables WebSockets. That thread was not confirmed resolved.


33-46: LGTM!

Also applies to: 534-560, 688-719, 721-740, 1116-1172

app/lib/services/restApi.test.ts (2)

308-330: 🩺 Stability & Availability | ⚡ Quick win

Missing test for sdk.delete() failure in removePushToken — underlying concern still unaddressed.

Only the success and no-token paths are tested. A previously raised concern that sdk.delete() failures may propagate and disrupt logout (suggesting a try/catch returning false) was never confirmed fixed. Add a test asserting removePushToken() resolves to false (or similar) when mockSdkDelete rejects, and verify restApi.ts actually guards against the rejection propagating into logout().

✅ Suggested additional test
 	it('returns undefined and does not call delete when there is no device token', async () => {
 		(require('../notifications').getDeviceToken as jest.Mock).mockReturnValue(undefined);
 		expect(await removePushToken()).toBeUndefined();
 		expect(mockSdkDelete).not.toHaveBeenCalled();
 	});
+
+	it('returns false and does not throw when sdk.delete() rejects', async () => {
+		mockSdkDelete.mockRejectedValueOnce(new Error('network error'));
+		await expect(removePushToken()).resolves.toBe(false);
+	});
 });

293-306: LGTM!

app/lib/services/connect.ts (1)

49-113: LGTM!

Also applies to: 165-182, 278-280

app/lib/methods/subscriptions/room.ts (1)

26-26: LGTM!

Also applies to: 35-37, 53-58, 58-58, 76-83, 106-106, 271-400

app/lib/services/__tests__/ddpConnectionPatch.test.ts (1)

159-251: LGTM!

Comment on lines +13 to +45
describe('getAuthHeaders', () => {
beforeEach(() => {
(sdk.getHeaders as jest.Mock).mockReset();
});

it('returns full headers including the session token for same-origin URLs', () => {
(sdk.getHeaders as jest.Mock).mockReturnValue({ 'User-Agent': 'RC Mobile', 'X-Auth-Token': 'tok', 'X-User-Id': 'uid' });
const headers = getAuthHeaders('https://open.rocket.chat/api/v1/settings');
expect(headers['X-Auth-Token']).toBe('tok');
expect(headers['X-User-Id']).toBe('uid');
expect(headers['User-Agent']).toBe('RC Mobile');
});

it('strips only the session token for cross-origin URLs, keeping other headers', () => {
(sdk.getHeaders as jest.Mock).mockReturnValue({
'User-Agent': 'RC Mobile',
Authorization: 'Basic abc',
'X-Auth-Token': 'tok',
'X-User-Id': 'uid'
});
const headers = getAuthHeaders('https://releases.rocket.chat/v2/server/supportedVersions');
expect(headers['X-Auth-Token']).toBeUndefined();
expect(headers['X-User-Id']).toBeUndefined();
expect(headers['User-Agent']).toBe('RC Mobile');
expect(headers.Authorization).toBe('Basic abc');
});

it('treats relative URLs as same-origin', () => {
(sdk.getHeaders as jest.Mock).mockReturnValue({ 'X-Auth-Token': 'tok' });
const headers = getAuthHeaders('/api/v1/x');
expect(headers['X-Auth-Token']).toBe('tok');
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Files:\n'
git ls-files | rg 'app/(lib/methods/helpers/(getAuthHeaders|isSameOrigin|fetch)\.test\.ts|sagas/selectServer\.ts)$|package\.json|tsconfig.*\.json' || true

printf '\nSelected file sizes:\n'
wc -l app/lib/methods/helpers/getAuthHeaders.test.ts app/lib/methods/helpers/isSameOrigin.test.ts app/lib/methods/helpers/fetch.test.ts app/sagas/selectServer.ts || true

printf '\nRelevant source:\n'
for f in app/lib/methods/helpers/getAuthHeaders.test.ts app/lib/methods/helpers/isSameOrigin.test.ts app/lib/methods/helpers/fetch.test.ts app/sagas/selectServer.ts; do
  echo "--- $f ---"
  cat -n "$f"
done

printf '\nSearch callback/type patterns in adjacent code:\n'
rg -n "describe\(|it\(|test\(|appSelector|function|const .*=\s*(async )?\(" app/lib/methods/helpers app/sagas/selectServer.ts --glob '*.ts' --glob '*.tsx' || true

printf '\nType config / lint rule hints:\n'
for f in $(git ls-files 'tsconfig*.json' package.json); do
  if rg -n '"strict"|"noImplicitAny"|"typedef"|"require-type-annotation"|"typescript-eslint"|"eslint' "$f" > /tmp/matches.$$; then
    echo "--- $f ---"
    cat "$f"
  fi
done

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 50390


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'tsconfig.json:\n'
cat -n tsconfig.json

printf '\nRelevant callback annotation occurrences in surrounding code:\n'
rg -n "appSelector\(|describe\(|test\(|it\(\) as |\): void =>|=> \{|async function|function\(|function \* handleSelectServer|function\* handleSelectServer" app/sagas/selectServer.ts app/lib/methods/helpers --glob '*.ts' --glob '*.tsx' | head -n 200

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 29254


Add explicit callback annotations.

These callbacks rely on TypeScript inference while the project uses TypeScript strict mode and the repo guideline requires explicit parameter/return annotations.

  • app/lib/methods/helpers/getAuthHeaders.test.ts#L13-L45 and app/lib/methods/helpers/isSameOrigin.test.ts#L3-L32: annotate describe, it, test, and beforeEach callbacks with void.
  • app/lib/methods/helpers/fetch.test.ts#L70-L119: annotate async test callbacks with Promise<void> and synchronous callbacks with void.
  • app/sagas/selectServer.ts#L141-L141: annotate the state parameter on the selector callback; the same selector callback at #L191 should be annotated too.

[low eff
ort_and_high_reward]

📍 Affects 4 files
  • app/lib/methods/helpers/getAuthHeaders.test.ts#L13-L45 (this comment)
  • app/lib/methods/helpers/isSameOrigin.test.ts#L3-L32
  • app/lib/methods/helpers/fetch.test.ts#L70-L119
  • app/sagas/selectServer.ts#L141-L141
🤖 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 `@app/lib/methods/helpers/getAuthHeaders.test.ts` around lines 13 - 45,
Explicitly annotate all affected callbacks: use void returns for describe, it,
test, and beforeEach callbacks in app/lib/methods/helpers/getAuthHeaders.test.ts
(anchor, lines 13-45) and app/lib/methods/helpers/isSameOrigin.test.ts (lines
3-32); use Promise<void> for async test callbacks and void for synchronous
callbacks in app/lib/methods/helpers/fetch.test.ts (lines 70-119). In
app/sagas/selectServer.ts, annotate the state parameter for the selector
callbacks at lines 141 and 191 with the appropriate state type.

Source: Coding guidelines

Comment thread app/lib/methods/helpers/isSameOrigin.test.ts Outdated
Comment thread app/lib/services/connect.ts Outdated
Comment thread app/lib/services/sdk.ts
@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

iOS Build Available

Rocket.Chat 4.75.0.109416

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.

3 participants