Set history visibility to "invited" for DMs and new non-public rooms when creating a room (#31974)
* Set history visibility to "invited" for DMs and non-public rooms * Update e2e tests and screenshots * lint * Revert screenshot * Add test that an override of historyVisibility still works
This commit is contained in:
@@ -38,6 +38,14 @@ test.describe("History sharing", function () {
|
|||||||
|
|
||||||
// Create the room and send a message
|
// Create the room and send a message
|
||||||
await createRoom(alicePage, "TestRoom", true);
|
await createRoom(alicePage, "TestRoom", true);
|
||||||
|
|
||||||
|
// The default history visibility for private rooms is "invited",
|
||||||
|
// so we need to change it to "shared" to ensure Bob can see the message when he joins.
|
||||||
|
const roomId = await aliceElementApp.getCurrentRoomIdFromUrl();
|
||||||
|
await aliceElementApp.client.sendStateEvent(roomId, "m.room.history_visibility", {
|
||||||
|
history_visibility: "shared",
|
||||||
|
});
|
||||||
|
|
||||||
await sendMessageInCurrentRoom(alicePage, "A message from Alice");
|
await sendMessageInCurrentRoom(alicePage, "A message from Alice");
|
||||||
|
|
||||||
// Send the invite to Bob
|
// Send the invite to Bob
|
||||||
@@ -101,6 +109,12 @@ test.describe("History sharing", function () {
|
|||||||
await bobPage.getByRole("option", { name: "TestRoom" }).click();
|
await bobPage.getByRole("option", { name: "TestRoom" }).click();
|
||||||
await bobPage.getByRole("button", { name: "Accept" }).click();
|
await bobPage.getByRole("button", { name: "Accept" }).click();
|
||||||
|
|
||||||
|
// The room now defaults to "invited" history visibility, so we need to set it to "shared" first
|
||||||
|
await aliceElementApp.client.sendStateEvent(roomId, "m.room.history_visibility", {
|
||||||
|
history_visibility: "shared",
|
||||||
|
});
|
||||||
|
await expect(bobPage.getByText("Alice made future room history visible to all room members.")).toBeVisible();
|
||||||
|
|
||||||
// Bob sends a message with "shared" visibility
|
// Bob sends a message with "shared" visibility
|
||||||
await sendMessageInCurrentRoom(bobPage, "Message1: 'shared' visibility");
|
await sendMessageInCurrentRoom(bobPage, "Message1: 'shared' visibility");
|
||||||
await expect(alicePage.getByText("Message1")).toBeVisible();
|
await expect(alicePage.getByText("Message1")).toBeVisible();
|
||||||
|
|||||||
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
+16
-3
@@ -16,7 +16,7 @@ import {
|
|||||||
RoomCreateTypeField,
|
RoomCreateTypeField,
|
||||||
RoomType,
|
RoomType,
|
||||||
type ICreateRoomOpts,
|
type ICreateRoomOpts,
|
||||||
type HistoryVisibility,
|
HistoryVisibility,
|
||||||
JoinRule,
|
JoinRule,
|
||||||
Preset,
|
Preset,
|
||||||
RestrictedAllowType,
|
RestrictedAllowType,
|
||||||
@@ -294,11 +294,24 @@ export default async function createRoom(client: MatrixClient, opts: IOpts): Pro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.historyVisibility) {
|
// Set history visibility to "invited" for DMs and non-public rooms unless explicitly overridden
|
||||||
|
// This ensures that room history is only visible to invited members by default
|
||||||
|
let historyVisibility = opts.historyVisibility;
|
||||||
|
if (!historyVisibility) {
|
||||||
|
// Determine if the room will be public based on the join rule or preset
|
||||||
|
const isPublicRoom = opts.joinRule === JoinRule.Public || createOpts.preset === Preset.PublicChat;
|
||||||
|
|
||||||
|
// For DMs and non-public rooms, set history visibility to "invited"
|
||||||
|
if (opts.dmUserId || !isPublicRoom) {
|
||||||
|
historyVisibility = HistoryVisibility.Invited;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (historyVisibility) {
|
||||||
createOpts.initial_state.push({
|
createOpts.initial_state.push({
|
||||||
type: EventType.RoomHistoryVisibility,
|
type: EventType.RoomHistoryVisibility,
|
||||||
content: {
|
content: {
|
||||||
history_visibility: opts.historyVisibility,
|
history_visibility: historyVisibility,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { mocked, type Mocked } from "jest-mock";
|
|||||||
import {
|
import {
|
||||||
type MatrixClient,
|
type MatrixClient,
|
||||||
type Device,
|
type Device,
|
||||||
|
HistoryVisibility,
|
||||||
Preset,
|
Preset,
|
||||||
RoomType,
|
RoomType,
|
||||||
JoinRule,
|
JoinRule,
|
||||||
@@ -58,7 +59,10 @@ describe("createRoom", () => {
|
|||||||
expect(client.createRoom).toHaveBeenCalledWith({
|
expect(client.createRoom).toHaveBeenCalledWith({
|
||||||
preset: "private_chat",
|
preset: "private_chat",
|
||||||
visibility: "private",
|
visibility: "private",
|
||||||
initial_state: [{ state_key: "", type: "m.room.guest_access", content: { guest_access: "can_join" } }],
|
initial_state: [
|
||||||
|
{ state_key: "", type: "m.room.guest_access", content: { guest_access: "can_join" } },
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -77,6 +81,7 @@ describe("createRoom", () => {
|
|||||||
algorithm: "m.megolm.v1.aes-sha2",
|
algorithm: "m.megolm.v1.aes-sha2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -104,6 +109,7 @@ describe("createRoom", () => {
|
|||||||
"io.element.msc4362.encrypt_state_events": true,
|
"io.element.msc4362.encrypt_state_events": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
// Room name is NOT included, since it needs to be encrypted.
|
// Room name is NOT included, since it needs to be encrypted.
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -146,6 +152,7 @@ describe("createRoom", () => {
|
|||||||
"io.element.msc4362.encrypt_state_events": true,
|
"io.element.msc4362.encrypt_state_events": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
// Room name is NOT included, since it needs to be encrypted.
|
// Room name is NOT included, since it needs to be encrypted.
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -178,6 +185,7 @@ describe("createRoom", () => {
|
|||||||
"io.element.msc4362.encrypt_state_events": true,
|
"io.element.msc4362.encrypt_state_events": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
// Room name is NOT included, since it needs to be encrypted.
|
// Room name is NOT included, since it needs to be encrypted.
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
@@ -218,6 +226,7 @@ describe("createRoom", () => {
|
|||||||
initial_state: [
|
initial_state: [
|
||||||
{ state_key: "", type: "m.room.guest_access", content: { guest_access: "can_join" } },
|
{ state_key: "", type: "m.room.guest_access", content: { guest_access: "can_join" } },
|
||||||
{ type: "m.space.parent", state_key: parentSpace.roomId, content: { canonical: true, via: [] } },
|
{ type: "m.space.parent", state_key: parentSpace.roomId, content: { canonical: true, via: [] } },
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -354,6 +363,31 @@ describe("createRoom", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should set history visibility to invited for DMs", async () => {
|
||||||
|
await createRoom(client, { dmUserId: "@bob:example.org" });
|
||||||
|
expect(client.createRoom).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
initial_state: expect.arrayContaining([
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "invited" } },
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should respect an explicit history visibility override", async () => {
|
||||||
|
await createRoom(client, {
|
||||||
|
createOpts: { preset: Preset.PrivateChat },
|
||||||
|
historyVisibility: HistoryVisibility.Shared,
|
||||||
|
});
|
||||||
|
expect(client.createRoom).toHaveBeenCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
initial_state: expect.arrayContaining([
|
||||||
|
{ type: "m.room.history_visibility", content: { history_visibility: "shared" } },
|
||||||
|
]),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
describe("room versions", () => {
|
describe("room versions", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
|
|||||||
Reference in New Issue
Block a user