@@ -62,7 +62,7 @@ route ClientApi where
63route FederationApi where
63route FederationApi where
64 /federation
64 /federation
65− POST {events: [GossipEvent], hopsRemaining: Int} /gossip headers {authorization: Text}
65+ POST {events: [GossipEvent], hopsRemaining: Int, fromServer: Text} /gossip headers {authorization: Text}
66 -> {ok: Bool}
66 -> {ok: Bool}
67 = RecvGossip
67 = RecvGossip
68 POST {toKey: Text, fromKey: Text, encryptedBlob: Text, timestamp: Int, originServer: Text, messageId: Text} /forward headers {authorization: Text}
68 POST {toKey: Text, fromKey: Text, encryptedBlob: Text, timestamp: Int, originServer: Text, messageId: Text} /forward headers {authorization: Text}
@@ -231,7 +231,7 @@ serve = \req -> case req of
231 then sendToEach result.peerServers (\server ->
231 then sendToEach result.peerServers (\server ->
232 httpPost (federationScheme ++ server ++ "/federation/gossip")
232 httpPost (federationScheme ++ server ++ "/federation/gossip")
233 {authorization: "Bearer " ++ federationSecret}
233 {authorization: "Bearer " ++ federationSecret}
234− {events: [{eventType: "online", pubkey: pubkey, server: serverHost, timestamp: t, ttl: 3600}], hopsRemaining: 2})
234+ {events: [{eventType: "online", pubkey: pubkey, server: serverHost, timestamp: t, ttl: 3600}], hopsRemaining: 2, fromServer: serverHost})
235 else yield {}
235 else yield {}
237 Poll {cursor, authorization, respond} -> do
237 Poll {cursor, authorization, respond} -> do
@@ -315,6 +315,9 @@ serve = \req -> case req of
316 AckMessages {messageIds, authorization, respond} -> do
316 AckMessages {messageIds, authorization, respond} -> do
318+ let dedupedIds = fold (\acc mid ->
319+ if count (do a <- acc; where a == mid; yield a) > 0 then acc
320+ else union acc [mid]) [] messageIds
318 result <- atomic do
321 result <- atomic do
319 pruneExpired t
322 pruneExpired t
320 sessions <- *sessions
323 sessions <- *sessions
@@ -324,7 +327,7 @@ serve = \req -> case req of
324 Nothing {} -> []
327 Nothing {} -> []
325 Just {value: s} -> do
328 Just {value: s} -> do
326 m <- messages
329 m <- messages
327− mid <- messageIds
330+ mid <- dedupedIds
328 where m.messageId == mid
331 where m.messageId == mid
329 where m.toKey == s.pubkey
332 where m.toKey == s.pubkey
@@ -383,7 +386,7 @@ serve = \req -> case req of
383 then respond {online: not (result.foundServer == ""), server: result.foundServer}
386 then respond {online: not (result.foundServer == ""), server: result.foundServer}
384 else respond {online: False {}, server: "unauthorized"}
387 else respond {online: False {}, server: "unauthorized"}
386− RecvGossip {events, hopsRemaining, authorization, respond} -> do
389+ RecvGossip {events, hopsRemaining, fromServer, authorization, respond} -> do
388 let authorized = verifyFederationAuth authorization
391 let authorized = verifyFederationAuth authorization
389 let cappedHops = if hopsRemaining > 5 then 5 else hopsRemaining
392 let cappedHops = if hopsRemaining > 5 then 5 else hopsRemaining
@@ -448,7 +451,14 @@ serve = \req -> case req of
448 set *presence = if validRequest
451 set *presence = if validRequest
449 then union cleaned deduped
452 then union cleaned deduped
450 else presence
453 else presence
454+ let validEvents = do
456+ where not (e.server == "")
457+ where not (e.pubkey == "")
458+ where e.timestamp <= t
459+ where e.timestamp + (clampTtl e.ttl) * 1000 > t
451− if validRequest && cappedHops > 1 && not (federationSecret == "")
461+ if validRequest && cappedHops > 1 && not (federationSecret == "") && count validEvents > 0
453 peerServers <- atomic do
463 peerServers <- atomic do
454 presence <- *presence
464 presence <- *presence
@@ -458,7 +468,7 @@ serve = \req -> case req of
458 else union acc [p.server]) [] presence)
468 else union acc [p.server]) [] presence)
459 let senderServers = fold (\acc e ->
469 let senderServers = fold (\acc e ->
460 if count (do a <- acc; where a == e.server; yield a) > 0 then acc
470 if count (do a <- acc; where a == e.server; yield a) > 0 then acc
461− else union acc [e.server]) [] events
471+ else union acc [e.server]) (if fromServer == "" then [] else [fromServer]) events
462 let targets = do
472 let targets = do
463 s <- peerServers
473 s <- peerServers
464 where count (do ss <- senderServers; where ss == s; yield ss) == 0
474 where count (do ss <- senderServers; where ss == s; yield ss) == 0
@@ -466,7 +476,7 @@ serve = \req -> case req of
466 sendToEach targets (\server ->
476 sendToEach targets (\server ->
467 httpPost (federationScheme ++ server ++ "/federation/gossip")
477 httpPost (federationScheme ++ server ++ "/federation/gossip")
468 {authorization: "Bearer " ++ federationSecret}
478 {authorization: "Bearer " ++ federationSecret}
469− {events: events, hopsRemaining: cappedHops - 1})
479+ {events: validEvents, hopsRemaining: cappedHops - 1, fromServer: serverHost})
470 else yield {}
480 else yield {}
471 respond {ok: validRequest}
481 respond {ok: validRequest}