fix(federation): harden processFriendRequestCreateEvent receiver-side
Two correctness/defense fixes plus regression tests in the existing in-memory drizzle test file. 1. Reverse-direction idempotency. The sender-side path in social.ts checks BOTH directions of friend_requests and returns 409 incoming_request_exists when an opposite-direction row exists. The receiver only matched from->to, so cross-fire (alice@A and bob@B both click "add friend" near-simultaneously) produced two opposite pending rows on each instance. The receiver now silent-accepts when either direction matches a pending row, mirroring the sender's both-direction check. 2. Self-target guard (defense-in-depth). Reject events whose from-identity equals to-identity (after normalizeOriginForCompare) with a new receiver-acknowledged 4xx code self_target_invalid. Sender's local cannot_friend_self should catch this, but the receiver does not trust upstream validation. Added to TERMINAL_REJECTION_REASONS so the standard rollback fires (mapped client-side to peer_rejected). Logged at console.warn. Spec updates: social.md inbound contract now documents both-direction idempotency and the self-target guard; federation.md and the s2s-friend-add design spec list the new terminal rejection reason.
This commit is contained in:
@@ -66,6 +66,7 @@ const TERMINAL_REJECTION_REASONS = new Set<string>([
|
||||
'recipient_not_found', // receiver doesn't know the target user
|
||||
'attribution_mismatch', // payload claims a homeInstance the source can't authoritatively speak for
|
||||
'unknown_event_type', // peer doesn't understand this eventType — never will
|
||||
'self_target_invalid', // payload's from-identity equals to-identity (sender's self-check should have caught this)
|
||||
]);
|
||||
|
||||
// ─── Worker State ───────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user