Use normal base64 encoding for RTC backend identities (#5129)

* Use normal base64 encoding for RTC backend identities

MSC4195 has been updated to specify that normal (non-URL-safe) base64 is the correct encoding for LiveKit participant identities.

* Test RTC backend identity computation
This commit is contained in:
Robin
2026-01-09 18:28:42 +01:00
committed by GitHub
parent b1a578f62e
commit 4d0d32307e
3 changed files with 32 additions and 5 deletions
@@ -394,4 +394,20 @@ describe("CallMembership", () => {
expect(membership.getMsUntilExpiry()).toEqual(DEFAULT_EXPIRE_DURATION - 1000);
});
});
it("uses unpadded base64 for RTC backend identities", async () => {
expect(
await CallMembership.computeRtcBackendIdentity(makeMockEvent(), {
kind: "rtc",
data: {
slot_id: "m.call#",
application: { "type": "m.call", "m.call.id": "", "m.call.intent": "voice" },
member: { user_id: "@alice:example.org", device_id: "AAAAAAA", id: "xyzRANDOMxyz" },
rtc_transports: [{ type: "livekit" }],
versions: [],
msc4354_sticky_key: "abc123",
},
}),
).toBe("2+h2ELE1XY/NsuveToZOekORCoyQMO6V0W7XZUWk5Q4");
});
});
@@ -339,6 +339,20 @@ describe("MatrixRTCSession", () => {
);
expect(sess.memberships).toHaveLength(0);
});
it("assigns RTC backend identities to memberships", async () => {
const mockRoom = makeMockRoom([membershipTemplate], testConfig.testCreateSticky);
sess = MatrixRTCSession.sessionForSlot(
client,
mockRoom,
callSession,
testConfig.createWithDefaults ? undefined : testConfig,
);
await flushPromises();
expect(sess?.memberships.length).toEqual(1);
// Backend identity is expected to not be hashed with a legacy (session) membership
expect(sess?.memberships[0].rtcBackendIdentity).toEqual("@mock:user.example:AAAAAAA");
});
},
);
+2 -5
View File
@@ -22,7 +22,7 @@ import type { RTCCallIntent, Transport } from "./types.ts";
import { type MatrixEvent, type IContent } from "../models/event.ts";
import { type RelationType } from "../@types/event.ts";
import { sha256 } from "../digest.ts";
import { encodeUnpaddedBase64Url } from "../base64.ts";
import { encodeUnpaddedBase64 } from "../base64.ts";
import { type Logger } from "../logger.ts";
/**
@@ -322,10 +322,7 @@ export class CallMembership {
}
public static async computeRtcIdentityRaw(userId: string, deviceId: string, memberId: string): Promise<string> {
const hashInput = `${userId}|${deviceId}|${memberId}`;
const hashBuffer = await sha256(hashInput);
const hashedString = encodeUnpaddedBase64Url(hashBuffer);
return hashedString;
return encodeUnpaddedBase64(await sha256(`${userId}|${deviceId}|${memberId}`));
}
public static membershipDataFromMatrixEvent(matrixEvent: MatrixEvent): MembershipData {