-
Notifications
You must be signed in to change notification settings - Fork 13k
chore: improve the way we send DDP connection data to hooks #38268 #38294
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
base: develop
Are you sure you want to change the base?
Changes from all commits
49051b1
3ca9f16
0b0a9a2
7bbe051
d02ff34
3d6bfed
83f3da5
4aea9c5
11eaf8c
668c2a3
fe4ed1f
ba3990c
3c5c1e0
ecf59a7
e76d829
4ed51c6
b94212c
7586e19
9c2b6db
5cf8c84
eac64ef
b65be50
9ce09a4
f86de12
73403e2
2a47751
64cf87c
6d3d051
cef0138
2361dad
fa604e3
497e50d
0700e17
a9830a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| import type { IncomingHttpHeaders } from 'http'; | ||
|
|
||
| import { hashLoginToken } from '@rocket.chat/account-utils'; | ||
| import { InstanceStatus } from '@rocket.chat/instance-status'; | ||
| import { getHeader } from '@rocket.chat/tools'; | ||
| import { Accounts } from 'meteor/accounts-base'; | ||
| import { Meteor } from 'meteor/meteor'; | ||
|
|
||
|
|
@@ -19,45 +19,40 @@ Accounts.onLogin((info: ILoginAttempt) => { | |
| } | ||
|
|
||
| const { resume } = methodArguments.find((arg) => 'resume' in arg) ?? {}; | ||
| const loginToken = resume ? hashLoginToken(resume) : ''; | ||
| const instanceId = InstanceStatus.id(); | ||
| const clientAddress = info.connection.clientAddress || getHeader(httpHeaders, 'x-real-ip'); | ||
| const userAgent = getHeader(httpHeaders, 'user-agent'); | ||
| const host = getHeader(httpHeaders, 'host'); | ||
|
|
||
| const eventObject = { | ||
| sauEvents.emit('sau.accounts.login', { | ||
| userId: info.user._id, | ||
| connection: { | ||
| ...info.connection, | ||
| ...(resume && { loginToken: Accounts._hashLoginToken(resume) }), | ||
| instanceId: InstanceStatus.id(), | ||
| httpHeaders: httpHeaders as IncomingHttpHeaders, | ||
| }, | ||
| }; | ||
| sauEvents.emit('accounts.login', eventObject); | ||
| deviceManagementEvents.emit('device-login', eventObject); | ||
| instanceId, | ||
| userAgent, | ||
| loginToken, | ||
| connectionId: info.connection.id, | ||
| clientAddress, | ||
| host, | ||
| }); | ||
|
|
||
| deviceManagementEvents.emit('device-login', { userId: info.user._id, userAgent, loginToken, clientAddress }); | ||
nazabucciarelli marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Check if DeviceManagementService listens to accounts.login and emits device-login
echo "=== Checking DeviceManagementService for device-login emission ==="
cat -n apps/meteor/server/services/device-management/service.ts
echo ""
echo "=== All device-login emissions in the codebase ==="
rg -n "emit.*device-login" --type ts -B 2 -A 2Repository: RocketChat/Rocket.Chat Length of output: 1956 🏁 Script executed: #!/bin/bash
# Check the context of the sauMonitorHooks.ts emission - what event triggers it
echo "=== Full context of sauMonitorHooks.ts ==="
cat -n apps/meteor/server/hooks/sauMonitorHooks.ts | head -50Repository: RocketChat/Rocket.Chat Length of output: 1988 🏁 Script executed: #!/bin/bash
# Find where accounts.login event is emitted
echo "=== Where is accounts.login event emitted ==="
rg -n "emit.*accounts\.login|services\.emit.*accounts\.login" --type ts -B 3 -A 3
echo ""
echo "=== Check if sauMonitor events configuration or accounts emission ==="
rg -n "accounts\.login" --type ts -B 2 -A 2 | head -100Repository: RocketChat/Rocket.Chat Length of output: 4361 🏁 Script executed: #!/bin/bash
# Check if sauMonitorHooks.ts or any Meteor hook emits accounts.login event
echo "=== Does sauMonitorHooks.ts emit accounts.login event ==="
rg -n "broadcast.*accounts\.login|api\.emit.*accounts\.login" --type ts -B 2 -A 2
echo ""
echo "=== Check Accounts.onLogin relationship to accounts.login event ==="
rg -n "Accounts\.onLogin" --type ts | head -20
echo ""
echo "=== Check where accounts.login event is broadcast from ==="
rg -n "broadcast\('accounts\.login" --type ts -B 5 -A 5Repository: RocketChat/Rocket.Chat Length of output: 2405
The concern is valid. In Enterprise Edition, two code paths emit the same event for a single login:
Both are triggered during the same login flow, causing the handler in 🤖 Prompt for AI Agents |
||
| }); | ||
|
|
||
| Accounts.onLogout((info) => { | ||
| const { httpHeaders } = info.connection; | ||
|
|
||
| if (!info.user) { | ||
| return; | ||
| } | ||
| sauEvents.emit('accounts.logout', { | ||
| userId: info.user._id, | ||
| connection: { instanceId: InstanceStatus.id(), ...info.connection, httpHeaders: httpHeaders as IncomingHttpHeaders }, | ||
| }); | ||
|
|
||
| sauEvents.emit('sau.accounts.logout', { userId: info.user._id, sessionId: info.connection.id }); | ||
| }); | ||
|
|
||
| Meteor.onConnection((connection) => { | ||
| connection.onClose(async () => { | ||
| const { httpHeaders } = connection; | ||
| sauEvents.emit('socket.disconnected', { | ||
| instanceId: InstanceStatus.id(), | ||
| ...connection, | ||
| httpHeaders: httpHeaders as IncomingHttpHeaders, | ||
| }); | ||
| sauEvents.emit('sau.socket.disconnected', { connectionId: connection.id, instanceId: InstanceStatus.id() }); | ||
| }); | ||
| }); | ||
|
|
||
| Meteor.onConnection((connection) => { | ||
| const { httpHeaders } = connection; | ||
|
|
||
| sauEvents.emit('socket.connected', { instanceId: InstanceStatus.id(), ...connection, httpHeaders: httpHeaders as IncomingHttpHeaders }); | ||
| // in case of implementing a listener of this event, define the parameters type in services/sauMonitor/events.ts | ||
| sauEvents.emit('sau.socket.connected', { instanceId: InstanceStatus.id(), connectionId: connection.id }); | ||
| }); | ||
|
Comment on lines
+56
to
58
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove inline implementation comment. Line 56 introduces a code comment in implementation; prefer documenting this in the events type file or docs instead. As per coding guidelines, ... 🧹 Proposed clean-up- // in case of implementing a listener of this event, define the parameters type in services/sauMonitor/events.ts
sauEvents.emit('sau.socket.connected', { instanceId: InstanceStatus.id(), connectionId: connection.id });🤖 Prompt for AI Agents |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,5 @@ | ||
| import type { ISocketConnectionLogged } from '@rocket.chat/core-typings'; | ||
| import { Emitter } from '@rocket.chat/emitter'; | ||
|
|
||
| export const deviceManagementEvents = new Emitter<{ | ||
| 'device-login': { userId: string; connection: ISocketConnectionLogged }; | ||
| 'device-login': { userId: string; userAgent: string; loginToken?: string; clientAddress: string }; | ||
| }>(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,16 @@ | ||
| import type { ISocketConnection, ISocketConnectionLogged } from '@rocket.chat/core-typings'; | ||
| import { Emitter } from '@rocket.chat/emitter'; | ||
|
|
||
| export const sauEvents = new Emitter<{ | ||
| 'accounts.login': { userId: string; connection: ISocketConnectionLogged }; | ||
| 'accounts.logout': { userId: string; connection: ISocketConnection }; | ||
| 'socket.connected': ISocketConnection; | ||
| 'socket.disconnected': ISocketConnection; | ||
| 'sau.accounts.login': { | ||
| userId: string; | ||
| instanceId: string; | ||
| connectionId: string; | ||
| loginToken?: string; | ||
| clientAddress: string; | ||
| userAgent: string; | ||
| host: string; | ||
| }; | ||
| 'sau.accounts.logout': { userId: string; sessionId: string }; | ||
| 'sau.socket.connected': { instanceId: string; connectionId: string }; | ||
| 'sau.socket.disconnected': { instanceId: string; connectionId: string }; | ||
| }>(); |
Uh oh!
There was an error while loading. Please reload this page.