fix: expire stale call pushes
This commit is contained in:
@@ -36,6 +36,9 @@ func payloadToData(pl *push.Payload) (map[string]string, error) {
|
||||
}
|
||||
data["topic"] = pl.Topic
|
||||
data["ts"] = pl.Timestamp.Format(time.RFC3339Nano)
|
||||
if pl.ExpiresAt != nil && !pl.ExpiresAt.IsZero() {
|
||||
data["expires_at"] = pl.ExpiresAt.UTC().Format(time.RFC3339Nano)
|
||||
}
|
||||
// Must use "xfrom" because "from" is a reserved word. Google did not bother to document it anywhere.
|
||||
data["xfrom"] = pl.From
|
||||
if pl.What == push.ActMsg {
|
||||
@@ -89,6 +92,15 @@ func payloadToData(pl *push.Payload) (map[string]string, error) {
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func pushExpired(data map[string]string) bool {
|
||||
expiresAt := data["expires_at"]
|
||||
if expiresAt == "" {
|
||||
return false
|
||||
}
|
||||
parsed, err := time.Parse(time.RFC3339Nano, expiresAt)
|
||||
return err == nil && !time.Now().UTC().Before(parsed)
|
||||
}
|
||||
|
||||
func clonePayload(src map[string]string) map[string]string {
|
||||
dst := make(map[string]string, len(src))
|
||||
maps.Copy(dst, src)
|
||||
@@ -103,6 +115,9 @@ func PrepareV1Notifications(rcpt *push.Receipt, config *configType) ([]*fcmv1.Me
|
||||
logs.Warn.Println("fcm push: could not parse payload:", err)
|
||||
return nil, nil
|
||||
}
|
||||
if pushExpired(data) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Device IDs to send pushes to.
|
||||
var devices map[t.Uid][]t.DeviceDef
|
||||
@@ -322,6 +337,11 @@ func apnsNotificationConfig(what, topic string, data map[string]string, unread i
|
||||
if config.TimeToLive > 0 {
|
||||
expires = time.Now().UTC().Add(time.Duration(config.TimeToLive) * time.Second)
|
||||
}
|
||||
if expiresAt := data["expires_at"]; expiresAt != "" {
|
||||
if parsed, err := time.Parse(time.RFC3339Nano, expiresAt); err == nil && parsed.Before(expires) {
|
||||
expires = parsed
|
||||
}
|
||||
}
|
||||
bundleId := config.ApnsBundleID
|
||||
pushType := common.ApnsPushTypeAlert
|
||||
priority := 10
|
||||
@@ -335,7 +355,10 @@ func apnsNotificationConfig(what, topic string, data map[string]string, unread i
|
||||
// a different adapter.
|
||||
// pushType = common.ApnsPushTypeVoip
|
||||
// bundleId += ".voip"
|
||||
expires = time.Now().UTC().Add(time.Duration(voipTimeToLive) * time.Second)
|
||||
callExpires := time.Now().UTC().Add(time.Duration(voipTimeToLive) * time.Second)
|
||||
if expires.After(callExpires) {
|
||||
expires = callExpires
|
||||
}
|
||||
} else if what == push.ActRead {
|
||||
priority = 5
|
||||
interruptionLevel = common.InterruptionLevelPassive
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package fcm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tinode/chat/server/push"
|
||||
"github.com/tinode/chat/server/store/types"
|
||||
)
|
||||
|
||||
func TestPayloadToDataIncludesCallExpiresAt(t *testing.T) {
|
||||
expiresAt := time.Date(2026, 9, 4, 10, 0, 30, 0, time.UTC)
|
||||
data, err := payloadToData(&push.Payload{
|
||||
What: push.ActMsg,
|
||||
Topic: "p2pTopic",
|
||||
From: "usrCaller",
|
||||
SeqId: 30,
|
||||
Webrtc: "started",
|
||||
ExpiresAt: &expiresAt,
|
||||
Content: map[string]any{
|
||||
"txt": "call",
|
||||
},
|
||||
Timestamp: time.Date(2026, 9, 4, 10, 0, 0, 0, time.UTC),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("payload data: %v", err)
|
||||
}
|
||||
if data["expires_at"] != expiresAt.Format(time.RFC3339Nano) {
|
||||
t.Fatalf("unexpected expires_at: %#v", data)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareV1NotificationsDropsExpiredCallInvite(t *testing.T) {
|
||||
expiresAt := time.Now().Add(-time.Second)
|
||||
messages, uids := PrepareV1Notifications(&push.Receipt{
|
||||
TenantID: 7,
|
||||
To: map[types.Uid]push.Recipient{
|
||||
42: {},
|
||||
},
|
||||
Payload: push.Payload{
|
||||
What: push.ActMsg,
|
||||
Topic: "p2pTopic",
|
||||
SeqId: 30,
|
||||
Webrtc: "started",
|
||||
ExpiresAt: &expiresAt,
|
||||
Content: map[string]any{
|
||||
"txt": "call",
|
||||
},
|
||||
Timestamp: time.Now().Add(-time.Minute),
|
||||
},
|
||||
}, &configType{})
|
||||
if len(messages) != 0 || len(uids) != 0 {
|
||||
t.Fatalf("expired call invite should be dropped: messages=%d uids=%#v", len(messages), uids)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user