Skip to content

Commit a4a4c76

Browse files
authored
fix(sessions): derive channel from direct-chat session keys in send-policy (#92022)
deriveChannelFromKey returned undefined for direct/dm keys, so channel-scoped send rules never fired for direct chats. Treat parts[0] as the channel for direct/dm keys too, matching deriveChatTypeFromKey.
1 parent b9e1099 commit a4a4c76

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

src/sessions/send-policy.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ describe("resolveSendPolicy", () => {
6767
sessionKey: "agent:main:other-channel:group:dev",
6868
expected: "allow",
6969
},
70+
{
71+
name: "channel-scoped deny fires for direct session key without explicit channel field",
72+
cfg: cfgWithRules([{ action: "deny", match: { channel: "demo-channel" } }]),
73+
sessionKey: "demo-channel:direct:user-1",
74+
expected: "deny",
75+
},
7076
])("$name", ({ cfg, entry, sessionKey, expected }) => {
7177
expect(resolveSendPolicy({ cfg, entry, sessionKey })).toBe(expected);
7278
});

src/sessions/send-policy.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ function deriveChannelFromKey(key?: string) {
4646
return undefined;
4747
}
4848
const parts = normalizedKey.split(":").filter(Boolean);
49-
if (parts.length >= 3 && (parts[1] === "group" || parts[1] === "channel")) {
49+
// Canonical key layout is <channel>:<peerKind>:<peerId>; parts[0] is the channel
50+
// for direct/dm peers too, so channel-scoped rules also fire for direct chats.
51+
if (
52+
parts.length >= 3 &&
53+
(parts[1] === "group" || parts[1] === "channel" || parts[1] === "direct" || parts[1] === "dm")
54+
) {
5055
return normalizeMatchValue(parts[0]);
5156
}
5257
return undefined;

0 commit comments

Comments
 (0)