Add enableClientWellKnownLookups

Gate client well-known lookups on enableClientWellKnownLookups

New URL param (default on), threaded from the embedder. When off, always
avoid client .well-known: skip the post-login poll (widget + SPA) and the
legacy MatrixRTC foci fallback. When on/unset, respect the transports
endpoint response: only fall back to .well-known on a 404 M_UNRECOGNIZED.
This commit is contained in:
David Langley
2026-07-10 18:49:10 +01:00
parent 59999b9b37
commit 23a9e0c85e
6 changed files with 212 additions and 74 deletions

View File

@@ -187,6 +187,13 @@ export interface UrlConfiguration {
*/ */
allowIceFallback: boolean; allowIceFallback: boolean;
/**
* Whether the app may make client `.well-known` lookups against the user's
* homeserver `server_name` (the post-login well-known poll and the legacy
* MatrixRTC foci `.well-known` fallback). Defaults to true.
*/
enableClientWellKnownLookups: boolean;
/** /**
* Whether the app should use per participant keys for E2EE. * Whether the app should use per participant keys for E2EE.
*/ */
@@ -371,6 +378,7 @@ export const computeUrlParams = (search = "", hash = ""): UrlParams => {
showControls: true, showControls: true,
hideScreensharing: false, hideScreensharing: false,
allowIceFallback: true, allowIceFallback: true,
enableClientWellKnownLookups: true,
perParticipantE2EE: true, perParticipantE2EE: true,
controlledAudioDevices: platform === "desktop" ? false : true, controlledAudioDevices: platform === "desktop" ? false : true,
skipLobby: true, skipLobby: true,
@@ -426,6 +434,7 @@ export const computeUrlParams = (search = "", hash = ""): UrlParams => {
showControls: true, showControls: true,
hideScreensharing: false, hideScreensharing: false,
allowIceFallback: false, allowIceFallback: false,
enableClientWellKnownLookups: true,
perParticipantE2EE: false, perParticipantE2EE: false,
controlledAudioDevices: false, controlledAudioDevices: false,
skipLobby: false, skipLobby: false,
@@ -472,6 +481,7 @@ export const computeUrlParams = (search = "", hash = ""): UrlParams => {
showControls: parser.getFlag("showControls"), showControls: parser.getFlag("showControls"),
hideScreensharing: parser.getFlag("hideScreensharing"), hideScreensharing: parser.getFlag("hideScreensharing"),
allowIceFallback: parser.getFlag("allowIceFallback"), allowIceFallback: parser.getFlag("allowIceFallback"),
enableClientWellKnownLookups: parser.getFlag("enableClientWellKnownLookups"),
perParticipantE2EE: parser.getFlag("perParticipantE2EE"), perParticipantE2EE: parser.getFlag("perParticipantE2EE"),
controlledAudioDevices: parser.getFlag("controlledAudioDevices"), controlledAudioDevices: parser.getFlag("controlledAudioDevices"),
skipLobby: isWidget ? parser.getFlag("skipLobby") : false, skipLobby: isWidget ? parser.getFlag("skipLobby") : false,

View File

@@ -44,6 +44,7 @@ import {
} from "../../../livekit/openIDSFU.ts"; } from "../../../livekit/openIDSFU.ts";
import { areLivekitTransportsEqual } from "../remoteMembers/MatrixLivekitMembers.ts"; import { areLivekitTransportsEqual } from "../remoteMembers/MatrixLivekitMembers.ts";
import { customLivekitUrl } from "../../../settings/settings.ts"; import { customLivekitUrl } from "../../../settings/settings.ts";
import { getUrlParams } from "../../../UrlParams.ts";
import { RtcTransportAutoDiscovery } from "./RtcTransportAutoDiscovery.ts"; import { RtcTransportAutoDiscovery } from "./RtcTransportAutoDiscovery.ts";
const logger = rootLogger.getChild("[LocalTransport]"); const logger = rootLogger.getChild("[LocalTransport]");
@@ -147,6 +148,7 @@ export const createLocalTransport$ = ({
const transportDiscovery = new RtcTransportAutoDiscovery({ const transportDiscovery = new RtcTransportAutoDiscovery({
client: client, client: client,
resolvedConfig: Config.get(), resolvedConfig: Config.get(),
enableClientWellKnownLookups: getUrlParams().enableClientWellKnownLookups,
wellKnownFetcher: AutoDiscovery.getRawClientConfig.bind(AutoDiscovery), wellKnownFetcher: AutoDiscovery.getRawClientConfig.bind(AutoDiscovery),
logger: logger, logger: logger,
}); });

View File

@@ -38,6 +38,11 @@ const wellKnownTransport: LivekitTransportConfig = {
livekit_service_url: "https://well-known.example.org", livekit_service_url: "https://well-known.example.org",
}; };
const configTransport: LivekitTransportConfig = {
type: "livekit",
livekit_service_url: "https://config.example.org",
};
function makeClient(): MockedObject<DiscoveryClient> { function makeClient(): MockedObject<DiscoveryClient> {
return { return {
getDomain: vi.fn().mockReturnValue("example.org"), getDomain: vi.fn().mockReturnValue("example.org"),
@@ -65,10 +70,29 @@ function makeWellKnown(rtcFoci?: Transport[]): IClientWellKnown {
} as unknown as IClientWellKnown; } as unknown as IClientWellKnown;
} }
// Error returned by a homeserver that does not implement the endpoint. This is
// the only failure that permits falling back to the legacy `.well-known` lookup.
const notImplementedError = new MatrixError({ errcode: "M_UNRECOGNIZED" }, 404);
function makeDiscovery(
overrides: Partial<RtcTransportAutoDiscoveryProps> & {
client: DiscoveryClient;
wellKnownFetcher: RtcTransportAutoDiscoveryProps["wellKnownFetcher"];
},
): RtcTransportAutoDiscovery {
return new RtcTransportAutoDiscovery({
resolvedConfig: makeResolvedConfig("https://config.example.org"),
enableClientWellKnownLookups: true,
logger: rootLogger,
...overrides,
});
}
describe("RtcTransportAutoDiscovery", () => { describe("RtcTransportAutoDiscovery", () => {
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
}); });
const VALID_TEST_CASES: Array<{ transports: Transport[] }> = [ const VALID_TEST_CASES: Array<{ transports: Transport[] }> = [
{ transports: [backendTransport] }, { transports: [backendTransport] },
// will pick the first livekit transport in the list, even if there are other non-livekit transports // will pick the first livekit transport in the list, even if there are other non-livekit transports
@@ -77,7 +101,6 @@ describe("RtcTransportAutoDiscovery", () => {
it.each(VALID_TEST_CASES)( it.each(VALID_TEST_CASES)(
"prefers backend transport over well-known and app config $transports", "prefers backend transport over well-known and app config $transports",
async ({ transports }) => { async ({ transports }) => {
// it("prefers backend transport over well-known and app config", async () => {
const client = makeClient(); const client = makeClient();
client._unstable_getRTCTransports.mockResolvedValue(transports); client._unstable_getRTCTransports.mockResolvedValue(transports);
@@ -85,12 +108,7 @@ describe("RtcTransportAutoDiscovery", () => {
.fn<(domain: string) => Promise<IClientWellKnown>>() .fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport])); .mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = new RtcTransportAutoDiscovery({ const discovery = makeDiscovery({ client, wellKnownFetcher });
client,
resolvedConfig: makeResolvedConfig("https://config.example.org"),
wellKnownFetcher,
logger: rootLogger,
});
await expect( await expect(
discovery.discoverPreferredTransport(), discovery.discoverPreferredTransport(),
@@ -120,12 +138,7 @@ describe("RtcTransportAutoDiscovery", () => {
.fn<(domain: string) => Promise<IClientWellKnown>>() .fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport])); .mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = new RtcTransportAutoDiscovery({ const discovery = makeDiscovery({ client, wellKnownFetcher });
client,
resolvedConfig: makeResolvedConfig("https://config.example.org"),
wellKnownFetcher,
logger: rootLogger,
});
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual( await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
backendTransport, backendTransport,
@@ -135,12 +148,15 @@ describe("RtcTransportAutoDiscovery", () => {
expect(wellKnownFetcher).not.toHaveBeenCalled(); expect(wellKnownFetcher).not.toHaveBeenCalled();
}); });
const INVALID_TEST_CASES: Array<{ transports: Transport[] }> = [ // A homeserver that implements the endpoint but returns no usable livekit
// transport has answered authoritatively, so we must NOT leak to the legacy
// `.well-known` lookup. Instead we fall straight through to app config.
const AUTHORITATIVE_EMPTY_CASES: Array<{ transports: Transport[] }> = [
{ transports: [] }, { transports: [] },
{ transports: [{ type: "not_livekit" }] }, { transports: [{ type: "not_livekit" }] },
]; ];
it.each(INVALID_TEST_CASES)( it.each(AUTHORITATIVE_EMPTY_CASES)(
"falls back to well-known when backend has no (valid) livekit transports $transports", "does not fall back to well-known when the backend answers without a livekit transport $transports",
async ({ transports }) => { async ({ transports }) => {
const client = makeClient(); const client = makeClient();
client._unstable_getRTCTransports.mockResolvedValue(transports); client._unstable_getRTCTransports.mockResolvedValue(transports);
@@ -149,21 +165,54 @@ describe("RtcTransportAutoDiscovery", () => {
.fn<(domain: string) => Promise<IClientWellKnown>>() .fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport])); .mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = new RtcTransportAutoDiscovery({ const discovery = makeDiscovery({ client, wellKnownFetcher });
client,
resolvedConfig: makeResolvedConfig("https://config.example.org"),
wellKnownFetcher,
logger: rootLogger,
});
await expect( await expect(
discovery.discoverPreferredTransport(), discovery.discoverPreferredTransport(),
).resolves.toStrictEqual(wellKnownTransport); ).resolves.toStrictEqual(configTransport);
expect(wellKnownFetcher).toHaveBeenCalledWith("example.org"); expect(wellKnownFetcher).not.toHaveBeenCalled();
}, },
); );
it("falls back to well-known only when the backend returns 404 M_UNRECOGNIZED", async () => {
const client = makeClient();
client._unstable_getRTCTransports.mockRejectedValue(notImplementedError);
const wellKnownFetcher = vi
.fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = makeDiscovery({ client, wellKnownFetcher });
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
wellKnownTransport,
);
expect(wellKnownFetcher).toHaveBeenCalledWith("example.org");
});
it("does not fall back to well-known when the backend fails with a non-M_UNRECOGNIZED errcode", async () => {
const client = makeClient();
// Same 404 status as the not-implemented case, but a different errcode: only
// M_UNRECOGNIZED is treated as "endpoint not implemented".
client._unstable_getRTCTransports.mockRejectedValue(
new MatrixError({ errcode: "M_UNKNOWN" }, 404),
);
const wellKnownFetcher = vi
.fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = makeDiscovery({ client, wellKnownFetcher });
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
configTransport,
);
expect(wellKnownFetcher).not.toHaveBeenCalled();
});
it("skips backend discovery in widget mode and uses well-known", async () => { it("skips backend discovery in widget mode and uses well-known", async () => {
const client = makeClient(); const client = makeClient();
// widget mode is detected by the absence of an access token // widget mode is detected by the absence of an access token
@@ -173,12 +222,7 @@ describe("RtcTransportAutoDiscovery", () => {
.fn<(domain: string) => Promise<IClientWellKnown>>() .fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport])); .mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = new RtcTransportAutoDiscovery({ const discovery = makeDiscovery({ client, wellKnownFetcher });
client,
resolvedConfig: makeResolvedConfig("https://config.example.org"),
wellKnownFetcher,
logger: rootLogger,
});
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual( await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
wellKnownTransport, wellKnownTransport,
@@ -188,44 +232,58 @@ describe("RtcTransportAutoDiscovery", () => {
expect(wellKnownFetcher).toHaveBeenCalledWith("example.org"); expect(wellKnownFetcher).toHaveBeenCalledWith("example.org");
}); });
it("falls back to app config when backend fails and well-known has no rtc_foci", async () => { it("does not make well-known lookups when disabled by config, even in widget mode", async () => {
const client = makeClient(); const client = makeClient();
client._unstable_getRTCTransports.mockRejectedValue( // widget mode: backend endpoint is not attempted
new MatrixError({ errcode: "M_UNKNOWN" }, 404), client.getAccessToken.mockReturnValue(null);
const wellKnownFetcher = vi
.fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
const discovery = makeDiscovery({
client,
wellKnownFetcher,
enableClientWellKnownLookups: false,
});
// The legacy well-known fallback is skipped entirely; only app config is used.
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
configTransport,
); );
expect(wellKnownFetcher).not.toHaveBeenCalled();
});
it("falls back to app config when the backend is not implemented and well-known has no rtc_foci", async () => {
const client = makeClient();
client._unstable_getRTCTransports.mockRejectedValue(notImplementedError);
const wellKnownFetcher = vi const wellKnownFetcher = vi
.fn<(domain: string) => Promise<IClientWellKnown>>() .fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue({} as IClientWellKnown); .mockResolvedValue({} as IClientWellKnown);
const discovery = new RtcTransportAutoDiscovery({ const discovery = makeDiscovery({ client, wellKnownFetcher });
client,
resolvedConfig: makeResolvedConfig("https://config.example.org"),
wellKnownFetcher,
logger: rootLogger,
});
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual( await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
{ configTransport,
type: "livekit",
livekit_service_url: "https://config.example.org",
},
); );
expect(wellKnownFetcher).toHaveBeenCalledWith("example.org");
}); });
it("returns null when backend, well-known and config are all unavailable", async () => { it("returns null when backend, well-known and config are all unavailable", async () => {
const client = makeClient(); const client = makeClient();
client._unstable_getRTCTransports.mockResolvedValue([]); client._unstable_getRTCTransports.mockRejectedValue(notImplementedError);
const wellKnownFetcher = vi const wellKnownFetcher = vi
.fn<(domain: string) => Promise<IClientWellKnown>>() .fn<(domain: string) => Promise<IClientWellKnown>>()
.mockResolvedValue({} as IClientWellKnown); .mockResolvedValue({} as IClientWellKnown);
const discovery = new RtcTransportAutoDiscovery({ const discovery = makeDiscovery({
client, client,
resolvedConfig: makeResolvedConfig(undefined),
wellKnownFetcher, wellKnownFetcher,
logger: rootLogger, resolvedConfig: makeResolvedConfig(undefined),
}); });
await expect(discovery.discoverPreferredTransport()).resolves.toBeNull(); await expect(discovery.discoverPreferredTransport()).resolves.toBeNull();

View File

@@ -8,7 +8,11 @@ import {
isLivekitTransportConfig, isLivekitTransportConfig,
type LivekitTransportConfig, type LivekitTransportConfig,
} from "matrix-js-sdk/lib/matrixrtc"; } from "matrix-js-sdk/lib/matrixrtc";
import { type IClientWellKnown, type MatrixClient } from "matrix-js-sdk"; import {
type IClientWellKnown,
type MatrixClient,
MatrixError,
} from "matrix-js-sdk";
import { type Logger } from "matrix-js-sdk/lib/logger"; import { type Logger } from "matrix-js-sdk/lib/logger";
import type { ResolvedConfigOptions } from "../../../config/ConfigOptions.ts"; import type { ResolvedConfigOptions } from "../../../config/ConfigOptions.ts";
@@ -22,13 +26,36 @@ type TransportDiscoveryClient = Pick<
export interface RtcTransportAutoDiscoveryProps { export interface RtcTransportAutoDiscoveryProps {
client: TransportDiscoveryClient; client: TransportDiscoveryClient;
resolvedConfig: ResolvedConfigOptions; resolvedConfig: ResolvedConfigOptions;
/**
* Whether client `.well-known` lookups against the homeserver's `server_name`
* are allowed. When false, the legacy MatrixRTC foci `.well-known` fallback is
* skipped entirely and only the backend endpoint and app config are used.
*/
enableClientWellKnownLookups: boolean;
wellKnownFetcher: (domain: string) => Promise<IClientWellKnown>; wellKnownFetcher: (domain: string) => Promise<IClientWellKnown>;
logger: Logger; logger: Logger;
} }
/**
* The outcome of querying the backend `/rtc/transports` endpoint.
*/
interface BackendTransportResult {
/** The livekit transport found via the backend endpoint, if any. */
transport: LivekitTransportConfig | null;
/**
* Whether the caller may fall back to the legacy `.well-known` lookup. True
* only when the backend endpoint is unavailable, i.e. it was not attempted
* (widget mode) or the homeserver does not implement it (404 M_UNRECOGNIZED).
* False when the endpoint answered authoritatively (a response without a
* livekit transport) or failed with any other error.
*/
mayFallBackToWellKnown: boolean;
}
export class RtcTransportAutoDiscovery { export class RtcTransportAutoDiscovery {
private readonly client: TransportDiscoveryClient; private readonly client: TransportDiscoveryClient;
private readonly resolvedConfig: ResolvedConfigOptions; private readonly resolvedConfig: ResolvedConfigOptions;
private readonly enableClientWellKnownLookups: boolean;
private readonly wellKnownFetcher: ( private readonly wellKnownFetcher: (
domain: string, domain: string,
) => Promise<IClientWellKnown>; ) => Promise<IClientWellKnown>;
@@ -37,38 +64,53 @@ export class RtcTransportAutoDiscovery {
public constructor({ public constructor({
client, client,
resolvedConfig, resolvedConfig,
enableClientWellKnownLookups,
wellKnownFetcher, wellKnownFetcher,
logger, logger,
}: RtcTransportAutoDiscoveryProps) { }: RtcTransportAutoDiscoveryProps) {
this.client = client; this.client = client;
this.resolvedConfig = resolvedConfig; this.resolvedConfig = resolvedConfig;
this.enableClientWellKnownLookups = enableClientWellKnownLookups;
this.wellKnownFetcher = wellKnownFetcher; this.wellKnownFetcher = wellKnownFetcher;
this.logger = logger.getChild("[RtcTransportAutoDiscovery]"); this.logger = logger.getChild("[RtcTransportAutoDiscovery]");
} }
public async discoverPreferredTransport(): Promise<LivekitTransportConfig | null> { public async discoverPreferredTransport(): Promise<LivekitTransportConfig | null> {
// 1) backend transports // 1) backend transports
const backendTransport = await this.tryBackendTransports(); const backend = await this.tryBackendTransports();
if (backendTransport) { if (backend.transport) {
this.logger.info( this.logger.info(
`Found backend transport: ${backendTransport.livekit_service_url}`, `Found backend transport: ${backend.transport.livekit_service_url}`,
); );
return backendTransport; return backend.transport;
} }
this.logger.info("No backend transport found, falling back to well-known");
// 2) .well-known transports // 2) .well-known transports
const wellKnownTransport = await this.tryWellKnownTransports(); // Only consulted when the backend endpoint was inconclusive (not attempted
if (wellKnownTransport) { // or not implemented) and client `.well-known` lookups are enabled. This
// avoids contacting the homeserver's `server_name` both when a modern
// endpoint has already given an authoritative answer and when lookups are
// disabled by config.
if (backend.mayFallBackToWellKnown && this.enableClientWellKnownLookups) {
this.logger.info( this.logger.info(
`Found .well-known transport: ${wellKnownTransport.livekit_service_url}`, "No backend transport found, falling back to well-known",
);
const wellKnownTransport = await this.tryWellKnownTransports();
if (wellKnownTransport) {
this.logger.info(
`Found .well-known transport: ${wellKnownTransport.livekit_service_url}`,
);
return wellKnownTransport;
}
} else {
this.logger.info(
this.enableClientWellKnownLookups
? "Skipping .well-known lookup: backend endpoint gave an authoritative response"
: "Skipping .well-known lookup: client well-known lookups are disabled",
); );
return wellKnownTransport;
} }
this.logger.info( this.logger.info("Falling back to app config");
"No .well-known transport found, falling back to app config",
);
// 3) app config URL // 3) app config URL
const configTransport = this.tryConfigTransport(); const configTransport = this.tryConfigTransport();
@@ -87,7 +129,7 @@ export class RtcTransportAutoDiscovery {
* This will not throw errors, but instead just log them and return null if the expected config is not found or malformed. * This will not throw errors, but instead just log them and return null if the expected config is not found or malformed.
* @private * @private
*/ */
private async tryBackendTransports(): Promise<LivekitTransportConfig | null> { private async tryBackendTransports(): Promise<BackendTransportResult> {
const client = this.client; const client = this.client;
// MSC4143: Attempt to fetch transports from backend. // MSC4143: Attempt to fetch transports from backend.
// TODO: Workaround for an issue in the js-sdk RoomWidgetClient that // TODO: Workaround for an issue in the js-sdk RoomWidgetClient that
@@ -104,21 +146,36 @@ export class RtcTransportAutoDiscovery {
); );
const first = transportList.find(isLivekitTransportConfig); const first = transportList.find(isLivekitTransportConfig);
if (first) { if (first) {
return first; return { transport: first, mayFallBackToWellKnown: false };
} else {
this.logger.info(
`No livekit transport found in getRTCTransports end point`,
transportList,
);
} }
// The homeserver implements the endpoint but returned no livekit
// transport. This is an authoritative answer, so we do not fall back
// to the legacy `.well-known` lookup.
this.logger.info(
`No livekit transport found in getRTCTransports end point`,
transportList,
);
return { transport: null, mayFallBackToWellKnown: false };
} catch (ex) { } catch (ex) {
this.logger.info(`Failed to use getRTCTransports end point: ${ex}`); // Only a 404 M_UNRECOGNIZED means the homeserver does not implement the
// endpoint, which is the one case where falling back to the legacy
// `.well-known` lookup is appropriate. Any other error is transient or
// unexpected, so we do not fall back.
if (ex instanceof MatrixError && ex.errcode === "M_UNRECOGNIZED") {
this.logger.info(
"getRTCTransports end point not implemented by homeserver",
);
return { transport: null, mayFallBackToWellKnown: true };
}
this.logger.warn(`Failed to use getRTCTransports end point: ${ex}`);
return { transport: null, mayFallBackToWellKnown: false };
} }
} else {
this.logger.debug(`getRTCTransports end point not available`);
} }
return null; // Not attempted (e.g. widget mode with no access token). Preserve the
// existing behaviour of allowing the legacy `.well-known` lookup.
this.logger.debug(`getRTCTransports end point not available`);
return { transport: null, mayFallBackToWellKnown: true };
} }
/** /**

View File

@@ -112,7 +112,7 @@ export async function initClient(
// the values around, but we initialise the matrix client in // the values around, but we initialise the matrix client in
// many different places so we'd have to pass it into all of // many different places so we'd have to pass it into all of
// them. // them.
const { e2eEnabled } = getUrlParams(); const { e2eEnabled, enableClientWellKnownLookups } = getUrlParams();
if (!e2eEnabled) { if (!e2eEnabled) {
logger.info("Disabling E2E: group call signalling will NOT be encrypted."); logger.info("Disabling E2E: group call signalling will NOT be encrypted.");
} }
@@ -166,7 +166,11 @@ export async function initClient(
// Otherwise, a sync may complete before the listener gets applied, // Otherwise, a sync may complete before the listener gets applied,
// and we will miss it. // and we will miss it.
const syncPromise = waitForSync(client); const syncPromise = waitForSync(client);
await client.startClient({ clientWellKnownPollPeriod: 60 * 10 }); // Leaving `clientWellKnownPollPeriod` unset stops the SDK polling the
// homeserver's `server_name` `.well-known` after login.
await client.startClient({
clientWellKnownPollPeriod: enableClientWellKnownLookups ? 60 * 10 : undefined,
});
await syncPromise; await syncPromise;
return client; return client;

View File

@@ -82,6 +82,7 @@ export const initializeWidget = (
baseUrl, baseUrl,
e2eEnabled, e2eEnabled,
allowIceFallback, allowIceFallback,
enableClientWellKnownLookups,
} = getUrlParams(); } = getUrlParams();
if (!roomId) throw new Error("Room ID must be supplied"); if (!roomId) throw new Error("Room ID must be supplied");
@@ -195,7 +196,13 @@ export const initializeWidget = (
// Wait for the config file to be ready (we load very early on so it might not // Wait for the config file to be ready (we load very early on so it might not
// be otherwise) // be otherwise)
await Config.init(); await Config.init();
await client.startClient({ clientWellKnownPollPeriod: 60 * 10 }); // Leaving `clientWellKnownPollPeriod` unset stops the SDK polling the
// homeserver's `server_name` `.well-known` after login.
await client.startClient({
clientWellKnownPollPeriod: enableClientWellKnownLookups
? 60 * 10
: undefined,
});
return client; return client;
}; };