@@ -28,7 +28,7 @@ type GossipEvent = {eventType: Text, pubkey: Text, server: Text, timestamp: Int,
29*sessions : [{token: Text, pubkey: Text, expiresAt: Int}]
29*sessions : [{token: Text, pubkey: Text, expiresAt: Int}]
31−*messages : [{messageId: Text, toKey: Text, fromKey: Text, encryptedBlob: Text, timestamp: Int, originServer: Text}]
31+*messages : [{messageId: Text, toKey: Text, fromKey: Text, encryptedBlob: Text, timestamp: Int, originServer: Text, receivedAt: Int}]
33*presence : [{pubkey: Text, server: Text, expiresAt: Int}]
33*presence : [{pubkey: Text, server: Text, expiresAt: Int}]
@@ -155,15 +155,18 @@ pruneExpired = \t -> do
156serve = \req -> case req of
156serve = \req -> case req of
158− ReqChallenge {pubkey, respond} -> do
158+ ReqChallenge {pubkey, respond} ->
160+ then respond {challenge: ""}
159− challenge <- genToken
162+ challenge <- genToken
160− t <- now
163+ t <- now
161− atomic do
164+ atomic do
162− pruneExpired t
165+ pruneExpired t
163− challenges <- *challenges
166+ challenges <- *challenges
164− set *challenges = union challenges
167+ set *challenges = union challenges
165− [{pubkey: pubkey, challenge: challenge, expiresAt: t + 60000}]
168+ [{pubkey: pubkey, challenge: challenge, expiresAt: t + 60000}]
166− respond {challenge: challenge}
169+ respond {challenge: challenge}
168 VerifyAuth {pubkey, challenge, signature, respond} -> do
171 VerifyAuth {pubkey, challenge, signature, respond} -> do
@@ -183,12 +186,12 @@ serve = \req -> case req of
183 let sigValid = case matched of
186 let sigValid = case matched of
184 Nothing {} -> False {}
187 Nothing {} -> False {}
185 _ -> verify (bytesFromHex pubkey) (textToBytes challenge) (bytesFromHex signature)
188 _ -> verify (bytesFromHex pubkey) (textToBytes challenge) (bytesFromHex signature)
186− set *challenges = case matched of
189+ set *challenges = if sigValid
187− Nothing {} -> challenges
189 c <- challenges
191 c <- challenges
190 where not (c.pubkey == pubkey && c.challenge == challenge)
192 where not (c.pubkey == pubkey && c.challenge == challenge)
192 let existingForKey = do
195 let existingForKey = do
193 s <- sessions
196 s <- sessions
194 where s.pubkey == pubkey
197 where s.pubkey == pubkey
@@ -245,7 +248,7 @@ serve = \req -> case req of
245 m <- messages
248 m <- messages
246 where m.toKey == s.pubkey
249 where m.toKey == s.pubkey
247 where m.timestamp >= t - messageMaxAge
250 where m.timestamp >= t - messageMaxAge
248− where m.timestamp >= cursor
251+ where m.receivedAt > cursor
249 yield {id: m.messageId, eventType: "message",
252 yield {id: m.messageId, eventType: "message",
250 payload: toJson {toKey: m.toKey, fromKey: m.fromKey,
253 payload: toJson {toKey: m.toKey, fromKey: m.fromKey,
251 encryptedBlob: m.encryptedBlob,
254 encryptedBlob: m.encryptedBlob,
@@ -272,7 +275,7 @@ serve = \req -> case req of
272 Just {value: s} -> if validInput
275 Just {value: s} -> if validInput
273 then union messages
276 then union messages
274 [{messageId: msgId, toKey: to, fromKey: s.pubkey,
277 [{messageId: msgId, toKey: to, fromKey: s.pubkey,
275− encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: ""}]
278+ encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: "", receivedAt: t}]
276 else messages
279 else messages
277 let localOnline = case session of
280 let localOnline = case session of
278 Nothing {} -> False {}
281 Nothing {} -> False {}
@@ -325,13 +328,9 @@ serve = \req -> case req of
325 where m.messageId == mid
328 where m.messageId == mid
326 where m.toKey == s.pubkey
329 where m.toKey == s.pubkey
330− where m.originServer == ""
332 set *messages = case session of
331 set *messages = case session of
333 Nothing {} -> messages
332 Nothing {} -> messages
334− Just {value: _} -> diff messages localAcked
333+ Just {value: _} -> diff messages ackedMessages
335 let ok = case session of
334 let ok = case session of
336 Nothing {} -> False {}
335 Nothing {} -> False {}
337 _ -> True {}
336 _ -> True {}
@@ -345,20 +344,11 @@ serve = \req -> case req of
345 if count (do a <- acc; where a == m.originServer; yield a) > 0 then acc
344 if count (do a <- acc; where a == m.originServer; yield a) > 0 then acc
346 else union acc [m.originServer]) [] fedMessages
345 else union acc [m.originServer]) [] fedMessages
347 if result.ok && count originServers > 0 && not (federationSecret == "")
346 if result.ok && count originServers > 0 && not (federationSecret == "")
348− then sendToEach originServers (\server -> do
347+ then sendToEach originServers (\server ->
349− ackResult <- httpPost (federationScheme ++ server ++ "/federation/ack")
348+ httpPost (federationScheme ++ server ++ "/federation/ack")
350 {authorization: "Bearer " ++ federationSecret}
349 {authorization: "Bearer " ++ federationSecret}
351 {messageIds: (do m <- fedMessages; where m.originServer == server; yield m.messageId),
350 {messageIds: (do m <- fedMessages; where m.originServer == server; yield m.messageId),
352− originServer: server, fromServer: serverHost}
351+ originServer: server, fromServer: serverHost})
355− messages <- *messages
356− set *messages = diff messages (do
358− mid <- (do fm <- fedMessages; where fm.originServer == server; yield fm.messageId)
359− where m.messageId == mid
362 else yield {}
352 else yield {}
363 respond {ok: result.ok}
353 respond {ok: result.ok}
@@ -396,7 +386,8 @@ serve = \req -> case req of
396 RecvGossip {events, hopsRemaining, authorization, respond} -> do
386 RecvGossip {events, hopsRemaining, authorization, respond} -> do
398 let authorized = verifyFederationAuth authorization
388 let authorized = verifyFederationAuth authorization
389+ let cappedHops = if hopsRemaining > 5 then 5 else hopsRemaining
399− let validRequest = authorized && hopsRemaining >= 1
390+ let validRequest = authorized && cappedHops >= 1
400 let onlineEntries = do
391 let onlineEntries = do
401 e <- events
392 e <- events
402 where e.eventType == "online"
393 where e.eventType == "online"
@@ -457,7 +448,7 @@ serve = \req -> case req of
457 set *presence = if validRequest
448 set *presence = if validRequest
458 then union cleaned deduped
449 then union cleaned deduped
459 else presence
450 else presence
460− if validRequest && hopsRemaining > 1 && not (federationSecret == "")
451+ if validRequest && cappedHops > 1 && not (federationSecret == "")
462 peerServers <- atomic do
453 peerServers <- atomic do
463 presence <- *presence
454 presence <- *presence
@@ -475,7 +466,7 @@ serve = \req -> case req of
475 sendToEach targets (\server ->
466 sendToEach targets (\server ->
476 httpPost (federationScheme ++ server ++ "/federation/gossip")
467 httpPost (federationScheme ++ server ++ "/federation/gossip")
477 {authorization: "Bearer " ++ federationSecret}
468 {authorization: "Bearer " ++ federationSecret}
478− {events: events, hopsRemaining: hopsRemaining - 1})
469+ {events: events, hopsRemaining: cappedHops - 1})
479 else yield {}
470 else yield {}
480 respond {ok: validRequest}
471 respond {ok: validRequest}
@@ -497,7 +488,7 @@ serve = \req -> case req of
497 set *messages = if shouldInsert
488 set *messages = if shouldInsert
498 then union messages
489 then union messages
499 [{messageId: messageId, toKey: toKey, fromKey: fromKey,
490 [{messageId: messageId, toKey: toKey, fromKey: fromKey,
500− encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: originServer}]
491+ encryptedBlob: encryptedBlob, timestamp: clampedTs, originServer: originServer, receivedAt: t}]
501 else messages
492 else messages
502 respond {ok: authorized && validOrigin && validFields}
493 respond {ok: authorized && validOrigin && validFields}