Provide a labs flag for encrypted state events (MSC3414) (#31513)
Signed-off-by: Skye Elliot <actuallyori@gmail.com> Co-authored-by: Skye Elliot <actuallyori@gmail.com>
This commit is contained in:
co-authored by
Skye Elliot
parent
6f0369e623
commit
ff3f069122
@@ -40,6 +40,7 @@ interface IProps {
|
||||
defaultName?: string;
|
||||
parentSpace?: Room;
|
||||
defaultEncrypted?: boolean;
|
||||
defaultStateEncrypted?: boolean;
|
||||
onFinished(proceed?: false): void;
|
||||
onFinished(proceed: true, opts: IOpts): void;
|
||||
}
|
||||
@@ -58,6 +59,11 @@ interface IState {
|
||||
* Indicates whether end-to-end encryption is enabled for the room.
|
||||
*/
|
||||
isEncrypted: boolean;
|
||||
/**
|
||||
* Indicates whether end-to-end state encryption is enabled for this room.
|
||||
* See MSC4362. Available if feature_msc4362_encrypted_state_events is enabled.
|
||||
*/
|
||||
isStateEncrypted: boolean;
|
||||
/**
|
||||
* The room name.
|
||||
*/
|
||||
@@ -117,6 +123,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
||||
this.state = {
|
||||
isPublicKnockRoom: defaultPublic || false,
|
||||
isEncrypted: this.props.defaultEncrypted ?? privateShouldBeEncrypted(cli),
|
||||
isStateEncrypted: this.props.defaultStateEncrypted ?? false,
|
||||
joinRule,
|
||||
name: this.props.defaultName || "",
|
||||
topic: "",
|
||||
@@ -141,7 +148,10 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
||||
const { alias } = this.state;
|
||||
createOpts.room_alias_name = alias.substring(1, alias.indexOf(":"));
|
||||
} else {
|
||||
const encryptedStateFeature = SettingsStore.getValue("feature_msc4362_encrypted_state_events", null, false);
|
||||
|
||||
opts.encryption = this.state.isEncrypted;
|
||||
opts.stateEncryption = encryptedStateFeature && this.state.isStateEncrypted;
|
||||
}
|
||||
|
||||
if (this.state.topic) {
|
||||
@@ -236,6 +246,10 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
||||
this.setState({ isEncrypted: evt.target.checked });
|
||||
};
|
||||
|
||||
private onStateEncryptedChange: ChangeEventHandler<HTMLInputElement> = (evt): void => {
|
||||
this.setState({ isStateEncrypted: evt.target.checked });
|
||||
};
|
||||
|
||||
private onAliasChange = (alias: string): void => {
|
||||
this.setState({ alias });
|
||||
};
|
||||
@@ -378,6 +392,29 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
||||
);
|
||||
}
|
||||
|
||||
let e2eeStateSection: JSX.Element | undefined;
|
||||
if (
|
||||
SettingsStore.getValue("feature_msc4362_encrypted_state_events", null, false) &&
|
||||
this.state.joinRule !== JoinRule.Public
|
||||
) {
|
||||
let microcopy: string;
|
||||
if (!this.state.canChangeEncryption) {
|
||||
microcopy = _t("create_room|encryption_forced");
|
||||
} else {
|
||||
microcopy = _t("create_room|state_encrypted_warning");
|
||||
}
|
||||
e2eeStateSection = (
|
||||
<SettingsToggleInput
|
||||
name="state-encryption-toggle"
|
||||
label={_t("create_room|state_encryption_label")}
|
||||
onChange={this.onStateEncryptedChange}
|
||||
checked={this.state.isStateEncrypted}
|
||||
disabled={!this.state.canChangeEncryption}
|
||||
helpMessage={microcopy}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
let federateLabel = _t("create_room|unfederated_label_default_off");
|
||||
if (SdkConfig.get().default_federate === false) {
|
||||
// We only change the label if the default setting is different to avoid jarring text changes to the
|
||||
@@ -441,6 +478,7 @@ export default class CreateRoomDialog extends React.Component<IProps, IState> {
|
||||
|
||||
{visibilitySection}
|
||||
{e2eeSection}
|
||||
{e2eeStateSection}
|
||||
{aliasField}
|
||||
{this.advancedSettingsEnabled && (
|
||||
<details onToggle={this.onDetailsToggled} className="mx_CreateRoomDialog_details">
|
||||
|
||||
@@ -40,6 +40,9 @@ const EncryptionEvent = ({ mxEvent, timestamp, ref }: IProps): ReactNode => {
|
||||
let subtitle: string;
|
||||
const dmPartner = DMRoomMap.shared().getUserIdForRoomId(roomId);
|
||||
const room = cli?.getRoom(roomId);
|
||||
|
||||
const stateEncrypted = content["io.element.msc4362.encrypt_state_events"] && cli.enableEncryptedStateEvents;
|
||||
|
||||
if (prevContent.algorithm === MEGOLM_ENCRYPTION_ALGORITHM) {
|
||||
subtitle = _t("timeline|m.room.encryption|parameters_changed");
|
||||
} else if (dmPartner) {
|
||||
@@ -47,6 +50,8 @@ const EncryptionEvent = ({ mxEvent, timestamp, ref }: IProps): ReactNode => {
|
||||
subtitle = _t("timeline|m.room.encryption|enabled_dm", { displayName });
|
||||
} else if (room && isLocalRoom(room)) {
|
||||
subtitle = _t("timeline|m.room.encryption|enabled_local");
|
||||
} else if (stateEncrypted) {
|
||||
subtitle = _t("timeline|m.room.encryption|state_enabled");
|
||||
} else {
|
||||
subtitle = _t("timeline|m.room.encryption|enabled");
|
||||
}
|
||||
@@ -54,7 +59,7 @@ const EncryptionEvent = ({ mxEvent, timestamp, ref }: IProps): ReactNode => {
|
||||
return (
|
||||
<EventTileBubble
|
||||
className="mx_cryptoEvent mx_cryptoEvent_icon"
|
||||
title={_t("common|encryption_enabled")}
|
||||
title={stateEncrypted ? _t("common|state_encryption_enabled") : _t("common|encryption_enabled")}
|
||||
subtitle={subtitle}
|
||||
timestamp={timestamp}
|
||||
/>
|
||||
|
||||
@@ -54,6 +54,7 @@ interface IState {
|
||||
history: HistoryVisibility;
|
||||
hasAliases: boolean;
|
||||
encrypted: boolean | null;
|
||||
stateEncrypted: boolean | null;
|
||||
showAdvancedSection: boolean;
|
||||
}
|
||||
|
||||
@@ -79,6 +80,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||
),
|
||||
hasAliases: false, // async loaded in componentDidMount
|
||||
encrypted: null, // async loaded in componentDidMount
|
||||
stateEncrypted: null, // async loaded in componentDidMount
|
||||
showAdvancedSection: false,
|
||||
};
|
||||
}
|
||||
@@ -89,6 +91,9 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||
this.setState({
|
||||
hasAliases: await this.hasAliases(),
|
||||
encrypted: Boolean(await this.context.getCrypto()?.isEncryptionEnabledInRoom(this.props.room.roomId)),
|
||||
stateEncrypted: Boolean(
|
||||
await this.context.getCrypto()?.isStateEncryptionEnabledInRoom(this.props.room.roomId),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -480,6 +485,7 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||
const client = this.context;
|
||||
const room = this.props.room;
|
||||
const isEncrypted = this.state.encrypted;
|
||||
const isStateEncrypted = this.state.stateEncrypted;
|
||||
const isEncryptionLoading = isEncrypted === null;
|
||||
const hasEncryptionPermission = room.currentState.mayClientSendStateEvent(EventType.RoomEncryption, client);
|
||||
const isEncryptionForceDisabled = shouldForceDisableEncryption(client);
|
||||
@@ -533,6 +539,14 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||
{isEncryptionForceDisabled && !isEncrypted && (
|
||||
<Caption>{_t("room_settings|security|encryption_forced")}</Caption>
|
||||
)}
|
||||
{isStateEncrypted && (
|
||||
<SettingsToggleInput
|
||||
name="enable-state-encryption"
|
||||
checked={isStateEncrypted}
|
||||
label={_t("common|state_encryption_enabled")}
|
||||
disabled={true}
|
||||
/>
|
||||
)}
|
||||
{encryptionSettings}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user