Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: client trying to subscribe to streams before completing the login process #34089

Merged
merged 2 commits into from
Dec 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cold-mangos-impress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@rocket.chat/meteor': patch
---

Fixed an issue that caused clients to not properly receive certain server notifications right after login
24 changes: 23 additions & 1 deletion apps/meteor/client/meteorOverrides/ddpOverREST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,35 @@ const withDDPOverREST = (_send: (this: Meteor.IMeteorConnection, message: Meteor
sdk.rest
.post(`/v1/${endpoint}/${method}`, restParams)
.then(({ message: _message }) => {
processResult(_message);
// Calling Meteor.loginWithToken before processing the result of the first login will ensure that the new login request
// is added to the top of the list of methodInvokers.
// The request itself will only be sent after the first login result is processed, but
// the Accounts.onLogin callbacks will be called before this request is effectively sent;
// This way, any requests done inside of onLogin callbacks will be added to the list
// and processed only after the Meteor.loginWithToken request is done
// So, the effective order is:
// 1. regular login with password is sent
// 2. result of the password login is received
// 3. login with token is added to the list of pending requests
// 4. result of the password login is processed
// 5. Accounts.onLogin callbacks are triggered, Meteor.userId is set
// 6. the request for the login with token is effectively sent
// 7. login with token result is processed
// 8. requests initiated inside of the Accounts.onLogin callback are then finally sent
//
// Keep in mind that there's a difference in how meteor3 processes the request results, compared to older meteor versions
// On meteor3, any collection writes triggered by a request result are done async, which means that the `processResult` call
// will not immediatelly trigger the callbacks, like it used to in older versions.
// That means that on meteor3+, it doesn't really make a difference if processResult is called before or after the Meteor.loginWithToken here
// as the result will be processed async, the loginWithToken call will be initiated before it is effectively processed anyway.
if (message.method === 'login') {
const parsedMessage = DDPCommon.parseDDP(_message) as { result?: { token?: string } };
if (parsedMessage.result?.token) {
Meteor.loginWithToken(parsedMessage.result.token);
}
}

processResult(_message);
})
.catch((error) => {
console.error(error);
Expand Down
Loading