diff --git a/pkg/connector/client.go b/pkg/connector/client.go index 378b3d4..24acebe 100644 --- a/pkg/connector/client.go +++ b/pkg/connector/client.go @@ -117,7 +117,17 @@ func (dc *DummyClient) Connect(ctx context.Context) { ); errors.Is(err, context.Canceled) { return } else if err != nil { - panic(err) + // Never panic here: a persistent error (e.g. an empty login ID failing + // GetPortalByKey under split portals) would otherwise boot-loop crash the + // host app on every startup (DROID-77263). Report a bridge-state error and + // stop generating instead. + log.Err(err).Msg("Failed to generate portal after login") + dc.UserLogin.BridgeState.Send(status.BridgeState{ + StateEvent: status.StateUnknownError, + Error: "dummy-generate-portal-failed", + Message: err.Error(), + }) + return } } }() diff --git a/pkg/connector/login.go b/pkg/connector/login.go index d805e38..86609c3 100644 --- a/pkg/connector/login.go +++ b/pkg/connector/login.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "go.mau.fi/util/jsontime" "go.mau.fi/util/random" @@ -148,8 +149,17 @@ func (dl *DummyLogin) SubmitUserInput(ctx context.Context, input map[string]stri if input["password"] == "incorrectpassword" { return nil, fmt.Errorf("incorrect password") } + username := input["username"] + if username == "" { + // The login form advertises "anything goes and it's used as the ID", so an empty + // username must keep working. Persisting a UserLogin with an empty ID is unsafe though: + // with split portals enabled, an empty receiver makes GetPortalByKey fail and crashes + // the host app on every startup (DROID-77263). Generate a random ID instead so the login + // ID can never be empty. + username = "dummy-" + strings.ToLower(random.String(12)) + } login, err := dl.User.NewLogin(ctx, &database.UserLogin{ - ID: networkid.UserLoginID(input["username"]), + ID: networkid.UserLoginID(username), RemoteName: input["password"], RemoteProfile: status.RemoteProfile{ Name: input["password"],