From 36c353abc7b40d8d9a951286ca7824bd3bfc6744 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 1 Mar 2026 12:37:13 +0200 Subject: [PATCH 1/3] federation/pdu: add AddSignature helper method --- federation/pdu/pdu.go | 13 +++++++++++++ federation/pdu/signature.go | 8 +------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/federation/pdu/pdu.go b/federation/pdu/pdu.go index cecee5b9..17db6995 100644 --- a/federation/pdu/pdu.go +++ b/federation/pdu/pdu.go @@ -123,6 +123,19 @@ func (pdu *PDU) ToClientEvent(roomVersion id.RoomVersion) (*event.Event, error) return evt, nil } +func (pdu *PDU) AddSignature(serverName string, keyID id.KeyID, signature string) { + if signature == "" { + return + } + if pdu.Signatures == nil { + pdu.Signatures = make(map[string]map[id.KeyID]string) + } + if _, ok := pdu.Signatures[serverName]; !ok { + pdu.Signatures[serverName] = make(map[id.KeyID]string) + } + pdu.Signatures[serverName][keyID] = signature +} + func marshalCanonical(data any) (jsontext.Value, error) { marshaledBytes, err := json.Marshal(data) if err != nil { diff --git a/federation/pdu/signature.go b/federation/pdu/signature.go index a7685cc6..04e7c5ef 100644 --- a/federation/pdu/signature.go +++ b/federation/pdu/signature.go @@ -28,13 +28,7 @@ func (pdu *PDU) Sign(roomVersion id.RoomVersion, serverName string, keyID id.Key return fmt.Errorf("failed to marshal redacted PDU to sign: %w", err) } signature := ed25519.Sign(privateKey, rawJSON) - if pdu.Signatures == nil { - pdu.Signatures = make(map[string]map[id.KeyID]string) - } - if _, ok := pdu.Signatures[serverName]; !ok { - pdu.Signatures[serverName] = make(map[id.KeyID]string) - } - pdu.Signatures[serverName][keyID] = base64.RawStdEncoding.EncodeToString(signature) + pdu.AddSignature(serverName, keyID, base64.RawStdEncoding.EncodeToString(signature)) return nil } From f8234ecf8556f72cf4711cf23e3d51411027c910 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 1 Mar 2026 13:23:32 +0200 Subject: [PATCH 2/3] event: add m.room.policy event type --- event/content.go | 3 +++ event/state.go | 12 ++++++++++++ event/type.go | 5 ++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/event/content.go b/event/content.go index d1ced268..4aa0593d 100644 --- a/event/content.go +++ b/event/content.go @@ -40,6 +40,9 @@ var TypeMap = map[Type]reflect.Type{ StateSpaceParent: reflect.TypeOf(SpaceParentEventContent{}), StateSpaceChild: reflect.TypeOf(SpaceChildEventContent{}), + StateRoomPolicy: reflect.TypeOf(RoomPolicyEventContent{}), + StateUnstableRoomPolicy: reflect.TypeOf(RoomPolicyEventContent{}), + StateLegacyPolicyRoom: reflect.TypeOf(ModPolicyContent{}), StateLegacyPolicyServer: reflect.TypeOf(ModPolicyContent{}), StateLegacyPolicyUser: reflect.TypeOf(ModPolicyContent{}), diff --git a/event/state.go b/event/state.go index 6d027e04..1df43351 100644 --- a/event/state.go +++ b/event/state.go @@ -343,3 +343,15 @@ func (efmc *ElementFunctionalMembersContent) Add(mxid id.UserID) bool { efmc.ServiceMembers = append(efmc.ServiceMembers, mxid) return true } + +type PolicyServerPublicKeys struct { + Ed25519 id.Ed25519 `json:"ed25519,omitempty"` +} + +type RoomPolicyEventContent struct { + Via string `json:"via,omitempty"` + PublicKeys *PolicyServerPublicKeys `json:"public_keys,omitempty"` + + // Deprecated, only for legacy use + PublicKey id.Ed25519 `json:"public_key"` +} diff --git a/event/type.go b/event/type.go index b193dc59..f337c127 100644 --- a/event/type.go +++ b/event/type.go @@ -113,7 +113,7 @@ func (et *Type) GuessClass() TypeClass { StatePinnedEvents.Type, StateTombstone.Type, StateEncryption.Type, StateBridge.Type, StateHalfShotBridge.Type, StateSpaceParent.Type, StateSpaceChild.Type, StatePolicyRoom.Type, StatePolicyServer.Type, StatePolicyUser.Type, StateElementFunctionalMembers.Type, StateBeeperRoomFeatures.Type, StateBeeperDisappearingTimer.Type, - StateMSC4391BotCommand.Type: + StateMSC4391BotCommand.Type, StateRoomPolicy.Type, StateUnstableRoomPolicy.Type: return StateEventType case EphemeralEventReceipt.Type, EphemeralEventTyping.Type, EphemeralEventPresence.Type: return EphemeralEventType @@ -195,6 +195,9 @@ var ( StateSpaceChild = Type{"m.space.child", StateEventType} StateSpaceParent = Type{"m.space.parent", StateEventType} + StateRoomPolicy = Type{"m.room.policy", StateEventType} + StateUnstableRoomPolicy = Type{"org.matrix.msc4284.policy", StateEventType} + StateLegacyPolicyRoom = Type{"m.room.rule.room", StateEventType} StateLegacyPolicyServer = Type{"m.room.rule.server", StateEventType} StateLegacyPolicyUser = Type{"m.room.rule.user", StateEventType} From 26a62a7eec2b30cb88baffe30596e3ba0d278f9d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sun, 1 Mar 2026 13:49:04 +0200 Subject: [PATCH 3/3] event: add missing omitempty --- event/state.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event/state.go b/event/state.go index 1df43351..ace170a5 100644 --- a/event/state.go +++ b/event/state.go @@ -353,5 +353,5 @@ type RoomPolicyEventContent struct { PublicKeys *PolicyServerPublicKeys `json:"public_keys,omitempty"` // Deprecated, only for legacy use - PublicKey id.Ed25519 `json:"public_key"` + PublicKey id.Ed25519 `json:"public_key,omitempty"` }