@@ -286,9 +286,11 @@ stripTrailingDot = \s ->
286286 else if take 1 s == "." && isTrailingDots (drop 1 s) then stripTrailingDot (drop 1 s)
287287 else take 1 s ++ stripTrailingDot (drop 1 s)
288288
289+normalizeServerName : Text -> Text
289290normalizeServerName = \s -> toLower (stripTrailingDot s)
290291
291292serverHostN = normalizeServerName serverHost
293+isLocalServer : Text -> Bool
292294isLocalServer = \s -> s == serverHostN
293295
294296containsSuffixN = \suffix suffixLen s ->
@@ -323,6 +325,7 @@ matchesHostname = \sn name ->
323325matchesHostnameOrSubdomain = \sn name ->
324326 matchesHostname sn name || containsSuffix ("." ++ name) sn
325327
328+isBadServerName : Text -> Bool
326329isBadServerName = \sn ->
327330 sn == ""
328331 || take 1 sn == "."
@@ -363,32 +366,40 @@ extractToken = \authHeader ->
363366 then Just {value: token}
364367 else Nothing {}
365368
369+verifySecret : Text -> Text -> Bool
366370verifySecret = \token secret ->
367371 secret != "" && safeCompare token secret
368372
373+verifyFederationAuth : Text -> Bool
369374verifyFederationAuth = \authorization ->
370375 case extractToken authorization of
371376 Nothing {} -> False {}
372377 Just {value: token} -> verifySecret token federationSecret
373378
379+verifyMaintenanceAuth : Text -> Bool
374380verifyMaintenanceAuth = \authorization ->
375381 case extractToken authorization of
376382 Nothing {} -> False {}
377383 Just {value: token} -> verifySecret token federationSecret || verifySecret token maintenanceSecret
378384
385+clampTtl : Int<S> -> Int<S>
379386clampTtl = clamp 1 maxPresenceTtl
380387
388+clampTimestamp : Timestamp -> Timestamp -> Timestamp
381389clampTimestamp = \timestamp t -> clamp (t - messageMaxAge) t timestamp
382390
391+deliveryToMessageStatus : DeliveryStatus -> MessageStatus
383392deliveryToMessageStatus = \ds -> case ds of
384393 DsDelivered {} -> MsDelivered {}
385394 DsFederated {} -> MsFederated {}
386395 DsQueued {} -> MsQueued {}
387396
397+nextSeqTs : Timestamp -> Timestamp -> Timestamp
388398nextSeqTs = \t seqCounter -> if t > seqCounter then t else seqCounter + 1
389399
390400takeN = \items n -> (fold (\acc e -> if acc.n >= n then acc else {n: acc.n + 1, items: union acc.items [e]}) {n: 0, items: []} items).items
391401
402+dedupMessageIds : [MessageIdHex] -> [MessageIdHex]
392403dedupMessageIds = \messageIds ->
393404 fold (\acc mid ->
394405 if count acc >= maxMessageIds then acc
@@ -502,9 +513,11 @@ capGossipPresence = \args ->
502513 (do e <- reclaimedEntries; yield (pubkeyServer e)),
503514 withinCapacity: False {}}
504515
516+countMessagesFor : [Message] -> PubkeyHex -> Timestamp -> Int
505517countMessagesFor = \messages toKey t ->
506518 count (do m <- messages; where m.toKey == toKey && m.receivedAt >= t - messageMaxAge; yield m)
507519
520+hasMessage : MessageIdHex -> PubkeyHex -> [{messageId: MessageIdHex, toKey: PubkeyHex | a}] -> Bool
508521hasMessage = \mid toKey items -> any items (\x -> x.messageId == mid && x.toKey == toKey)
509522
510523
@@ -627,13 +640,11 @@ mergeGossipPresence = \presence deduped trustedOffline fromServer t ->
627640 gossipPeerServers: collectPeerServers capResult.finalPresence (\p -> p.server),
628641 withinCapacity: capResult.withinCapacity}
629642
630−rejectFederation = \t respond -> do
631− maybePruneAndBroadcast t
632− yield (respond {ok: False {}})
633−
634643withFederationAuth = \authorization t respond precondition action ->
635644 if not (verifyFederationAuth authorization) || not precondition
636− then rejectFederation t respond
645+ then do
646+ maybePruneAndBroadcast t
647+ yield (respond {ok: False {}})
637648 else action
638649
639650maybePruneAndBroadcast = \t -> do