mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-04 19:56:45 +02:00
Promote "Share encrypted history" from labs (#33281)
* Promote "Share encrypted history" from labs * fix lint * Update labs.md * update snapshots * Update unit tests * update playwright screenshot
This commit is contained in:
parent
c02b970d35
commit
c4638d1773
@ -13,7 +13,6 @@ import { createRoom, sendMessageInCurrentRoom } from "./utils";
|
||||
|
||||
test.use({
|
||||
displayName: "Alice",
|
||||
labsFlags: ["feature_share_history_on_invite"],
|
||||
});
|
||||
|
||||
/** Tests for MSC4268: encrypted history sharing */
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@ -446,7 +446,6 @@ export default function RoomHeader({
|
||||
const roomName = useRoomName(room);
|
||||
const joinRule = useRoomState(room, (state) => state.getJoinRule());
|
||||
const historyVisibility = useRoomState(room, (state) => state.getHistoryVisibility());
|
||||
const historySharingEnabled = useFeatureEnabled("feature_share_history_on_invite");
|
||||
const dmMember = useDmMember(room);
|
||||
const isDirectMessage = !!dmMember;
|
||||
const isRoomEncrypted = useIsEncrypted(client, room);
|
||||
@ -532,7 +531,7 @@ export default function RoomHeader({
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
{isRoomEncrypted && historySharingEnabled && historyVisibilityIcon(historyVisibility)}
|
||||
{isRoomEncrypted && historyVisibilityIcon(historyVisibility)}
|
||||
</Text>
|
||||
</Box>
|
||||
</button>
|
||||
|
||||
@ -1577,9 +1577,6 @@
|
||||
"report_to_moderators": "Report to moderators",
|
||||
"report_to_moderators_description": "In rooms that support moderation, the “Report” button will let you report abuse to room moderators.",
|
||||
"room_list_sections": "Room list sections",
|
||||
"share_history_on_invite": "Share encrypted history with new members",
|
||||
"share_history_on_invite_description": "When inviting a user to an encrypted room that has history visibility set to \"shared\", share encrypted history with that user, and accept encrypted history when you are invited to such a room.",
|
||||
"share_history_on_invite_warning": "This feature is EXPERIMENTAL and not all security precautions are implemented. Do not enable on production accounts.",
|
||||
"sliding_sync": "Sliding Sync mode",
|
||||
"sliding_sync_description": "Under active development, cannot be disabled. Currently, not compatible with Element Call.",
|
||||
"sliding_sync_disabled_notice": "Sign in again to disable",
|
||||
|
||||
@ -212,7 +212,6 @@ export interface Settings {
|
||||
"feature_mjolnir": IFeature;
|
||||
"feature_custom_themes": IFeature;
|
||||
"feature_exclude_insecure_devices": IFeature;
|
||||
"feature_share_history_on_invite": IFeature;
|
||||
"feature_html_topic": IFeature;
|
||||
"feature_bridge_state": IFeature;
|
||||
"feature_jump_to_date": IFeature;
|
||||
@ -522,29 +521,6 @@ export const SETTINGS: Settings = {
|
||||
supportedLevelsAreOrdered: true,
|
||||
default: false,
|
||||
},
|
||||
"feature_share_history_on_invite": {
|
||||
isFeature: true,
|
||||
labsGroup: LabGroup.Encryption,
|
||||
displayName: _td("labs|share_history_on_invite"),
|
||||
description: () => (
|
||||
<>
|
||||
{_t("labs|share_history_on_invite_description")}
|
||||
<div className="mx_SettingsFlag_microcopy">
|
||||
{_t(
|
||||
"settings|warning",
|
||||
{},
|
||||
{
|
||||
w: (sub) => <span className="mx_SettingsTab_microcopy_warning">{sub}</span>,
|
||||
description: _t("labs|share_history_on_invite_warning"),
|
||||
},
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
),
|
||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG_PRIORITISED,
|
||||
supportedLevelsAreOrdered: true,
|
||||
default: false,
|
||||
},
|
||||
// Defaulted to true Feb 26, intention is to remove entirely, all being well,
|
||||
// as this fixes bugs where display name / avatar are missing and also makes
|
||||
// Element Web consistent with Element X.
|
||||
|
||||
@ -544,11 +544,9 @@ export class RoomViewStore extends EventEmitter {
|
||||
|
||||
const joinOpts: IJoinRoomOpts = {
|
||||
viaServers,
|
||||
acceptSharedHistory: true,
|
||||
...(payload.opts ?? {}),
|
||||
};
|
||||
if (SettingsStore.getValue("feature_share_history_on_invite")) {
|
||||
joinOpts.acceptSharedHistory = true;
|
||||
}
|
||||
try {
|
||||
const cli = MatrixClientPeg.safeGet();
|
||||
await retry<Room, MatrixError>(
|
||||
|
||||
@ -228,10 +228,10 @@ export default class MultiInviter {
|
||||
}
|
||||
}
|
||||
|
||||
const opts: InviteOpts = {};
|
||||
const opts: InviteOpts = {
|
||||
shareEncryptedHistory: true,
|
||||
};
|
||||
if (this.reason !== undefined) opts.reason = this.reason;
|
||||
if (SettingsStore.getValue("feature_share_history_on_invite")) opts.shareEncryptedHistory = true;
|
||||
|
||||
return this.matrixClient.invite(roomId, addr, opts);
|
||||
} else {
|
||||
throw new Error("Unsupported address");
|
||||
|
||||
@ -212,7 +212,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
aria-labelledby="_r_1c3_"
|
||||
aria-labelledby="_r_1cl_"
|
||||
class="_banner_n7ud0_8"
|
||||
data-type="critical"
|
||||
role="status"
|
||||
@ -238,7 +238,7 @@ exports[`RoomView for a local room in state ERROR should match the snapshot 1`]
|
||||
>
|
||||
<p
|
||||
class="_typography_6v6n8_153 _font-body-md-medium_6v6n8_60 _title_1xryk_24"
|
||||
id="_r_1c3_"
|
||||
id="_r_1cl_"
|
||||
>
|
||||
Could not start a chat with this user
|
||||
</p>
|
||||
@ -417,7 +417,7 @@ exports[`RoomView for a local room in state NEW should match the snapshot 1`] =
|
||||
>
|
||||
<svg
|
||||
aria-label="Messages in this room are not end-to-end encrypted"
|
||||
aria-labelledby="_r_197_"
|
||||
aria-labelledby="_r_19j_"
|
||||
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
||||
color="var(--cpd-color-icon-info-primary)"
|
||||
fill="currentColor"
|
||||
@ -693,6 +693,24 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
|
||||
>
|
||||
@user:example.com
|
||||
</span>
|
||||
<svg
|
||||
aria-label="New members see history"
|
||||
aria-labelledby="_r_1cf_"
|
||||
class="mx_RoomHeader_icon"
|
||||
color="var(--cpd-color-icon-info-primary)"
|
||||
fill="currentColor"
|
||||
height="16px"
|
||||
viewBox="0 0 24 24"
|
||||
width="16px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
|
||||
/>
|
||||
<path
|
||||
d="M13 8a1 1 0 1 0-2 0v4a1 1 0 0 0 .293.707l2.83 2.83a1 1 0 0 0 1.414-1.414L13 11.586z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
@ -2838,6 +2856,24 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
||||
>
|
||||
!roomviewshouldnotdisplaythetimelinewhentheroomencryptionisloading:example.org
|
||||
</span>
|
||||
<svg
|
||||
aria-label="New members see history"
|
||||
aria-labelledby="_r_gc_"
|
||||
class="mx_RoomHeader_icon"
|
||||
color="var(--cpd-color-icon-info-primary)"
|
||||
fill="currentColor"
|
||||
height="16px"
|
||||
viewBox="0 0 24 24"
|
||||
width="16px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M18.93 8A8 8 0 1 1 4 12a1 1 0 1 0-2 0c0 5.523 4.477 10 10 10s10-4.477 10-10a10 10 0 0 0-.832-4A10 10 0 0 0 12 2a9.99 9.99 0 0 0-8 3.999V4a1 1 0 0 0-2 0v4a1 1 0 0 0 1 1h4a1 1 0 0 0 0-2H5.755A7.99 7.99 0 0 1 12 4a8 8 0 0 1 6.93 4"
|
||||
/>
|
||||
<path
|
||||
d="M13 8a1 1 0 1 0-2 0v4a1 1 0 0 0 .293.707l2.83 2.83a1 1 0 0 0 1.414-1.414L13 11.586z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
@ -3023,7 +3059,7 @@ exports[`RoomView should not display the timeline when the room encryption is lo
|
||||
tabindex="0"
|
||||
>
|
||||
<div
|
||||
aria-labelledby="_r_gc_"
|
||||
aria-labelledby="_r_gh_"
|
||||
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
||||
data-testid="e2e-icon"
|
||||
style="width: 12px; height: 12px;"
|
||||
@ -3358,7 +3394,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-label="Chat"
|
||||
aria-labelledby="_r_kg_"
|
||||
aria-labelledby="_r_ks_"
|
||||
class="_icon-button_1215g_8"
|
||||
data-kind="primary"
|
||||
role="button"
|
||||
@ -3385,7 +3421,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-label="Threads"
|
||||
aria-labelledby="_r_kl_"
|
||||
aria-labelledby="_r_l1_"
|
||||
class="_icon-button_1215g_8"
|
||||
data-kind="primary"
|
||||
role="button"
|
||||
@ -3412,7 +3448,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
aria-labelledby="_r_kq_"
|
||||
aria-labelledby="_r_l6_"
|
||||
class="_icon-button_1215g_8"
|
||||
data-kind="primary"
|
||||
role="button"
|
||||
@ -3442,7 +3478,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
||||
>
|
||||
<div
|
||||
aria-label="0 members"
|
||||
aria-labelledby="_r_kv_"
|
||||
aria-labelledby="_r_lb_"
|
||||
class="mx_AccessibleButton mx_FacePile"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@ -3527,7 +3563,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
aria-labelledby="_r_l8_"
|
||||
aria-labelledby="_r_lk_"
|
||||
class="_icon-button_1215g_8"
|
||||
data-kind="secondary"
|
||||
data-testid="base-card-close-button"
|
||||
@ -3587,7 +3623,7 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
|
||||
>
|
||||
<svg
|
||||
aria-label="Messages in this room are not end-to-end encrypted"
|
||||
aria-labelledby="_r_ld_"
|
||||
aria-labelledby="_r_lp_"
|
||||
class="mx_E2EIcon mx_MessageComposer_e2eIcon"
|
||||
color="var(--cpd-color-icon-info-primary)"
|
||||
fill="currentColor"
|
||||
|
||||
@ -60,7 +60,6 @@ import WidgetStore, { type IApp } from "../../../../../../src/stores/WidgetStore
|
||||
import { UIFeature } from "../../../../../../src/settings/UIFeature";
|
||||
import { SettingLevel } from "../../../../../../src/settings/SettingLevel";
|
||||
import { ElementCallMemberEventType } from "../../../../../../src/call-types";
|
||||
import { defaultWatchManager } from "../../../../../../src/settings/Settings.tsx";
|
||||
|
||||
jest.mock("../../../../../../src/utils/ShieldUtils");
|
||||
jest.mock("../../../../../../src/hooks/right-panel/useCurrentPhase", () => ({
|
||||
@ -723,25 +722,9 @@ describe("RoomHeader", () => {
|
||||
],
|
||||
{ addToState: true },
|
||||
);
|
||||
let featureEnabled = true;
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||
(flag) => flag === "feature_share_history_on_invite" && featureEnabled,
|
||||
);
|
||||
|
||||
render(<RoomHeader room={room} />, getWrapper());
|
||||
await waitFor(() => getByLabelText(document.body, "New members see history"));
|
||||
|
||||
// Disable the labs flag and check the icon disappears
|
||||
featureEnabled = false;
|
||||
act(() =>
|
||||
defaultWatchManager.notifyUpdate(
|
||||
"feature_share_history_on_invite",
|
||||
null,
|
||||
SettingLevel.DEVICE,
|
||||
featureEnabled,
|
||||
),
|
||||
);
|
||||
expect(queryByLabelText(document.body, "New members see history")).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("shows a user icon if the room is encrypted and has world readable history", async () => {
|
||||
@ -758,10 +741,6 @@ describe("RoomHeader", () => {
|
||||
],
|
||||
{ addToState: true },
|
||||
);
|
||||
const featureEnabled = true;
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation(
|
||||
(flag) => flag === "feature_share_history_on_invite" && featureEnabled,
|
||||
);
|
||||
|
||||
render(<RoomHeader room={room} />, getWrapper());
|
||||
await waitFor(() => getByLabelText(document.body, "Anyone can see history"));
|
||||
|
||||
@ -56,7 +56,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
aria-labelledby="_r_13s_"
|
||||
aria-labelledby="_r_14k_"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
@ -83,7 +83,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
|
||||
style="--cpd-icon-button-size: 100%;"
|
||||
>
|
||||
<svg
|
||||
aria-labelledby="_r_141_"
|
||||
aria-labelledby="_r_14p_"
|
||||
fill="currentColor"
|
||||
height="1em"
|
||||
viewBox="0 0 24 24"
|
||||
@ -98,7 +98,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-label="Threads"
|
||||
aria-labelledby="_r_146_"
|
||||
aria-labelledby="_r_14u_"
|
||||
class="_icon-button_1215g_8"
|
||||
data-kind="primary"
|
||||
role="button"
|
||||
@ -125,7 +125,7 @@ exports[`RoomHeader dm does not show the face pile for DMs 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-label="Room info"
|
||||
aria-labelledby="_r_14b_"
|
||||
aria-labelledby="_r_153_"
|
||||
class="_icon-button_1215g_8"
|
||||
data-kind="primary"
|
||||
role="button"
|
||||
|
||||
@ -24,7 +24,7 @@ describe("/invite", () => {
|
||||
|
||||
await command.run(client, roomId, null, args).promise;
|
||||
|
||||
expect(client.invite).toHaveBeenCalledWith(roomId, "@u:s.co", {});
|
||||
expect(client.invite).toHaveBeenCalledWith(roomId, "@u:s.co", { shareEncryptedHistory: true });
|
||||
});
|
||||
|
||||
it("should provide the invite reason if we supply it", async () => {
|
||||
@ -35,6 +35,9 @@ describe("/invite", () => {
|
||||
|
||||
await command.run(client, roomId, null, args).promise;
|
||||
|
||||
expect(client.invite).toHaveBeenCalledWith(roomId, "@u:s.co", { reason: "They are a very nice person" });
|
||||
expect(client.invite).toHaveBeenCalledWith(roomId, "@u:s.co", {
|
||||
reason: "They are a very nice person",
|
||||
shareEncryptedHistory: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -213,7 +213,7 @@ describe("RoomViewStore", function () {
|
||||
dis.dispatch({ action: Action.ViewRoom, room_id: roomId });
|
||||
dis.dispatch({ action: Action.JoinRoom });
|
||||
await untilDispatch(Action.JoinRoomReady, dis);
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(roomId, { viaServers: [] });
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(roomId, { acceptSharedHistory: true, viaServers: [] });
|
||||
expect(roomViewStore.isJoining()).toBe(true);
|
||||
});
|
||||
|
||||
@ -229,14 +229,14 @@ describe("RoomViewStore", function () {
|
||||
}),
|
||||
);
|
||||
await untilDispatch(Action.JoinRoomReady, dis);
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(alias, { viaServers: ["server1"] });
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(alias, { acceptSharedHistory: true, viaServers: ["server1"] });
|
||||
expect(roomViewStore.isJoining()).toBe(true);
|
||||
});
|
||||
|
||||
it("can auto-join a room", async () => {
|
||||
dis.dispatch({ action: Action.ViewRoom, room_id: roomId, auto_join: true });
|
||||
await untilDispatch(Action.JoinRoomReady, dis);
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(roomId, { viaServers: [] });
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(roomId, { acceptSharedHistory: true, viaServers: [] });
|
||||
expect(roomViewStore.isJoining()).toBe(true);
|
||||
});
|
||||
|
||||
@ -282,7 +282,7 @@ describe("RoomViewStore", function () {
|
||||
await untilDispatch(Action.JoinRoomReady, dis);
|
||||
|
||||
expect(roomViewStore.isJoining()).toBeTruthy();
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(alias, { viaServers: [] });
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(alias, { acceptSharedHistory: true, viaServers: [] });
|
||||
});
|
||||
|
||||
it("emits ViewRoomError if the alias lookup fails", async () => {
|
||||
@ -548,11 +548,7 @@ describe("RoomViewStore", function () {
|
||||
expect(mocked(dis.dispatch).mock.calls[2][0]).toEqual({ action: "prompt_ask_to_join" });
|
||||
});
|
||||
|
||||
it("sets 'acceptSharedHistory' if that option is enabled", async () => {
|
||||
jest.spyOn(SettingsStore, "getValue").mockImplementation((settingName, roomId, value) => {
|
||||
return settingName === "feature_share_history_on_invite"; // this is enabled, everything else is disabled.
|
||||
});
|
||||
|
||||
it("sets 'acceptSharedHistory'", async () => {
|
||||
dis.dispatch({ action: Action.ViewRoom, room_id: roomId });
|
||||
dis.dispatch({ action: Action.JoinRoom });
|
||||
await untilDispatch(Action.JoinRoomReady, dis);
|
||||
|
||||
@ -120,9 +120,9 @@ describe("MultiInviter", () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(3);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, { shareEncryptedHistory: true });
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, { shareEncryptedHistory: true });
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, { shareEncryptedHistory: true });
|
||||
|
||||
expectAllInvitedResult(result);
|
||||
});
|
||||
@ -138,9 +138,9 @@ describe("MultiInviter", () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(3);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, { shareEncryptedHistory: true });
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, { shareEncryptedHistory: true });
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, { shareEncryptedHistory: true });
|
||||
|
||||
expectAllInvitedResult(result);
|
||||
});
|
||||
@ -153,7 +153,7 @@ describe("MultiInviter", () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(1);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, { shareEncryptedHistory: true });
|
||||
|
||||
// The resolved state is 'invited' for all users.
|
||||
// With the above client expectations, the test ensures that only the first user is invited.
|
||||
@ -255,15 +255,5 @@ describe("MultiInviter", () => {
|
||||
`"This space is unfederated. You cannot invite people from external servers."`,
|
||||
);
|
||||
});
|
||||
|
||||
it("should set shareEncryptedHistory if that setting is enabled", async () => {
|
||||
mocked(SettingsStore.getValue).mockImplementation((settingName, roomId, value) => {
|
||||
return settingName === "feature_share_history_on_invite"; // this is enabled, everything else is disabled.
|
||||
});
|
||||
await inviter.invite([MXID1]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(1);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, { shareEncryptedHistory: true });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -119,14 +119,6 @@ Do not send or receive messages to/from devices that are not properly verified.
|
||||
receive your messages at all on those devices, and if they send messages, you will not be able to read them, but you
|
||||
will be aware that a message exists.
|
||||
|
||||
## Share encrypted history with new members (`feature_share_history_on_invite`) [In Development]
|
||||
|
||||
When inviting users to an encrypted room with shared history (i.e. a room with the "Who can read history?" setting set
|
||||
to "Members only (since the point in time of selecting this option)"), send the keys for previous messages to the
|
||||
invitee so they can read them.
|
||||
|
||||
Both the inviter and the invitee must set this labs flag, before the invitation is sent.
|
||||
|
||||
## Encrypted state events (MSC4362) (`feature_msc4362_encrypted_state_events`)
|
||||
|
||||
Encrypt most of the state events in the room, including the room name and topic.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user