Add labs option for history sharing on invite (#30313)
* Add labs option for "share history on invite" * Set `acceptSharedHistory` when joining a room * set `shareEncryptedHistory` when sending an invite * Update src/i18n/strings/en_EN.json Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --------- Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
committed by
GitHub
parent
c79c8c836b
commit
ab6ef2fa85
@@ -1534,6 +1534,9 @@
|
||||
"render_reaction_images_description": "Sometimes referred to as \"custom emojis\".",
|
||||
"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.",
|
||||
"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.",
|
||||
"sliding_sync_disabled_notice": "Log out and back in to disable",
|
||||
|
||||
@@ -205,6 +205,7 @@ 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;
|
||||
@@ -503,6 +504,29 @@ 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,
|
||||
},
|
||||
"useOnlyCurrentProfiles": {
|
||||
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||
displayName: _td("settings|disable_historical_profile"),
|
||||
|
||||
@@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type ReactNode } from "react";
|
||||
import * as utils from "matrix-js-sdk/src/utils";
|
||||
import { MatrixError, JoinRule, type Room, type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixError, JoinRule, type Room, type MatrixEvent, type IJoinRoomOpts } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type ViewRoom as ViewRoomEvent } from "@matrix-org/analytics-events/types/typescript/ViewRoom";
|
||||
@@ -512,15 +512,19 @@ export class RoomViewStore extends EventEmitter {
|
||||
// take a copy of roomAlias & roomId as they may change by the time the join is complete
|
||||
const { roomAlias, roomId = payload.roomId } = this.state;
|
||||
const address = roomAlias || roomId!;
|
||||
const viaServers = this.state.viaServers || [];
|
||||
|
||||
const joinOpts: IJoinRoomOpts = {
|
||||
viaServers: this.state.viaServers || [],
|
||||
...(payload.opts ?? {}),
|
||||
};
|
||||
if (SettingsStore.getValue("feature_share_history_on_invite")) {
|
||||
joinOpts.acceptSharedHistory = true;
|
||||
}
|
||||
|
||||
try {
|
||||
const cli = MatrixClientPeg.safeGet();
|
||||
await retry<Room, MatrixError>(
|
||||
() =>
|
||||
cli.joinRoom(address, {
|
||||
viaServers,
|
||||
...(payload.opts || {}),
|
||||
}),
|
||||
() => cli.joinRoom(address, joinOpts),
|
||||
NUM_JOIN_RETRY,
|
||||
(err) => {
|
||||
// if we received a Gateway timeout or Cloudflare timeout then retry
|
||||
|
||||
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { MatrixError, type MatrixClient, EventType, type EmptyObject } from "matrix-js-sdk/src/matrix";
|
||||
import { MatrixError, type MatrixClient, EventType, type EmptyObject, type InviteOpts } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
@@ -183,7 +183,11 @@ export default class MultiInviter {
|
||||
}
|
||||
}
|
||||
|
||||
return this.matrixClient.invite(roomId, addr, this.reason);
|
||||
const opts: InviteOpts = {};
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -440,6 +440,17 @@ 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.
|
||||
});
|
||||
|
||||
dis.dispatch({ action: Action.ViewRoom, room_id: roomId });
|
||||
dis.dispatch({ action: Action.JoinRoom });
|
||||
await untilDispatch(Action.JoinRoomReady, dis);
|
||||
expect(mockClient.joinRoom).toHaveBeenCalledWith(roomId, { acceptSharedHistory: true, viaServers: [] });
|
||||
});
|
||||
});
|
||||
|
||||
describe("Action.JoinRoomError", () => {
|
||||
|
||||
@@ -96,9 +96,9 @@ describe("MultiInviter", () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(3);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, {});
|
||||
|
||||
expectAllInvitedResult(result);
|
||||
});
|
||||
@@ -114,9 +114,9 @@ describe("MultiInviter", () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(3);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(2, ROOMID, MXID2, {});
|
||||
expect(client.invite).toHaveBeenNthCalledWith(3, ROOMID, MXID3, {});
|
||||
|
||||
expectAllInvitedResult(result);
|
||||
});
|
||||
@@ -129,7 +129,7 @@ describe("MultiInviter", () => {
|
||||
const result = await inviter.invite([MXID1, MXID2, MXID3]);
|
||||
|
||||
expect(client.invite).toHaveBeenCalledTimes(1);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, undefined);
|
||||
expect(client.invite).toHaveBeenNthCalledWith(1, ROOMID, MXID1, {});
|
||||
|
||||
// The resolved state is 'invited' for all users.
|
||||
// With the above client expectations, the test ensures that only the first user is invited.
|
||||
@@ -231,5 +231,15 @@ 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 });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user