Skip to content

Commit 6b7467c

Browse files
committed
Stop calling rtc/transport in widget mode
1 parent 40fdef8 commit 6b7467c

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

src/livekit/openIDSFU.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ export async function getSFUConfigWithOpenID(
137137
);
138138
logger?.info(`Got JWT from call's active focus URL.`);
139139
} catch (e) {
140+
logger?.debug(`Failed fetching jwt with matrix 2.0 endpoint:`, e);
140141
if (e instanceof NotSupportedError) {
141142
logger?.warn(
142143
`Failed fetching jwt with matrix 2.0 endpoint (retry with legacy) Not supported`,

src/state/CallViewModel/localMember/LocalTransport.test.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from "matrix-js-sdk/lib/matrixrtc";
2222
import { BehaviorSubject, lastValueFrom } from "rxjs";
2323
import fetchMock from "fetch-mock";
24+
import { AutoDiscovery } from "matrix-js-sdk/lib/autodiscovery";
2425

2526
import {
2627
mockConfig,
@@ -60,6 +61,7 @@ describe("LocalTransport", () => {
6061
client: {
6162
// eslint-disable-next-line @typescript-eslint/naming-convention
6263
_unstable_getRTCTransports: async () => Promise.resolve([]),
64+
getAccessToken: vi.fn().mockReturnValue("access_token"),
6365
getDomain: () => "",
6466
baseUrl: "example.org",
6567
// These won't be called in this error path but satisfy the type
@@ -102,6 +104,7 @@ describe("LocalTransport", () => {
102104
baseUrl: "https://lk.example.org",
103105
// Use empty domain to skip .well-known and use config directly
104106
getDomain: () => "",
107+
getAccessToken: vi.fn().mockReturnValue("access_token"),
105108
// eslint-disable-next-line @typescript-eslint/naming-convention
106109
_unstable_getRTCTransports: async () => Promise.resolve([]),
107110
getOpenIdToken: vi.fn(),
@@ -149,6 +152,7 @@ describe("LocalTransport", () => {
149152
getOpenIdToken: vi.fn(),
150153
getDeviceId: vi.fn(),
151154
baseUrl: "https://lk.example.org",
155+
getAccessToken: vi.fn().mockReturnValue("access_token"),
152156
},
153157
ownMembershipIdentity: ownMemberMock,
154158
forceJwtEndpoint: JwtEndpointVersion.Legacy,
@@ -217,6 +221,7 @@ describe("LocalTransport", () => {
217221
getDomain: () => "",
218222
// eslint-disable-next-line @typescript-eslint/naming-convention
219223
_unstable_getRTCTransports: async () => Promise.resolve([]),
224+
getAccessToken: vi.fn().mockReturnValue("access_token"),
220225
getOpenIdToken: vi.fn(),
221226
getDeviceId: vi.fn(),
222227
baseUrl: "https://lk.example.org",
@@ -273,6 +278,7 @@ describe("LocalTransport", () => {
273278
// eslint-disable-next-line @typescript-eslint/naming-convention
274279
_unstable_getRTCTransports: async () =>
275280
Promise.resolve([aliceTransport]),
281+
getAccessToken: vi.fn().mockReturnValue("access_token"),
276282
getOpenIdToken: vi.fn(),
277283
getDeviceId: vi.fn(),
278284
baseUrl: "https://lk.example.org",
@@ -323,6 +329,7 @@ describe("LocalTransport", () => {
323329
getDomain: vi.fn().mockReturnValue(""),
324330
// eslint-disable-next-line @typescript-eslint/naming-convention
325331
_unstable_getRTCTransports: vi.fn().mockResolvedValue([]),
332+
getAccessToken: vi.fn().mockReturnValue("access_token"),
326333
getOpenIdToken: vi.fn(),
327334
getDeviceId: vi.fn(),
328335
},
@@ -410,6 +417,49 @@ describe("LocalTransport", () => {
410417
});
411418
});
412419

420+
it("Should not call _unstable_getRTCTransports in widget mode but use well-known", async () => {
421+
mockConfig({
422+
livekit: { livekit_service_url: "https://do-not-use.lk.example.org" },
423+
});
424+
425+
localTransportOpts.client.getDomain.mockReturnValue("example.org");
426+
427+
vi.spyOn(AutoDiscovery, "getRawClientConfig").mockImplementation(
428+
async (domain) => {
429+
if (domain === "example.org") {
430+
return Promise.resolve({
431+
"org.matrix.msc4143.rtc_foci": [
432+
{
433+
type: "livekit",
434+
livekit_service_url: "https://use-me.jwt.call.example.org",
435+
},
436+
],
437+
});
438+
}
439+
return Promise.resolve({});
440+
},
441+
);
442+
443+
localTransportOpts.client.getAccessToken.mockReturnValue(null);
444+
const { advertised$, active$ } =
445+
createLocalTransport$(localTransportOpts);
446+
openIdResolver.resolve?.(openIdResponse);
447+
expect(advertised$.value).toBe(null);
448+
expect(active$.value).toBe(null);
449+
await flushPromises();
450+
451+
expect(
452+
localTransportOpts.client._unstable_getRTCTransports,
453+
).not.toHaveBeenCalled();
454+
455+
const expectedTransport = {
456+
type: "livekit",
457+
livekit_service_url: "https://use-me.jwt.call.example.org",
458+
};
459+
460+
expect(advertised$.value).toStrictEqual(expectedTransport);
461+
});
462+
413463
it("fails fast if the openID request fails for backend config", async () => {
414464
localTransportOpts.client._unstable_getRTCTransports.mockResolvedValue([
415465
{ type: "livekit", livekit_service_url: "https://lk.example.org" },
@@ -481,6 +531,7 @@ describe("LocalTransport", () => {
481531
baseUrl: "https://example.org",
482532
// eslint-disable-next-line @typescript-eslint/naming-convention
483533
_unstable_getRTCTransports: async () => Promise.resolve([]),
534+
getAccessToken: vi.fn().mockReturnValue("access_token"),
484535
// These won't be called in this error path but satisfy the type
485536
getOpenIdToken: vi.fn(),
486537
getDeviceId: vi.fn(),

src/state/CallViewModel/localMember/LocalTransport.ts

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ interface Props {
5656
memberships$: Behavior<Epoch<CallMembership[]>>;
5757
client: Pick<
5858
MatrixClient,
59-
"getDomain" | "baseUrl" | "_unstable_getRTCTransports"
59+
"getDomain" | "baseUrl" | "_unstable_getRTCTransports" | "getAccessToken"
6060
> &
6161
OpenIDClientParts;
6262
// Used by the jwt service to create the livekit room and compute the livekit alias.
@@ -314,7 +314,7 @@ const FOCI_WK_KEY = "org.matrix.msc4143.rtc_foci";
314314
async function makeTransport(
315315
client: Pick<
316316
MatrixClient,
317-
"getDomain" | "baseUrl" | "_unstable_getRTCTransports"
317+
"getDomain" | "baseUrl" | "_unstable_getRTCTransports" | "getAccessToken"
318318
> &
319319
OpenIDClientParts,
320320
membership: CallMembershipIdentityParts,
@@ -371,36 +371,53 @@ async function makeTransport(
371371
for (const potentialTransport of transports) {
372372
if (isLivekitTransportConfig(potentialTransport)) {
373373
try {
374+
logger.info(
375+
`makeTransport: check transport authentication for "${potentialTransport.livekit_service_url}"`,
376+
);
374377
// This will call the jwt/sfu/get endpoint to pre create the livekit room.
375378
return await doOpenIdAndJWTFromUrl(
376379
potentialTransport.livekit_service_url,
377380
);
378381
} catch (ex) {
382+
logger.debug(
383+
`makeTransport: Could not use SFU service "${potentialTransport.livekit_service_url}" as SFU`,
384+
ex,
385+
);
379386
// Explictly throw these
380387
if (ex instanceof FailToGetOpenIdToken) {
381388
throw ex;
382389
}
383390
if (ex instanceof NoMatrix2AuthorizationService) {
384391
throw ex;
385392
}
386-
logger.debug(
387-
`Could not use SFU service "${potentialTransport.livekit_service_url}" as SFU`,
388-
ex,
389-
);
390393
}
394+
} else {
395+
logger.info(
396+
`makeTransport: "${potentialTransport.livekit_service_url}" is not a valid livekit transport as SFU`,
397+
);
391398
}
392399
}
393400
return null;
394401
}
395402

396403
// MSC4143: Attempt to fetch transports from backend.
397-
if ("_unstable_getRTCTransports" in client) {
404+
// TODO: Workaround for an issue in the js-sdk RoomWidgetClient that
405+
// is not yet implementing _unstable_getRTCTransports properly (via widget API new action).
406+
// For now we just skip this call if we are in a widget.
407+
// In widget mode the client is a `RoomWidgetClient` which has no access token (it is using the widget API).
408+
// Could be removed once the js-sdk is fixed (https://github.com/matrix-org/matrix-js-sdk/issues/5245)
409+
const isSPA = !!client.getAccessToken();
410+
if (isSPA && "_unstable_getRTCTransports" in client) {
411+
logger.info(
412+
"makeTransport: First try to use getRTCTransports end point ...",
413+
);
398414
try {
415+
// TODO This should also check for server support?
399416
const transportList = await client._unstable_getRTCTransports();
400417
const selectedTransport = await getFirstUsableTransport(transportList);
401418
if (selectedTransport) {
402419
logger.info(
403-
"Using backend-configured (client.getRTCTransports) SFU",
420+
"makeTransport: ...Using backend-configured (client.getRTCTransports) SFU",
404421
selectedTransport,
405422
);
406423
return selectedTransport;
@@ -424,6 +441,10 @@ async function makeTransport(
424441
}
425442
}
426443

444+
logger.info(
445+
`makeTransport: Trying to get transports from .well-known/matrix/client on domain ${client.getDomain()} ...`,
446+
);
447+
427448
// Legacy MSC4143 (to be removed) WELL_KNOWN: Prioritize the .well-known/matrix/client, if available.
428449
const domain = client.getDomain();
429450
if (domain) {
@@ -441,6 +462,10 @@ async function makeTransport(
441462
}
442463
}
443464

465+
logger.info(
466+
`makeTransport: No valid transport found via backend or .well-known, falling back to config if available.`,
467+
);
468+
444469
// CONFIG: Least prioritized; Load from config file
445470
const urlFromConf = Config.get().livekit?.livekit_service_url;
446471
if (urlFromConf) {

0 commit comments

Comments
 (0)