mirror of
https://github.com/tulir/gomuks.git
synced 2025-04-20 10:33:41 -05:00
Merge branch 'main' into nexy7574/render-tombstone
This commit is contained in:
commit
4176cc38ed
6 changed files with 25 additions and 6 deletions
|
@ -60,6 +60,7 @@ type HiClient struct {
|
||||||
syncLock sync.Mutex
|
syncLock sync.Mutex
|
||||||
stopSync atomic.Pointer[context.CancelFunc]
|
stopSync atomic.Pointer[context.CancelFunc]
|
||||||
encryptLock sync.Mutex
|
encryptLock sync.Mutex
|
||||||
|
loginLock sync.Mutex
|
||||||
|
|
||||||
requestQueueWakeup chan struct{}
|
requestQueueWakeup chan struct{}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
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)
|
err := h.CheckServerVersions(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -101,6 +101,8 @@ func (h *HiClient) processGetRoomState(ctx context.Context, roomID id.RoomID, fe
|
||||||
room, err := h.DB.Room.Get(ctx, roomID)
|
room, err := h.DB.Room.Get(ctx, roomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get room from database: %w", err)
|
return fmt.Errorf("failed to get room from database: %w", err)
|
||||||
|
} else if room == nil {
|
||||||
|
return fmt.Errorf("room not found")
|
||||||
}
|
}
|
||||||
updatedRoom := &database.Room{
|
updatedRoom := &database.Room{
|
||||||
ID: room.ID,
|
ID: room.ID,
|
||||||
|
|
|
@ -126,16 +126,17 @@ func (h *HiClient) maybeDiscardOutboundSession(ctx context.Context, newMembershi
|
||||||
prevMembership = event.Membership(gjson.GetBytes(evt.Unsigned.PrevContent.VeryRaw, "membership").Str)
|
prevMembership = event.Membership(gjson.GetBytes(evt.Unsigned.PrevContent.VeryRaw, "membership").Str)
|
||||||
}
|
}
|
||||||
if prevMembership == "unknown" || prevMembership == "" {
|
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 {
|
if err != nil {
|
||||||
zerolog.Ctx(ctx).Warn().Err(err).
|
zerolog.Ctx(ctx).Warn().Err(err).
|
||||||
Stringer("room_id", evt.RoomID).
|
Stringer("room_id", evt.RoomID).
|
||||||
Str("user_id", evt.GetStateKey()).
|
Str("user_id", evt.GetStateKey()).
|
||||||
Msg("Failed to get previous membership")
|
Msg("Failed to get previous membership")
|
||||||
return false
|
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 ||
|
if prevMembership == newMembership ||
|
||||||
(prevMembership == event.MembershipInvite && newMembership == event.MembershipJoin && h.shouldShareKeysToInvitedUsers(ctx, evt.RoomID)) ||
|
(prevMembership == event.MembershipInvite && newMembership == event.MembershipJoin && h.shouldShareKeysToInvitedUsers(ctx, evt.RoomID)) ||
|
||||||
(prevMembership == event.MembershipJoin && newMembership == event.MembershipInvite) ||
|
(prevMembership == event.MembershipJoin && newMembership == event.MembershipInvite) ||
|
||||||
|
|
|
@ -26,6 +26,7 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
|
||||||
const [email, setEmail] = useState("")
|
const [email, setEmail] = useState("")
|
||||||
const [requestID, setRequestID] = useState("")
|
const [requestID, setRequestID] = useState("")
|
||||||
const [code, setCode] = useState("")
|
const [code, setCode] = useState("")
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
|
|
||||||
const onChangeEmail = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
const onChangeEmail = (evt: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
@ -41,16 +42,18 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
|
||||||
|
|
||||||
const requestCode = (evt: React.FormEvent) => {
|
const requestCode = (evt: React.FormEvent) => {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
|
setLoading(true)
|
||||||
beeper.doStartLogin(domain).then(
|
beeper.doStartLogin(domain).then(
|
||||||
request => beeper.doRequestCode(domain, request, email).then(
|
request => beeper.doRequestCode(domain, request, email).then(
|
||||||
() => setRequestID(request),
|
() => setRequestID(request),
|
||||||
err => setError(`Failed to request code: ${err}`),
|
err => setError(`Failed to request code: ${err}`),
|
||||||
),
|
),
|
||||||
err => setError(`Failed to start login: ${err}`),
|
err => setError(`Failed to start login: ${err}`),
|
||||||
)
|
).finally(() => setLoading(false))
|
||||||
}
|
}
|
||||||
const submitCode = (evt: React.FormEvent) => {
|
const submitCode = (evt: React.FormEvent) => {
|
||||||
evt.preventDefault()
|
evt.preventDefault()
|
||||||
|
setLoading(true)
|
||||||
beeper.doSubmitCode(domain, requestID, code).then(
|
beeper.doSubmitCode(domain, requestID, code).then(
|
||||||
token => {
|
token => {
|
||||||
client.rpc.loginCustom(`https://matrix.${domain}`, {
|
client.rpc.loginCustom(`https://matrix.${domain}`, {
|
||||||
|
@ -59,7 +62,7 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
|
||||||
}).catch(err => setError(`Failed to login with token: ${err}`))
|
}).catch(err => setError(`Failed to login with token: ${err}`))
|
||||||
},
|
},
|
||||||
err => setError(`Failed to submit code: ${err}`),
|
err => setError(`Failed to submit code: ${err}`),
|
||||||
)
|
).finally(() => setLoading(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
return <form onSubmit={requestID ? submitCode : requestCode} className="beeper-login">
|
return <form onSubmit={requestID ? submitCode : requestCode} className="beeper-login">
|
||||||
|
@ -83,6 +86,7 @@ const BeeperLogin = ({ domain, client }: BeeperLoginProps) => {
|
||||||
<button
|
<button
|
||||||
className="beeper-login-button primary-color-button"
|
className="beeper-login-button primary-color-button"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
disabled={loading}
|
||||||
>{requestID ? "Submit Code" : "Request Code"}</button>
|
>{requestID ? "Submit Code" : "Request Code"}</button>
|
||||||
{error && <div className="error">
|
{error && <div className="error">
|
||||||
{error}
|
{error}
|
||||||
|
|
|
@ -31,9 +31,11 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
|
||||||
const [password, setPassword] = useState("")
|
const [password, setPassword] = useState("")
|
||||||
const [homeserverURL, setHomeserverURL] = useState("")
|
const [homeserverURL, setHomeserverURL] = useState("")
|
||||||
const [loginFlows, setLoginFlows] = useState<string[] | null>(null)
|
const [loginFlows, setLoginFlows] = useState<string[] | null>(null)
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
const [error, setError] = useState("")
|
const [error, setError] = useState("")
|
||||||
|
|
||||||
const loginSSO = () => {
|
const loginSSO = () => {
|
||||||
|
setLoading(true)
|
||||||
fetch("_gomuks/sso", {
|
fetch("_gomuks/sso", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({ homeserver_url: homeserverURL }),
|
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}`
|
window.location.href = `${homeserverURL}/_matrix/client/v3/login/sso/redirect?redirectUrl=${redir}`
|
||||||
},
|
},
|
||||||
err => setError(`Failed to start SSO login: ${err}`),
|
err => setError(`Failed to start SSO login: ${err}`),
|
||||||
)
|
).finally(() => setLoading(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
const login = (evt: React.FormEvent) => {
|
const login = (evt: React.FormEvent) => {
|
||||||
|
@ -61,10 +63,11 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
|
||||||
} else if (!loginFlows.includes("m.login.password")) {
|
} else if (!loginFlows.includes("m.login.password")) {
|
||||||
loginSSO()
|
loginSSO()
|
||||||
} else {
|
} else {
|
||||||
|
setLoading(true)
|
||||||
client.rpc.login(homeserverURL, username, password).then(
|
client.rpc.login(homeserverURL, username, password).then(
|
||||||
() => {},
|
() => {},
|
||||||
err => setError(err.toString()),
|
err => setError(err.toString()),
|
||||||
)
|
).finally(() => setLoading(false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,11 +146,13 @@ export const LoginScreen = ({ client }: LoginScreenProps) => {
|
||||||
{supportsSSO && <button
|
{supportsSSO && <button
|
||||||
className="mx-login-button primary-color-button"
|
className="mx-login-button primary-color-button"
|
||||||
type={supportsPassword ? "button" : "submit"}
|
type={supportsPassword ? "button" : "submit"}
|
||||||
|
disabled={loading}
|
||||||
onClick={supportsPassword ? loginSSO : undefined}
|
onClick={supportsPassword ? loginSSO : undefined}
|
||||||
>Login with SSO</button>}
|
>Login with SSO</button>}
|
||||||
{supportsPassword && <button
|
{supportsPassword && <button
|
||||||
className="mx-login-button primary-color-button"
|
className="mx-login-button primary-color-button"
|
||||||
type="submit"
|
type="submit"
|
||||||
|
disabled={loading}
|
||||||
>Login{supportsSSO || beeperDomain ? " with password" : ""}</button>}
|
>Login{supportsSSO || beeperDomain ? " with password" : ""}</button>}
|
||||||
</div>
|
</div>
|
||||||
{error && <div className="error">
|
{error && <div className="error">
|
||||||
|
|
Loading…
Add table
Reference in a new issue