From 1427aa4203a5610be22bdb43eaab391cf83d88cb Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:41:51 +0000 Subject: [PATCH 01/18] fix mx_EncryptionInfo_spinner padding in dialogs --- res/css/views/right_panel/_EncryptionInfo.scss | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/res/css/views/right_panel/_EncryptionInfo.scss b/res/css/views/right_panel/_EncryptionInfo.scss index e13b1b6802..b3d4275f60 100644 --- a/res/css/views/right_panel/_EncryptionInfo.scss +++ b/res/css/views/right_panel/_EncryptionInfo.scss @@ -14,13 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_UserInfo { - .mx_EncryptionInfo_spinner { - .mx_Spinner { - margin-top: 25px; - margin-bottom: 15px; - } - - text-align: center; +.mx_EncryptionInfo_spinner { + .mx_Spinner { + margin-top: 25px; + margin-bottom: 15px; } + + text-align: center; } From 76738184003e1e2ad8d24ad2fbbab3b5dab2afc2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:43:59 +0000 Subject: [PATCH 02/18] switch to using an explicit verify button when cross-signing a new login --- .../structures/auth/SetupEncryptionBody.js | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 3e7264dfec..d2b3fbd3b9 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -19,6 +19,8 @@ import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; import SdkConfig from '../../../SdkConfig'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; +import Modal from '../../../Modal'; +import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog'; import * as sdk from '../../../index'; import { SetupEncryptionStore, @@ -81,6 +83,22 @@ export default class SetupEncryptionBody extends React.Component { store.usePassPhrase(); } + _onVerifyClick = () => { + const cli = MatrixClientPeg.get(); + const userId = cli.getUserId(); + const requestPromise = cli.requestVerification(userId); + + this.props.onFinished(true); + Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, { + verificationRequestPromise: requestPromise, + member: cli.getUser(userId), + onFinished: async () => { + const request = await requestPromise; + request.cancel(); + }, + }); + } + onSkipClick = () => { const store = SetupEncryptionStore.sharedInstance(); store.skip(); @@ -132,32 +150,24 @@ export default class SetupEncryptionBody extends React.Component { ; } + let verifyButton; + if (store.hasDevicesToVerifyAgainst) { + verifyButton = + { _t("Verify against another session") } + ; + } + const brand = SdkConfig.get().brand; return (

{_t( - "Confirm your identity by verifying this login from one of your other sessions, " + - "granting it access to encrypted messages.", + "Verify this login to access your encrypted messages and " + + "prove to others that this login is really you." )}

-

{_t( - "This requires the latest %(brand)s on your other devices:", - { brand }, - )}

- -
-
-
{_t("%(brand)s Web", { brand })}
-
{_t("%(brand)s Desktop", { brand })}
-
-
-
{_t("%(brand)s iOS", { brand })}
-
{_t("%(brand)s Android", { brand })}
-
-

{_t("or another cross-signing capable Matrix client")}

-
+ {verifyButton} {useRecoveryKeyButton} {_t("Skip")} From 6df8157a40e6da23850ad5fd1a17294d6ba23382 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:45:44 +0000 Subject: [PATCH 03/18] cancel VRD at the Modal level, so clicking in the bg cancels it --- .../views/dialogs/NewSessionReviewDialog.js | 4 ++++ .../views/dialogs/VerificationRequestDialog.js | 13 ++----------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/components/views/dialogs/NewSessionReviewDialog.js b/src/components/views/dialogs/NewSessionReviewDialog.js index e17501da40..5172f29405 100644 --- a/src/components/views/dialogs/NewSessionReviewDialog.js +++ b/src/components/views/dialogs/NewSessionReviewDialog.js @@ -66,6 +66,10 @@ export default class NewSessionReviewDialog extends React.PureComponent { Modal.createTrackedDialog('New Session Verification', 'Starting dialog', VerificationRequestDialog, { verificationRequestPromise: requestPromise, member: cli.getUser(userId), + onFinished: async () => { + const request = await requestPromise; + request.cancel(); + }, }); } diff --git a/src/components/views/dialogs/VerificationRequestDialog.js b/src/components/views/dialogs/VerificationRequestDialog.js index 3a6e9a2d10..2a5b7ae699 100644 --- a/src/components/views/dialogs/VerificationRequestDialog.js +++ b/src/components/views/dialogs/VerificationRequestDialog.js @@ -25,11 +25,11 @@ export default class VerificationRequestDialog extends React.Component { verificationRequest: PropTypes.object, verificationRequestPromise: PropTypes.object, onFinished: PropTypes.func.isRequired, + member: PropTypes.string, }; constructor(...args) { super(...args); - this.onFinished = this.onFinished.bind(this); this.state = {}; if (this.props.verificationRequest) { this.state.verificationRequest = this.props.verificationRequest; @@ -50,7 +50,7 @@ export default class VerificationRequestDialog extends React.Component { const title = request && request.isSelfVerification ? _t("Verify other session") : _t("Verification Request"); - return ; } - - async onFinished() { - this.props.onFinished(); - let request = this.props.verificationRequest; - if (!request && this.props.verificationRequestPromise) { - request = await this.props.verificationRequestPromise; - } - request.cancel(); - } } From 5b48e13eb91760bd71b088d93da29e9e291301a9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:46:15 +0000 Subject: [PATCH 04/18] add explicit link to edit devices from one's own UserInfo --- src/components/views/right_panel/UserInfo.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/views/right_panel/UserInfo.tsx b/src/components/views/right_panel/UserInfo.tsx index a4b5cd0fbb..ea8c467d13 100644 --- a/src/components/views/right_panel/UserInfo.tsx +++ b/src/components/views/right_panel/UserInfo.tsx @@ -46,6 +46,7 @@ import EncryptionPanel from "./EncryptionPanel"; import {useAsyncMemo} from '../../../hooks/useAsyncMemo'; import {legacyVerifyUser, verifyDevice, verifyUser} from '../../../verification'; import {Action} from "../../../dispatcher/actions"; +import { USER_SECURITY_TAB } from "../dialogs/UserSettingsDialog"; import {useIsEncrypted} from "../../../hooks/useIsEncrypted"; import BaseCard from "./BaseCard"; import {E2EStatus} from "../../../utils/ShieldUtils"; @@ -1362,6 +1363,20 @@ const BasicUserInfo: React.FC<{ } } + let editDevices; + if (member.userId == cli.getUserId()) { + editDevices = (

+ { + dis.dispatch({ + action: Action.ViewUserSettings, + initialTabId: USER_SECURITY_TAB, + }); + }}> + { _t("Edit devices") } + +

) + } + const securitySection = (

{ _t("Security") }

@@ -1371,6 +1386,7 @@ const BasicUserInfo: React.FC<{ loading={showDeviceListSpinner} devices={devices} userId={member.userId} /> } + { editDevices }
); From aa0cca9306f2e56f134a82937c87e397346cd8b9 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:46:47 +0000 Subject: [PATCH 05/18] report IP of self-verification reqs --- .../views/toasts/VerificationRequestToast.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 8c8a74b2be..73440eb822 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -38,6 +38,7 @@ interface IProps { interface IState { counter: number; device?: DeviceInfo; + IP?: string; } export default class VerificationRequestToast extends React.PureComponent { @@ -66,9 +67,15 @@ export default class VerificationRequestToast extends React.PureComponent { + request.cancel(); + }, }, null, /* priority = */ false, /* static = */ true); } await request.accept(); @@ -131,9 +141,10 @@ export default class VerificationRequestToast extends React.PureComponent Date: Mon, 8 Mar 2021 04:49:59 +0000 Subject: [PATCH 06/18] only prompt to verify if we have an MSK or we have devices to verify against --- src/stores/SetupEncryptionStore.js | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 981ce6eca9..525678f9a3 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -49,6 +49,7 @@ export class SetupEncryptionStore extends EventEmitter { cli.on("crypto.verification.request", this.onVerificationRequest); cli.on('userTrustStatusChanged', this._onUserTrustStatusChanged); + const requestsInProgress = cli.getVerificationRequestsToDeviceInProgress(cli.getUserId()); if (requestsInProgress.length) { // If there are multiple, we take the most recent. Equally if the user sends another request from @@ -75,7 +76,8 @@ export class SetupEncryptionStore extends EventEmitter { } async fetchKeyInfo() { - const keys = await MatrixClientPeg.get().isSecretStored('m.cross_signing.master', false); + const cli = MatrixClientPeg.get(); + const keys = await cli.isSecretStored('m.cross_signing.master', false); if (keys === null || Object.keys(keys).length === 0) { this.keyId = null; this.keyInfo = null; @@ -85,7 +87,22 @@ export class SetupEncryptionStore extends EventEmitter { this.keyInfo = keys[this.keyId]; } - this.phase = PHASE_INTRO; + // do we have any other devices which are E2EE which we can verify against? + const dehydratedDevice = await cli.getDehydratedDevice(); + this.hasDevicesToVerifyAgainst = cli.getStoredDevicesForUser(cli.getUserId()).some( + device => + device.getIdentityKey() && + (!dehydratedDevice || (device.deviceId != dehydratedDevice.device_id)) + ); + + if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) { + // skip before we can even render anything. + // XXX: this causes a dialog box flash + this.phase = PHASE_FINISHED; + } + else { + this.phase = PHASE_INTRO; + } this.emit("update"); } From c73097a5b0d48e648ffaae8b74b5949b4773335b Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:51:16 +0000 Subject: [PATCH 07/18] fix unhelpful 'Review...' toast wording --- src/toasts/BulkUnverifiedSessionsToast.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/toasts/BulkUnverifiedSessionsToast.ts b/src/toasts/BulkUnverifiedSessionsToast.ts index 41717e0804..bc129ebd54 100644 --- a/src/toasts/BulkUnverifiedSessionsToast.ts +++ b/src/toasts/BulkUnverifiedSessionsToast.ts @@ -39,7 +39,7 @@ export const showToast = (deviceIds: Set) => { ToastStore.sharedInstance().addOrReplaceToast({ key: TOAST_KEY, - title: _t("Review where you’re logged in"), + title: _t("You have unverified logins"), icon: "verification_warning", props: { description: _t("Verify all your sessions to ensure your account & messages are safe"), From 96ebbad959bf3a169a2d8911fba585bb61360919 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 04:54:44 +0000 Subject: [PATCH 08/18] switch UnverifiedSessionToast to route to check sessions rather than verify the new login given the chances are that the new login will be stuck doing initial sync, and won't be in position to be verified until its finished. --- src/i18n/strings/en_EN.json | 17 +++++++-------- src/toasts/UnverifiedSessionToast.ts | 31 +++++++++++++++------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e8a4b86c77..0b6f68a738 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -725,7 +725,7 @@ "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.", "Yes": "Yes", "No": "No", - "Review where you’re logged in": "Review where you’re logged in", + "You have unverified logins": "You have unverified logins", "Verify all your sessions to ensure your account & messages are safe": "Verify all your sessions to ensure your account & messages are safe", "Review": "Review", "Later": "Later", @@ -749,7 +749,8 @@ "Safeguard against losing access to encrypted messages & data": "Safeguard against losing access to encrypted messages & data", "Other users may not trust it": "Other users may not trust it", "New login. Was this you?": "New login. Was this you?", - "Verify the new login accessing your account: %(name)s": "Verify the new login accessing your account: %(name)s", + "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s": "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", + "Check your devices": "Check your devices", "What's new?": "What's new?", "What's New": "What's New", "Update": "Update", @@ -974,7 +975,7 @@ "Folder": "Folder", "Pin": "Pin", "Your server isn't responding to some requests.": "Your server isn't responding to some requests.", - "From %(deviceName)s (%(deviceId)s)": "From %(deviceName)s (%(deviceId)s)", + "From %(deviceName)s (%(deviceId)s) from %(IP)s": "From %(deviceName)s (%(deviceId)s) from %(IP)s", "Decline (%(counter)s)": "Decline (%(counter)s)", "Accept to continue:": "Accept to continue:", "Remove": "Remove", @@ -1711,6 +1712,7 @@ "Failed to deactivate user": "Failed to deactivate user", "Role": "Role", "This client does not support end-to-end encryption.": "This client does not support end-to-end encryption.", + "Edit devices": "Edit devices", "Security": "Security", "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.", "Verify by scanning": "Verify by scanning", @@ -2611,13 +2613,8 @@ "Decide where your account is hosted": "Decide where your account is hosted", "Use Security Key or Phrase": "Use Security Key or Phrase", "Use Security Key": "Use Security Key", - "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.", - "This requires the latest %(brand)s on your other devices:": "This requires the latest %(brand)s on your other devices:", - "%(brand)s Web": "%(brand)s Web", - "%(brand)s Desktop": "%(brand)s Desktop", - "%(brand)s iOS": "%(brand)s iOS", - "%(brand)s Android": "%(brand)s Android", - "or another cross-signing capable Matrix client": "or another cross-signing capable Matrix client", + "Verify against another session": "Verify against another session", + "Verify this login to access your encrypted messages and prove to others that this login is really you.": "Verify this login to access your encrypted messages and prove to others that this login is really you.", "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.", "Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.", "Without completing security on this session, it won’t have access to encrypted messages.": "Without completing security on this session, it won’t have access to encrypted messages.", diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts index 9dedd2b137..32635e689a 100644 --- a/src/toasts/UnverifiedSessionToast.ts +++ b/src/toasts/UnverifiedSessionToast.ts @@ -15,38 +15,36 @@ limitations under the License. */ import { _t } from '../languageHandler'; +import dis from "../dispatcher/dispatcher"; import { MatrixClientPeg } from '../MatrixClientPeg'; import Modal from '../Modal'; import DeviceListener from '../DeviceListener'; import NewSessionReviewDialog from '../components/views/dialogs/NewSessionReviewDialog'; import ToastStore from "../stores/ToastStore"; import GenericToast from "../components/views/toasts/GenericToast"; +import { Action } from "../dispatcher/actions"; +import { USER_SECURITY_TAB } from "../components/views/dialogs/UserSettingsDialog"; function toastKey(deviceId: string) { return "unverified_session_" + deviceId; } -export const showToast = (deviceId: string) => { +export const showToast = async (deviceId: string) => { const cli = MatrixClientPeg.get(); const onAccept = () => { - Modal.createTrackedDialog('New Session Review', 'Starting dialog', NewSessionReviewDialog, { - userId: cli.getUserId(), - device: cli.getStoredDevice(cli.getUserId(), deviceId), - onFinished: (r) => { - if (!r) { - /* This'll come back false if the user clicks "this wasn't me" and saw a warning dialog */ - DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); - } - }, - }, null, /* priority = */ false, /* static = */ true); + DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); + dis.dispatch({ + action: Action.ViewUserSettings, + initialTabId: USER_SECURITY_TAB, + }); }; const onReject = () => { DeviceListener.sharedInstance().dismissUnverifiedSessions([deviceId]); }; - const device = cli.getStoredDevice(cli.getUserId(), deviceId); + const device = await cli.getDevice(deviceId); ToastStore.sharedInstance().addOrReplaceToast({ key: toastKey(deviceId), @@ -54,8 +52,13 @@ export const showToast = (deviceId: string) => { icon: "verification_warning", props: { description: _t( - "Verify the new login accessing your account: %(name)s", { name: device.getDisplayName()}), - acceptLabel: _t("Verify"), + "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", { + name: device.display_name, + deviceID: deviceId, + IP: device.last_seen_ip, + } + ), + acceptLabel: _t("Check your devices"), onAccept, rejectLabel: _t("Later"), onReject, From 997d6e12811015f3c60d3813f1018fd9d5ac10e8 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 05:08:01 +0000 Subject: [PATCH 09/18] lint --- src/components/structures/auth/SetupEncryptionBody.js | 4 +--- src/stores/SetupEncryptionStore.js | 5 ++--- src/toasts/UnverifiedSessionToast.ts | 10 ++++------ 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index d2b3fbd3b9..d40192f9c1 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -157,13 +157,11 @@ export default class SetupEncryptionBody extends React.Component {
; } - const brand = SdkConfig.get().brand; - return (

{_t( "Verify this login to access your encrypted messages and " + - "prove to others that this login is really you." + "prove to others that this login is really you.", )}

diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 525678f9a3..fdabfa8019 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -92,15 +92,14 @@ export class SetupEncryptionStore extends EventEmitter { this.hasDevicesToVerifyAgainst = cli.getStoredDevicesForUser(cli.getUserId()).some( device => device.getIdentityKey() && - (!dehydratedDevice || (device.deviceId != dehydratedDevice.device_id)) + (!dehydratedDevice || (device.deviceId != dehydratedDevice.device_id)), ); if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) { // skip before we can even render anything. // XXX: this causes a dialog box flash this.phase = PHASE_FINISHED; - } - else { + } else { this.phase = PHASE_INTRO; } this.emit("update"); diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts index 32635e689a..d375ef6112 100644 --- a/src/toasts/UnverifiedSessionToast.ts +++ b/src/toasts/UnverifiedSessionToast.ts @@ -17,9 +17,7 @@ limitations under the License. import { _t } from '../languageHandler'; import dis from "../dispatcher/dispatcher"; import { MatrixClientPeg } from '../MatrixClientPeg'; -import Modal from '../Modal'; import DeviceListener from '../DeviceListener'; -import NewSessionReviewDialog from '../components/views/dialogs/NewSessionReviewDialog'; import ToastStore from "../stores/ToastStore"; import GenericToast from "../components/views/toasts/GenericToast"; import { Action } from "../dispatcher/actions"; @@ -53,10 +51,10 @@ export const showToast = async (deviceId: string) => { props: { description: _t( "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", { - name: device.display_name, - deviceID: deviceId, - IP: device.last_seen_ip, - } + name: device.display_name, + deviceID: deviceId, + IP: device.last_seen_ip, + }, ), acceptLabel: _t("Check your devices"), onAccept, From 7abc48a71679de4afa37fe73d8edf966f29af43e Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 05:30:02 +0000 Subject: [PATCH 10/18] lint --- src/components/structures/auth/SetupEncryptionBody.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index d40192f9c1..4e3d106eb1 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -17,7 +17,6 @@ limitations under the License. import React from 'react'; import PropTypes from 'prop-types'; import { _t } from '../../../languageHandler'; -import SdkConfig from '../../../SdkConfig'; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import Modal from '../../../Modal'; import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDialog'; From 1629b7e62a3179ca756717bd60cf25746871b16d Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 16:44:14 +0000 Subject: [PATCH 11/18] s/IP/ip/; s/from/at/ --- .../views/toasts/VerificationRequestToast.tsx | 10 +++++----- src/i18n/strings/en_EN.json | 4 ++-- src/toasts/UnverifiedSessionToast.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/views/toasts/VerificationRequestToast.tsx b/src/components/views/toasts/VerificationRequestToast.tsx index 73440eb822..82c6b0b952 100644 --- a/src/components/views/toasts/VerificationRequestToast.tsx +++ b/src/components/views/toasts/VerificationRequestToast.tsx @@ -38,7 +38,7 @@ interface IProps { interface IState { counter: number; device?: DeviceInfo; - IP?: string; + ip?: string; } export default class VerificationRequestToast extends React.PureComponent { @@ -71,10 +71,10 @@ export default class VerificationRequestToast extends React.PureComponentrequests.": "Your server isn't responding to some requests.", - "From %(deviceName)s (%(deviceId)s) from %(IP)s": "From %(deviceName)s (%(deviceId)s) from %(IP)s", + "From %(deviceName)s (%(deviceId)s) at %(ip)s": "From %(deviceName)s (%(deviceId)s) at %(ip)s", "Decline (%(counter)s)": "Decline (%(counter)s)", "Accept to continue:": "Accept to continue:", "Delete": "Delete", diff --git a/src/toasts/UnverifiedSessionToast.ts b/src/toasts/UnverifiedSessionToast.ts index d375ef6112..e0ea323033 100644 --- a/src/toasts/UnverifiedSessionToast.ts +++ b/src/toasts/UnverifiedSessionToast.ts @@ -50,10 +50,10 @@ export const showToast = async (deviceId: string) => { icon: "verification_warning", props: { description: _t( - "A new login is accessing your account: %(name)s (%(deviceID)s) from %(IP)s", { + "A new login is accessing your account: %(name)s (%(deviceID)s) at %(ip)s", { name: device.display_name, deviceID: deviceId, - IP: device.last_seen_ip, + ip: device.last_seen_ip, }, ), acceptLabel: _t("Check your devices"), From 14b828ecc63652d7aac081c28bafd07fa8119d61 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 17:58:30 +0000 Subject: [PATCH 12/18] shorten verify button label --- src/components/structures/auth/SetupEncryptionBody.js | 2 +- src/i18n/strings/en_EN.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 4e3d106eb1..431762cade 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -152,7 +152,7 @@ export default class SetupEncryptionBody extends React.Component { let verifyButton; if (store.hasDevicesToVerifyAgainst) { verifyButton = - { _t("Verify against another session") } + { _t("Verify with another session") } ; } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 98a0ceb5d1..68664fa0dd 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2714,7 +2714,7 @@ "Decide where your account is hosted": "Decide where your account is hosted", "Use Security Key or Phrase": "Use Security Key or Phrase", "Use Security Key": "Use Security Key", - "Verify against another session": "Verify against another session", + "Verify with another session": "Verify with another session", "Verify this login to access your encrypted messages and prove to others that this login is really you.": "Verify this login to access your encrypted messages and prove to others that this login is really you.", "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.", "Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.", From b3cd6fcc9bf11d5070dd5697ee8756dc6bde34f2 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 17:59:02 +0000 Subject: [PATCH 13/18] vertically align labels in AccessibleButtons if their height is pushed out by wrapped text elsewhere --- res/css/views/elements/_AccessibleButton.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss index 9c26f8f120..b115130c8f 100644 --- a/res/css/views/elements/_AccessibleButton.scss +++ b/res/css/views/elements/_AccessibleButton.scss @@ -26,7 +26,8 @@ limitations under the License. padding: 7px 18px; text-align: center; border-radius: 8px; - display: inline-block; + display: flex; + align-items: center; font-size: $font-14px; } From 9d99b2f239e1bb6c7179239aa0729bbac122f987 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 17:59:10 +0000 Subject: [PATCH 14/18] remove errand whitespace --- src/stores/SetupEncryptionStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index fdabfa8019..2ed778b294 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -49,7 +49,6 @@ export class SetupEncryptionStore extends EventEmitter { cli.on("crypto.verification.request", this.onVerificationRequest); cli.on('userTrustStatusChanged', this._onUserTrustStatusChanged); - const requestsInProgress = cli.getVerificationRequestsToDeviceInProgress(cli.getUserId()); if (requestsInProgress.length) { // If there are multiple, we take the most recent. Equally if the user sends another request from From c543f0a2d0d7178e6c7efb271315c674b443fb28 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 22:29:08 +0000 Subject: [PATCH 15/18] fix AccessibleButton label positioning now they can wrap --- res/css/views/elements/_AccessibleButton.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss index b115130c8f..e13f765e63 100644 --- a/res/css/views/elements/_AccessibleButton.scss +++ b/res/css/views/elements/_AccessibleButton.scss @@ -28,6 +28,7 @@ limitations under the License. border-radius: 8px; display: flex; align-items: center; + justify-content: center; font-size: $font-14px; } From d388f877b463cdc16dfb5e4cb0e649502871af81 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 23:28:44 +0000 Subject: [PATCH 16/18] add PHASE_LOADING to SetupEncryptionStore to avoid flashing cross-signing setup --- src/components/structures/auth/CompleteSecurity.js | 5 ++++- .../structures/auth/SetupEncryptionBody.js | 3 ++- src/stores/SetupEncryptionStore.js | 13 +++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/structures/auth/CompleteSecurity.js b/src/components/structures/auth/CompleteSecurity.js index c73691611d..b18776e0ea 100644 --- a/src/components/structures/auth/CompleteSecurity.js +++ b/src/components/structures/auth/CompleteSecurity.js @@ -20,6 +20,7 @@ import { _t } from '../../../languageHandler'; import * as sdk from '../../../index'; import { SetupEncryptionStore, + PHASE_LOADING, PHASE_INTRO, PHASE_BUSY, PHASE_DONE, @@ -58,7 +59,9 @@ export default class CompleteSecurity extends React.Component { let icon; let title; - if (phase === PHASE_INTRO) { + if (phase === PHASE_LOADING) { + return null; + } else if (phase === PHASE_INTRO) { icon = ; title = _t("Verify this login"); } else if (phase === PHASE_DONE) { diff --git a/src/components/structures/auth/SetupEncryptionBody.js b/src/components/structures/auth/SetupEncryptionBody.js index 431762cade..32f0f41024 100644 --- a/src/components/structures/auth/SetupEncryptionBody.js +++ b/src/components/structures/auth/SetupEncryptionBody.js @@ -23,6 +23,7 @@ import VerificationRequestDialog from '../../views/dialogs/VerificationRequestDi import * as sdk from '../../../index'; import { SetupEncryptionStore, + PHASE_LOADING, PHASE_INTRO, PHASE_BUSY, PHASE_DONE, @@ -222,7 +223,7 @@ export default class SetupEncryptionBody extends React.Component {
); - } else if (phase === PHASE_BUSY) { + } else if (phase === PHASE_BUSY || phase === PHASE_LOADING) { const Spinner = sdk.getComponent('views.elements.Spinner'); return ; } else { diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 2ed778b294..28ab76edc0 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -19,11 +19,12 @@ import { MatrixClientPeg } from '../MatrixClientPeg'; import { accessSecretStorage, AccessCancelledError } from '../SecurityManager'; import { PHASE_DONE as VERIF_PHASE_DONE } from "matrix-js-sdk/src/crypto/verification/request/VerificationRequest"; -export const PHASE_INTRO = 0; -export const PHASE_BUSY = 1; -export const PHASE_DONE = 2; //final done stage, but still showing UX -export const PHASE_CONFIRM_SKIP = 3; -export const PHASE_FINISHED = 4; //UX can be closed +export const PHASE_LOADING = 0; +export const PHASE_INTRO = 1; +export const PHASE_BUSY = 2; +export const PHASE_DONE = 3; //final done stage, but still showing UX +export const PHASE_CONFIRM_SKIP = 4; +export const PHASE_FINISHED = 5; //UX can be closed export class SetupEncryptionStore extends EventEmitter { static sharedInstance() { @@ -36,7 +37,7 @@ export class SetupEncryptionStore extends EventEmitter { return; } this._started = true; - this.phase = PHASE_BUSY; + this.phase = PHASE_LOADING; this.verificationRequest = null; this.backupInfo = null; From 72f28240aa7fc274e70035af24ce908633fc1630 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Mon, 8 Mar 2021 23:28:54 +0000 Subject: [PATCH 17/18] fix AccessibleButton layout some more --- res/css/views/elements/_AccessibleButton.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/views/elements/_AccessibleButton.scss b/res/css/views/elements/_AccessibleButton.scss index e13f765e63..0075dcb511 100644 --- a/res/css/views/elements/_AccessibleButton.scss +++ b/res/css/views/elements/_AccessibleButton.scss @@ -26,7 +26,7 @@ limitations under the License. padding: 7px 18px; text-align: center; border-radius: 8px; - display: flex; + display: inline-flex; align-items: center; justify-content: center; font-size: $font-14px; From 41c87c757028ad00da4b4850374843d1661da00a Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Tue, 9 Mar 2021 13:35:42 +0000 Subject: [PATCH 18/18] remove obsolete comment --- src/stores/SetupEncryptionStore.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js index 28ab76edc0..3839f27a77 100644 --- a/src/stores/SetupEncryptionStore.js +++ b/src/stores/SetupEncryptionStore.js @@ -97,7 +97,6 @@ export class SetupEncryptionStore extends EventEmitter { if (!this.hasDevicesToVerifyAgainst && !this.keyInfo) { // skip before we can even render anything. - // XXX: this causes a dialog box flash this.phase = PHASE_FINISHED; } else { this.phase = PHASE_INTRO;