Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Use .well-known to discover a default rendezvous server for use with Sign in with QR #11655

Merged
merged 1 commit into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/components/views/auth/LoginWithQR.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,11 @@ export default class LoginWithQR extends React.Component<IProps, IState> {
private generateCode = async (): Promise<void> => {
let rendezvous: MSC3906Rendezvous;
try {
const fallbackRzServer = this.props.client.getClientWellKnown()?.["io.element.rendezvous"]?.server;
const transport = new MSC3886SimpleHttpRendezvousTransport<MSC3903ECDHPayload>({
onFailure: this.onFailure,
client: this.props.client,
fallbackRzServer,
});

const channel = new MSC3903ECDHv2RendezvousChannel<MSC3906RendezvousPayload>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
IServerVersions,
UNSTABLE_MSC3882_CAPABILITY,
Capabilities,
IClientWellKnown,
} from "matrix-js-sdk/src/matrix";

import { _t } from "../../../../languageHandler";
Expand All @@ -30,6 +31,7 @@ interface IProps {
onShowQr: () => void;
versions?: IServerVersions;
capabilities?: Capabilities;
wellKnown?: IClientWellKnown;
}

export default class LoginWithQRSection extends React.Component<IProps> {
Expand All @@ -43,7 +45,9 @@ export default class LoginWithQRSection extends React.Component<IProps> {
const capability = UNSTABLE_MSC3882_CAPABILITY.findIn<IMSC3882GetLoginTokenCapability>(this.props.capabilities);
const msc3882Supported =
!!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;

// don't show anything if no method is available
Expand Down
10 changes: 8 additions & 2 deletions src/components/views/settings/tabs/user/SessionManagerTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
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 { logger } from "matrix-js-sdk/src/logger";

Expand Down Expand Up @@ -180,6 +180,7 @@ const SessionManagerTab: React.FC = () => {
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 onDeviceExpandToggle = (deviceId: ExtendedDevice["device_id"]): void => {
if (expandedDeviceIds.includes(deviceId)) {
Expand Down Expand Up @@ -329,7 +330,12 @@ const SessionManagerTab: React.FC = () => {
/>
</SettingsSubsection>
)}
<LoginWithQRSection onShowQr={onShowQrClicked} versions={clientVersions} capabilities={capabilities} />
<LoginWithQRSection
onShowQr={onShowQrClicked}
versions={clientVersions}
capabilities={capabilities}
wellKnown={wellKnown}
/>
</SettingsSection>
</SettingsTab>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ function makeClient() {
currentState: {
on: jest.fn(),
},
getClientWellKnown: jest.fn().mockReturnValue({}),
} as unknown as MatrixClient);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ limitations under the License.

import { render } from "@testing-library/react";
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 LoginWithQRSection from "../../../../../src/components/views/settings/devices/LoginWithQRSection";
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";

function makeClient() {
function makeClient(wellKnown: IClientWellKnown) {
return mocked({
getUser: jest.fn(),
isGuest: jest.fn().mockReturnValue(false),
Expand All @@ -37,6 +37,7 @@ function makeClient() {
currentState: {
on: jest.fn(),
},
getClientWellKnown: jest.fn().mockReturnValue(wellKnown),
} as unknown as MatrixClient);
}

Expand All @@ -49,12 +50,13 @@ function makeVersions(unstableFeatures: Record<string, boolean>): IServerVersion

describe("<LoginWithQRSection />", () => {
beforeAll(() => {
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(makeClient());
jest.spyOn(MatrixClientPeg, "get").mockReturnValue(makeClient({}));
});

const defaultProps = {
onShowQr: () => {},
versions: makeVersions({}),
wellKnown: {},
};

const getComponent = (props = {}) => <LoginWithQRSection {...defaultProps} {...props} />;
Expand Down Expand Up @@ -114,5 +116,22 @@ describe("<LoginWithQRSection />", () => {
);
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();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,44 @@ exports[`<LoginWithQRSection /> should render panel MSC3882 + MSC3886 1`] = `
</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`] = `
<div>
<div
Expand Down
Loading