bridgev2/portal: validate capabilities when updating disappearing timer

This commit is contained in:
Tulir Asokan 2025-08-25 18:36:03 +03:00
commit c3a422347c
3 changed files with 16 additions and 0 deletions

View file

@ -67,6 +67,8 @@ var (
ErrPowerLevelsNotSupported error = WrapErrorInStatus(errors.New("this bridge does not support changing group power levels")).WithIsCertain(true).WithErrorAsMessage().WithSendNotice(false)
ErrRemoteEchoTimeout = WrapErrorInStatus(errors.New("remote echo timed out")).WithIsCertain(false).WithSendNotice(true).WithErrorReason(event.MessageStatusTooOld)
ErrRemoteAckTimeout = WrapErrorInStatus(errors.New("remote ack timed out")).WithIsCertain(false).WithSendNotice(true).WithErrorReason(event.MessageStatusTooOld)
ErrDisappearingTimerUnsupported error = WrapErrorInStatus(errors.New("invalid disappearing timer")).WithIsCertain(true)
)
// Common login interface errors

View file

@ -1488,6 +1488,10 @@ func handleMatrixRoomMeta[APIType any, ContentType any](
portal.sendSuccessStatus(ctx, evt, 0, "")
return EventHandlingResultIgnored
}
if !sender.Client.GetCapabilities(ctx, portal).DisappearingTimer.Supports(typedContent) {
portal.sendRoomMeta(ctx, nil, time.Now(), event.StateBeeperDisappearingTimer, "", portal.Disappear.ToEventContent())
return EventHandlingResultFailed.WithMSSError(ErrDisappearingTimerUnsupported)
}
}
var prevContent ContentType
if evt.Unsigned.PrevContent != nil {
@ -1508,6 +1512,9 @@ func handleMatrixRoomMeta[APIType any, ContentType any](
})
if err != nil {
log.Err(err).Msg("Failed to handle Matrix room metadata")
if evt.Type == event.StateBeeperDisappearingTimer {
portal.sendRoomMeta(ctx, nil, time.Now(), event.StateBeeperDisappearingTimer, "", portal.Disappear.ToEventContent())
}
return EventHandlingResultFailed.WithMSSError(err)
}
if changed {

View file

@ -76,6 +76,13 @@ type DisappearingTimerCapability struct {
OmitEmptyTimer bool `json:"omit_empty_timer,omitempty"`
}
func (dtc *DisappearingTimerCapability) Supports(content *BeeperDisappearingTimer) bool {
if dtc == nil || content.Type == DisappearingTypeNone {
return true
}
return slices.Contains(dtc.Types, content.Type) && slices.Contains(dtc.Timers, content.Timer)
}
type CapabilityMsgType = MessageType
// Message types which are used for event capability signaling, but aren't real values for the msgtype field.