Skip to content

Commit 1fce220

Browse files
authored
Merge pull request #3828 from element-hq/valere/fix/stop_calling_msc4143_in_widget
Stop calling rtc/transport in widget mode
2 parents ce1cd9a + f316ece commit 1fce220

File tree

3 files changed

+77
-8
lines changed

3 files changed

+77
-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: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ describe("LocalTransport", () => {
6060
client: {
6161
// eslint-disable-next-line @typescript-eslint/naming-convention
6262
_unstable_getRTCTransports: async () => Promise.resolve([]),
63+
getAccessToken: vi.fn().mockReturnValue("access_token"),
6364
getDomain: () => "",
6465
baseUrl: "example.org",
6566
// These won't be called in this error path but satisfy the type
@@ -102,6 +103,7 @@ describe("LocalTransport", () => {
102103
baseUrl: "https://lk.example.org",
103104
// Use empty domain to skip .well-known and use config directly
104105
getDomain: () => "",
106+
getAccessToken: vi.fn().mockReturnValue("access_token"),
105107
// eslint-disable-next-line @typescript-eslint/naming-convention
106108
_unstable_getRTCTransports: async () => Promise.resolve([]),
107109
getOpenIdToken: vi.fn(),
@@ -149,6 +151,7 @@ describe("LocalTransport", () => {
149151
getOpenIdToken: vi.fn(),
150152
getDeviceId: vi.fn(),
151153
baseUrl: "https://lk.example.org",
154+
getAccessToken: vi.fn().mockReturnValue("access_token"),
152155
},
153156
ownMembershipIdentity: ownMemberMock,
154157
forceJwtEndpoint: JwtEndpointVersion.Legacy,
@@ -217,6 +220,7 @@ describe("LocalTransport", () => {
217220
getDomain: () => "",
218221
// eslint-disable-next-line @typescript-eslint/naming-convention
219222
_unstable_getRTCTransports: async () => Promise.resolve([]),
223+
getAccessToken: vi.fn().mockReturnValue("access_token"),
220224
getOpenIdToken: vi.fn(),
221225
getDeviceId: vi.fn(),
222226
baseUrl: "https://lk.example.org",
@@ -273,6 +277,7 @@ describe("LocalTransport", () => {
273277
// eslint-disable-next-line @typescript-eslint/naming-convention
274278
_unstable_getRTCTransports: async () =>
275279
Promise.resolve([aliceTransport]),
280+
getAccessToken: vi.fn().mockReturnValue("access_token"),
276281
getOpenIdToken: vi.fn(),
277282
getDeviceId: vi.fn(),
278283
baseUrl: "https://lk.example.org",
@@ -323,6 +328,7 @@ describe("LocalTransport", () => {
323328
getDomain: vi.fn().mockReturnValue(""),
324329
// eslint-disable-next-line @typescript-eslint/naming-convention
325330
_unstable_getRTCTransports: vi.fn().mockResolvedValue([]),
331+
getAccessToken: vi.fn().mockReturnValue("access_token"),
326332
getOpenIdToken: vi.fn(),
327333
getDeviceId: vi.fn(),
328334
},
@@ -410,6 +416,42 @@ describe("LocalTransport", () => {
410416
});
411417
});
412418

419+
it("Should not call _unstable_getRTCTransports in widget mode but use well-known", async () => {
420+
mockConfig({
421+
livekit: { livekit_service_url: "https://do-not-use.lk.example.org" },
422+
});
423+
424+
localTransportOpts.client.getDomain.mockReturnValue("example.org");
425+
426+
fetchMock.getOnce("https://example.org/.well-known/matrix/client", {
427+
"org.matrix.msc4143.rtc_foci": [
428+
{
429+
type: "livekit",
430+
livekit_service_url: "https://use-me.jwt.call.example.org",
431+
},
432+
],
433+
});
434+
435+
localTransportOpts.client.getAccessToken.mockReturnValue(null);
436+
const { advertised$, active$ } =
437+
createLocalTransport$(localTransportOpts);
438+
openIdResolver.resolve?.(openIdResponse);
439+
expect(advertised$.value).toBe(null);
440+
expect(active$.value).toBe(null);
441+
await flushPromises();
442+
443+
expect(
444+
localTransportOpts.client._unstable_getRTCTransports,
445+
).not.toHaveBeenCalled();
446+
447+
const expectedTransport = {
448+
type: "livekit",
449+
livekit_service_url: "https://use-me.jwt.call.example.org",
450+
};
451+
452+
expect(advertised$.value).toStrictEqual(expectedTransport);
453+
});
454+
413455
it("fails fast if the openID request fails for backend config", async () => {
414456
localTransportOpts.client._unstable_getRTCTransports.mockResolvedValue([
415457
{ type: "livekit", livekit_service_url: "https://lk.example.org" },
@@ -481,6 +523,7 @@ describe("LocalTransport", () => {
481523
baseUrl: "https://example.org",
482524
// eslint-disable-next-line @typescript-eslint/naming-convention
483525
_unstable_getRTCTransports: async () => Promise.resolve([]),
526+
getAccessToken: vi.fn().mockReturnValue("access_token"),
484527
// These won't be called in this error path but satisfy the type
485528
getOpenIdToken: vi.fn(),
486529
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)