Merge branch 'main' into nexy7574/render-tombstone

This commit is contained in:
Tulir Asokan 2025-03-28 12:50:56 +02:00
commit 4176cc38ed
6 changed files with 25 additions and 6 deletions

View file

@ -60,6 +60,7 @@ type HiClient struct {
syncLock sync.Mutex
stopSync atomic.Pointer[context.CancelFunc]
encryptLock sync.Mutex
loginLock sync.Mutex
requestQueueWakeup chan struct{}

View file

@ -36,6 +36,12 @@ func (h *HiClient) LoginPassword(ctx context.Context, homeserverURL, username, p
}
func (h *HiClient) Login(ctx context.Context, req *mautrix.ReqLogin) error {
h.loginLock.Lock()
defer h.loginLock.Unlock()
if h.IsLoggedIn() {
return fmt.Errorf("already logged in")
}
err := h.CheckServerVersions(ctx)
if err != nil {
return err

View file

@ -101,6 +101,8 @@ func (h *HiClient) processGetRoomState(ctx context.Context, roomID id.RoomID, fe
room, err := h.DB.Room.Get(ctx, roomID)
if err != nil {
return fmt.Errorf("failed to get room from database: %w", err)
} else if room == nil {
return fmt.Errorf("room not found")
}
updatedRoom := &database.Room{
ID: room.ID,

View file

@ -126,15 +126,16 @@ func (h *HiClient) maybeDiscardOutboundSession(ctx context.Context, newMembershi
prevMembership = event.Membership(gjson.GetBytes(evt.Unsigned.PrevContent.VeryRaw, "membership").Str)
}
if prevMembership == "unknown" || prevMembership == "" {
cs, err := h.DB.CurrentState.Get(ctx, evt.RoomID, event.StateMember, h.Account.UserID.String())
cs, err := h.DB.CurrentState.Get(ctx, evt.RoomID, event.StateMember, evt.GetStateKey())
if err != nil {
zerolog.Ctx(ctx).Warn().Err(err).
Stringer("room_id", evt.RoomID).
Str("user_id", evt.GetStateKey()).
Msg("Failed to get previous membership")
return false
} else if cs != nil {
prevMembership = event.Membership(gjson.GetBytes(cs.Content, "membership").Str)
}
prevMembership = event.Membership(gjson.GetBytes(cs.Content, "membership").Str)
}
if prevMembership == newMembership ||
(prevMembership == event.MembershipInvite && newMembership == event.MembershipJoin && h.shouldShareKeysToInvitedUsers(ctx, evt.RoomID)) ||

View file

@ -26,6 +26,7 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
const [email, setEmail] = useState("")
const [requestID, setRequestID] = useState("")
const [code, setCode] = useState("")
const [loading, setLoading] = useState(false)
const [error, setError] = useState("")
const onChangeEmail = (evt: React.ChangeEvent<HTMLInputElement>) => {
@ -41,16 +42,18 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
const requestCode = (evt: React.FormEvent) => {
evt.preventDefault()
setLoading(true)
beeper.doStartLogin(domain).then(
request => beeper.doRequestCode(domain, request, email).then(
() => setRequestID(request),
err => setError(`Failed to request code: ${err}`),
),
err => setError(`Failed to start login: ${err}`),
)
).finally(() => setLoading(false))
}
const submitCode = (evt: React.FormEvent) => {
evt.preventDefault()
setLoading(true)
beeper.doSubmitCode(domain, requestID, code).then(
token => {
client.rpc.loginCustom(`https://matrix.${domain}`, {
@ -59,7 +62,7 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
}).catch(err => setError(`Failed to login with token: ${err}`))
},
err => setError(`Failed to submit code: ${err}`),
)
).finally(() => setLoading(false))
}
return <form onSubmit={requestID ? submitCode : requestCode} className="beeper-login">
@ -83,6 +86,7 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
<button
className="beeper-login-button primary-color-button"
type="submit"
disabled={loading}
>{requestID ? "Submit Code" : "Request Code"}</button>
{error && <div className="error">
{error}

View file

@ -31,9 +31,11 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
const [password, setPassword] = useState("")
const [homeserverURL, setHomeserverURL] = useState("")
const [loginFlows, setLoginFlows] = useState<string[] | null>(null)
const [loading, setLoading] = useState(false)
const [error, setError] = useState("")
const loginSSO = () => {
setLoading(true)
fetch("_gomuks/sso", {
method: "POST",
body: JSON.stringify({ homeserver_url: homeserverURL }),
@ -51,7 +53,7 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
window.location.href = `${homeserverURL}/_matrix/client/v3/login/sso/redirect?redirectUrl=${redir}`
},
err => setError(`Failed to start SSO login: ${err}`),
)
).finally(() => setLoading(false))
}
const login = (evt: React.FormEvent) => {
@ -61,10 +63,11 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
} else if (!loginFlows.includes("m.login.password")) {
loginSSO()
} else {
setLoading(true)
client.rpc.login(homeserverURL, username, password).then(
() => {},
err => setError(err.toString()),
)
).finally(() => setLoading(false))
}
}
@ -143,11 +146,13 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
{supportsSSO && <button
className="mx-login-button primary-color-button"
type={supportsPassword ? "button" : "submit"}
disabled={loading}
onClick={supportsPassword ? loginSSO : undefined}
>Login with SSO</button>}
{supportsPassword && <button
className="mx-login-button primary-color-button"
type="submit"
disabled={loading}
>Login{supportsSSO || beeperDomain ? " with password" : ""}</button>}
</div>
{error && <div className="error">