diff --git a/keyserver/api/api.go b/keyserver/api/api.go index 3933961c..54eb04f8 100644 --- a/keyserver/api/api.go +++ b/keyserver/api/api.go @@ -15,6 +15,7 @@ package api import ( + "bytes" "context" "encoding/json" "strings" @@ -73,6 +74,26 @@ type DeviceMessage struct { DeviceChangeID int64 } +// DeviceKeysEqual returns true if the device keys updates contain the +// same display name and key JSON. This will return false if either of +// the updates is not a device keys update, or if the user ID/device ID +// differ between the two. +func (m1 *DeviceMessage) DeviceKeysEqual(m2 *DeviceMessage) bool { + if m1.DeviceKeys == nil || m2.DeviceKeys == nil { + return false + } + if m1.UserID != m2.UserID || m1.DeviceID != m2.DeviceID { + return false + } + if m1.DisplayName != m2.DisplayName { + return false // different display names + } + if len(m1.KeyJSON) == 0 || len(m2.KeyJSON) == 0 { + return false // either is empty + } + return bytes.Equal(m1.KeyJSON, m2.KeyJSON) +} + // DeviceKeys represents a set of device keys for a single device // https://matrix.org/docs/spec/client_server/r0.6.1#post-matrix-client-r0-keys-upload type DeviceKeys struct { diff --git a/keyserver/internal/internal.go b/keyserver/internal/internal.go index 0c264b71..dc3c404b 100644 --- a/keyserver/internal/internal.go +++ b/keyserver/internal/internal.go @@ -718,7 +718,7 @@ func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.Device for _, existingKey := range existing { // Do not treat the absence of keys as equal, or else we will not emit key changes // when users delete devices which never had a key to begin with as both KeyJSONs are nil. - if bytes.Equal(existingKey.KeyJSON, newKey.KeyJSON) && len(existingKey.KeyJSON) > 0 { + if existingKey.DeviceKeysEqual(&newKey) { exists = true break }