Skip to content

chore: replace deprecated methods in 8.0.0#6644

Merged
OtavioStasiak merged 7 commits intodevelopfrom
chore.replace-deprecated-methods
Sep 25, 2025
Merged

chore: replace deprecated methods in 8.0.0#6644
OtavioStasiak merged 7 commits intodevelopfrom
chore.replace-deprecated-methods

Conversation

@OtavioStasiak
Copy link
Contributor

@OtavioStasiak OtavioStasiak commented Sep 12, 2025

Proposed changes

replace deprecated methods in 8.0.0, related to RocketChat/Rocket.Chat#36146.

Issue(s)

https://rocketchat.atlassian.net/browse/NATIVE-942

How to test or reproduce

  • Open the app;
  • Change your password;
  • Edit your profile;

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

Further comments

Summary by CodeRabbit

  • New Features

    • Adds a public roles endpoint enabling detailed user listings for public roles; on newer servers role queries return user lists, older servers fallback to previous behavior.
  • Refactor

    • Unified profile and password save flows into a single save action.
    • Password changes now require both current and new passwords (current is validated/hashed).
    • Simplified two-factor handling during profile/password updates for clearer behavior and errors.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 12, 2025

Warning

Rate limit exceeded

@OtavioStasiak has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 8 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0546157 and ff71091.

📒 Files selected for processing (2)
  • app/lib/services/restApi.ts (2 hunks)
  • app/views/ProfileView/index.tsx (1 hunks)

Walkthrough

Adds IRoleUser and a new REST endpoint roles.getUsersInPublicRoles. Refactors restApi.getUsersRoles to be version-gated (returns boolean or IRoleUser[]) and removes exports saveUserProfileMethod and setUserPassword. Updates ChangePasswordView and ProfileView to call saveUserProfile with revised parameters and remove two-factor argument passing.

Changes

