diff --git a/ee/apps/ddp-streamer/src/DDPStreamer.ts b/ee/apps/ddp-streamer/src/DDPStreamer.ts index 275f26ae05e0..7e413e61688d 100644 --- a/ee/apps/ddp-streamer/src/DDPStreamer.ts +++ b/ee/apps/ddp-streamer/src/DDPStreamer.ts @@ -2,6 +2,7 @@ import crypto from 'crypto'; import { MeteorService, Presence, ServiceClass } from '@rocket.chat/core-services'; import { InstanceStatus } from '@rocket.chat/instance-status'; +import { Users } from '@rocket.chat/models'; import polka from 'polka'; import { throttle } from 'underscore'; import WebSocket from 'ws'; @@ -123,12 +124,34 @@ export class DDPStreamer extends ServiceClass { } }); - server.on(DDP_EVENTS.LOGGED, (info) => { + async function sendUserData(client: Client, userId: string) { + // TODO figure out what fields to send. maybe to to export function getBaseUserFields to a package + const loggedUser = await Users.findOneById(userId, { + projection: { name: 1, username: 1, settings: 1, roles: 1, active: 1, statusLivechat: 1, statusDefault: 1 }, + }); + if (!loggedUser) { + return; + } + + // using setImmediate here so login's method result is sent before we send the user data + setImmediate(async () => server.added(client, 'users', userId, loggedUser)); + } + server.on(DDP_EVENTS.LOGGED, async (info: Client) => { const { userId, connection } = info; - Presence.newConnection(userId, connection.id, nodeID); + if (!userId) { + throw new Error('User not logged in'); + } + + await Presence.newConnection(userId, connection.id, nodeID); + this.updateConnections(); + // mimic Meteor's default publication that sends user data after login + await sendUserData(info, userId); + + server.emit('presence', { userId, connection }); + this.api?.broadcast('accounts.login', { userId, connection }); }); diff --git a/ee/apps/ddp-streamer/src/configureServer.ts b/ee/apps/ddp-streamer/src/configureServer.ts index 489f9606c07d..ed187db498cc 100644 --- a/ee/apps/ddp-streamer/src/configureServer.ts +++ b/ee/apps/ddp-streamer/src/configureServer.ts @@ -2,9 +2,7 @@ import { EventEmitter } from 'events'; import { Account, Presence, MeteorService, MeteorError } from '@rocket.chat/core-services'; import { UserStatus } from '@rocket.chat/core-typings'; -import { Users } from '@rocket.chat/models'; -import type { Client } from './Client'; import { Server } from './Server'; import { DDP_EVENTS, WS_ERRORS } from './constants'; import { Autoupdate } from './lib/Autoupdate'; @@ -66,19 +64,6 @@ server.publish(autoUpdateCollection, function () { this.ready(); }); -async function sendUserData(client: Client, userId: string) { - // TODO figure out what fields to send. maybe to to export function getBaseUserFields to a package - const loggedUser = await Users.findOneById(userId, { - projection: { name: 1, username: 1, settings: 1, roles: 1, active: 1, statusLivechat: 1, statusDefault: 1 }, - }); - if (!loggedUser) { - return; - } - - // using setImmediate here so login's method result is sent before we send the user data - setImmediate(async () => server.added(client, 'users', userId, loggedUser)); -} - server.methods({ async 'login'({ resume, user, password }: { resume: string; user: { username: string }; password: string }) { try { @@ -95,9 +80,6 @@ server.methods({ server.emit(DDP_EVENTS.LOGGED, this); - // mimic Meteor's default publication that sends user data after login - await sendUserData(this, result.uid); - return { id: result.uid, token: result.token,