Remove abandoned MSC3886, MSC3903, MSC3906 implementations (#28274)
* Remove abandoned MSC3886, MSC3903, MSC3906 implementations Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Iterate Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Remove stale snapshots * Improve coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
parent
6d0d237c79
commit
5b5348ec1e
13 changed files with 60 additions and 1373 deletions
|
@ -24,10 +24,6 @@ export enum Phase {
|
|||
WaitingForDevice,
|
||||
Verifying,
|
||||
Error,
|
||||
/**
|
||||
* @deprecated the MSC3906 implementation is deprecated in favour of MSC4108.
|
||||
*/
|
||||
LegacyConnected,
|
||||
}
|
||||
|
||||
export enum Click {
|
||||
|
|
|
@ -9,11 +9,6 @@ Please see LICENSE files in the repository root for full details.
|
|||
import React from "react";
|
||||
import {
|
||||
ClientRendezvousFailureReason,
|
||||
LegacyRendezvousFailureReason,
|
||||
MSC3886SimpleHttpRendezvousTransport,
|
||||
MSC3903ECDHPayload,
|
||||
MSC3903ECDHv2RendezvousChannel,
|
||||
MSC3906Rendezvous,
|
||||
MSC4108FailureReason,
|
||||
MSC4108RendezvousSession,
|
||||
MSC4108SecureChannel,
|
||||
|
@ -23,29 +18,21 @@ import {
|
|||
RendezvousIntent,
|
||||
} from "matrix-js-sdk/src/rendezvous";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { HTTPError, MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import { Click, Mode, Phase } from "./LoginWithQR-types";
|
||||
import LoginWithQRFlow from "./LoginWithQRFlow";
|
||||
import { wrapRequestWithDialog } from "../../../utils/UserInteractiveAuth";
|
||||
import { _t } from "../../../languageHandler";
|
||||
|
||||
interface IProps {
|
||||
client: MatrixClient;
|
||||
mode: Mode;
|
||||
legacy: boolean;
|
||||
onFinished(...args: any): void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
phase: Phase;
|
||||
rendezvous?: MSC3906Rendezvous | MSC4108SignInWithQR;
|
||||
rendezvous?: MSC4108SignInWithQR;
|
||||
mediaPermissionError?: boolean;
|
||||
|
||||
// MSC3906
|
||||
confirmationDigits?: string;
|
||||
|
||||
// MSC4108
|
||||
verificationUri?: string;
|
||||
userCode?: string;
|
||||
checkCode?: string;
|
||||
|
@ -54,25 +41,18 @@ interface IState {
|
|||
}
|
||||
|
||||
export enum LoginWithQRFailureReason {
|
||||
/**
|
||||
* @deprecated the MSC3906 implementation is deprecated in favour of MSC4108.
|
||||
*/
|
||||
RateLimited = "rate_limited",
|
||||
CheckCodeMismatch = "check_code_mismatch",
|
||||
}
|
||||
|
||||
export type FailureReason = RendezvousFailureReason | LoginWithQRFailureReason;
|
||||
|
||||
// n.b MSC3886/MSC3903/MSC3906 that this is based on are now closed.
|
||||
// However, we want to keep this implementation around for some time.
|
||||
// TODO: define an end-of-life date for this implementation.
|
||||
|
||||
/**
|
||||
* A component that allows sign in and E2EE set up with a QR code.
|
||||
*
|
||||
* It implements `login.reciprocate` capabilities and showing QR codes.
|
||||
*
|
||||
* This uses the unstable feature of MSC3906: https://github.com/matrix-org/matrix-spec-proposals/pull/3906
|
||||
* This uses the unstable feature of MSC4108: https://github.com/matrix-org/matrix-spec-proposals/pull/4108
|
||||
*/
|
||||
export default class LoginWithQR extends React.Component<IProps, IState> {
|
||||
private finished = false;
|
||||
|
@ -104,9 +84,6 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
if (this.state.rendezvous) {
|
||||
const rendezvous = this.state.rendezvous;
|
||||
rendezvous.onFailure = undefined;
|
||||
if (rendezvous instanceof MSC3906Rendezvous) {
|
||||
await rendezvous.cancel(LegacyRendezvousFailureReason.UserCancelled);
|
||||
}
|
||||
this.setState({ rendezvous: undefined });
|
||||
}
|
||||
if (mode === Mode.Show) {
|
||||
|
@ -119,60 +96,7 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
// eslint-disable-next-line react/no-direct-mutation-state
|
||||
this.state.rendezvous.onFailure = undefined;
|
||||
// calling cancel will call close() as well to clean up the resources
|
||||
if (this.state.rendezvous instanceof MSC3906Rendezvous) {
|
||||
this.state.rendezvous.cancel(LegacyRendezvousFailureReason.UserCancelled);
|
||||
} else {
|
||||
this.state.rendezvous.cancel(MSC4108FailureReason.UserCancelled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async legacyApproveLogin(): Promise<void> {
|
||||
if (!(this.state.rendezvous instanceof MSC3906Rendezvous)) {
|
||||
throw new Error("Rendezvous not found");
|
||||
}
|
||||
if (!this.props.client) {
|
||||
throw new Error("No client to approve login with");
|
||||
}
|
||||
this.setState({ phase: Phase.Loading });
|
||||
|
||||
try {
|
||||
logger.info("Requesting login token");
|
||||
|
||||
const { login_token: loginToken } = await wrapRequestWithDialog(this.props.client.requestLoginToken, {
|
||||
matrixClient: this.props.client,
|
||||
title: _t("auth|qr_code_login|sign_in_new_device"),
|
||||
})();
|
||||
|
||||
this.setState({ phase: Phase.WaitingForDevice });
|
||||
|
||||
const newDeviceId = await this.state.rendezvous.approveLoginOnExistingDevice(loginToken);
|
||||
if (!newDeviceId) {
|
||||
// user denied
|
||||
return;
|
||||
}
|
||||
if (!this.props.client.getCrypto()) {
|
||||
// no E2EE to set up
|
||||
this.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.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: ClientRendezvousFailureReason.Unknown });
|
||||
this.state.rendezvous.cancel(MSC4108FailureReason.UserCancelled);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -182,28 +106,18 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
private generateAndShowCode = async (): Promise<void> => {
|
||||
let rendezvous: MSC4108SignInWithQR | MSC3906Rendezvous;
|
||||
let rendezvous: MSC4108SignInWithQR;
|
||||
try {
|
||||
const fallbackRzServer = this.props.client?.getClientWellKnown()?.["io.element.rendezvous"]?.server;
|
||||
|
||||
if (this.props.legacy) {
|
||||
const transport = new MSC3886SimpleHttpRendezvousTransport<MSC3903ECDHPayload>({
|
||||
onFailure: this.onFailure,
|
||||
client: this.props.client,
|
||||
fallbackRzServer,
|
||||
});
|
||||
const channel = new MSC3903ECDHv2RendezvousChannel(transport, undefined, this.onFailure);
|
||||
rendezvous = new MSC3906Rendezvous(channel, this.props.client, this.onFailure);
|
||||
} else {
|
||||
const transport = new MSC4108RendezvousSession({
|
||||
onFailure: this.onFailure,
|
||||
client: this.props.client,
|
||||
fallbackRzServer,
|
||||
});
|
||||
await transport.send("");
|
||||
const channel = new MSC4108SecureChannel(transport, undefined, this.onFailure);
|
||||
rendezvous = new MSC4108SignInWithQR(channel, false, this.props.client, this.onFailure);
|
||||
}
|
||||
const transport = new MSC4108RendezvousSession({
|
||||
onFailure: this.onFailure,
|
||||
client: this.props.client,
|
||||
fallbackRzServer,
|
||||
});
|
||||
await transport.send("");
|
||||
const channel = new MSC4108SecureChannel(transport, undefined, this.onFailure);
|
||||
rendezvous = new MSC4108SignInWithQR(channel, false, this.props.client, this.onFailure);
|
||||
|
||||
await rendezvous.generateCode();
|
||||
this.setState({
|
||||
|
@ -218,10 +132,7 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
try {
|
||||
if (rendezvous instanceof MSC3906Rendezvous) {
|
||||
const confirmationDigits = await rendezvous.startAfterShowingCode();
|
||||
this.setState({ phase: Phase.LegacyConnected, confirmationDigits });
|
||||
} else if (this.ourIntent === RendezvousIntent.RECIPROCATE_LOGIN_ON_EXISTING_DEVICE) {
|
||||
if (this.ourIntent === RendezvousIntent.RECIPROCATE_LOGIN_ON_EXISTING_DEVICE) {
|
||||
// MSC4108-Flow: NewScanned
|
||||
await rendezvous.negotiateProtocols();
|
||||
const { verificationUri } = await rendezvous.deviceAuthorizationGrant();
|
||||
|
@ -234,18 +145,9 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
// we ask the user to confirm that the channel is secure
|
||||
} catch (e: RendezvousError | unknown) {
|
||||
logger.error("Error whilst approving login", e);
|
||||
if (rendezvous instanceof MSC3906Rendezvous) {
|
||||
// only set to error phase if it hasn't already been set by onFailure or similar
|
||||
if (this.state.phase !== Phase.Error) {
|
||||
this.setState({ phase: Phase.Error, failureReason: LegacyRendezvousFailureReason.Unknown });
|
||||
}
|
||||
} else {
|
||||
await rendezvous?.cancel(
|
||||
e instanceof RendezvousError
|
||||
? (e.code as MSC4108FailureReason)
|
||||
: ClientRendezvousFailureReason.Unknown,
|
||||
);
|
||||
}
|
||||
await rendezvous?.cancel(
|
||||
e instanceof RendezvousError ? (e.code as MSC4108FailureReason) : ClientRendezvousFailureReason.Unknown,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -298,7 +200,6 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
public reset(): void {
|
||||
this.setState({
|
||||
rendezvous: undefined,
|
||||
confirmationDigits: undefined,
|
||||
verificationUri: undefined,
|
||||
failureReason: undefined,
|
||||
userCode: undefined,
|
||||
|
@ -311,16 +212,12 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
private onClick = async (type: Click, checkCode?: string): Promise<void> => {
|
||||
switch (type) {
|
||||
case Click.Cancel:
|
||||
if (this.state.rendezvous instanceof MSC3906Rendezvous) {
|
||||
await this.state.rendezvous?.cancel(LegacyRendezvousFailureReason.UserCancelled);
|
||||
} else {
|
||||
await this.state.rendezvous?.cancel(MSC4108FailureReason.UserCancelled);
|
||||
}
|
||||
await this.state.rendezvous?.cancel(MSC4108FailureReason.UserCancelled);
|
||||
this.reset();
|
||||
this.onFinished(false);
|
||||
break;
|
||||
case Click.Approve:
|
||||
await (this.props.legacy ? this.legacyApproveLogin() : this.approveLogin(checkCode));
|
||||
await this.approveLogin(checkCode);
|
||||
break;
|
||||
case Click.Decline:
|
||||
await this.state.rendezvous?.declineLoginOnExistingDevice();
|
||||
|
@ -328,11 +225,7 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
this.onFinished(false);
|
||||
break;
|
||||
case Click.Back:
|
||||
if (this.state.rendezvous instanceof MSC3906Rendezvous) {
|
||||
await this.state.rendezvous?.cancel(LegacyRendezvousFailureReason.UserCancelled);
|
||||
} else {
|
||||
await this.state.rendezvous?.cancel(MSC4108FailureReason.UserCancelled);
|
||||
}
|
||||
await this.state.rendezvous?.cancel(MSC4108FailureReason.UserCancelled);
|
||||
this.onFinished(false);
|
||||
break;
|
||||
case Click.ShowQr:
|
||||
|
@ -342,20 +235,6 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
if (this.state.rendezvous instanceof MSC3906Rendezvous) {
|
||||
return (
|
||||
<LoginWithQRFlow
|
||||
onClick={this.onClick}
|
||||
phase={this.state.phase}
|
||||
code={this.state.phase === Phase.ShowingQR ? this.state.rendezvous?.code : undefined}
|
||||
confirmationDigits={
|
||||
this.state.phase === Phase.LegacyConnected ? this.state.confirmationDigits : undefined
|
||||
}
|
||||
failureReason={this.state.failureReason}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<LoginWithQRFlow
|
||||
onClick={this.onClick}
|
||||
|
|
|
@ -7,11 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
*/
|
||||
|
||||
import React, { createRef, ReactNode } from "react";
|
||||
import {
|
||||
ClientRendezvousFailureReason,
|
||||
LegacyRendezvousFailureReason,
|
||||
MSC4108FailureReason,
|
||||
} from "matrix-js-sdk/src/rendezvous";
|
||||
import { ClientRendezvousFailureReason, MSC4108FailureReason } from "matrix-js-sdk/src/rendezvous";
|
||||
import ChevronLeftIcon from "@vector-im/compound-design-tokens/assets/web/icons/chevron-left";
|
||||
import CheckCircleSolidIcon from "@vector-im/compound-design-tokens/assets/web/icons/check-circle-solid";
|
||||
import ErrorIcon from "@vector-im/compound-design-tokens/assets/web/icons/error";
|
||||
|
@ -23,21 +19,11 @@ import { _t } from "../../../languageHandler";
|
|||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import QRCode from "../elements/QRCode";
|
||||
import Spinner from "../elements/Spinner";
|
||||
import { Icon as InfoIcon } from "../../../../res/img/element-icons/i.svg";
|
||||
import { Click, Phase } from "./LoginWithQR-types";
|
||||
import SdkConfig from "../../../SdkConfig";
|
||||
import { FailureReason, LoginWithQRFailureReason } from "./LoginWithQR";
|
||||
import { XOR } from "../../../@types/common";
|
||||
import { ErrorMessage } from "../../structures/ErrorMessage";
|
||||
|
||||
/**
|
||||
* @deprecated the MSC3906 implementation is deprecated in favour of MSC4108.
|
||||
*/
|
||||
interface MSC3906Props extends Pick<Props, "phase" | "onClick" | "failureReason"> {
|
||||
code?: string;
|
||||
confirmationDigits?: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
phase: Phase;
|
||||
code?: Uint8Array;
|
||||
|
@ -47,19 +33,15 @@ interface Props {
|
|||
checkCode?: string;
|
||||
}
|
||||
|
||||
// n.b MSC3886/MSC3903/MSC3906 that this is based on are now closed.
|
||||
// However, we want to keep this implementation around for some time.
|
||||
// TODO: define an end-of-life date for this implementation.
|
||||
|
||||
/**
|
||||
* A component that implements the UI for sign in and E2EE set up with a QR code.
|
||||
*
|
||||
* This supports the unstable features of MSC3906 and MSC4108
|
||||
* This supports the unstable features of MSC4108
|
||||
*/
|
||||
export default class LoginWithQRFlow extends React.Component<XOR<Props, MSC3906Props>> {
|
||||
export default class LoginWithQRFlow extends React.Component<Props> {
|
||||
private checkCodeInput = createRef<HTMLInputElement>();
|
||||
|
||||
public constructor(props: XOR<Props, MSC3906Props>) {
|
||||
public constructor(props: Props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
|
@ -104,20 +86,17 @@ export default class LoginWithQRFlow extends React.Component<XOR<Props, MSC3906P
|
|||
|
||||
switch (this.props.failureReason) {
|
||||
case MSC4108FailureReason.UnsupportedProtocol:
|
||||
case LegacyRendezvousFailureReason.UnsupportedProtocol:
|
||||
title = _t("auth|qr_code_login|error_unsupported_protocol_title");
|
||||
message = _t("auth|qr_code_login|error_unsupported_protocol");
|
||||
break;
|
||||
|
||||
case MSC4108FailureReason.UserCancelled:
|
||||
case LegacyRendezvousFailureReason.UserCancelled:
|
||||
title = _t("auth|qr_code_login|error_user_cancelled_title");
|
||||
message = _t("auth|qr_code_login|error_user_cancelled");
|
||||
break;
|
||||
|
||||
case MSC4108FailureReason.AuthorizationExpired:
|
||||
case ClientRendezvousFailureReason.Expired:
|
||||
case LegacyRendezvousFailureReason.Expired:
|
||||
title = _t("auth|qr_code_login|error_expired_title");
|
||||
message = _t("auth|qr_code_login|error_expired");
|
||||
break;
|
||||
|
@ -162,7 +141,6 @@ export default class LoginWithQRFlow extends React.Component<XOR<Props, MSC3906P
|
|||
message = _t("auth|qr_code_login|error_etag_missing");
|
||||
break;
|
||||
|
||||
case LegacyRendezvousFailureReason.HomeserverLacksSupport:
|
||||
case ClientRendezvousFailureReason.HomeserverLacksSupport:
|
||||
success = null;
|
||||
Icon = QrCodeIcon;
|
||||
|
@ -200,40 +178,6 @@ export default class LoginWithQRFlow extends React.Component<XOR<Props, MSC3906P
|
|||
);
|
||||
break;
|
||||
}
|
||||
case Phase.LegacyConnected:
|
||||
backButton = false;
|
||||
main = (
|
||||
<>
|
||||
<p>{_t("auth|qr_code_login|confirm_code_match")}</p>
|
||||
<div className="mx_LoginWithQR_confirmationDigits">{this.props.confirmationDigits}</div>
|
||||
<div className="mx_LoginWithQR_confirmationAlert">
|
||||
<div>
|
||||
<InfoIcon />
|
||||
</div>
|
||||
<div>{_t("auth|qr_code_login|approve_access_warning")}</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
buttons = (
|
||||
<>
|
||||
<AccessibleButton
|
||||
data-testid="approve-login-button"
|
||||
kind="primary"
|
||||
onClick={this.handleClick(Click.Approve)}
|
||||
>
|
||||
{_t("action|approve")}
|
||||
</AccessibleButton>
|
||||
<AccessibleButton
|
||||
data-testid="decline-login-button"
|
||||
kind="primary_outline"
|
||||
onClick={this.handleClick(Click.Decline)}
|
||||
>
|
||||
{_t("action|cancel")}
|
||||
</AccessibleButton>
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Phase.OutOfBandConfirmation:
|
||||
backButton = false;
|
||||
main = (
|
||||
|
@ -288,8 +232,7 @@ export default class LoginWithQRFlow extends React.Component<XOR<Props, MSC3906P
|
|||
break;
|
||||
case Phase.ShowingQR:
|
||||
if (this.props.code) {
|
||||
const data =
|
||||
typeof this.props.code !== "string" ? this.props.code : Buffer.from(this.props.code ?? "");
|
||||
const data = this.props.code;
|
||||
|
||||
main = (
|
||||
<>
|
||||
|
|
|
@ -8,10 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
|||
|
||||
import React from "react";
|
||||
import {
|
||||
IGetLoginTokenCapability,
|
||||
IServerVersions,
|
||||
GET_LOGIN_TOKEN_CAPABILITY,
|
||||
Capabilities,
|
||||
IClientWellKnown,
|
||||
OidcClientConfig,
|
||||
MatrixClient,
|
||||
|
@ -28,27 +25,11 @@ import { useMatrixClientContext } from "../../../../contexts/MatrixClientContext
|
|||
interface IProps {
|
||||
onShowQr: () => void;
|
||||
versions?: IServerVersions;
|
||||
capabilities?: Capabilities;
|
||||
wellKnown?: IClientWellKnown;
|
||||
oidcClientConfig?: OidcClientConfig;
|
||||
isCrossSigningReady?: boolean;
|
||||
}
|
||||
|
||||
function shouldShowQrLegacy(
|
||||
versions?: IServerVersions,
|
||||
wellKnown?: IClientWellKnown,
|
||||
capabilities?: Capabilities,
|
||||
): boolean {
|
||||
// Needs server support for (get_login_token or OIDC Device Authorization Grant) and MSC3886:
|
||||
// in r0 of MSC3882 it is exposed as a feature flag, but in stable and unstable r1 it is a capability
|
||||
const loginTokenCapability = GET_LOGIN_TOKEN_CAPABILITY.findIn<IGetLoginTokenCapability>(capabilities);
|
||||
const getLoginTokenSupported =
|
||||
!!versions?.unstable_features?.["org.matrix.msc3882"] || !!loginTokenCapability?.enabled;
|
||||
const msc3886Supported =
|
||||
!!versions?.unstable_features?.["org.matrix.msc3886"] || !!wellKnown?.["io.element.rendezvous"]?.server;
|
||||
return getLoginTokenSupported && msc3886Supported;
|
||||
}
|
||||
|
||||
export function shouldShowQr(
|
||||
cli: MatrixClient,
|
||||
isCrossSigningReady: boolean,
|
||||
|
@ -73,15 +54,12 @@ export function shouldShowQr(
|
|||
const LoginWithQRSection: React.FC<IProps> = ({
|
||||
onShowQr,
|
||||
versions,
|
||||
capabilities,
|
||||
wellKnown,
|
||||
oidcClientConfig,
|
||||
isCrossSigningReady,
|
||||
}) => {
|
||||
const cli = useMatrixClientContext();
|
||||
const offerShowQr = oidcClientConfig
|
||||
? shouldShowQr(cli, !!isCrossSigningReady, oidcClientConfig, versions, wellKnown)
|
||||
: shouldShowQrLegacy(versions, wellKnown, capabilities);
|
||||
const offerShowQr = shouldShowQr(cli, !!isCrossSigningReady, oidcClientConfig, versions, wellKnown);
|
||||
|
||||
return (
|
||||
<SettingsSubsection heading={_t("settings|sessions|sign_in_with_qr")}>
|
||||
|
|
|
@ -181,7 +181,6 @@ const SessionManagerTab: React.FC<{
|
|||
const userId = matrixClient?.getUserId();
|
||||
const currentUserMember = (userId && matrixClient?.getUser(userId)) || undefined;
|
||||
const clientVersions = useAsyncMemo(() => matrixClient.getVersions(), [matrixClient]);
|
||||
const capabilities = useAsyncMemo(async () => matrixClient?.getCapabilities(), [matrixClient]);
|
||||
const wellKnown = useMemo(() => matrixClient?.getClientWellKnown(), [matrixClient]);
|
||||
const oidcClientConfig = useAsyncMemo(async () => {
|
||||
try {
|
||||
|
@ -292,12 +291,7 @@ const SessionManagerTab: React.FC<{
|
|||
if (signInWithQrMode) {
|
||||
return (
|
||||
<Suspense fallback={<Spinner />}>
|
||||
<LoginWithQR
|
||||
mode={signInWithQrMode}
|
||||
onFinished={onQrFinish}
|
||||
client={matrixClient}
|
||||
legacy={!oidcClientConfig && !showMsc4108QrCode}
|
||||
/>
|
||||
<LoginWithQR mode={signInWithQrMode} onFinished={onQrFinish} client={matrixClient} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
@ -308,7 +302,6 @@ const SessionManagerTab: React.FC<{
|
|||
<LoginWithQRSection
|
||||
onShowQr={onShowQrClicked}
|
||||
versions={clientVersions}
|
||||
capabilities={capabilities}
|
||||
wellKnown={wellKnown}
|
||||
oidcClientConfig={oidcClientConfig}
|
||||
isCrossSigningReady={isCrossSigningReady}
|
||||
|
|
|
@ -250,13 +250,11 @@
|
|||
"phone_label": "Phone",
|
||||
"phone_optional_label": "Phone (optional)",
|
||||
"qr_code_login": {
|
||||
"approve_access_warning": "By approving access for this device, it will have full access to your account.",
|
||||
"check_code_explainer": "This will verify that the connection to your other device is secure.",
|
||||
"check_code_heading": "Enter the number shown on your other device",
|
||||
"check_code_input_label": "2-digit code",
|
||||
"check_code_mismatch": "The numbers don't match",
|
||||
"completing_setup": "Completing set up of your new device",
|
||||
"confirm_code_match": "Check that the code below matches with your other device:",
|
||||
"error_etag_missing": "An unexpected error occurred. This may be due to a browser extension, proxy server, or server misconfiguration.",
|
||||
"error_expired": "Sign in expired. Please try again.",
|
||||
"error_expired_title": "The sign in was not completed in time",
|
||||
|
@ -284,7 +282,6 @@
|
|||
"security_code": "Security code",
|
||||
"security_code_prompt": "If asked, enter the code below on your other device.",
|
||||
"select_qr_code": "Select \"%(scanQRCode)s\"",
|
||||
"sign_in_new_device": "Sign in new device",
|
||||
"unsupported_explainer": "Your account provider doesn't support signing into a new device with a QR code.",
|
||||
"unsupported_heading": "QR code not supported",
|
||||
"waiting_for_device": "Waiting for device to sign in"
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { AuthDict } from "matrix-js-sdk/src/interactive-auth";
|
||||
import { UIAResponse } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import Modal from "../Modal";
|
||||
import InteractiveAuthDialog, { InteractiveAuthDialogProps } from "../components/views/dialogs/InteractiveAuthDialog";
|
||||
|
||||
type FunctionWithUIA<R, A> = (auth?: AuthDict, ...args: A[]) => Promise<UIAResponse<R>>;
|
||||
|
||||
export function wrapRequestWithDialog<R, A = any>(
|
||||
requestFunction: FunctionWithUIA<R, A>,
|
||||
opts: Omit<InteractiveAuthDialogProps<R>, "makeRequest" | "onFinished">,
|
||||
): (...args: A[]) => Promise<R> {
|
||||
return async function (...args): Promise<R> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const boundFunction = requestFunction.bind(opts.matrixClient) as FunctionWithUIA<R, A>;
|
||||
boundFunction(undefined, ...args)
|
||||
.then((res) => resolve(res as R))
|
||||
.catch((error) => {
|
||||
if (error.httpStatus !== 401 || !error.data?.flows) {
|
||||
// doesn't look like an interactive-auth failure
|
||||
return reject(error);
|
||||
}
|
||||
|
||||
Modal.createDialog(InteractiveAuthDialog, {
|
||||
...opts,
|
||||
authData: error.data,
|
||||
makeRequest: (authData: AuthDict) => boundFunction(authData, ...args),
|
||||
onFinished: (success, result) => {
|
||||
if (success) {
|
||||
resolve(result as R);
|
||||
} else {
|
||||
reject(result);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue