Skip to content

Commit

Permalink
fix: client trying to subscribe to streams before completing the logi…
Browse files Browse the repository at this point in the history
…n process (#34089)
  • Loading branch information
pierre-lehnen-rc authored and ggazzo committed Dec 5, 2024
1 parent f5c2840 commit 4b209f4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 1 deletion.
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

0 comments on commit 4b209f4

Please sign in to comment.