fix(broker): topic-tagged sends bypass direct-target pre-flight
handleSend's pre-flight check rejected #<topicId> sends because the target wasn't matched by @group / * / pubkey, so it fell into the "direct" branch and looked for a peer with that pubkey. Topic targets need their own class — delivery happens via topic_member, not by matching connected peers. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1855,16 +1855,22 @@ async function handleSend(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-flight: for direct sends (not @group, not *), verify at least one
|
// Pre-flight: for direct sends (not @group, not #topic, not *), verify
|
||||||
// matching connected peer exists BEFORE queueing. Prevents silent drops
|
// at least one matching connected peer exists BEFORE queueing. Prevents
|
||||||
// when a user sends to a typo, their own pubkey with no other session,
|
// silent drops when a user sends to a typo, their own pubkey with no
|
||||||
// or a peer who has disconnected. The CLI's resolveClient already guards
|
// other session, or a peer who has disconnected. The CLI's
|
||||||
// name-based targets; this catches raw-pubkey and CLI-bypassing clients.
|
// resolveClient already guards name-based targets; this catches
|
||||||
|
// raw-pubkey and CLI-bypassing clients.
|
||||||
const isGroupTargetEarly = msg.targetSpec.startsWith("@");
|
const isGroupTargetEarly = msg.targetSpec.startsWith("@");
|
||||||
|
const isTopicTargetEarly = msg.targetSpec.startsWith("#");
|
||||||
const isBroadcastEarly =
|
const isBroadcastEarly =
|
||||||
msg.targetSpec === "*" ||
|
msg.targetSpec === "*" ||
|
||||||
(isGroupTargetEarly && msg.targetSpec === "@all");
|
(isGroupTargetEarly && msg.targetSpec === "@all");
|
||||||
const isDirectEarly = !isGroupTargetEarly && !isBroadcastEarly && msg.targetSpec !== "*";
|
const isDirectEarly =
|
||||||
|
!isGroupTargetEarly &&
|
||||||
|
!isTopicTargetEarly &&
|
||||||
|
!isBroadcastEarly &&
|
||||||
|
msg.targetSpec !== "*";
|
||||||
if (isDirectEarly) {
|
if (isDirectEarly) {
|
||||||
// Identify candidate recipient connections — anyone in the mesh whose
|
// Identify candidate recipient connections — anyone in the mesh whose
|
||||||
// member or session pubkey matches the target. Then check grants to
|
// member or session pubkey matches the target. Then check grants to
|
||||||
|
|||||||
Reference in New Issue
Block a user