Gracefully handle rate limit response when attempting to Sign in with QR (#11809)

* Gracefully hand rate limit response when attempting to Sign in with QR

* Don't cancel after rate limit

* Update src/components/views/auth/LoginWithQR.tsx

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>

* Add missing import

* Fix mock of error

---------

Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Hugh Nimmo-Smith 2024-01-11 16:11:47 +00:00 committed by GitHub
parent 6187c8c884
commit 54b71140b8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 131 additions and 18 deletions

View file

@ -19,7 +19,7 @@ import { MSC3906Rendezvous, MSC3906RendezvousPayload, RendezvousFailureReason }
import { MSC3886SimpleHttpRendezvousTransport } from "matrix-js-sdk/src/rendezvous/transports";
import { MSC3903ECDHPayload, MSC3903ECDHv2RendezvousChannel } from "matrix-js-sdk/src/rendezvous/channels";
import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClient } from "matrix-js-sdk/src/matrix";
import { HTTPError, MatrixClient } from "matrix-js-sdk/src/matrix";
import { _t } from "../../../languageHandler";
import { wrapRequestWithDialog } from "../../../utils/UserInteractiveAuth";
@ -63,10 +63,16 @@ interface IState {
phase: Phase;
rendezvous?: MSC3906Rendezvous;
confirmationDigits?: string;
failureReason?: RendezvousFailureReason;
failureReason?: FailureReason;
mediaPermissionError?: boolean;
}
export enum LoginWithQRFailureReason {
RateLimited = "rate_limited",
}
export type FailureReason = RendezvousFailureReason | LoginWithQRFailureReason;
/**
* A component that allows sign in and E2EE set up with a QR code.
*
@ -136,16 +142,27 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
// user denied
return;
}
if (!this.props.client.crypto) {
if (!this.props.client.getCrypto()) {
// no E2EE to set up
this.props.onFinished(true);
return;
}
this.setState({ phase: Phase.Verifying });
await this.state.rendezvous.verifyNewDeviceOnExistingDevice();
// clean up our state:
try {
await this.state.rendezvous.close();
} finally {
this.setState({ rendezvous: undefined });
}
this.props.onFinished(true);
} catch (e) {
logger.error("Error whilst approving sign in", e);
if (e instanceof HTTPError && e.httpStatus === 429) {
// 429: rate limit
this.setState({ phase: Phase.Error, failureReason: LoginWithQRFailureReason.RateLimited });
return;
}
this.setState({ phase: Phase.Error, failureReason: RendezvousFailureReason.Unknown });
}
};