Cohort / File(s) Summary
Type definitions
app/definitions/IUser.ts
Adds export interface IRoleUser { _id: string; username: string; roles: string[]; }. No changes to existing IUser.
REST endpoint definitions
app/definitions/rest/v1/roles.ts
Adds GET 'roles.getUsersInPublicRoles' returning { users: IRoleUser[]; success: boolean }. Existing 'roles.getUsersInRole' unchanged.
Service layer refactor
app/lib/services/restApi.ts
Imports IRoleUser. Removes exports saveUserProfileMethod and setUserPassword. Updates getUsersRoles signature to `async (): Promise<boolean
Change password flow
app/views/ChangePasswordView/index.tsx
Replaces Services.setUserPassword(newPassword) with Services.saveUserProfile({ newPassword, currentPassword } as IProfileParams). Includes currentPassword (hashed via sha256 on profile path) in payload. Removes saveUserProfileMethod usage and two-factor options branching; 2FA error handling remains in catch.
Profile submit flow
app/views/ProfileView/index.tsx
Replaces Services.saveUserProfileMethod(params, customFields, twoFactor...) with Services.saveUserProfile(params, customFields). Removes construction/passing of two-factor options; validation and state handling otherwise unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor UI as UI
  participant Svc as restApi.getUsersRoles
  participant SDK as sdk
  participant Store as reduxStore

  UI->>Svc: getUsersRoles()
  Svc->>Store: read serverVersion
  alt serverVersion >= 7.10.0
    Svc->>SDK: GET roles.getUsersInPublicRoles
    SDK-->>Svc: { success, users: IRoleUser[] }
    alt success
      Svc-->>UI: IRoleUser[]
    else failure
      Svc-->>UI: false
    end
  else legacy
    Svc->>SDK: methodCall('getUserRoles')
    SDK-->>Svc: boolean
    Svc-->>UI: boolean
  end
Loading
sequenceDiagram
  autonumber
  actor User
  participant View as ChangePasswordView / ProfileView
  participant Svc as Services.saveUserProfile
  participant API as Server

  User->>View: Submit (currentPassword, newPassword, ...)
  View->>Svc: saveUserProfile(IProfileParams, customFields?)
  Svc->>API: POST saveUserProfile
  alt success
    API-->>Svc: 200 OK
    Svc-->>View: resolve
    View-->>User: Success
  else requires 2FA / error
    API-->>Svc: error (e.g., 2FA required)
    Svc-->>View: reject(error)
    View-->>User: Show error / 2FA prompt
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • diegolmello

Poem

A rabbit hops through code so neat,
New roles and endpoints find their seat.
Old calls trimmed, the save made clear,
Version checks guide which way to steer.
Carrots cheer — the merge is near! 🥕🐇

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “chore: replace deprecated methods in 8.0.0” succinctly describes the primary change of replacing deprecated client methods in response to server updates and follows conventional commit style, making it clear and directly related to the changeset.
Linked Issues Check ✅ Passed The pull request replaces all deprecated server endpoints—getUserRoles, setUserPassword, and saveUserProfile—by removing the old method exports and updating client calls to use the new saveUserProfile API, as well as version-gated logic for getUsersRoles to call the new roles.getUsersInPublicRoles endpoint, fully satisfying the objectives of NATIVE-942.
Out of Scope Changes Check ✅ Passed All code modifications, including defining IRoleUser, adding the new roles.getUsersInPublicRoles endpoint, and updating password and profile views, directly support replacing the deprecated methods and integrating the new server behavior without introducing unrelated functionality.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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

❤️ Share

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

Copy link
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: 1

Caution

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

⚠️ Outside diff range comments (2)
app/views/ProfileView/index.tsx (1)

196-213: Duplicate/contradictory setUser dispatch and shadowed user variable

  • You dispatch setUser up to twice and the second dispatch uses the outer user (selector) while the inner const user = { ... } is block-scoped and ignored afterward.
  • This can overwrite state with stale data and causes unnecessary renders.

Unify to a single dispatch and avoid shadowing.

-			if (result) {
+			if (result) {
 				logEvent(events.PROFILE_SAVE_CHANGES);
 				if ('realname' in params) {
 					params.name = params.realname;
 					delete params.realname;
 				}
-				if (customFields) {
-					dispatch(setUser({ customFields, ...params }));
-					setCustomFields(customFields);
-				} else {
-					dispatch(setUser({ ...params }));
-					const user = { ...getValues(), ...params };
-					Object.entries(user).forEach(([key, value]) => setValue(key as any, value));
-				}
-				dispatch(setUser({ ...user, ...params, customFields }));
+				const updated = { ...user, ...params, ...(customFields ? { customFields } : {}) };
+				dispatch(setUser(updated));
+				if (customFields) {
+					setCustomFields(customFields);
+				} else {
+					const formValues = { ...getValues(), ...params };
+					Object.entries(formValues).forEach(([key, value]) => setValue(key as any, value));
+				}
 				EventEmitter.emit(LISTENER, { message: I18n.t('Profile_saved_successfully') });
 			}
app/views/ChangePasswordView/index.tsx (1)

68-75: Broken validation: confirm password compares against a non-existent field

yup.ref('password') should reference newPassword. As-is, validation can never pass.

-			.oneOf([yup.ref('password'), null], I18n.t('Passwords_do_not_match'))
+			.oneOf([yup.ref('newPassword')], I18n.t('Passwords_do_not_match'))
🧹 Nitpick comments (7)
app/definitions/IUser.ts (1)

152-156: Prefer deriving from IUser to prevent type drift

IRoleUser duplicates IUser fields. Derive from IUser to keep types in sync if IUser changes.

-export interface IRoleUser {
-	_id: string;
-	username: string;
-	roles: string[];
-}
+export interface IRoleUser extends Pick<IUser, '_id' | 'username'> {
+	roles: string[];
+}
app/definitions/rest/v1/roles.ts (1)

77-82: Confirm response shape/pagination for roles.getUsersInPublicRoles

If the server can return large datasets, lack of params (offset/count) could be heavy. Also ensure the response is exactly { users: IRoleUser[]; success: boolean } on all supported servers.

Would you like me to add optional offset/count params and type them behind a version check?

app/views/ProfileView/index.tsx (1)

228-236: 2FA code is stored but never sent with the request

Given saveUserProfile no longer accepts a 2FA arg, confirm twoFactor() configures the SDK to include the code (e.g., via headers) on the subsequent request. If not, this retry path won’t succeed.

If SDK is already handling it globally, consider removing twoFactorCode state to simplify.

app/views/ChangePasswordView/index.tsx (1)

134-137: Type casting hides contract issues

Casting to IProfileParams works but masks that many fields are optional in some flows. Consider introducing a dedicated type for password changes (e.g., IChangePasswordParams) or allowing Partial<IProfileParams> in saveUserProfile.

If you want, I can raise a follow-up PR to introduce the dedicated type and adjust saveUserProfile accordingly.

app/lib/services/restApi.ts (3)

1081-1093: Unclear return contract for getUsersRoles; consider a stable shape

Returning boolean | IRoleUser[] forces callers to discriminate types and is easy to misuse. Also, legacy getUserRoles likely doesn’t return a boolean; verify its actual payload.

Proposed stable contract:

-export const getUsersRoles = async (): Promise<boolean | IRoleUser[]> => {
+export const getUsersRoles = async (): Promise<{ supported: boolean; users: IRoleUser[] }> => {
   const serverVersion = reduxStore.getState().server.version;
   if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '8.0.0')) {
-    const response = await sdk.get('roles.getUsersInPublicRoles');
-    if (response.success) {
-      return response.users;
-    }
-    return false;
+    const response = await sdk.get('roles.getUsersInPublicRoles');
+    return { supported: !!response.success, users: response.success ? response.users : [] };
   }
-  return sdk.methodCall('getUserRoles');
+  // Back-compat: return "unsupported" with empty users
+  return { supported: false, users: [] };
 };

And update call sites accordingly. If you prefer not to change the signature, at least document and enforce type guards at usage.


1085-1088: Type the REST response for safety

If sdk.get supports generics, add a typed response to ensure users/success are validated at compile time.

Example:

const response: { users: IRoleUser[]; success: boolean } = await sdk.get('roles.getUsersInPublicRoles');

631-637: Consider accepting Partial

users.updateOwnBasicInfo accepts partial data. Allowing Partial<IProfileParams> would remove the need for casts across callers.

-export const saveUserProfile = (
-	data: IProfileParams | Pick<IProfileParams, 'username' | 'name'>,
+export const saveUserProfile = (
+	data: Partial<IProfileParams>,
 	customFields?: { [key: string | number]: string }
 ) =>
   sdk.post('users.updateOwnBasicInfo', { data, customFields });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 056056c and d2fa902.

📒 Files selected for processing (5)
  • app/definitions/IUser.ts (1 hunks)
  • app/definitions/rest/v1/roles.ts (2 hunks)
  • app/lib/services/restApi.ts (2 hunks)
  • app/views/ChangePasswordView/index.tsx (3 hunks)
  • app/views/ProfileView/index.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
app/definitions/rest/v1/roles.ts (1)
app/definitions/IUser.ts (1)
  • IRoleUser (152-156)
app/lib/services/restApi.ts (2)
app/definitions/IUser.ts (1)
  • IRoleUser (152-156)
app/lib/methods/helpers/compareServerVersion.ts (1)
  • compareServerVersion (10-15)
app/views/ChangePasswordView/index.tsx (2)
app/lib/services/index.ts (1)
  • Services (4-7)
app/definitions/IProfile.ts (1)
  • IProfileParams (3-12)
app/views/ProfileView/index.tsx (1)
app/lib/services/index.ts (1)
  • Services (4-7)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: ESLint and Test / run-eslint-and-test
🔇 Additional comments (2)
app/definitions/rest/v1/roles.ts (1)

3-3: Import change looks good

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

8-8: Import looks good

Copy link
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: 0

♻️ Duplicate comments (1)
app/views/ChangePasswordView/index.tsx (1)

108-112: Address inconsistent currentPassword hashing.

The currentPassword is sent in plain text here, while the profile view path (line 134) hashes it with sha256. This inconsistency may cause server-side validation issues or security concerns.

Apply this diff to hash the currentPassword consistently:

-		const { newPassword, currentPassword } = inputValues;
+		const { newPassword, currentPassword } = inputValues;
 
 		try {
 			setValue('saving', true);
-			await Services.saveUserProfile({ newPassword, currentPassword: sha256(currentPassword) } as IProfileParams);
+			await Services.saveUserProfile({ newPassword, currentPassword: sha256(currentPassword) } as IProfileParams);
🧹 Nitpick comments (1)
app/views/ChangePasswordView/index.tsx (1)

135-135: Consider removing the unnecessary empty line.

There's an empty line that doesn't add value to code readability.

Apply this diff to remove the unnecessary empty line:

 				const params = { currentPassword: sha256(currentPassword), newPassword, username, email: emails?.[0].address || '' };
-
 				const result = await Services.saveUserProfile(params);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d2fa902 and 546f8b6.

📒 Files selected for processing (1)
  • app/views/ChangePasswordView/index.tsx (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
app/views/ChangePasswordView/index.tsx (2)
app/lib/services/index.ts (1)
  • Services (4-7)
app/definitions/IProfile.ts (1)
  • IProfileParams (3-12)
🔇 Additional comments (2)
app/views/ChangePasswordView/index.tsx (2)

10-10: LGTM! Added necessary type import.

The import of IProfileParams is correctly added to support the new typing requirements for the password change operations.


134-136: LGTM! Proper parameter construction and API call.

The parameters are correctly constructed with hashed currentPassword, and the simplified saveUserProfile call aligns with the deprecated method removal objectives. The type casting to IProfileParams is appropriate.

@OtavioStasiak OtavioStasiak had a problem deploying to experimental_android_build September 25, 2025 17:08 — with GitHub Actions Failure
@OtavioStasiak OtavioStasiak merged commit 258654c into develop Sep 25, 2025
6 of 16 checks passed
@OtavioStasiak OtavioStasiak deleted the chore.replace-deprecated-methods branch September 25, 2025 18:48
@Rohit3523 Rohit3523 mentioned this pull request Sep 26, 2025
10 tasks
OtavioStasiak added a commit that referenced this pull request Oct 21, 2025
* feat: deprecate getUserRoles

* feat: remove deprecated method setUserPassword and setUserProfileMethod

* fix: comments

* fix: encrypt currentPassword

* fix: change serverVersion to compare in getUserRoles
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants