mirror of https://github.com/vector-im/riot-web
Use .well-known to discover a default rendezvous server for use with Sign in with QR (#11655)
parent
0518af70ac
commit
8442f1cf10
|
@ -153,9 +153,11 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
|
||||||
private generateCode = async (): Promise<void> => {
|
private generateCode = async (): Promise<void> => {
|
||||||
let rendezvous: MSC3906Rendezvous;
|
let rendezvous: MSC3906Rendezvous;
|
||||||
try {
|
try {
|
||||||
|
const fallbackRzServer = this.props.client.getClientWellKnown()?.["io.element.rendezvous"]?.server;
|
||||||
const transport = new MSC3886SimpleHttpRendezvousTransport<MSC3903ECDHPayload>({
|
const transport = new MSC3886SimpleHttpRendezvousTransport<MSC3903ECDHPayload>({
|
||||||
onFailure: this.onFailure,
|
onFailure: this.onFailure,
|
||||||
client: this.props.client,
|
client: this.props.client,
|
||||||
|
fallbackRzServer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const channel = new MSC3903ECDHv2RendezvousChannel<MSC3906RendezvousPayload>(
|
const channel = new MSC3903ECDHv2RendezvousChannel<MSC3906RendezvousPayload>(
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
IServerVersions,
|
IServerVersions,
|
||||||
UNSTABLE_MSC3882_CAPABILITY,
|
UNSTABLE_MSC3882_CAPABILITY,
|
||||||
Capabilities,
|
Capabilities,
|
||||||
|
IClientWellKnown,
|
||||||
} from "matrix-js-sdk/src/matrix";
|
} from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { _t } from "../../../../languageHandler";
|
import { _t } from "../../../../languageHandler";
|
||||||
|
@ -30,6 +31,7 @@ interface IProps {
|
||||||
onShowQr: () => void;
|
onShowQr: () => void;
|
||||||
versions?: IServerVersions;
|
versions?: IServerVersions;
|
||||||
capabilities?: Capabilities;
|
capabilities?: Capabilities;
|
||||||
|
wellKnown?: IClientWellKnown;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class LoginWithQRSection extends React.Component<IProps> {
|
export default class LoginWithQRSection extends React.Component<IProps> {
|
||||||
|
@ -43,7 +45,9 @@ export default class LoginWithQRSection extends React.Component<IProps> {
|
||||||
const capability = UNSTABLE_MSC3882_CAPABILITY.findIn<IMSC3882GetLoginTokenCapability>(this.props.capabilities);
|
const capability = UNSTABLE_MSC3882_CAPABILITY.findIn<IMSC3882GetLoginTokenCapability>(this.props.capabilities);
|
||||||
const msc3882Supported =
|
const msc3882Supported =
|
||||||
!!this.props.versions?.unstable_features?.["org.matrix.msc3882"] || !!capability?.enabled;
|
!!this.props.versions?.unstable_features?.["org.matrix.msc3882"] || !!capability?.enabled;
|
||||||
const msc3886Supported = !!this.props.versions?.unstable_features?.["org.matrix.msc3886"];
|
const msc3886Supported =
|
||||||
|
!!this.props.versions?.unstable_features?.["org.matrix.msc3886"] ||
|
||||||
|
this.props.wellKnown?.["io.element.rendezvous"]?.server;
|
||||||
const offerShowQr = msc3882Supported && msc3886Supported;
|
const offerShowQr = msc3882Supported && msc3886Supported;
|
||||||
|
|
||||||
// don't show anything if no method is available
|
// don't show anything if no method is available
|
||||||
|
|
|
@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback, useContext, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
import { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
|
@ -180,6 +180,7 @@ const SessionManagerTab: React.FC = () => {
|
||||||
const currentUserMember = (userId && matrixClient?.getUser(userId)) || undefined;
|
const currentUserMember = (userId && matrixClient?.getUser(userId)) || undefined;
|
||||||
const clientVersions = useAsyncMemo(() => matrixClient.getVersions(), [matrixClient]);
|
const clientVersions = useAsyncMemo(() => matrixClient.getVersions(), [matrixClient]);
|
||||||
const capabilities = useAsyncMemo(async () => matrixClient?.getCapabilities(), [matrixClient]);
|
const capabilities = useAsyncMemo(async () => matrixClient?.getCapabilities(), [matrixClient]);
|
||||||
|
const wellKnown = useMemo(() => matrixClient?.getClientWellKnown(), [matrixClient]);
|
||||||
|
|
||||||
const onDeviceExpandToggle = (deviceId: ExtendedDevice["device_id"]): void => {
|
const onDeviceExpandToggle = (deviceId: ExtendedDevice["device_id"]): void => {
|
||||||
if (expandedDeviceIds.includes(deviceId)) {
|
if (expandedDeviceIds.includes(deviceId)) {
|
||||||
|
@ -329,7 +330,12 @@ const SessionManagerTab: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
</SettingsSubsection>
|
</SettingsSubsection>
|
||||||
)}
|
)}
|
||||||
<LoginWithQRSection onShowQr={onShowQrClicked} versions={clientVersions} capabilities={capabilities} />
|
<LoginWithQRSection
|
||||||
|
onShowQr={onShowQrClicked}
|
||||||
|
versions={clientVersions}
|
||||||
|
capabilities={capabilities}
|
||||||
|
wellKnown={wellKnown}
|
||||||
|
/>
|
||||||
</SettingsSection>
|
</SettingsSection>
|
||||||
</SettingsTab>
|
</SettingsTab>
|
||||||
);
|
);
|
||||||
|
|
|
@ -51,6 +51,7 @@ function makeClient() {
|
||||||
currentState: {
|
currentState: {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
},
|
},
|
||||||
|
getClientWellKnown: jest.fn().mockReturnValue({}),
|
||||||
} as unknown as MatrixClient);
|
} as unknown as MatrixClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,13 @@ limitations under the License.
|
||||||
|
|
||||||
import { render } from "@testing-library/react";
|
import { render } from "@testing-library/react";
|
||||||
import { mocked } from "jest-mock";
|
import { mocked } from "jest-mock";
|
||||||
import { IServerVersions, MatrixClient, UNSTABLE_MSC3882_CAPABILITY } from "matrix-js-sdk/src/matrix";
|
import { IClientWellKnown, IServerVersions, MatrixClient, UNSTABLE_MSC3882_CAPABILITY } from "matrix-js-sdk/src/matrix";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import LoginWithQRSection from "../../../../../src/components/views/settings/devices/LoginWithQRSection";
|
import LoginWithQRSection from "../../../../../src/components/views/settings/devices/LoginWithQRSection";
|
||||||
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
|
||||||
|
|
||||||
function makeClient() {
|
function makeClient(wellKnown: IClientWellKnown) {
|
||||||
return mocked({
|
return mocked({
|
||||||
getUser: jest.fn(),
|
getUser: jest.fn(),
|
||||||
isGuest: jest.fn().mockReturnValue(false),
|
isGuest: jest.fn().mockReturnValue(false),
|
||||||
|
@ -37,6 +37,7 @@ function makeClient() {
|
||||||
currentState: {
|
currentState: {
|
||||||
on: jest.fn(),
|
on: jest.fn(),
|
||||||
},
|
},
|
||||||
|
getClientWellKnown: jest.fn().mockReturnValue(wellKnown),
|
||||||
} as unknown as MatrixClient);
|
} as unknown as MatrixClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,12 +50,13 @@ function makeVersions(unstableFeatures: Record<string, boolean>): IServerVersion
|
||||||
|
|
||||||
describe("<LoginWithQRSection />", () => {
|
describe("<LoginWithQRSection />", () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(makeClient());
|
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(makeClient({}));
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
onShowQr: () => {},
|
onShowQr: () => {},
|
||||||
versions: makeVersions({}),
|
versions: makeVersions({}),
|
||||||
|
wellKnown: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const getComponent = (props = {}) => <LoginWithQRSection {...defaultProps} {...props} />;
|
const getComponent = (props = {}) => <LoginWithQRSection {...defaultProps} {...props} />;
|
||||||
|
@ -114,5 +116,22 @@ describe("<LoginWithQRSection />", () => {
|
||||||
);
|
);
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("MSC3882 r1 + .well-known", async () => {
|
||||||
|
const wellKnown = {
|
||||||
|
"io.element.rendezvous": {
|
||||||
|
server: "https://rz.local",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(makeClient(wellKnown));
|
||||||
|
const { container } = render(
|
||||||
|
getComponent({
|
||||||
|
versions: makeVersions({}),
|
||||||
|
capabilities: { [UNSTABLE_MSC3882_CAPABILITY.name]: { enabled: true } },
|
||||||
|
wellKnown,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -46,6 +46,44 @@ exports[`<LoginWithQRSection /> should render panel MSC3882 + MSC3886 1`] = `
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`<LoginWithQRSection /> should render panel MSC3882 r1 + .well-known 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsectionHeading"
|
||||||
|
>
|
||||||
|
<h3
|
||||||
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
|
>
|
||||||
|
Sign in with QR code
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="mx_SettingsSubsection_content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_LoginWithQRSection"
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
class="mx_SettingsTab_subsectionText"
|
||||||
|
>
|
||||||
|
You can use this device to sign in a new device with a QR code. You will need to scan the QR code shown on this device with your device that's signed out.
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="mx_AccessibleButton mx_AccessibleButton_hasKind mx_AccessibleButton_kind_primary"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Show QR code
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`<LoginWithQRSection /> should render panel MSC3882 r1 + MSC3886 1`] = `
|
exports[`<LoginWithQRSection /> should render panel MSC3882 r1 + MSC3886 1`] = `
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Reference in New Issue