Merge branch 'main' into tulir/event-auth
Some checks failed
Go / Lint (latest) (push) Has been cancelled
Go / Build (old, libolm) (push) Has been cancelled
Go / Build (latest, libolm) (push) Has been cancelled
Go / Build (old, goolm) (push) Has been cancelled
Go / Build (latest, goolm) (push) Has been cancelled

This commit is contained in:
Tulir Asokan 2025-08-25 17:16:33 +03:00
commit d58676232b
8 changed files with 79 additions and 21 deletions

View file

@ -117,11 +117,15 @@ func MergeCaption(textPart, mediaPart *ConvertedMessagePart) *ConvertedMessagePa
mediaPart.Content.EnsureHasHTML()
mediaPart.Content.Body += "\n\n" + textPart.Content.Body
mediaPart.Content.FormattedBody += "<br><br>" + textPart.Content.FormattedBody
mediaPart.Content.Mentions = mediaPart.Content.Mentions.Merge(textPart.Content.Mentions)
mediaPart.Content.BeeperLinkPreviews = append(mediaPart.Content.BeeperLinkPreviews, textPart.Content.BeeperLinkPreviews...)
} else {
mediaPart.Content.FileName = mediaPart.Content.Body
mediaPart.Content.Body = textPart.Content.Body
mediaPart.Content.Format = textPart.Content.Format
mediaPart.Content.FormattedBody = textPart.Content.FormattedBody
mediaPart.Content.Mentions = textPart.Content.Mentions
mediaPart.Content.BeeperLinkPreviews = textPart.Content.BeeperLinkPreviews
}
if metaMerger, ok := mediaPart.DBMetadata.(database.MetaMerger); ok {
metaMerger.CopyFrom(textPart.DBMetadata)

View file

@ -4038,7 +4038,15 @@ func DisappearingMessageNotice(expiration time.Duration, implicit bool) *event.M
return content
}
func (portal *Portal) UpdateDisappearingSetting(ctx context.Context, setting database.DisappearingSetting, sender MatrixAPI, ts time.Time, implicit, save bool) bool {
type UpdateDisappearingSettingOpts struct {
Sender MatrixAPI
Timestamp time.Time
Implicit bool
Save bool
SendNotice bool
}
func (portal *Portal) UpdateDisappearingSetting(ctx context.Context, setting database.DisappearingSetting, opts UpdateDisappearingSettingOpts) bool {
if setting.Timer == 0 {
setting.Type = event.DisappearingTypeNone
}
@ -4047,7 +4055,7 @@ func (portal *Portal) UpdateDisappearingSetting(ctx context.Context, setting dat
}
portal.Disappear.Type = setting.Type
portal.Disappear.Timer = setting.Timer
if save {
if opts.Save {
err := portal.Save(ctx)
if err != nil {
zerolog.Ctx(ctx).Err(err).Msg("Failed to save portal to database after updating disappearing setting")
@ -4057,21 +4065,21 @@ func (portal *Portal) UpdateDisappearingSetting(ctx context.Context, setting dat
return true
}
portal.sendRoomMeta(ctx, sender, ts, event.StateBeeperDisappearingTimer, "", setting.ToEventContent())
content := DisappearingMessageNotice(setting.Timer, implicit)
if sender == nil {
sender = portal.Bridge.Bot
if opts.Sender == nil {
opts.Sender = portal.Bridge.Bot
}
_, err := sender.SendMessage(ctx, portal.MXID, event.EventMessage, &event.Content{
portal.sendRoomMeta(ctx, opts.Sender, opts.Timestamp, event.StateBeeperDisappearingTimer, "", setting.ToEventContent())
content := DisappearingMessageNotice(setting.Timer, opts.Implicit)
_, err := opts.Sender.SendMessage(ctx, portal.MXID, event.EventMessage, &event.Content{
Parsed: content,
}, &MatrixSendExtra{Timestamp: ts})
}, &MatrixSendExtra{Timestamp: opts.Timestamp})
if err != nil {
zerolog.Ctx(ctx).Err(err).Msg("Failed to send disappearing messages notice")
} else {
zerolog.Ctx(ctx).Debug().
Dur("new_timer", portal.Disappear.Timer).
Bool("implicit", implicit).
Bool("implicit", opts.Implicit).
Msg("Sent disappearing messages notice")
}
return true
@ -4162,7 +4170,13 @@ func (portal *Portal) UpdateInfo(ctx context.Context, info *ChatInfo, source *Us
changed = portal.updateAvatar(ctx, info.Avatar, sender, ts) || changed
}
if info.Disappear != nil {
changed = portal.UpdateDisappearingSetting(ctx, *info.Disappear, sender, ts, false, false) || changed
changed = portal.UpdateDisappearingSetting(ctx, *info.Disappear, UpdateDisappearingSettingOpts{
Sender: sender,
Timestamp: ts,
Implicit: false,
Save: false,
SendNotice: true,
}) || changed
}
if info.ParentID != nil {
changed = portal.updateParent(ctx, *info.ParentID, source) || changed

View file

@ -1,4 +1,4 @@
-- v0 -> v17 (compatible with v15+): Latest revision
-- v0 -> v18 (compatible with v15+): Latest revision
CREATE TABLE IF NOT EXISTS crypto_account (
account_id TEXT PRIMARY KEY,
device_id TEXT NOT NULL,
@ -73,6 +73,8 @@ CREATE TABLE IF NOT EXISTS crypto_megolm_inbound_session (
key_backup_version TEXT NOT NULL DEFAULT '',
PRIMARY KEY (account_id, session_id)
);
-- Useful index to find keys that need backing up
CREATE INDEX crypto_megolm_inbound_session_backup_idx ON crypto_megolm_inbound_session(account_id, key_backup_version) WHERE session IS NOT NULL;
CREATE TABLE IF NOT EXISTS crypto_megolm_outbound_session (
account_id TEXT,

View file

@ -0,0 +1,2 @@
-- v18 (compatible with v15+): Add an index to the megolm_inbound_session table to make finding sessions to backup faster
CREATE INDEX crypto_megolm_inbound_session_backup_idx ON crypto_megolm_inbound_session(account_id, key_backup_version) WHERE session IS NOT NULL;

View file

@ -18,6 +18,7 @@ import (
// This is used by Content.ParseRaw() for creating the correct type of struct.
var TypeMap = map[Type]reflect.Type{
StateMember: reflect.TypeOf(MemberEventContent{}),
StateThirdPartyInvite: reflect.TypeOf(ThirdPartyInviteEventContent{}),
StatePowerLevels: reflect.TypeOf(PowerLevelsEventContent{}),
StateCanonicalAlias: reflect.TypeOf(CanonicalAliasEventContent{}),
StateRoomName: reflect.TypeOf(RoomNameEventContent{}),

View file

@ -7,8 +7,6 @@
package event
import (
"encoding/json"
"maunium.net/go/mautrix/id"
)
@ -47,11 +45,25 @@ type MemberEventContent struct {
MSC4293RedactEvents bool `json:"org.matrix.msc4293.redact_events,omitempty"`
}
type ThirdPartyInvite struct {
DisplayName string `json:"display_name"`
Signed struct {
Token string `json:"token"`
Signatures json.RawMessage `json:"signatures"`
MXID string `json:"mxid"`
} `json:"signed"`
type SignedThirdPartyInvite struct {
Token string `json:"token"`
Signatures map[string]map[id.KeyID]string `json:"signatures,omitempty"`
MXID string `json:"mxid"`
}
type ThirdPartyInvite struct {
DisplayName string `json:"display_name"`
Signed SignedThirdPartyInvite `json:"signed"`
}
type ThirdPartyInviteEventContent struct {
DisplayName string `json:"display_name"`
KeyValidityURL string `json:"key_validity_url"`
PublicKey id.Ed25519 `json:"public_key"`
PublicKeys []ThirdPartyInviteKey `json:"public_keys,omitempty"`
}
type ThirdPartyInviteKey struct {
KeyValidityURL string `json:"key_validity_url,omitempty"`
PublicKey id.Ed25519 `json:"public_key"`
}

View file

@ -273,6 +273,18 @@ func (m *Mentions) Has(userID id.UserID) bool {
return m != nil && slices.Contains(m.UserIDs, userID)
}
func (m *Mentions) Merge(other *Mentions) *Mentions {
if m == nil {
return other
} else if other == nil {
return m
}
return &Mentions{
UserIDs: slices.Concat(m.UserIDs, other.UserIDs),
Room: m.Room || other.Room,
}
}
type EncryptedFileInfo struct {
attachment.EncryptedFile
URL id.ContentURIString `json:"url"`

View file

@ -57,7 +57,18 @@ type uriAble interface {
}
func MarkdownMention(id uriAble) string {
return MarkdownLink(id.String(), id.URI().MatrixToURL())
return MarkdownMentionWithName(id.String(), id)
}
func MarkdownMentionWithName(name string, id uriAble) string {
return MarkdownLink(name, id.URI().MatrixToURL())
}
func MarkdownMentionRoomID(name string, id id.RoomID, via ...string) string {
if name == "" {
name = id.String()
}
return MarkdownLink(name, id.URI(via...).MatrixToURL())
}
func MarkdownLink(name string, url string) string {