Move SFU authentication into livekit/auth and choose the endpoint by role

The OpenID flow moves to src/livekit/auth/openID.ts with the SFU config
types in a sibling file, takes an options object, and replaces the
MatrixRTC mode with the role we take on the transport plus the session's
slot ID instead of a hard-coded m.call#ROOM.

This changes behaviour: publishers on a livekit_service_url transport
always use the legacy /sfu/get endpoint, so that subscribers can predict
their user:device participant identity, and subscribers always use the
default /get_token endpoint. The MatrixRTC mode no longer influences which
endpoint is used.
This commit is contained in:
Robin
2026-10-12 10:17:39 +02:00
committed by Johannes Marbach
parent f260755f46
commit 17c3223883
21 changed files with 708 additions and 804 deletions
@@ -19,7 +19,7 @@ import {
trackEpoch,
} from "../../ObservableScope.ts";
import { ECConnectionFactory } from "./ConnectionFactory.ts";
import { type OpenIDClientParts } from "../../../livekit/openIDSFU.ts";
import { type ClientOpenIDParts } from "../../../livekit/auth";
import {
mockMediaDevices,
mockRtcMembership,
@@ -40,7 +40,7 @@ import { localRtcMember, testJWTToken } from "../../../utils/test-fixtures.ts";
let testScope: ObservableScope;
let ecConnectionFactory: ECConnectionFactory;
let mockClient: OpenIDClientParts;
let mockClient: ClientOpenIDParts;
let lkRoomFactory: () => LivekitRoom;
const createdMockLivekitRooms: Map<string, LivekitRoom> = new Map();
@@ -49,7 +49,6 @@ beforeEach(() => {
testScope = new ObservableScope();
mockClient = {
getOpenIdToken: vi.fn().mockReturnValue(""),
getDeviceId: vi.fn().mockReturnValue("DEV000"),
};
lkRoomFactory = vi.fn().mockImplementation(() => {
@@ -71,6 +70,7 @@ beforeEach(() => {
ecConnectionFactory = new ECConnectionFactory(
mockClient,
"!roomid:example.org",
"m.call#ROOM",
mockMediaDevices({}),
new BehaviorSubject<ProcessorState>({
supported: true,
@@ -82,7 +82,7 @@ beforeEach(() => {
);
//TODO a bit annoying to have to do a http mock?
fetchMock.post(`path:/sfu/get`, (url) => {
const sfuConfigResponse = (url: string): { status: number; body: object } => {
const domain = new URL(url).hostname; // Extract the domain from the URL
return {
status: 200,
@@ -91,7 +91,9 @@ beforeEach(() => {
jwt: testJWTToken,
},
};
});
};
fetchMock.post(`path:/sfu/get`, sfuConfigResponse);
fetchMock.post(`path:/get_token`, sfuConfigResponse);
});
afterEach(() => {