fix(call): serve RTC transports to Element Call over MSC4515 — calls work again
CI / Build & Quality Checks (push) Successful in 2m6s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 9s
CI / Trigger Desktop Build (push) Successful in 10s
CI / Playwright smoke (e2e) (push) Successful in 1m42s
CI / Build & Quality Checks (push) Successful in 2m6s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 9s
CI / Trigger Desktop Build (push) Successful in 10s
CI / Playwright smoke (e2e) (push) Successful in 1m42s
Since the upstream v0.25.0 merge, Element Call in widget mode no longer reads .well-known for its LiveKit transport; it asks the HOST via the widget API (org.matrix.msc4515.get_rtc_transports, capability org.matrix.msc4515.rtc_transports). cinny never granted the capability nor implemented WidgetDriver.getRtcTransports(), so discovery returned nothing and every join failed with "Call is not supported" (MISSING_MATRIX_RTC_TRANSPORT) — the [LocalMembership] Multiple Transport Errors line in the browser console. - matrix-widget-api 1.17.0 -> 1.18.0 (adds MSC4515; also changes the sendDelayedEvent driver signature, adapted — parent delay ids were removed from the draft). - Grant MSC4515RtcTransports in getCallCapabilities. - CallWidgetDriver.getRtcTransports(): homeserver /rtc/transports (MSC4143) first, then the .well-known org.matrix.msc4143.rtc_foci list (what matrix.lotusguild.org advertises today). Unit-tested. Server side needs no change: the well-known already carries the livekit focus and the JWT service answers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import type { MatrixClient } from 'matrix-js-sdk';
|
||||
import { CallWidgetDriver } from './CallWidgetDriver';
|
||||
|
||||
// MSC4515: Element Call (widget mode) asks the host for RTC transports. Without a
|
||||
// working answer every call fails with MISSING_MATRIX_RTC_TRANSPORT.
|
||||
function fakeClient(opts: {
|
||||
serverTransports?: unknown[] | Error;
|
||||
wellKnown?: Record<string, unknown>;
|
||||
}): MatrixClient {
|
||||
return {
|
||||
getDeviceId: () => 'DEV',
|
||||
getSafeUserId: () => '@me:example.org',
|
||||
_unstable_getRTCTransports: async () => {
|
||||
if (opts.serverTransports instanceof Error) throw opts.serverTransports;
|
||||
return opts.serverTransports ?? [];
|
||||
},
|
||||
getClientWellKnown: () => opts.wellKnown,
|
||||
} as unknown as MatrixClient;
|
||||
}
|
||||
|
||||
const focus = { type: 'livekit', livekit_service_url: 'https://matrix.example.org' };
|
||||
|
||||
test('getRtcTransports prefers the homeserver MSC4143 endpoint', async () => {
|
||||
const driver = new CallWidgetDriver(fakeClient({ serverTransports: [focus] }), '!r:x');
|
||||
const r = await driver.getRtcTransports();
|
||||
assert.deepEqual(r.rtc_transports, [focus]);
|
||||
});
|
||||
|
||||
test('getRtcTransports falls back to .well-known rtc_foci when the endpoint 404s', async () => {
|
||||
const driver = new CallWidgetDriver(
|
||||
fakeClient({
|
||||
serverTransports: new Error('404'),
|
||||
wellKnown: { 'org.matrix.msc4143.rtc_foci': [focus, { junk: true }, null] },
|
||||
}),
|
||||
'!r:x',
|
||||
);
|
||||
const r = await driver.getRtcTransports();
|
||||
assert.deepEqual(r.rtc_transports, [focus]);
|
||||
});
|
||||
|
||||
test('getRtcTransports returns an empty list when nothing is advertised', async () => {
|
||||
const driver = new CallWidgetDriver(
|
||||
fakeClient({ serverTransports: [], wellKnown: { 'm.homeserver': {} } }),
|
||||
'!r:x',
|
||||
);
|
||||
const r = await driver.getRtcTransports();
|
||||
assert.deepEqual(r.rtc_transports, []);
|
||||
});
|
||||
|
||||
test('the MSC4515 capability is granted to the call widget', async () => {
|
||||
const driver = new CallWidgetDriver(fakeClient({}), '!r:x');
|
||||
const allowed = await driver.validateCapabilities(
|
||||
new Set(['org.matrix.msc4515.rtc_transports', 'org.example.not_allowed']),
|
||||
);
|
||||
assert.deepEqual(Array.from(allowed), ['org.matrix.msc4515.rtc_transports']);
|
||||
});
|
||||
Reference in New Issue
Block a user