Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

enforced key backup setup #9729

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/DeviceListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,11 @@ export default class DeviceListener {
}
// returns null when key backup status hasn't finished being checked
const isKeyBackupEnabled = MatrixClientPeg.get().getKeyBackupEnabled();
this.keyBackupStatusChecked = isKeyBackupEnabled !== null;

// Ensure user can't dismiss the toast if secure backup is required
if (isKeyBackupEnabled === false && !isSecureBackupRequired()) {
this.keyBackupStatusChecked = isKeyBackupEnabled !== null;
}

if (isKeyBackupEnabled === false) {
dis.dispatch({ action: Action.ReportKeyBackupNotEnabled });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ enum Phase {
const PASSWORD_MIN_SCORE = 4; // So secure, many characters, much complex, wow, etc, etc.

interface IProps extends IDialogProps {
hasCancel: boolean;
accountPassword: string;
forceReset: boolean;
}
Expand Down Expand Up @@ -96,7 +95,6 @@ interface IState {
*/
export default class CreateSecretStorageDialog extends React.PureComponent<IProps, IState> {
public static defaultProps: Partial<IProps> = {
hasCancel: true,
forceReset: false,
};
private recoveryKey: IRecoveryKey;
Expand Down Expand Up @@ -871,7 +869,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent<IProp
onFinished={this.props.onFinished}
title={this.titleForPhase(this.state.phase)}
titleClass={titleClass}
hasCancel={this.props.hasCancel && [Phase.Passphrase].includes(this.state.phase)}
hasCancel={this.state.canSkip}
fixedWidth={false}
>
<div>
Expand Down
6 changes: 6 additions & 0 deletions src/components/structures/MatrixChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ import { VoiceBroadcastResumer } from '../../voice-broadcast';
import GenericToast from "../views/toasts/GenericToast";
import { Linkify } from "../views/elements/Linkify";
import RovingSpotlightDialog, { Filter } from '../views/dialogs/spotlight/SpotlightDialog';
import { isSecureBackupRequired } from '../../utils/WellKnownUtils';

// legacy export
export { default as Views } from "../../Views";
Expand Down Expand Up @@ -826,6 +827,11 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
hideAnalyticsToast();
SettingsStore.setValue("pseudonymousAnalyticsOptIn", null, SettingLevel.ACCOUNT, false);
break;
case Action.ReportKeyBackupNotEnabled:
if (isSecureBackupRequired()) {
this.setStateForNewView({ view: Views.COMPLETE_SECURITY });
}
break;
case Action.ShowThread: {
const {
rootEvent,
Expand Down
3 changes: 2 additions & 1 deletion src/components/structures/auth/CompleteSecurity.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import SetupEncryptionBody from "./SetupEncryptionBody";
import AccessibleButton from '../../views/elements/AccessibleButton';
import CompleteSecurityBody from "../../views/auth/CompleteSecurityBody";
import AuthPage from "../../views/auth/AuthPage";
import { isSecureBackupRequired } from '../../../utils/WellKnownUtils';

interface IProps {
onFinished: () => void;
Expand Down Expand Up @@ -91,7 +92,7 @@ export default class CompleteSecurity extends React.Component<IProps, IState> {
}

let skipButton;
if (phase === Phase.Intro || phase === Phase.ConfirmReset) {
if ((phase === Phase.Intro || phase === Phase.ConfirmReset) && !isSecureBackupRequired()) {
skipButton = (
<AccessibleButton onClick={this.onSkipClick} className="mx_CompleteSecurity_skip" aria-label={_t("Skip verification for now")} />
);
Expand Down
16 changes: 15 additions & 1 deletion src/toasts/SetupEncryptionToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import ToastStore from "../stores/ToastStore";
import GenericToast from "../components/views/toasts/GenericToast";
import SecurityCustomisations from "../customisations/Security";
import Spinner from "../components/views/elements/Spinner";
import { isSecureBackupRequired } from '../utils/WellKnownUtils';

const TOAST_KEY = "setupencryption";

Expand Down Expand Up @@ -78,6 +79,10 @@ const onReject = () => {
DeviceListener.sharedInstance().dismissEncryptionSetup();
};

type LatterButton = {
rejectLabel?: string;
}

export const showToast = (kind: Kind) => {
if (SecurityCustomisations.setupEncryptionNeeded?.(kind)) {
return;
Expand All @@ -99,6 +104,12 @@ export const showToast = (kind: Kind) => {
}
};

// Ensure user can't dismiss the toast if secure backup is required
let latterButton: LatterButton = { rejectLabel: _t("Later") };
if (kind === Kind.SET_UP_ENCRYPTION && isSecureBackupRequired()) {
latterButton = {};
}

ToastStore.sharedInstance().addOrReplaceToast({
key: TOAST_KEY,
title: getTitle(kind),
Expand All @@ -107,14 +118,17 @@ export const showToast = (kind: Kind) => {
description: getDescription(kind),
acceptLabel: getSetupCaption(kind),
onAccept,
rejectLabel: _t("Later"),
onReject,
...latterButton
},
component: GenericToast,
priority: kind === Kind.VERIFY_THIS_SESSION ? 95 : 40,
});
};

export const hideToast = () => {
// Ensure user can't dismiss the toast if secure backup is required
if (isSecureBackupRequired()) return;

ToastStore.sharedInstance().dismissToast(TOAST_KEY);
};