diff --git a/database/kvstore.go b/database/kvstore.go index 077d659..ff9ba2b 100644 --- a/database/kvstore.go +++ b/database/kvstore.go @@ -34,6 +34,8 @@ const ( KVNACServToken = "nacserv_override_token" KVNACServURL = "nacserv_override_url" + + KVHackyNACErrorPersistence = "hacky_nac_error_persistence" ) func (kvq *KeyValueQuery) Get(key string) (value string) { diff --git a/main.go b/main.go index 7c8f787..1e491bf 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,7 @@ package main import ( "context" _ "embed" + "encoding/json" "errors" "sync" @@ -114,7 +115,11 @@ func (br *IMBridge) Start() { err := user.Start() if errors.Is(err, ErrNoNAC) { user.zlog.Warn().Msg("NAC not configured, logging out user") - user.BridgeState.Send(status.BridgeState{StateEvent: status.StateUnknownError, Error: "im-nacserv-not-configured"}) + state := status.BridgeState{StateEvent: status.StateUnknownError, Error: "im-nacserv-not-configured"} + stateForDB := state.Fill(user) + user.BridgeState.Send(state) + data, _ := json.Marshal(&stateForDB) + br.DB.KV.Set(database.KVHackyNACErrorPersistence, string(data)) user.AppleRegistration = nil // TODO don't ignore errors user.Update(context.TODO()) @@ -123,7 +128,14 @@ func (br *IMBridge) Start() { } } if !startedAnyUsers { - br.SendGlobalBridgeState(status.BridgeState{StateEvent: status.StateUnconfigured}) + if hackyNACErrorPersistence := br.DB.KV.Get(database.KVHackyNACErrorPersistence); hackyNACErrorPersistence != "" { + var state status.BridgeState + _ = json.Unmarshal([]byte(hackyNACErrorPersistence), &state) + br.ZLog.Debug().Interface("bridge_state", state).Msg("Sending cached NAC error state") + br.GetUserByMXID(state.UserID).BridgeState.Send(state) + } else { + br.SendGlobalBridgeState(status.BridgeState{StateEvent: status.StateUnconfigured}) + } } br.WaitWebsocketConnected() diff --git a/provisioning.go b/provisioning.go index fb50a0b..e5b001e 100644 --- a/provisioning.go +++ b/provisioning.go @@ -411,6 +411,7 @@ func (prov *ProvisioningAPI) SetRelay(w http.ResponseWriter, r *http.Request) { // Now that we know the relay exists, save it to the database prov.bridge.DB.KV.Set(database.KVNACServURL, req.URL) prov.bridge.DB.KV.Set(database.KVNACServToken, req.Token) + user.bridge.DB.KV.Delete(database.KVHackyNACErrorPersistence) if user.IM != nil { user.IM.NACServ = user.makeNACClient() diff --git a/user.go b/user.go index 8627ae6..807b262 100644 --- a/user.go +++ b/user.go @@ -280,6 +280,7 @@ func (user *User) Start() error { if cfg == nil { cfg = &ids.Config{} user.AppleRegistration = cfg + user.bridge.DB.KV.Delete(database.KVHackyNACErrorPersistence) } ctx := user.zlog.WithContext(context.TODO()) err := user.IM.Configure(ctx, cfg, false) @@ -314,6 +315,7 @@ func (user *User) Logout() { user.zlog.Warn().Err(err).Msg("Failed to logout") } user.BridgeState.Send(status.BridgeState{StateEvent: status.StateLoggedOut}) + user.bridge.DB.KV.Delete(database.KVHackyNACErrorPersistence) user.Stop() user.AppleRegistration = nil // TODO don't ignore errors