From 0016d8e744a1c345af8494745f805b2d38d2405e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 19 May 2020 11:36:44 +0100 Subject: [PATCH 01/13] Add e2ee_default_for_private_rooms to control default e2ee behaviour Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/CreateRoomDialog.js | 3 ++- src/components/views/dialogs/InviteDialog.js | 5 ++--- src/components/views/right_panel/UserInfo.js | 4 ++-- src/createRoom.js | 7 ++++++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index fb08afa5f7..df5f559e3b 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -25,6 +25,7 @@ import { _t } from '../../../languageHandler'; import {MatrixClientPeg} from '../../../MatrixClientPeg'; import {Key} from "../../../Keyboard"; import SettingsStore from "../../../settings/SettingsStore"; +import {privateShouldBeEncrypted} from "../../../createRoom"; export default createReactClass({ displayName: 'CreateRoomDialog', @@ -37,7 +38,7 @@ export default createReactClass({ const config = SdkConfig.get(); return { isPublic: this.props.defaultPublic || false, - isEncrypted: true, + isEncrypted: privateShouldBeEncrypted(), name: "", topic: "", alias: "", diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index 7cbbf8ba64..6b7d2ff69d 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -31,9 +31,8 @@ import dis from "../../../dispatcher"; import IdentityAuthClient from "../../../IdentityAuthClient"; import Modal from "../../../Modal"; import {humanizeTime} from "../../../utils/humanize"; -import createRoom, {canEncryptToAllUsers} from "../../../createRoom"; +import createRoom, {canEncryptToAllUsers, privateShouldBeEncrypted} from "../../../createRoom"; import {inviteMultipleToRoom} from "../../../RoomInvite"; -import SettingsStore from '../../../settings/SettingsStore'; import RoomListStore, {TAG_DM} from "../../../stores/RoomListStore"; import {Key} from "../../../Keyboard"; @@ -574,7 +573,7 @@ export default class InviteDialog extends React.PureComponent { const createRoomOptions = {inlineErrors: true}; - if (SettingsStore.getValue("feature_cross_signing")) { + if (privateShouldBeEncrypted()) { // Check whether all users have uploaded device keys before. // If so, enable encryption in the new room. const has3PidMembers = targets.some(t => t instanceof ThreepidMember); diff --git a/src/components/views/right_panel/UserInfo.js b/src/components/views/right_panel/UserInfo.js index 478dc90418..68139e5726 100644 --- a/src/components/views/right_panel/UserInfo.js +++ b/src/components/views/right_panel/UserInfo.js @@ -25,7 +25,7 @@ import dis from '../../../dispatcher'; import Modal from '../../../Modal'; import * as sdk from '../../../index'; import { _t } from '../../../languageHandler'; -import createRoom from '../../../createRoom'; +import createRoom, {privateShouldBeEncrypted} from '../../../createRoom'; import DMRoomMap from '../../../utils/DMRoomMap'; import AccessibleButton from '../elements/AccessibleButton'; import SdkConfig from '../../../SdkConfig'; @@ -111,7 +111,7 @@ async function openDMForUser(matrixClient, userId) { dmUserId: userId, }; - if (SettingsStore.getValue("feature_cross_signing")) { + if (privateShouldBeEncrypted()) { // Check whether all users have uploaded device keys before. // If so, enable encryption in the new room. const usersToDevicesMap = await matrixClient.downloadKeys([userId]); diff --git a/src/createRoom.js b/src/createRoom.js index a39d2c2216..2573c438c2 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -24,6 +24,7 @@ import * as Rooms from "./Rooms"; import DMRoomMap from "./utils/DMRoomMap"; import {getAddressType} from "./UserAddress"; import SettingsStore from "./settings/SettingsStore"; +import SdkConfig from "./SdkConfig"; /** * Create a new room, and switch to it. @@ -227,7 +228,7 @@ export async function ensureDMExists(client, userId) { roomId = existingDMRoom.roomId; } else { let encryption; - if (SettingsStore.getValue("feature_cross_signing")) { + if (privateShouldBeEncrypted()) { encryption = canEncryptToAllUsers(client, [userId]); } roomId = await createRoom({encryption, dmUserId: userId, spinner: false, andView: false}); @@ -235,3 +236,7 @@ export async function ensureDMExists(client, userId) { } return roomId; } + +export function privateShouldBeEncrypted() { + return SettingsStore.getValue("feature_cross_signing") && SdkConfig.get().e2ee_default_for_private_rooms !== false; +} From cbc2aee746f7dddf42ed76eb2418bdf29a681758 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 22:22:01 +0100 Subject: [PATCH 02/13] Add js-sdk mechanism for polling client well-known for config Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/MatrixClientPeg.ts | 2 + src/integrations/IntegrationManagers.js | 58 ++++++++++--------------- src/widgets/Jitsi.ts | 34 +++++---------- 3 files changed, 35 insertions(+), 59 deletions(-) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index c6ee6c546f..1ac929ab73 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -49,6 +49,7 @@ export interface IOpts { initialSyncLimit?: number; pendingEventOrdering?: "detached" | "chronological"; lazyLoadMembers?: boolean; + clientWellKnownPollPeriod?: number; } export interface IMatrixClientPeg { @@ -209,6 +210,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; opts.lazyLoadMembers = true; + opts.clientWellKnownPollPeriod = 4 * 60 * 60; // 4 hours // Connect the matrix client to the dispatcher and setting handlers MatrixActionCreators.start(this.matrixClient); diff --git a/src/integrations/IntegrationManagers.js b/src/integrations/IntegrationManagers.js index 3ba1aab135..5fd28d7c54 100644 --- a/src/integrations/IntegrationManagers.js +++ b/src/integrations/IntegrationManagers.js @@ -21,10 +21,8 @@ import {IntegrationManagerInstance, KIND_ACCOUNT, KIND_CONFIG, KIND_HOMESERVER} import type {MatrixClient, MatrixEvent, Room} from "matrix-js-sdk"; import WidgetUtils from "../utils/WidgetUtils"; import {MatrixClientPeg} from "../MatrixClientPeg"; -import {AutoDiscovery} from "matrix-js-sdk"; import SettingsStore from "../settings/SettingsStore"; -const HS_MANAGERS_REFRESH_INTERVAL = 8 * 60 * 60 * 1000; // 8 hours const KIND_PREFERENCE = [ // Ordered: first is most preferred, last is least preferred. KIND_ACCOUNT, @@ -44,7 +42,6 @@ export class IntegrationManagers { _managers: IntegrationManagerInstance[] = []; _client: MatrixClient; - _wellknownRefreshTimerId: number = null; _primaryManager: IntegrationManagerInstance; constructor() { @@ -55,20 +52,19 @@ export class IntegrationManagers { this.stopWatching(); this._client = MatrixClientPeg.get(); this._client.on("accountData", this._onAccountData); + this._client.on("WellKnown.client", this._setupHomeserverManagers); this._compileManagers(); - setInterval(() => this._setupHomeserverManagers(), HS_MANAGERS_REFRESH_INTERVAL); } stopWatching(): void { if (!this._client) return; this._client.removeListener("accountData", this._onAccountData); - if (this._wellknownRefreshTimerId !== null) clearInterval(this._wellknownRefreshTimerId); + this._client.removeListener("WellKnown.client", this._setupHomeserverManagers); } _compileManagers() { this._managers = []; this._setupConfiguredManager(); - this._setupHomeserverManagers(); this._setupAccountManagers(); } @@ -82,39 +78,31 @@ export class IntegrationManagers { } } - async _setupHomeserverManagers() { - if (!MatrixClientPeg.get()) return; - try { - console.log("Updating homeserver-configured integration managers..."); - const homeserverDomain = MatrixClientPeg.getHomeserverName(); - const discoveryResponse = await AutoDiscovery.getRawClientConfig(homeserverDomain); - if (discoveryResponse && discoveryResponse['m.integrations']) { - let managers = discoveryResponse['m.integrations']['managers']; - if (!Array.isArray(managers)) managers = []; // make it an array so we can wipe the HS managers + async _setupHomeserverManagers(discoveryResponse) { + console.log("Updating homeserver-configured integration managers..."); + if (discoveryResponse && discoveryResponse['m.integrations']) { + let managers = discoveryResponse['m.integrations']['managers']; + if (!Array.isArray(managers)) managers = []; // make it an array so we can wipe the HS managers - console.log(`Homeserver has ${managers.length} integration managers`); + console.log(`Homeserver has ${managers.length} integration managers`); - // Clear out any known managers for the homeserver - // TODO: Log out of the scalar clients - this._managers = this._managers.filter(m => m.kind !== KIND_HOMESERVER); + // Clear out any known managers for the homeserver + // TODO: Log out of the scalar clients + this._managers = this._managers.filter(m => m.kind !== KIND_HOMESERVER); - // Now add all the managers the homeserver wants us to have - for (const hsManager of managers) { - if (!hsManager["api_url"]) continue; - this._managers.push(new IntegrationManagerInstance( - KIND_HOMESERVER, - hsManager["api_url"], - hsManager["ui_url"], // optional - )); - } - - this._primaryManager = null; // reset primary - } else { - console.log("Homeserver has no integration managers"); + // Now add all the managers the homeserver wants us to have + for (const hsManager of managers) { + if (!hsManager["api_url"]) continue; + this._managers.push(new IntegrationManagerInstance( + KIND_HOMESERVER, + hsManager["api_url"], + hsManager["ui_url"], // optional + )); } - } catch (e) { - console.error(e); - // Errors during discovery are non-fatal + + this._primaryManager = null; // reset primary + } else { + console.log("Homeserver has no integration managers"); } } diff --git a/src/widgets/Jitsi.ts b/src/widgets/Jitsi.ts index 15df4953aa..f6ac766020 100644 --- a/src/widgets/Jitsi.ts +++ b/src/widgets/Jitsi.ts @@ -16,10 +16,8 @@ limitations under the License. import SdkConfig from "../SdkConfig"; import {MatrixClientPeg} from "../MatrixClientPeg"; -import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery"; const JITSI_WK_PROPERTY = "im.vector.riot.jitsi"; -const JITSI_WK_CHECK_INTERVAL = 2 * 60 * 60 * 1000; // 2 hours, arbitrarily selected export interface JitsiWidgetData { conferenceId: string; @@ -36,33 +34,21 @@ export class Jitsi { return this.domain || 'jitsi.riot.im'; } - constructor() { - // We rely on the first call to be an .update() instead of doing one here. Doing one - // here could result in duplicate calls to the homeserver. - - // Start a timer to update the server info regularly - setInterval(() => this.update(), JITSI_WK_CHECK_INTERVAL); - } - public async update(): Promise { // Start with a default of the config's domain let domain = (SdkConfig.get()['jitsi'] || {})['preferredDomain'] || 'jitsi.riot.im'; - // Now request the .well-known config to see if it changed - if (MatrixClientPeg.get()) { - try { - console.log("Attempting to get Jitsi conference information from homeserver"); + const cli = MatrixClientPeg.get(); + const discoveryResponse = cli && MatrixClientPeg.get().getClientWellKnown(); - const homeserverDomain = MatrixClientPeg.getHomeserverName(); - const discoveryResponse = await AutoDiscovery.getRawClientConfig(homeserverDomain); - if (discoveryResponse && discoveryResponse[JITSI_WK_PROPERTY]) { - const wkPreferredDomain = discoveryResponse[JITSI_WK_PROPERTY]['preferredDomain']; - if (wkPreferredDomain) domain = wkPreferredDomain; - } - } catch (e) { - // These are non-fatal errors - console.error(e); - } + if (cli) { + cli.on("WellKnown.client", this.update); + } + + console.log("Attempting to get Jitsi conference information from homeserver"); + if (discoveryResponse && discoveryResponse[JITSI_WK_PROPERTY]) { + const wkPreferredDomain = discoveryResponse[JITSI_WK_PROPERTY]['preferredDomain']; + if (wkPreferredDomain) domain = wkPreferredDomain; } // Put the result into memory for us to use later From 3f72a590f56c41d8be7faeb79199140520cbb03e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 22:37:12 +0100 Subject: [PATCH 03/13] move e2ee-default switch to well-known from config.json Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/createRoom.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/createRoom.js b/src/createRoom.js index 79e9a517ba..affdf196a7 100644 --- a/src/createRoom.js +++ b/src/createRoom.js @@ -23,8 +23,8 @@ import dis from "./dispatcher/dispatcher"; import * as Rooms from "./Rooms"; import DMRoomMap from "./utils/DMRoomMap"; import {getAddressType} from "./UserAddress"; -import SettingsStore from "./settings/SettingsStore"; -import SdkConfig from "./SdkConfig"; + +const E2EE_WK_KEY = "im.vector.riot.e2ee"; /** * Create a new room, and switch to it. @@ -238,5 +238,11 @@ export async function ensureDMExists(client, userId) { } export function privateShouldBeEncrypted() { - return SettingsStore.getValue("feature_cross_signing") && SdkConfig.get().e2ee_default_for_private_rooms !== false; + const clientWellKnown = MatrixClientPeg.get().getClientWellKnown(); + if (clientWellKnown && clientWellKnown[E2EE_WK_KEY]) { + const defaultDisabled = clientWellKnown[E2EE_WK_KEY]["default"] === false; + return !defaultDisabled; + } + + return true; } From 366c60cb2d332c0e89c6f287e79321914dedf053 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 22:57:51 +0100 Subject: [PATCH 04/13] fix ee listener add Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/widgets/Jitsi.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/widgets/Jitsi.ts b/src/widgets/Jitsi.ts index f6ac766020..4dda48c3a3 100644 --- a/src/widgets/Jitsi.ts +++ b/src/widgets/Jitsi.ts @@ -42,7 +42,7 @@ export class Jitsi { const discoveryResponse = cli && MatrixClientPeg.get().getClientWellKnown(); if (cli) { - cli.on("WellKnown.client", this.update); + cli.on("WellKnown.client", () => this.update); } console.log("Attempting to get Jitsi conference information from homeserver"); From a2fb96eb8f5d498d5af6d608a29d892ed219ccdd Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 22:59:14 +0100 Subject: [PATCH 05/13] Update Create Room Dialog microcopy for e2ee-default:false Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/CreateRoomDialog.js | 10 +++++++++- src/i18n/strings/en_EN.json | 3 ++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/CreateRoomDialog.js b/src/components/views/dialogs/CreateRoomDialog.js index e318258586..42a8b10d5e 100644 --- a/src/components/views/dialogs/CreateRoomDialog.js +++ b/src/components/views/dialogs/CreateRoomDialog.js @@ -195,6 +195,14 @@ export default createReactClass({ let e2eeSection; if (!this.state.isPublic && SettingsStore.getValue("feature_cross_signing")) { + let microcopy; + if (privateShouldBeEncrypted()) { + microcopy = _t("You can’t disable this later. Bridges & most bots won’t work yet."); + } else { + microcopy = _t("Your server admin has disabled end-to-end encryption by default " + + "in private rooms & Direct Messages."); + } + e2eeSection = -

{ _t("You can’t disable this later. Bridges & most bots won’t work yet.") }

+

{ microcopy }

; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8f7e8ea6b6..176a668949 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1588,8 +1588,9 @@ "Please enter a name for the room": "Please enter a name for the room", "Set a room address to easily share your room with other people.": "Set a room address to easily share your room with other people.", "This room is private, and can only be joined by invitation.": "This room is private, and can only be joined by invitation.", - "Enable end-to-end encryption": "Enable end-to-end encryption", "You can’t disable this later. Bridges & most bots won’t work yet.": "You can’t disable this later. Bridges & most bots won’t work yet.", + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.", + "Enable end-to-end encryption": "Enable end-to-end encryption", "Create a public room": "Create a public room", "Create a private room": "Create a private room", "Name": "Name", From 702bbe3bcd64485406d608311e42fa0339cbfc47 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 23:09:14 +0100 Subject: [PATCH 06/13] Add e2ee-default:false notice to Setting>Security Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../tabs/user/_SecurityUserSettingsTab.scss | 21 +++++++++++++++++++ res/img/feather-customised/alert-triangle.svg | 5 +++++ .../tabs/user/SecurityUserSettingsTab.js | 10 +++++++++ 3 files changed, 36 insertions(+) create mode 100644 res/img/feather-customised/alert-triangle.svg diff --git a/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss b/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss index 8700f8747d..abcf80fc65 100644 --- a/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss +++ b/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss @@ -63,4 +63,25 @@ limitations under the License. font-size: inherit; } } + + .mx_SecurityUserSettingsTab_warning { + color: $notice-primary-color;; + position: relative; + padding-left: 32px; + margin-top: 30px; + + &::before { + mask-repeat: no-repeat; + mask-position: 0 center; + mask-size: $font-16px; + position: absolute; + width: $font-16px; + height: $font-16px; + content: ""; + top: 0; + left: 0; + background-color: $notice-primary-color; + mask-image: url('$(res)/img/feather-customised/alert-triangle.svg'); + } + } } diff --git a/res/img/feather-customised/alert-triangle.svg b/res/img/feather-customised/alert-triangle.svg new file mode 100644 index 0000000000..ceb664790f --- /dev/null +++ b/res/img/feather-customised/alert-triangle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js index bed057f03d..ea9865660c 100644 --- a/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/SecurityUserSettingsTab.js @@ -26,6 +26,7 @@ import Modal from "../../../../../Modal"; import * as sdk from "../../../../.."; import {sleep} from "../../../../../utils/promise"; import dis from "../../../../../dispatcher/dispatcher"; +import {privateShouldBeEncrypted} from "../../../../../createRoom"; export class IgnoredUser extends React.Component { static propTypes = { @@ -320,8 +321,17 @@ export default class SecurityUserSettingsTab extends React.Component { const E2eAdvancedPanel = sdk.getComponent('views.settings.E2eAdvancedPanel'); + let warning; + if (!privateShouldBeEncrypted()) { + warning =
+ { _t("Your server admin has disabled end-to-end encryption by default " + + "in private rooms & Direct Messages.") } +
; + } + return (
+ {warning}
{_t("Security & Privacy")}
{_t("Where you’re logged in")} From 2dda93bf1ae13d5b357aa0919cbd4443944fbc0f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 23:09:57 +0100 Subject: [PATCH 07/13] delint Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/dialogs/InviteDialog.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js index c0b7582909..7ac9e21518 100644 --- a/src/components/views/dialogs/InviteDialog.js +++ b/src/components/views/dialogs/InviteDialog.js @@ -33,7 +33,6 @@ import Modal from "../../../Modal"; import {humanizeTime} from "../../../utils/humanize"; import createRoom, {canEncryptToAllUsers, privateShouldBeEncrypted} from "../../../createRoom"; import {inviteMultipleToRoom} from "../../../RoomInvite"; -import SettingsStore from '../../../settings/SettingsStore'; import {Key} from "../../../Keyboard"; import {Action} from "../../../dispatcher/actions"; import {RoomListStoreTempProxy} from "../../../stores/room-list/RoomListStoreTempProxy"; From d3523afd292b4917eedfdce34babb252903fa444 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 1 Jun 2020 23:11:47 +0100 Subject: [PATCH 08/13] delint scss and i18n Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss b/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss index abcf80fc65..9c59de92c4 100644 --- a/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss +++ b/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss @@ -65,7 +65,7 @@ limitations under the License. } .mx_SecurityUserSettingsTab_warning { - color: $notice-primary-color;; + color: $notice-primary-color; position: relative; padding-left: 32px; margin-top: 30px; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 176a668949..7908af1267 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -881,6 +881,7 @@ "Key backup": "Key backup", "Message search": "Message search", "Cross-signing": "Cross-signing", + "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.", "Security & Privacy": "Security & Privacy", "Where you’re logged in": "Where you’re logged in", "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Manage the names of and sign out of your sessions below or verify them in your User Profile.", @@ -1589,7 +1590,6 @@ "Set a room address to easily share your room with other people.": "Set a room address to easily share your room with other people.", "This room is private, and can only be joined by invitation.": "This room is private, and can only be joined by invitation.", "You can’t disable this later. Bridges & most bots won’t work yet.": "You can’t disable this later. Bridges & most bots won’t work yet.", - "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.", "Enable end-to-end encryption": "Enable end-to-end encryption", "Create a public room": "Create a public room", "Create a private room": "Create a private room", From 48c535e578738af73a980f27fa109eaba4b8640c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 2 Jun 2020 21:40:32 +0100 Subject: [PATCH 09/13] hide setup encryption toasts on an e2ee-default:false config Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/DeviceListener.ts | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/DeviceListener.ts b/src/DeviceListener.ts index ca51b5ac1c..b825e7bf3f 100644 --- a/src/DeviceListener.ts +++ b/src/DeviceListener.ts @@ -23,13 +23,13 @@ import { import { hideToast as hideSetupEncryptionToast, Kind as SetupKind, - Kind, showToast as showSetupEncryptionToast } from "./toasts/SetupEncryptionToast"; import { hideToast as hideUnverifiedSessionsToast, showToast as showUnverifiedSessionsToast } from "./toasts/UnverifiedSessionToast"; +import {privateShouldBeEncrypted} from "./createRoom"; const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000; @@ -170,6 +170,14 @@ export default class DeviceListener { return this.keyBackupInfo; } + private shouldShowSetupEncryptionToast() { + // In a default configuration, show the toasts. If the well-known config causes e2ee default to be false + // then do not show the toasts until user is in at least one encrypted room. + if (privateShouldBeEncrypted()) return true; + const cli = MatrixClientPeg.get(); + return cli && cli.getRooms().some(r => cli.isRoomEncrypted(r.roomId)); + } + async _recheck() { const cli = MatrixClientPeg.get(); @@ -188,7 +196,7 @@ export default class DeviceListener { if (this.dismissedThisDeviceToast || crossSigningReady) { hideSetupEncryptionToast(); - } else { + } else if (this.shouldShowSetupEncryptionToast()) { // make sure our keys are finished downloading await cli.downloadKeys([cli.getUserId()]); // cross signing isn't enabled - nag to enable it @@ -200,10 +208,10 @@ export default class DeviceListener { const backupInfo = await this._getKeyBackupInfo(); if (backupInfo) { // No cross-signing on account but key backup available (upgrade encryption) - showSetupEncryptionToast(Kind.UPGRADE_ENCRYPTION); + showSetupEncryptionToast(SetupKind.UPGRADE_ENCRYPTION); } else { // No cross-signing or key backup on account (set up encryption) - showSetupEncryptionToast(Kind.SET_UP_ENCRYPTION); + showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION); } } } From 170acef796ab4cfccc99326a590e66f9f344390f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 2 Jun 2020 21:54:38 +0100 Subject: [PATCH 10/13] Fix sizing of the security warning icon Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- .../settings/tabs/user/_SecurityUserSettingsTab.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss b/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss index 9c59de92c4..d6466a03f9 100644 --- a/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss +++ b/res/css/views/settings/tabs/user/_SecurityUserSettingsTab.scss @@ -67,16 +67,16 @@ limitations under the License. .mx_SecurityUserSettingsTab_warning { color: $notice-primary-color; position: relative; - padding-left: 32px; + padding-left: 40px; margin-top: 30px; &::before { mask-repeat: no-repeat; mask-position: 0 center; - mask-size: $font-16px; + mask-size: $font-24px; position: absolute; - width: $font-16px; - height: $font-16px; + width: $font-24px; + height: $font-24px; content: ""; top: 0; left: 0; From 5156388fc66fed7ac9734a40f229bb69c516d0b9 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 Jun 2020 12:25:57 +0100 Subject: [PATCH 11/13] Change well known poll period to 2 hours to match existing Jitsi poll Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/MatrixClientPeg.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 1ac929ab73..bc550c1935 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -210,7 +210,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { // the react sdk doesn't work without this, so don't allow opts.pendingEventOrdering = "detached"; opts.lazyLoadMembers = true; - opts.clientWellKnownPollPeriod = 4 * 60 * 60; // 4 hours + opts.clientWellKnownPollPeriod = 2 * 60 * 60; // 2 hours // Connect the matrix client to the dispatcher and setting handlers MatrixActionCreators.start(this.matrixClient); From a674131a8c6ab2e723ed14cc5ece896720395f3f Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 Jun 2020 13:58:17 +0100 Subject: [PATCH 12/13] Fix Jitsi wellknown hooks Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Lifecycle.js | 2 +- src/widgets/Jitsi.ts | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index 0494628472..bf442e93d5 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -619,7 +619,7 @@ async function startMatrixClient(startSyncing=true) { } // Now that we have a MatrixClientPeg, update the Jitsi info - await Jitsi.getInstance().update(); + await Jitsi.getInstance().start(); // dispatch that we finished starting up to wire up any other bits // of the matrix client that cannot be set prior to starting up. diff --git a/src/widgets/Jitsi.ts b/src/widgets/Jitsi.ts index 4dda48c3a3..858685b86a 100644 --- a/src/widgets/Jitsi.ts +++ b/src/widgets/Jitsi.ts @@ -34,17 +34,20 @@ export class Jitsi { return this.domain || 'jitsi.riot.im'; } - public async update(): Promise { + public start() { + const cli = MatrixClientPeg.get(); + cli.on("WellKnown.client", this.update); + const discoveryResponse = cli.getClientWellKnown(); + if (discoveryResponse) { + // if we missed the first WellKnown.client event then call update anyway + this.update(discoveryResponse); + } + } + + private update = async (discoveryResponse): Promise => { // Start with a default of the config's domain let domain = (SdkConfig.get()['jitsi'] || {})['preferredDomain'] || 'jitsi.riot.im'; - const cli = MatrixClientPeg.get(); - const discoveryResponse = cli && MatrixClientPeg.get().getClientWellKnown(); - - if (cli) { - cli.on("WellKnown.client", () => this.update); - } - console.log("Attempting to get Jitsi conference information from homeserver"); if (discoveryResponse && discoveryResponse[JITSI_WK_PROPERTY]) { const wkPreferredDomain = discoveryResponse[JITSI_WK_PROPERTY]['preferredDomain']; @@ -54,7 +57,7 @@ export class Jitsi { // Put the result into memory for us to use later this.domain = domain; console.log("Jitsi conference domain:", this.preferredDomain); - } + }; /** * Parses the given URL into the data needed for a Jitsi widget, if the widget From d92f742205d65341893d3df981f9ffca9c4a4481 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 Jun 2020 14:09:45 +0100 Subject: [PATCH 13/13] Fix Jitsi wellknown hooks some more Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/widgets/Jitsi.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/widgets/Jitsi.ts b/src/widgets/Jitsi.ts index 858685b86a..a52f8182aa 100644 --- a/src/widgets/Jitsi.ts +++ b/src/widgets/Jitsi.ts @@ -37,11 +37,8 @@ export class Jitsi { public start() { const cli = MatrixClientPeg.get(); cli.on("WellKnown.client", this.update); - const discoveryResponse = cli.getClientWellKnown(); - if (discoveryResponse) { - // if we missed the first WellKnown.client event then call update anyway - this.update(discoveryResponse); - } + // call update initially in case we missed the first WellKnown.client event and for if no well-known present + this.update(cli.getClientWellKnown()); } private update = async (discoveryResponse): Promise => {