RocketChat / RocketChat/Rocket.Chat
saveUserIdentity coerces missing username/name to literal "undefined", corrupting VideoConference and CallHistory user references
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 46.1k
- Forks
- 13.9k
- Avg merge
- 3d 3h
- Merged PRs (30d)
- 130
Description
Description:
When saveUserIdentity receives a partial update (for example, only name), it still coerces optional fields with String(rawName).trim() / String(rawUsername).trim().
If one field is omitted, that omitted field can become the literal string "undefined" in internal variables.
Because change detection is computed from these coerced values, usernameChanged/nameChanged can be incorrectly true even when a field was not provided. Later reference updates use those values and can persist "undefined" into user reference fields in video_conference and call_history.
Steps to reproduce:
- Create a user with existing call/video references (e.g., make at least one media call/video conference so entries exist in call_history / video_conference).
- Call POST /api/v1/users.updateOwnBasicInfo with only name in data (omit username), for example:
{
"data": {
"name": "New Display Name"
}
} - Check updated references in video_conference and/or call_history for that user.
Expected behavior:
Only provided fields should be treated as changed.
A name-only update must not alter username references, and no reference field should ever be written as literal "undefined".
Actual behavior:
Omitted optional fields are coerced to string "undefined", and downstream reference updates can write "undefined" into persisted username/name reference fields in video_conference and call_history.
Server Setup Information:
- Version of Rocket.Chat Server: develop (source-level verification)
- License Type: N/A
- Number of Users: N/A
- Operating System: N/A
- Deployment Method: N/A
- Number of Running Instances: N/A
- DB Replicaset Oplog: N/A
- NodeJS Version: N/A
- MongoDB Version: N/A
Client Setup Information
- Desktop App or Browser Version: N/A (API reproduction)
- Operating System: N/A
Additional context
Relevant code paths:
-
apps/meteor/app/lib/server/functions/saveUserIdentity.ts
- String(rawName).trim() / String(rawUsername).trim()
- nameChanged / usernameChanged computed from coerced values
- reference writes in VideoConference.updateUserReferences and CallHistory.updateUserReferences
-
packages/rest-typings/src/v1/users/UsersUpdateOwnBasicInfoParamsPOST.ts
- name and username are independently optional
- apps/meteor/server/methods/saveUserProfile.ts
- still calls saveUserIdentity for partial identity updates
Relevant logs:
No server exception is required for this bug; it is a data integrity issue caused by incorrect field coercion/change detection logic.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with apps/meteor/app/lib/server/functions/saveUserIdentity.ts, then trace the partial-update call from apps/meteor/server/methods/saveUserProfile.ts and the optional fields in UsersUpdateOwnBasicInfoParamsPOST.ts. Reproduce the name-only POST request and inspect VideoConference.updateUserReferences and CallHistory.updateUserReferences; done means omitted fields are not treated as changed and references contain no literal "undefined".
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- api, backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 65/100