You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by as...@apache.org on 2026/10/12 01:08:15 UTC
(maka) 01/04: fix(bots): apply channel sender settings before routing
This is an automated email from the ASF dual-hosted git repository.
Astro-Han pushed a commit to branch fix/channels-settings-roundtrip
in repository https://gitbox.apache.org/repos/asf/maka.git
commit e23717932f3344afefc70014406bfd1fe818a5a0
Author: AstroHan <le...@outlook.com>
AuthorDate: Sun Oct 11 22:28:27 2026 +1000
fix(bots): apply channel sender settings before routing
Generated-by: Codex
---
.../bot-incoming-session-lifecycle.test.ts | 21 ++++++++--
.../src/bots/__tests__/base-adapter.test.ts | 48 +++++++++++++++++-----
.../src/bots/__tests__/bot-user-allowlist.test.ts | 39 ------------------
.../src/bots/__tests__/discord-bridge.test.ts | 35 ++++++++++++++++
.../src/bots/__tests__/im-channel-mapping.test.ts | 39 ------------------
packages/runtime/src/bots/base-adapter.ts | 5 ++-
packages/runtime/src/bots/dingtalk-bridge.ts | 4 +-
packages/runtime/src/bots/discord-bridge.ts | 3 +-
packages/runtime/src/bots/feishu-bridge.ts | 19 ++-------
packages/runtime/src/bots/qq-bridge.ts | 3 +-
packages/runtime/src/bots/telegram-bridge.ts | 47 +++++++--------------
packages/runtime/src/bots/wechat-bridge.ts | 5 +--
packages/runtime/src/bots/wecom-bridge.ts | 12 ++----
13 files changed, 121 insertions(+), 159 deletions(-)
diff --git a/apps/desktop/src/main/__tests__/bot-incoming-session-lifecycle.test.ts b/apps/desktop/src/main/__tests__/bot-incoming-session-lifecycle.test.ts
index e1594d270d..db37edaedf 100644
--- a/apps/desktop/src/main/__tests__/bot-incoming-session-lifecycle.test.ts
+++ b/apps/desktop/src/main/__tests__/bot-incoming-session-lifecycle.test.ts
@@ -19,7 +19,8 @@
import assert from 'node:assert/strict';
import { describe, test } from 'node:test';
-import type { BotIncomingMessage, BotRegistry } from '@maka/runtime/bots';
+import { BaseBotAdapter, type BotIncomingMessage, type BotRegistry } from '@maka/runtime/bots';
+import { createDefaultBotChannel } from '@maka/core/bot-chat-settings';
import { createBotIncomingMainService } from '../bot-incoming-main.js';
import { BotSessionUnavailableError } from '../bot-session-adapter.js';
import { waitFor as pollFor } from '@maka/core/test-only/async-primitives';
@@ -31,6 +32,12 @@ async function waitFor(predicate: () => boolean): Promise<void> {
});
}
+class IncomingAdapter extends BaseBotAdapter {
+ async start(): Promise<void> {}
+ async stop(): Promise<void> {}
+ receive(message: BotIncomingMessage): void { this.emitIncomingMessage(message); }
+}
+
describe('bot session lifecycle bindings', () => {
test('rebinds a conversation after its archived session rejects a send', async () => {
const created: string[] = [];
@@ -127,7 +134,7 @@ describe('bot session lifecycle bindings', () => {
});
});
-test('WorkHub routing bypasses Bot Session creation, explore preparation and reset commands', async () => {
+test('channel admission precedes WorkHub routing, Bot Session creation and reset commands', async () => {
let routed = 0;
let closed = false;
const unexpected = async (): Promise<never> => { throw new Error('Bot Session must not be used'); };
@@ -139,7 +146,15 @@ test('WorkHub routing bypasses Bot Session creation, explore preparation and res
async close() { closed = true; },
},
});
- await service.handleBotIncomingMessage({ platform: 'qq', userId: 'user', userName: 'User', chatId: 'chat', isGroup: false, receivedAt: 1, text: '重置', sourceMessageId: 'source' });
+ const adapter = new IncomingAdapter('qq', { ...createDefaultBotChannel('qq'), allowedUserIds: ['user'] });
+ const pending: Promise<void>[] = [];
+ adapter.on('message', (message: BotIncomingMessage) => pending.push(service.handleBotIncomingMessage(message)));
+ const message: BotIncomingMessage = { platform: 'qq', userId: 'outsider', userName: 'User', chatId: 'chat', isGroup: false, receivedAt: 1, text: '重置', sourceMessageId: 'source' };
+ adapter.receive(message);
+ await Promise.all(pending);
+ assert.equal(routed, 0);
+ adapter.receive({ ...message, userId: 'user' });
+ await Promise.all(pending);
assert.equal(routed, 1);
await service.close();
assert.equal(closed, true);
diff --git a/packages/runtime/src/bots/__tests__/base-adapter.test.ts b/packages/runtime/src/bots/__tests__/base-adapter.test.ts
index b2a4afb9b6..51b1d08cdc 100644
--- a/packages/runtime/src/bots/__tests__/base-adapter.test.ts
+++ b/packages/runtime/src/bots/__tests__/base-adapter.test.ts
@@ -19,7 +19,7 @@
import assert from 'node:assert/strict';
import { describe, test } from 'node:test';
-import { createDefaultBotChannel } from '@maka/core/settings';
+import { BOT_PROVIDERS, createDefaultBotChannel } from '@maka/core/settings';
import {
BaseBotAdapter,
botReadinessFromSettings,
@@ -77,15 +77,43 @@ describe('BaseBotAdapter', () => {
assert.equal(adapter.getStatus().readiness, 'configured');
});
- test('does NOT restart when only allowedUserIds changes (runtime filter, not connection parameter)', () => {
- const base = createDefaultBotChannel('telegram');
- assert.equal(
- botSettingsRequireRestart(
- { ...base, allowedUserIds: ['123'] },
- { ...base, allowedUserIds: undefined },
- ),
- false,
- );
+ test('admits only listed senders in every channel and applies policy updates without restarting', () => {
+ for (const platform of BOT_PROVIDERS) {
+ const settings = { ...createDefaultBotChannel(platform), allowedUserIds: ['owner'] };
+ const adapter = new TestAdapter(platform, settings);
+ const messages: BotIncomingMessage[] = [];
+ adapter.on('message', (message) => messages.push(message));
+ const incoming = (userId: string, receivedAt: number): BotIncomingMessage => ({
+ platform,
+ userId,
+ userName: 'owner',
+ chatId: 'owner',
+ isGroup: true,
+ text: 'hello',
+ sourceMessageId: String(receivedAt),
+ receivedAt,
+ });
+ const owner = incoming('owner', 1);
+ adapter.publish(owner);
+ for (const userId of ['outsider', 'owner-extra', '']) adapter.publish(incoming(userId, 2));
+ assert.deepEqual(messages, [owner], platform);
+ assert.equal(adapter.getStatus().lastEventAt, 1, platform);
+
+ assert.deepEqual(adapter.updateSettings({ ...settings, allowedUserIds: ['outsider'] }), {
+ needsRestart: false,
+ });
+ adapter.publish(incoming('owner', 3));
+ const nextOwner = incoming('outsider', 4);
+ adapter.publish(nextOwner);
+ assert.deepEqual(messages, [owner, nextOwner], platform);
+
+ for (const allowedUserIds of [[], undefined]) {
+ adapter.updateSettings({ ...settings, allowedUserIds });
+ const unrestricted = incoming('any-user', messages.length + 5);
+ adapter.publish(unrestricted);
+ assert.equal(messages.at(-1), unrestricted, platform);
+ }
+ }
});
test('derives readiness only from current credential facts', () => {
diff --git a/packages/runtime/src/bots/__tests__/bot-user-allowlist.test.ts b/packages/runtime/src/bots/__tests__/bot-user-allowlist.test.ts
deleted file mode 100644
index 1f6cc8d2cc..0000000000
--- a/packages/runtime/src/bots/__tests__/bot-user-allowlist.test.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { strict as assert } from 'node:assert';
-import { describe, it } from 'node:test';
-
-import { __TEST__ } from '../telegram-bridge.js';
-
-const { isAllowedUser } = __TEST__;
-
-describe('isAllowedUser', () => {
- it('defaults open and otherwise requires an exact user-id match', () => {
- const cases: Array<[string[] | undefined, string, boolean]> = [
- [undefined, '12345', true],
- [[], '12345', true],
- [['12345', '67890'], '67890', true],
- [['1234567890'], '123', false],
- ];
- for (const [allowlist, userId, expected] of cases) {
- assert.equal(isAllowedUser(allowlist, userId), expected, `${allowlist}:${userId}`);
- }
- });
-});
diff --git a/packages/runtime/src/bots/__tests__/discord-bridge.test.ts b/packages/runtime/src/bots/__tests__/discord-bridge.test.ts
index d7579ef3f1..fdc97c0dca 100644
--- a/packages/runtime/src/bots/__tests__/discord-bridge.test.ts
+++ b/packages/runtime/src/bots/__tests__/discord-bridge.test.ts
@@ -20,6 +20,7 @@
import { strict as assert } from 'node:assert';
import { describe, it } from 'node:test';
import { createDefaultBotChannel } from '@maka/core/settings';
+import type { BotIncomingMessage } from '../types.js';
import { DiscordBotBridge, __TEST__ } from '../discord-bridge.js';
@@ -48,6 +49,40 @@ class ResetTrackingDiscordBridge extends DiscordBotBridge {
}
describe('resume gateway url lifecycle', () => {
+ it('drops unlisted gateway senders in direct and group messages', () => {
+ const settings = { ...createDefaultBotChannel('discord'), allowedUserIds: ['owner'] };
+ const bridge = new ResetTrackingDiscordBridge('discord', settings);
+ const messages: BotIncomingMessage[] = [];
+ const statuses: unknown[] = [];
+ bridge.on('message', (message) => messages.push(message));
+ bridge.on('statusChange', (status) => statuses.push(status));
+ for (const guild_id of [undefined, 'guild']) {
+ for (const userId of ['outsider', 'owner']) {
+ bridge.receive(
+ JSON.stringify({
+ op: 0,
+ t: 'MESSAGE_CREATE',
+ d: {
+ id: `${guild_id}:${userId}`,
+ channel_id: 'chat',
+ guild_id,
+ content: 'hello',
+ author: { id: userId, username: 'owner' },
+ },
+ }),
+ );
+ }
+ }
+ assert.deepEqual(
+ messages.map((message) => [message.userId, message.isGroup]),
+ [
+ ['owner', false],
+ ['owner', true],
+ ],
+ );
+ assert.equal(statuses.length, 2);
+ });
+
it('clears resumeGatewayUrl when the session is dropped', () => {
const bridge = new ResetTrackingDiscordBridge('discord', {
...createDefaultBotChannel('discord'),
diff --git a/packages/runtime/src/bots/__tests__/im-channel-mapping.test.ts b/packages/runtime/src/bots/__tests__/im-channel-mapping.test.ts
index f03adfe7f7..db6cfb6478 100644
--- a/packages/runtime/src/bots/__tests__/im-channel-mapping.test.ts
+++ b/packages/runtime/src/bots/__tests__/im-channel-mapping.test.ts
@@ -55,29 +55,6 @@ describe('IM channel event mapping', () => {
assert.equal(JSON.stringify(event).includes('must-not-cross'), false);
});
- it('drops Feishu group messages outside the local allowlist', () => {
- // PR1197 review: the Lark SDK dmAllowlist is DM-only, so a group message
- // from an unauthorized sender must be dropped by the bridge's own local
- // allowlist. Empty/absent list allows all (asserted implicitly by the
- // mapping test above, which passes no allowlist and returns an event).
- const message = {
- messageId: 'om_2',
- chatId: 'oc_2',
- chatType: 'group',
- senderId: 'ou_blocked',
- senderName: 'Mallory',
- content: 'hello',
- rawContentType: 'text',
- resources: [],
- mentions: [],
- mentionAll: false,
- mentionedBot: true,
- createTime: 123,
- raw: {},
- } satisfies NormalizedMessage;
- assert.equal(feishuMessageToEvent(message, 456, ['ou_allowed']), null);
- });
-
it('maps a WeCom direct text message to the sender conversation', () => {
const frame = {
headers: { req_id: 'req_1' },
@@ -102,22 +79,6 @@ describe('IM channel event mapping', () => {
});
});
- it('drops WeCom messages outside the local allowlist', () => {
- const frame = {
- headers: { req_id: 'req_2' },
- body: {
- msgid: 'msg_2',
- aibotid: 'bot_1',
- chatid: 'group_1',
- chattype: 'group',
- from: { userid: 'blocked_user' },
- msgtype: 'text',
- text: { content: 'question' },
- },
- } as WsFrame<TextMessage>;
- assert.equal(wecomTextFrameToEvent(frame, 789, ['allowed_user']), null);
- });
-
it('force-closes a Feishu raw socket even when the channel handshake never completed', async () => {
const calls: string[] = [];
await closeLarkChannel({
diff --git a/packages/runtime/src/bots/base-adapter.ts b/packages/runtime/src/bots/base-adapter.ts
index 112c74cb3e..d368dbff3b 100644
--- a/packages/runtime/src/bots/base-adapter.ts
+++ b/packages/runtime/src/bots/base-adapter.ts
@@ -72,9 +72,12 @@ export abstract class BaseBotAdapter extends EventEmitter implements BotBridge {
return { needsRestart };
}
- protected emitIncomingMessage(message: BotIncomingMessage): void {
+ protected emitIncomingMessage(message: BotIncomingMessage): boolean {
+ const allowedUserIds = this.settings.allowedUserIds;
+ if (allowedUserIds?.length && !allowedUserIds.includes(message.userId)) return false;
this.lastEventAt = message.receivedAt;
this.emit('message', message);
+ return true;
}
protected emitStatusChange(): void {
diff --git a/packages/runtime/src/bots/dingtalk-bridge.ts b/packages/runtime/src/bots/dingtalk-bridge.ts
index e2655a8ed9..87f77b159e 100644
--- a/packages/runtime/src/bots/dingtalk-bridge.ts
+++ b/packages/runtime/src/bots/dingtalk-bridge.ts
@@ -432,9 +432,7 @@ export class DingTalkBotBridge extends WsBridgeBase implements SendCapable {
}
if (payload) {
const event = dingTalkPayloadToEvent(payload, Date.now());
- if (event) {
- this.lastEventAt = event.receivedAt;
- this.emitIncomingMessage(event);
+ if (event && this.emitIncomingMessage(event)) {
this.emitStatusChange();
}
}
diff --git a/packages/runtime/src/bots/discord-bridge.ts b/packages/runtime/src/bots/discord-bridge.ts
index c24526e92c..6e210c2731 100644
--- a/packages/runtime/src/bots/discord-bridge.ts
+++ b/packages/runtime/src/bots/discord-bridge.ts
@@ -297,8 +297,7 @@ export class DiscordBotBridge extends GatewayBridgeBase implements SendCapable {
if (type === 'MESSAGE_CREATE') {
const event = discordMessageToEvent(d as DiscordMessagePayload, Date.now());
if (!event) return;
- this.lastEventAt = event.receivedAt;
- this.emitIncomingMessage(event);
+ if (!this.emitIncomingMessage(event)) return;
this.emitStatusChange();
return;
}
diff --git a/packages/runtime/src/bots/feishu-bridge.ts b/packages/runtime/src/bots/feishu-bridge.ts
index 82fe9553f0..ccf4a6dd55 100644
--- a/packages/runtime/src/bots/feishu-bridge.ts
+++ b/packages/runtime/src/bots/feishu-bridge.ts
@@ -41,20 +41,8 @@ export async function closeLarkChannel(channel: ClosableLarkChannel): Promise<vo
await channel.disconnect().catch(() => {});
}
-export function feishuMessageToEvent(
- message: NormalizedMessage,
- receivedAt: number,
- allowedUserIds?: ReadonlyArray<string>,
-) {
+export function feishuMessageToEvent(message: NormalizedMessage, receivedAt: number) {
if (!message.content.trim() || !message.senderId || !message.chatId) return null;
- // PR-BOT-USER-ALLOWLIST-0 / PR1197 review: the Lark SDK policy gate only
- // enforces the allowlist for DMs (PolicyGate.evaluateGroup checks
- // groupAllowlist + requireMention, and this bridge sets requireMention:false),
- // so group messages from unauthorized senders slip past the SDK. Mirror the
- // WeCom/Telegram local check: an empty/absent list allows all, otherwise the
- // sender must be listed. Dropped silently — no bounce that would let scanners
- // enumerate the policy.
- if (allowedUserIds?.length && !allowedUserIds.includes(message.senderId)) return null;
return {
platform: 'feishu' as const,
userId: message.senderId,
@@ -194,12 +182,11 @@ export class FeishuBotBridge extends BaseBotAdapter implements SendCapable {
this.unsubscribe.push(
channel.on('message', (message) => {
const receivedAt = Date.now();
- const event = feishuMessageToEvent(message, receivedAt, this.settings.allowedUserIds);
+ const event = feishuMessageToEvent(message, receivedAt);
if (!event || this.channel !== channel) return;
- this.lastEventAt = receivedAt;
+ if (!this.emitIncomingMessage(event)) return;
this.readiness = 'operational';
this.reason = undefined;
- this.emitIncomingMessage(event);
this.emitStatusChange();
}),
channel.on('error', (error) => {
diff --git a/packages/runtime/src/bots/qq-bridge.ts b/packages/runtime/src/bots/qq-bridge.ts
index a2c431f84b..2171dc3ed3 100644
--- a/packages/runtime/src/bots/qq-bridge.ts
+++ b/packages/runtime/src/bots/qq-bridge.ts
@@ -393,8 +393,7 @@ export class QQBotBridge extends GatewayBridgeBase implements SendCapable {
event = qqC2CMessageToEvent(d as QQC2CMessagePayload, receivedAt);
}
if (!event) return;
- this.lastEventAt = event.receivedAt;
- this.emitIncomingMessage(event);
+ if (!this.emitIncomingMessage(event)) return;
this.emitStatusChange();
}
diff --git a/packages/runtime/src/bots/telegram-bridge.ts b/packages/runtime/src/bots/telegram-bridge.ts
index e3437d6242..526ea1fc23 100644
--- a/packages/runtime/src/bots/telegram-bridge.ts
+++ b/packages/runtime/src/bots/telegram-bridge.ts
@@ -133,18 +133,6 @@ function normalizeTelegramPrivateChatId(value: string): number | undefined {
return Number.isSafeInteger(numeric) ? numeric : undefined;
}
-/**
- * PR-BOT-USER-ALLOWLIST-0: runtime allowlist gate. `undefined` or empty
- * means no restriction; any other set is enforced as exact match against
- * the platform-native user id. The settings normalize layer already
- * trims, dedups, and caps the persisted array, so this function only
- * has to do membership.
- */
-function isAllowedUser(allowedUserIds: ReadonlyArray<string> | undefined, userId: string): boolean {
- if (!allowedUserIds || allowedUserIds.length === 0) return true;
- return allowedUserIds.includes(userId);
-}
-
/**
* PR-BOT-NON-TEXT-MESSAGE-ACK-0 (external bot research): map a Telegram
* `message` object to a stable {@link BotAttachmentKind} so the handler
@@ -246,7 +234,6 @@ export const __TEST__ = {
buildTelegramSendBody,
normalizeTelegramReplyToMessageId,
normalizeTelegramPrivateChatId,
- isAllowedUser,
classifyTelegramSendResponse,
createTelegramReplyStream,
telegramDraftId,
@@ -452,27 +439,23 @@ export class TelegramBotBridge extends BaseBotAdapter implements SendCapable {
private handleTelegramMessage(message: any): void {
if (!message?.from) return;
const userId = String(message.from.id);
- // PR-BOT-USER-ALLOWLIST-0: drop unauthorized senders silently when an
- // allowlist is configured. No bounce reply — that would let scanners
- // enumerate the policy by toggling IDs. Status fields are NOT updated
- // for dropped messages so the bridge's `lastEventAt` continues to
- // reflect authentic activity from authorized users only.
- if (!isAllowedUser(this.settings.allowedUserIds, userId)) return;
- this.lastEventAt = Date.now();
+ const attachmentKind = telegramAttachmentKind(message);
+ if (
+ !this.emitIncomingMessage({
+ platform: 'telegram',
+ userId,
+ userName: message.from.username ?? message.from.first_name ?? userId,
+ chatId: String(message.chat?.id ?? ''),
+ isGroup: message.chat?.type === 'group' || message.chat?.type === 'supergroup',
+ text: message.text ?? message.caption ?? '',
+ sourceMessageId: String(message.message_id ?? ''),
+ receivedAt: Date.now(),
+ ...(attachmentKind ? { attachmentKind } : {}),
+ })
+ )
+ return;
this.readiness = 'operational';
this.reason = undefined;
- const attachmentKind = telegramAttachmentKind(message);
- this.emitIncomingMessage({
- platform: 'telegram',
- userId,
- userName: message.from.username ?? message.from.first_name ?? userId,
- chatId: String(message.chat?.id ?? ''),
- isGroup: message.chat?.type === 'group' || message.chat?.type === 'supergroup',
- text: message.text ?? message.caption ?? '',
- sourceMessageId: String(message.message_id ?? ''),
- receivedAt: this.lastEventAt,
- ...(attachmentKind ? { attachmentKind } : {}),
- });
this.emitStatusChange();
}
diff --git a/packages/runtime/src/bots/wechat-bridge.ts b/packages/runtime/src/bots/wechat-bridge.ts
index ab9fc63d53..28c61f9387 100644
--- a/packages/runtime/src/bots/wechat-bridge.ts
+++ b/packages/runtime/src/bots/wechat-bridge.ts
@@ -227,9 +227,9 @@ export class WechatBridge extends BaseBotAdapter implements SendCapable {
cursor.sinceEpochSeconds,
Math.floor(event.receivedAt / 1000),
);
+ if (!this.emitIncomingMessage(event)) continue;
this.readiness = 'operational';
this.reason = undefined;
- this.emitIncomingMessage(event);
this.emitStatusChange();
}
return true;
@@ -274,10 +274,9 @@ export class WechatBridge extends BaseBotAdapter implements SendCapable {
for (const message of messages) {
const event = mapWechatIlinkMessage(message);
if (!event) continue;
+ if (!this.emitIncomingMessage(event)) continue;
this.readiness = 'operational';
this.reason = undefined;
- this.lastEventAt = Date.now();
- this.emitIncomingMessage(event);
this.emitStatusChange();
}
if (this.running && messages.length === 0) await sleep(800);
diff --git a/packages/runtime/src/bots/wecom-bridge.ts b/packages/runtime/src/bots/wecom-bridge.ts
index 07cf6ddf5d..150740d0fd 100644
--- a/packages/runtime/src/bots/wecom-bridge.ts
+++ b/packages/runtime/src/bots/wecom-bridge.ts
@@ -40,16 +40,11 @@ const quietLogger = {
error() {},
};
-export function wecomTextFrameToEvent(
- frame: WsFrame<TextMessage>,
- receivedAt: number,
- allowedUserIds?: ReadonlyArray<string>,
-) {
+export function wecomTextFrameToEvent(frame: WsFrame<TextMessage>, receivedAt: number) {
const body = frame.body;
if (!body || body.msgtype !== 'text' || typeof body.text?.content !== 'string') return null;
const userId = body.from?.userid;
if (typeof userId !== 'string' || !userId) return null;
- if (allowedUserIds?.length && !allowedUserIds.includes(userId)) return null;
const isGroup = body.chattype === 'group';
const chatId = isGroup ? body.chatid : userId;
if (typeof chatId !== 'string' || !chatId) return null;
@@ -199,12 +194,11 @@ export class WeComBotBridge extends BaseBotAdapter implements SendCapable {
private wire(client: WSClient, botId: string): void {
client.on('message.text', (frame) => {
const receivedAt = Date.now();
- const event = wecomTextFrameToEvent(frame, receivedAt, this.settings.allowedUserIds);
+ const event = wecomTextFrameToEvent(frame, receivedAt);
if (!event || this.client !== client) return;
- this.lastEventAt = receivedAt;
+ if (!this.emitIncomingMessage(event)) return;
this.readiness = 'operational';
this.reason = undefined;
- this.emitIncomingMessage(event);
this.emitStatusChange();
});
client.on('authenticated', () => {
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org