mirror of
https://github.com/vector-im/element-call.git
synced 2026-08-17 20:39:19 +00:00
Remove well-known discovery
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
type MockedObject,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import { type IClientWellKnown, MatrixError } from "matrix-js-sdk";
|
||||
import { MatrixError } from "matrix-js-sdk";
|
||||
import { logger as rootLogger } from "matrix-js-sdk/lib/logger";
|
||||
import {
|
||||
type LivekitTransportConfig,
|
||||
@@ -33,9 +33,9 @@ const backendTransport: LivekitTransportConfig = {
|
||||
livekit_service_url: "https://backend.example.org",
|
||||
};
|
||||
|
||||
const wellKnownTransport: LivekitTransportConfig = {
|
||||
const configTransport: LivekitTransportConfig = {
|
||||
type: "livekit",
|
||||
livekit_service_url: "https://well-known.example.org",
|
||||
livekit_service_url: "https://config.example.org",
|
||||
};
|
||||
|
||||
function makeClient(): MockedObject<DiscoveryClient> {
|
||||
@@ -59,12 +59,6 @@ function makeResolvedConfig(livekitServiceUrl?: string): ResolvedConfigOptions {
|
||||
} as ResolvedConfigOptions;
|
||||
}
|
||||
|
||||
function makeWellKnown(rtcFoci?: Transport[]): IClientWellKnown {
|
||||
return {
|
||||
"org.matrix.msc4143.rtc_foci": rtcFoci,
|
||||
} as unknown as IClientWellKnown;
|
||||
}
|
||||
|
||||
describe("RtcTransportAutoDiscovery", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
@@ -75,33 +69,30 @@ describe("RtcTransportAutoDiscovery", () => {
|
||||
{ transports: [{ type: "not_livekit" }, backendTransport] },
|
||||
];
|
||||
it.each(VALID_TEST_CASES)(
|
||||
"prefers backend transport over well-known and app config $transports",
|
||||
"prefers backend transport other app config $transports",
|
||||
async ({ transports }) => {
|
||||
// it("prefers backend transport over well-known and app config", async () => {
|
||||
const client = makeClient();
|
||||
client._unstable_getRTCTransports.mockResolvedValue(transports);
|
||||
|
||||
const wellKnownFetcher = vi
|
||||
.fn<(domain: string) => Promise<IClientWellKnown>>()
|
||||
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
|
||||
|
||||
const discovery = new RtcTransportAutoDiscovery({
|
||||
client,
|
||||
resolvedConfig: makeResolvedConfig("https://config.example.org"),
|
||||
wellKnownFetcher,
|
||||
resolvedConfig: makeResolvedConfig(configTransport.livekit_service_url),
|
||||
logger: rootLogger,
|
||||
});
|
||||
|
||||
await expect(
|
||||
discovery.discoverPreferredTransport(),
|
||||
).resolves.toStrictEqual(backendTransport);
|
||||
|
||||
const discoveredTransport = await discovery.discoverPreferredTransport();
|
||||
|
||||
expect(discoveredTransport).toStrictEqual(backendTransport);
|
||||
expect(discoveredTransport).not.toStrictEqual(configTransport);
|
||||
|
||||
expect(client._unstable_getRTCTransports).toHaveBeenCalledTimes(1);
|
||||
expect(wellKnownFetcher).not.toHaveBeenCalled();
|
||||
|
||||
},
|
||||
);
|
||||
|
||||
it("Retries limit_exceeded backend transport over well-known", async () => {
|
||||
it("Retries limit_exceeded backend transport", async () => {
|
||||
const client = makeClient();
|
||||
client._unstable_getRTCTransports
|
||||
.mockRejectedValueOnce(
|
||||
@@ -116,14 +107,10 @@ describe("RtcTransportAutoDiscovery", () => {
|
||||
)
|
||||
.mockResolvedValue([backendTransport]);
|
||||
|
||||
const wellKnownFetcher = vi
|
||||
.fn<(domain: string) => Promise<IClientWellKnown>>()
|
||||
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
|
||||
|
||||
const discovery = new RtcTransportAutoDiscovery({
|
||||
client,
|
||||
resolvedConfig: makeResolvedConfig("https://config.example.org"),
|
||||
wellKnownFetcher,
|
||||
logger: rootLogger,
|
||||
});
|
||||
|
||||
@@ -132,7 +119,6 @@ describe("RtcTransportAutoDiscovery", () => {
|
||||
);
|
||||
|
||||
expect(client._unstable_getRTCTransports).toHaveBeenCalledTimes(2);
|
||||
expect(wellKnownFetcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
const INVALID_TEST_CASES: Array<{ transports: Transport[] }> = [
|
||||
@@ -140,91 +126,32 @@ describe("RtcTransportAutoDiscovery", () => {
|
||||
{ transports: [{ type: "not_livekit" }] },
|
||||
];
|
||||
it.each(INVALID_TEST_CASES)(
|
||||
"falls back to well-known when backend has no (valid) livekit transports $transports",
|
||||
"falls back to config when backend has no (valid) livekit transports $transports",
|
||||
async ({ transports }) => {
|
||||
const client = makeClient();
|
||||
client._unstable_getRTCTransports.mockResolvedValue(transports);
|
||||
|
||||
const wellKnownFetcher = vi
|
||||
.fn<(domain: string) => Promise<IClientWellKnown>>()
|
||||
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
|
||||
|
||||
const discovery = new RtcTransportAutoDiscovery({
|
||||
client,
|
||||
resolvedConfig: makeResolvedConfig("https://config.example.org"),
|
||||
wellKnownFetcher,
|
||||
resolvedConfig: makeResolvedConfig(configTransport.livekit_service_url),
|
||||
logger: rootLogger,
|
||||
});
|
||||
|
||||
await expect(
|
||||
discovery.discoverPreferredTransport(),
|
||||
).resolves.toStrictEqual(wellKnownTransport);
|
||||
const discoveredTransport = await discovery.discoverPreferredTransport();
|
||||
expect(discoveredTransport).not.toStrictEqual(backendTransport);
|
||||
expect(discoveredTransport).toStrictEqual(configTransport);
|
||||
|
||||
expect(wellKnownFetcher).toHaveBeenCalledWith("example.org");
|
||||
},
|
||||
);
|
||||
|
||||
it("skips backend discovery in widget mode and uses well-known", async () => {
|
||||
const client = makeClient();
|
||||
// widget mode is detected by the absence of an access token
|
||||
client.getAccessToken.mockReturnValue(null);
|
||||
|
||||
const wellKnownFetcher = vi
|
||||
.fn<(domain: string) => Promise<IClientWellKnown>>()
|
||||
.mockResolvedValue(makeWellKnown([wellKnownTransport]));
|
||||
|
||||
const discovery = new RtcTransportAutoDiscovery({
|
||||
client,
|
||||
resolvedConfig: makeResolvedConfig("https://config.example.org"),
|
||||
wellKnownFetcher,
|
||||
logger: rootLogger,
|
||||
});
|
||||
|
||||
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
|
||||
wellKnownTransport,
|
||||
);
|
||||
|
||||
expect(client._unstable_getRTCTransports).not.toHaveBeenCalled();
|
||||
expect(wellKnownFetcher).toHaveBeenCalledWith("example.org");
|
||||
});
|
||||
|
||||
it("falls back to app config when backend fails and well-known has no rtc_foci", async () => {
|
||||
const client = makeClient();
|
||||
client._unstable_getRTCTransports.mockRejectedValue(
|
||||
new MatrixError({ errcode: "M_UNKNOWN" }, 404),
|
||||
);
|
||||
|
||||
const wellKnownFetcher = vi
|
||||
.fn<(domain: string) => Promise<IClientWellKnown>>()
|
||||
.mockResolvedValue({} as IClientWellKnown);
|
||||
|
||||
const discovery = new RtcTransportAutoDiscovery({
|
||||
client,
|
||||
resolvedConfig: makeResolvedConfig("https://config.example.org"),
|
||||
wellKnownFetcher,
|
||||
logger: rootLogger,
|
||||
});
|
||||
|
||||
await expect(discovery.discoverPreferredTransport()).resolves.toStrictEqual(
|
||||
{
|
||||
type: "livekit",
|
||||
livekit_service_url: "https://config.example.org",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("returns null when backend, well-known and config are all unavailable", async () => {
|
||||
it("returns null when backend and config are all unavailable", async () => {
|
||||
const client = makeClient();
|
||||
client._unstable_getRTCTransports.mockResolvedValue([]);
|
||||
|
||||
const wellKnownFetcher = vi
|
||||
.fn<(domain: string) => Promise<IClientWellKnown>>()
|
||||
.mockResolvedValue({} as IClientWellKnown);
|
||||
|
||||
const discovery = new RtcTransportAutoDiscovery({
|
||||
client,
|
||||
resolvedConfig: makeResolvedConfig(undefined),
|
||||
wellKnownFetcher,
|
||||
logger: rootLogger,
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
isLivekitTransportConfig,
|
||||
type LivekitTransportConfig,
|
||||
} from "matrix-js-sdk/lib/matrixrtc";
|
||||
import { type IClientWellKnown, type MatrixClient } from "matrix-js-sdk";
|
||||
import { type MatrixClient } from "matrix-js-sdk";
|
||||
import { type Logger } from "matrix-js-sdk/lib/logger";
|
||||
|
||||
import type { ResolvedConfigOptions } from "../../../config/ConfigOptions.ts";
|
||||
@@ -22,27 +22,21 @@ type TransportDiscoveryClient = Pick<
|
||||
export interface RtcTransportAutoDiscoveryProps {
|
||||
client: TransportDiscoveryClient;
|
||||
resolvedConfig: ResolvedConfigOptions;
|
||||
wellKnownFetcher: (domain: string) => Promise<IClientWellKnown>;
|
||||
logger: Logger;
|
||||
}
|
||||
|
||||
export class RtcTransportAutoDiscovery {
|
||||
private readonly client: TransportDiscoveryClient;
|
||||
private readonly resolvedConfig: ResolvedConfigOptions;
|
||||
private readonly wellKnownFetcher: (
|
||||
domain: string,
|
||||
) => Promise<IClientWellKnown>;
|
||||
private readonly logger: Logger;
|
||||
|
||||
public constructor({
|
||||
client,
|
||||
resolvedConfig,
|
||||
wellKnownFetcher,
|
||||
logger,
|
||||
}: RtcTransportAutoDiscoveryProps) {
|
||||
this.client = client;
|
||||
this.resolvedConfig = resolvedConfig;
|
||||
this.wellKnownFetcher = wellKnownFetcher;
|
||||
this.logger = logger.getChild("[RtcTransportAutoDiscovery]");
|
||||
}
|
||||
|
||||
@@ -56,21 +50,7 @@ export class RtcTransportAutoDiscovery {
|
||||
return backendTransport;
|
||||
}
|
||||
|
||||
this.logger.info("No backend transport found, falling back to well-known");
|
||||
// 2) .well-known transports
|
||||
const wellKnownTransport = await this.tryWellKnownTransports();
|
||||
if (wellKnownTransport) {
|
||||
this.logger.info(
|
||||
`Found .well-known transport: ${wellKnownTransport.livekit_service_url}`,
|
||||
);
|
||||
return wellKnownTransport;
|
||||
}
|
||||
|
||||
this.logger.info(
|
||||
"No .well-known transport found, falling back to app config",
|
||||
);
|
||||
|
||||
// 3) app config URL
|
||||
// 2) app config URL
|
||||
const configTransport = this.tryConfigTransport();
|
||||
if (configTransport) {
|
||||
this.logger.info(
|
||||
@@ -110,44 +90,6 @@ export class RtcTransportAutoDiscovery {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the first rtc_foci from the .well-known/matrix/client.
|
||||
* This will not throw errors, but instead just log them and return null if the expected config is not found or malformed.
|
||||
* @private
|
||||
*/
|
||||
private async tryWellKnownTransports(): Promise<LivekitTransportConfig | null> {
|
||||
// Legacy MSC4143 (to be removed) WELL_KNOWN: Prioritize the .well-known/matrix/client, if available.
|
||||
const client = this.client;
|
||||
const domain = client.getDomain();
|
||||
if (domain) {
|
||||
// we use AutoDiscovery instead of relying on the MatrixClient having already
|
||||
// been fully configured and started
|
||||
|
||||
const wellKnownFoci = await this.wellKnownFetcher(domain);
|
||||
|
||||
const fociConfig = wellKnownFoci["org.matrix.msc4143.rtc_foci"];
|
||||
if (fociConfig) {
|
||||
if (!Array.isArray(fociConfig)) {
|
||||
this.logger.warn(
|
||||
`org.matrix.msc4143.rtc_foci is not an array in .well-known`,
|
||||
);
|
||||
} else {
|
||||
return fociConfig[0];
|
||||
}
|
||||
} else {
|
||||
this.logger.info(
|
||||
`No .well-known "org.matrix.msc4143.rtc_foci" found for ${domain}`,
|
||||
wellKnownFoci,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Should never happen, but just in case
|
||||
this.logger.warn(`No domain configured for client`);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private tryConfigTransport(): LivekitTransportConfig | null {
|
||||
const url = this.resolvedConfig.livekit?.livekit_service_url;
|
||||
if (url) {
|
||||
|
||||
Reference in New Issue
Block a user