diff --git a/src/createRoom.ts b/src/createRoom.ts index 955e3a5707..66177d812b 100644 --- a/src/createRoom.ts +++ b/src/createRoom.ts @@ -132,6 +132,8 @@ export default async function createRoom(opts: IOpts): Promise { events: { // Allow all users to send video member updates [VIDEO_CHANNEL_MEMBER]: 0, + // Make widgets immutable, even to admins + "im.vector.modular.widgets": 200, // Annoyingly, we have to reiterate all the defaults here [EventType.RoomName]: 50, [EventType.RoomAvatar]: 50, @@ -142,6 +144,10 @@ export default async function createRoom(opts: IOpts): Promise { [EventType.RoomServerAcl]: 100, [EventType.RoomEncryption]: 100, }, + users: { + // Temporarily give ourselves the power to set up a widget + [client.getUserId()]: 200, + }, }; } } @@ -264,6 +270,11 @@ export default async function createRoom(opts: IOpts): Promise { if (opts.roomType === RoomType.ElementVideo) { // Set up video rooms with a Jitsi widget await addVideoChannel(roomId, createOpts.name); + + // Reset our power level back to admin so that the widget becomes immutable + const room = client.getRoom(roomId); + const plEvent = room?.currentState.getStateEvents(EventType.RoomPowerLevels, ""); + await client.setPowerLevel(roomId, client.getUserId(), 100, plEvent); } }).then(function() { // NB createRoom doesn't block on the client seeing the echo that the diff --git a/test/createRoom-test.ts b/test/createRoom-test.ts index b10de07e6a..5143db0d70 100644 --- a/test/createRoom-test.ts +++ b/test/createRoom-test.ts @@ -37,20 +37,34 @@ describe("createRoom", () => { setupAsyncStoreWithClient(WidgetStore.instance, client); jest.spyOn(WidgetUtils, "waitForRoomWidget").mockResolvedValue(); + const userId = client.getUserId(); const roomId = await createRoom({ roomType: RoomType.ElementVideo }); + const [[{ power_level_content_override: { - events: { [VIDEO_CHANNEL_MEMBER]: videoMemberPower }, + users: { + [userId]: userPower, + }, + events: { + "im.vector.modular.widgets": widgetPower, + [VIDEO_CHANNEL_MEMBER]: videoMemberPower, + }, }, }]] = mocked(client.createRoom).mock.calls as any; // no good type const [[widgetRoomId, widgetStateKey]] = mocked(client.sendStateEvent).mock.calls; - // We should have set up the Jitsi widget + // We should have had enough power to be able to set up the Jitsi widget + expect(userPower).toBeGreaterThanOrEqual(widgetPower); + // and should have actually set it up expect(widgetRoomId).toEqual(roomId); expect(widgetStateKey).toEqual("im.vector.modular.widgets"); // All members should be able to update their connected devices expect(videoMemberPower).toEqual(0); + // Jitsi widget should be immutable for admins + expect(widgetPower).toBeGreaterThan(100); + // and we should have been reset back to admin + expect(client.setPowerLevel).toHaveBeenCalledWith(roomId, userId, 100, undefined); }); });