From 4ef3d176d9d633f1f100075f4c3c60379d66f34a Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 7 Apr 2021 19:16:29 -0600 Subject: [PATCH 1/3] Add ability to hide post-login encryption setup with customisation point This is primarily intended for alternative setup UI or where the customisations end up configuring encryption some other way. If used without respecting the warnings in the docs, the user could end up at a blank page - use with caution, and only as directed. --- src/components/structures/auth/CompleteSecurity.js | 12 +++++++++++- src/customisations/Security.ts | 14 +++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/CompleteSecurity.js b/src/components/structures/auth/CompleteSecurity.js index 49fcf20415..2c46fe9823 100644 --- a/src/components/structures/auth/CompleteSecurity.js +++ b/src/components/structures/auth/CompleteSecurity.js @@ -28,6 +28,7 @@ import { } from '../../../stores/SetupEncryptionStore'; import SetupEncryptionBody from "./SetupEncryptionBody"; import {replaceableComponent} from "../../../utils/replaceableComponent"; +import SecurityCustomisations from "../../../customisations/Security"; @replaceableComponent("structures.auth.CompleteSecurity") export default class CompleteSecurity extends React.Component { @@ -45,6 +46,13 @@ export default class CompleteSecurity extends React.Component { _onStoreUpdate = () => { const store = SetupEncryptionStore.sharedInstance(); + + // Skip "you're done" phase if the UI isn't shown + if (store.phase === PHASE_DONE && SecurityCustomisations.SHOW_ENCRYPTION_SETUP_UI === false) { + this.props.onFinished(true); + return; + } + this.setState({phase: store.phase}); }; @@ -61,7 +69,9 @@ export default class CompleteSecurity extends React.Component { let icon; let title; - if (phase === PHASE_LOADING) { + // If the encryption UI is hidden then we can simply return nothing - the UI doesn't + // need to be running in order to set up encryption with the SecurityCustomisations. + if (phase === PHASE_LOADING || SecurityCustomisations.SHOW_ENCRYPTION_SETUP_UI === false) { return null; } else if (phase === PHASE_INTRO) { icon = ; diff --git a/src/customisations/Security.ts b/src/customisations/Security.ts index 96b5b62cdb..e215c5cb24 100644 --- a/src/customisations/Security.ts +++ b/src/customisations/Security.ts @@ -74,8 +74,20 @@ export interface ISecurityCustomisations { catchAccessSecretStorageError?: typeof catchAccessSecretStorageError, setupEncryptionNeeded?: typeof setupEncryptionNeeded, getDehydrationKey?: typeof getDehydrationKey, + + /** + * When false, disables the post-login UI from showing. If there's + * an error during setup, that will be shown to the user. + * + * Note: when this is set to false then the app will assume the user's + * encryption is set up some other way which would circumvent the default + * UI, such as by presenting alternative UI. + */ + SHOW_ENCRYPTION_SETUP_UI?: boolean, // default true } // A real customisation module will define and export one or more of the // customisation points that make up `ISecurityCustomisations`. -export default {} as ISecurityCustomisations; +export default { + SHOW_ENCRYPTION_SETUP_UI: true, +} as ISecurityCustomisations; From d89bbe216725da0524ae40ff593c645b4f8ab822 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 8 Apr 2021 09:20:14 -0600 Subject: [PATCH 2/3] Move check to MatrixChat --- src/components/structures/MatrixChat.tsx | 19 +++++++++++++------ .../structures/auth/CompleteSecurity.js | 12 +----------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 532b1f4225..2a3559b3a4 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -80,10 +80,11 @@ import DialPadModal from "../views/voip/DialPadModal"; import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast'; import { shouldUseLoginForWelcome } from "../../utils/pages"; import SpaceStore from "../../stores/SpaceStore"; +import SpaceRoomDirectory from "./SpaceRoomDirectory"; import {replaceableComponent} from "../../utils/replaceableComponent"; import RoomListStore from "../../stores/room-list/RoomListStore"; import {RoomUpdateCause} from "../../stores/room-list/models"; -import defaultDispatcher from "../../dispatcher/dispatcher"; +import SecurityCustomisations from "../../customisations/Security"; /** constants for MatrixChat.state.view */ export enum Views { @@ -202,6 +203,7 @@ interface IState { ready: boolean; threepidInvite?: IThreepidInvite, roomOobData?: object; + viaServers?: string[]; pendingInitialSync?: boolean; justRegistered?: boolean; roomJustCreatedOpts?: IOpts; @@ -395,7 +397,11 @@ export default class MatrixChat extends React.PureComponent { const crossSigningIsSetUp = cli.getStoredCrossSigningForUser(cli.getUserId()); if (crossSigningIsSetUp) { - this.setStateForNewView({ view: Views.COMPLETE_SECURITY }); + if (SecurityCustomisations.SHOW_ENCRYPTION_SETUP_UI === false) { + this.onLoggedIn(); + } else { + this.setStateForNewView({view: Views.COMPLETE_SECURITY}); + } } else if (await cli.doesServerSupportUnstableFeature("org.matrix.e2e_cross_signing")) { this.setStateForNewView({ view: Views.E2E_SETUP }); } else { @@ -690,10 +696,10 @@ export default class MatrixChat extends React.PureComponent { } case Action.ViewRoomDirectory: { if (SpaceStore.instance.activeSpace) { - defaultDispatcher.dispatch({ - action: "view_room", - room_id: SpaceStore.instance.activeSpace.roomId, - }); + Modal.createTrackedDialog("Space room directory", "", SpaceRoomDirectory, { + space: SpaceStore.instance.activeSpace, + initialText: payload.initialText, + }, "mx_SpaceRoomDirectory_dialogWrapper", false, true); } else { const RoomDirectory = sdk.getComponent("structures.RoomDirectory"); Modal.createTrackedDialog('Room directory', '', RoomDirectory, { @@ -928,6 +934,7 @@ export default class MatrixChat extends React.PureComponent { page_type: PageTypes.RoomView, threepidInvite: roomInfo.threepid_invite, roomOobData: roomInfo.oob_data, + viaServers: roomInfo.via_servers, ready: true, roomJustCreatedOpts: roomInfo.justCreatedOpts, }, () => { diff --git a/src/components/structures/auth/CompleteSecurity.js b/src/components/structures/auth/CompleteSecurity.js index 2c46fe9823..49fcf20415 100644 --- a/src/components/structures/auth/CompleteSecurity.js +++ b/src/components/structures/auth/CompleteSecurity.js @@ -28,7 +28,6 @@ import { } from '../../../stores/SetupEncryptionStore'; import SetupEncryptionBody from "./SetupEncryptionBody"; import {replaceableComponent} from "../../../utils/replaceableComponent"; -import SecurityCustomisations from "../../../customisations/Security"; @replaceableComponent("structures.auth.CompleteSecurity") export default class CompleteSecurity extends React.Component { @@ -46,13 +45,6 @@ export default class CompleteSecurity extends React.Component { _onStoreUpdate = () => { const store = SetupEncryptionStore.sharedInstance(); - - // Skip "you're done" phase if the UI isn't shown - if (store.phase === PHASE_DONE && SecurityCustomisations.SHOW_ENCRYPTION_SETUP_UI === false) { - this.props.onFinished(true); - return; - } - this.setState({phase: store.phase}); }; @@ -69,9 +61,7 @@ export default class CompleteSecurity extends React.Component { let icon; let title; - // If the encryption UI is hidden then we can simply return nothing - the UI doesn't - // need to be running in order to set up encryption with the SecurityCustomisations. - if (phase === PHASE_LOADING || SecurityCustomisations.SHOW_ENCRYPTION_SETUP_UI === false) { + if (phase === PHASE_LOADING) { return null; } else if (phase === PHASE_INTRO) { icon = ; From 1e551585c093180aaa269c4cb1d6894f47774ae2 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 8 Apr 2021 09:33:39 -0600 Subject: [PATCH 3/3] Fix copy/paste fail --- src/components/structures/MatrixChat.tsx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 2a3559b3a4..d9ed7d061b 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -80,10 +80,10 @@ import DialPadModal from "../views/voip/DialPadModal"; import { showToast as showMobileGuideToast } from '../../toasts/MobileGuideToast'; import { shouldUseLoginForWelcome } from "../../utils/pages"; import SpaceStore from "../../stores/SpaceStore"; -import SpaceRoomDirectory from "./SpaceRoomDirectory"; import {replaceableComponent} from "../../utils/replaceableComponent"; import RoomListStore from "../../stores/room-list/RoomListStore"; import {RoomUpdateCause} from "../../stores/room-list/models"; +import defaultDispatcher from "../../dispatcher/dispatcher"; import SecurityCustomisations from "../../customisations/Security"; /** constants for MatrixChat.state.view */ @@ -203,7 +203,6 @@ interface IState { ready: boolean; threepidInvite?: IThreepidInvite, roomOobData?: object; - viaServers?: string[]; pendingInitialSync?: boolean; justRegistered?: boolean; roomJustCreatedOpts?: IOpts; @@ -696,10 +695,10 @@ export default class MatrixChat extends React.PureComponent { } case Action.ViewRoomDirectory: { if (SpaceStore.instance.activeSpace) { - Modal.createTrackedDialog("Space room directory", "", SpaceRoomDirectory, { - space: SpaceStore.instance.activeSpace, - initialText: payload.initialText, - }, "mx_SpaceRoomDirectory_dialogWrapper", false, true); + defaultDispatcher.dispatch({ + action: "view_room", + room_id: SpaceStore.instance.activeSpace.roomId, + }); } else { const RoomDirectory = sdk.getComponent("structures.RoomDirectory"); Modal.createTrackedDialog('Room directory', '', RoomDirectory, { @@ -934,7 +933,6 @@ export default class MatrixChat extends React.PureComponent { page_type: PageTypes.RoomView, threepidInvite: roomInfo.threepid_invite, roomOobData: roomInfo.oob_data, - viaServers: roomInfo.via_servers, ready: true, roomJustCreatedOpts: roomInfo.justCreatedOpts, }, () => {