diff --git a/config/config.go b/config/config.go index e2df2ac..f7f6b1f 100644 --- a/config/config.go +++ b/config/config.go @@ -20,6 +20,7 @@ import ( "io/ioutil" "gopkg.in/yaml.v2" + "maunium.net/go/mautrix/id" "maunium.net/go/mautrix/appservice" ) @@ -77,6 +78,17 @@ type Config struct { Logging appservice.LogConfig `yaml:"logging"` } +func (config *Config) CanDoublePuppet(userID id.UserID) bool { + if len(config.Bridge.LoginSharedSecret) == 0 { + // Automatic login not enabled + return false + } else if _, homeserver, _ := userID.Parse(); homeserver != config.Homeserver.Domain { + // user is on another homeserver + return false + } + return true +} + func (config *Config) setDefaults() { config.AppService.Database.MaxOpenConns = 20 config.AppService.Database.MaxIdleConns = 2 diff --git a/custompuppet.go b/custompuppet.go index 7d5b773..372ebb0 100644 --- a/custompuppet.go +++ b/custompuppet.go @@ -44,7 +44,7 @@ func (puppet *Puppet) SwitchCustomMXID(accessToken string, mxid id.UserID) error puppet.CustomMXID = mxid puppet.AccessToken = accessToken - err := puppet.StartCustomMXID() + err := puppet.StartCustomMXID(false) if err != nil { return err } @@ -108,7 +108,7 @@ func (puppet *Puppet) clearCustomMXID() { puppet.customUser = nil } -func (puppet *Puppet) StartCustomMXID() error { +func (puppet *Puppet) StartCustomMXID(reloginOnFail bool) error { if len(puppet.CustomMXID) == 0 { puppet.clearCustomMXID() return nil @@ -120,10 +120,12 @@ func (puppet *Puppet) StartCustomMXID() error { } resp, err := intent.Whoami() if err != nil { - puppet.clearCustomMXID() - return err - } - if resp.UserID != puppet.CustomMXID { + if !reloginOnFail || (errors.Is(err, mautrix.MUnknownToken) && !puppet.tryRelogin(err, "initializing double puppeting")) { + puppet.clearCustomMXID() + return err + } + intent.AccessToken = puppet.AccessToken + } else if resp.UserID != puppet.CustomMXID { puppet.clearCustomMXID() return ErrMismatchingMXID } @@ -250,8 +252,30 @@ func (puppet *Puppet) handleTypingEvent(portal *Portal, evt *event.Event) { } } +func (puppet *Puppet) tryRelogin(cause error, action string) bool { + if !puppet.bridge.Config.CanDoublePuppet(puppet.CustomMXID) { + return false + } + puppet.log.Debugfln("Trying to relogin after '%v' while %s", cause, action) + accessToken, err := puppet.loginWithSharedSecret(puppet.CustomMXID) + if err != nil { + puppet.log.Errorfln("Failed to relogin after '%v' while %s: %v", cause, action, err) + return false + } + puppet.log.Infofln("Successfully relogined after '%v' while %s", cause, action) + puppet.AccessToken = accessToken + return true +} + func (puppet *Puppet) OnFailedSync(_ *mautrix.RespSync, err error) (time.Duration, error) { puppet.log.Warnln("Sync error:", err) + if errors.Is(err, mautrix.MUnknownToken) { + if !puppet.tryRelogin(err, "syncing") { + return 0, err + } + puppet.customIntent.AccessToken = puppet.AccessToken + return 0, nil + } return 10 * time.Second, nil } diff --git a/main.go b/main.go index 663a406..8aae7fa 100644 --- a/main.go +++ b/main.go @@ -363,7 +363,7 @@ func (bridge *Bridge) StartUsers() { for _, loopuppet := range bridge.GetAllPuppetsWithCustomMXID() { go func(puppet *Puppet) { puppet.log.Debugln("Starting custom puppet", puppet.CustomMXID) - err := puppet.StartCustomMXID() + err := puppet.StartCustomMXID(true) if err != nil { puppet.log.Errorln("Failed to start custom puppet:", err) } diff --git a/user.go b/user.go index b019d3f..1edfffb 100644 --- a/user.go +++ b/user.go @@ -461,11 +461,7 @@ func (user *User) PostLogin() { } func (user *User) tryAutomaticDoublePuppeting() { - if len(user.bridge.Config.Bridge.LoginSharedSecret) == 0 { - // Automatic login not enabled - return - } else if _, homeserver, _ := user.MXID.Parse(); homeserver != user.bridge.Config.Homeserver.Domain { - // user is on another homeserver + if !user.bridge.Config.CanDoublePuppet(user.MXID) { return } user.log.Debugln("Checking if double puppeting needs to be enabled")