diff --git a/config/bridge.go b/config/bridge.go index 1ddd842..6fe0acb 100644 --- a/config/bridge.go +++ b/config/bridge.go @@ -32,7 +32,7 @@ type BridgeConfig struct { DisplaynameTemplate string `yaml:"displayname_template"` ChannelNameTemplate string `yaml:"channel_name_template"` GuildNameTemplate string `yaml:"guild_name_template"` - PrivateChatPortalMeta bool `yaml:"private_chat_portal_meta"` + PrivateChatPortalMeta string `yaml:"private_chat_portal_meta"` PrivateChannelCreateLimit int `yaml:"startup_private_channel_create_limit"` PortalMessageBuffer int `yaml:"portal_message_buffer"` diff --git a/config/upgrade.go b/config/upgrade.go index 9daeca3..d40d675 100644 --- a/config/upgrade.go +++ b/config/upgrade.go @@ -1,5 +1,5 @@ // mautrix-discord - A Matrix-Discord puppeting bridge. -// Copyright (C) 2022 Tulir Asokan +// Copyright (C) 2023 Tulir Asokan // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -31,7 +31,15 @@ func DoUpgrade(helper *up.Helper) { helper.Copy(up.Str, "bridge", "displayname_template") helper.Copy(up.Str, "bridge", "channel_name_template") helper.Copy(up.Str, "bridge", "guild_name_template") - helper.Copy(up.Bool, "bridge", "private_chat_portal_meta") + if legacyPrivateChatPortalMeta, ok := helper.Get(up.Bool, "bridge", "private_chat_portal_meta"); ok { + updatedPrivateChatPortalMeta := "default" + if legacyPrivateChatPortalMeta == "true" { + updatedPrivateChatPortalMeta = "always" + } + helper.Set(up.Str, updatedPrivateChatPortalMeta, "bridge", "private_chat_portal_meta") + } else { + helper.Copy(up.Str, "bridge", "private_chat_portal_meta") + } helper.Copy(up.Int, "bridge", "startup_private_channel_create_limit") helper.Copy(up.Int, "bridge", "portal_message_buffer") helper.Copy(up.Bool, "bridge", "delivery_receipts") diff --git a/example-config.yaml b/example-config.yaml index 984ec59..f1c3575 100644 --- a/example-config.yaml +++ b/example-config.yaml @@ -97,9 +97,11 @@ bridge: # Available variables: # .Name - Guild name guild_name_template: '{{.Name}}' - # Should the bridge explicitly set the avatar and room name for DM portal rooms? - # This is implicitly enabled in encrypted rooms. - private_chat_portal_meta: false + # Whether to explicitly set the avatar and room name for private chat portal rooms. + # If set to `default`, this will be enabled in encrypted rooms and disabled in unencrypted rooms. + # If set to `always`, all DM rooms will have explicit names and avatars set. + # If set to `never`, DM rooms will never have names and avatars set. + private_chat_portal_meta: default portal_message_buffer: 128 diff --git a/portal.go b/portal.go index 0f6ac84..7a6c036 100644 --- a/portal.go +++ b/portal.go @@ -336,6 +336,12 @@ func (portal *Portal) UpdateBridgeInfo() { } } +func (portal *Portal) shouldSetDMRoomMetadata() bool { + return !portal.IsPrivateChat() || + portal.bridge.Config.Bridge.PrivateChatPortalMeta == "always" || + (portal.IsEncrypted() && portal.bridge.Config.Bridge.PrivateChatPortalMeta != "never") +} + func (portal *Portal) GetEncryptionEventContent() (evt *event.EncryptionEventContent) { evt = &event.EncryptionEventContent{Algorithm: id.AlgorithmMegolmV1} if rot := portal.bridge.Config.Bridge.Encryption.Rotation; rot.EnableCustom { @@ -375,13 +381,32 @@ func (portal *Portal) CreateMatrixRoom(user *User, channel *discordgo.Channel) e StateKey: &bridgeInfoStateKey, }} - if !portal.AvatarURL.IsEmpty() { + var invite []id.UserID + + if portal.bridge.Config.Bridge.Encryption.Default { + initialState = append(initialState, &event.Event{ + Type: event.StateEncryption, + Content: event.Content{ + Parsed: portal.GetEncryptionEventContent(), + }, + }) + portal.Encrypted = true + + if portal.IsPrivateChat() { + invite = append(invite, portal.bridge.Bot.UserID) + } + } + + if !portal.AvatarURL.IsEmpty() && portal.shouldSetDMRoomMetadata() { initialState = append(initialState, &event.Event{ Type: event.StateRoomAvatar, Content: event.Content{Parsed: &event.RoomAvatarEventContent{ URL: portal.AvatarURL, }}, }) + portal.AvatarSet = true + } else { + portal.AvatarSet = false } creationContent := make(map[string]interface{}) @@ -417,23 +442,7 @@ func (portal *Portal) CreateMatrixRoom(user *User, channel *discordgo.Channel) e }) } - var invite []id.UserID - - if portal.bridge.Config.Bridge.Encryption.Default { - initialState = append(initialState, &event.Event{ - Type: event.StateEncryption, - Content: event.Content{ - Parsed: portal.GetEncryptionEventContent(), - }, - }) - portal.Encrypted = true - - if portal.IsPrivateChat() { - invite = append(invite, portal.bridge.Bot.UserID) - } - } - - resp, err := intent.CreateRoom(&mautrix.ReqCreateRoom{ + req := &mautrix.ReqCreateRoom{ Visibility: "private", Name: portal.Name, Topic: portal.Topic, @@ -442,15 +451,18 @@ func (portal *Portal) CreateMatrixRoom(user *User, channel *discordgo.Channel) e IsDirect: portal.IsPrivateChat(), InitialState: initialState, CreationContent: creationContent, - }) + } + if !portal.shouldSetDMRoomMetadata() { + req.Name = "" + } + resp, err := intent.CreateRoom(req) if err != nil { portal.log.Warnln("Failed to create room:", err) return err } - portal.NameSet = true - portal.TopicSet = true - portal.AvatarSet = !portal.AvatarURL.IsEmpty() + portal.NameSet = len(req.Name) > 0 + portal.TopicSet = len(req.Topic) > 0 portal.MXID = resp.RoomID portal.bridge.portalsLock.Lock() portal.bridge.portalsByMXID[portal.MXID] = portal @@ -1727,9 +1739,7 @@ func (portal *Portal) UpdateName(meta *discordgo.Channel) bool { } func (portal *Portal) UpdateNameDirect(name string) bool { - if portal.Name == name && (portal.NameSet || portal.MXID == "") { - return false - } else if !portal.Encrypted && !portal.bridge.Config.Bridge.PrivateChatPortalMeta && portal.IsPrivateChat() { + if portal.Name == name && (portal.NameSet || portal.MXID == "" || !portal.shouldSetDMRoomMetadata()) { return false } portal.log.Debugfln("Updating name %q -> %q", portal.Name, name) @@ -1740,7 +1750,7 @@ func (portal *Portal) UpdateNameDirect(name string) bool { } func (portal *Portal) updateRoomName() { - if portal.MXID != "" { + if portal.MXID != "" && portal.shouldSetDMRoomMetadata() { _, err := portal.MainIntent().SetRoomName(portal.MXID, portal.Name) if err != nil { portal.log.Warnln("Failed to update room name:", err) @@ -1751,9 +1761,7 @@ func (portal *Portal) updateRoomName() { } func (portal *Portal) UpdateAvatarFromPuppet(puppet *Puppet) bool { - if portal.Avatar == puppet.Avatar && portal.AvatarURL == puppet.AvatarURL && (portal.AvatarSet || portal.MXID == "") { - return false - } else if !portal.Encrypted && !portal.bridge.Config.Bridge.PrivateChatPortalMeta && portal.IsPrivateChat() { + if portal.Avatar == puppet.Avatar && portal.AvatarURL == puppet.AvatarURL && (portal.AvatarSet || portal.MXID == "" || !portal.shouldSetDMRoomMetadata()) { return false } portal.log.Debugfln("Updating avatar from puppet %q -> %q", portal.Avatar, puppet.Avatar) @@ -1786,7 +1794,7 @@ func (portal *Portal) UpdateGroupDMAvatar(iconID string) bool { } func (portal *Portal) updateRoomAvatar() { - if portal.MXID == "" || portal.AvatarURL.IsEmpty() { + if portal.MXID == "" || portal.AvatarURL.IsEmpty() || !portal.shouldSetDMRoomMetadata() { return } _, err := portal.MainIntent().SetRoomAvatar(portal.MXID, portal.AvatarURL)