Aggregate device verification toasts into one toast
'Review' now opens the only place we can verify our own devices: our user info.pull/21833/head
parent
698a539866
commit
e5d06b1acb
|
@ -20,12 +20,9 @@ import * as sdk from './index';
|
|||
import { _t } from './languageHandler';
|
||||
import ToastStore from './stores/ToastStore';
|
||||
|
||||
function toastKey(deviceId) {
|
||||
return 'unverified_session_' + deviceId;
|
||||
}
|
||||
|
||||
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
|
||||
const THIS_DEVICE_TOAST_KEY = 'setupencryption';
|
||||
const OTHER_DEVICES_TOAST_KEY = 'reviewsessions';
|
||||
|
||||
export default class DeviceListener {
|
||||
static sharedInstance() {
|
||||
|
@ -34,8 +31,6 @@ export default class DeviceListener {
|
|||
}
|
||||
|
||||
constructor() {
|
||||
// set of device IDs we're currently showing toasts for
|
||||
this._activeNagToasts = new Set();
|
||||
// device IDs for which the user has dismissed the verify toast ('Later')
|
||||
this._dismissed = new Set();
|
||||
// has the user dismissed any of the various nag toasts to setup encryption on this device?
|
||||
|
@ -71,8 +66,11 @@ export default class DeviceListener {
|
|||
this._keyBackupFetchedAt = null;
|
||||
}
|
||||
|
||||
dismissVerification(deviceId) {
|
||||
this._dismissed.add(deviceId);
|
||||
async dismissVerifications() {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const devices = await cli.getStoredDevicesForUser(cli.getUserId());
|
||||
this._dismissed = new Set(devices.filter(d => d.deviceId !== cli.deviceId).map(d => d.deviceId));
|
||||
|
||||
this._recheck();
|
||||
}
|
||||
|
||||
|
@ -202,33 +200,28 @@ export default class DeviceListener {
|
|||
// as long as cross-signing isn't ready,
|
||||
// you can't see or dismiss any device toasts
|
||||
if (crossSigningReady) {
|
||||
const newActiveToasts = new Set();
|
||||
const unverifiedDeviceIds = new Set();
|
||||
|
||||
const devices = await cli.getStoredDevicesForUser(cli.getUserId());
|
||||
for (const device of devices) {
|
||||
if (device.deviceId == cli.deviceId) continue;
|
||||
|
||||
const deviceTrust = await cli.checkDeviceTrust(cli.getUserId(), device.deviceId);
|
||||
if (deviceTrust.isCrossSigningVerified() || this._dismissed.has(device.deviceId)) {
|
||||
ToastStore.sharedInstance().dismissToast(toastKey(device.deviceId));
|
||||
} else {
|
||||
this._activeNagToasts.add(device.deviceId);
|
||||
ToastStore.sharedInstance().addOrReplaceToast({
|
||||
key: toastKey(device.deviceId),
|
||||
title: _t("Unverified login. Was this you?"),
|
||||
icon: "verification_warning",
|
||||
props: { device },
|
||||
component: sdk.getComponent("toasts.UnverifiedSessionToast"),
|
||||
});
|
||||
newActiveToasts.add(device.deviceId);
|
||||
if (!deviceTrust.isCrossSigningVerified() && !this._dismissed.has(device.deviceId)) {
|
||||
unverifiedDeviceIds.add(device.deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
// clear any other outstanding toasts (eg. logged out devices)
|
||||
for (const deviceId of this._activeNagToasts) {
|
||||
if (!newActiveToasts.has(deviceId)) ToastStore.sharedInstance().dismissToast(toastKey(deviceId));
|
||||
if (unverifiedDeviceIds.size > 0) {
|
||||
ToastStore.sharedInstance().addOrReplaceToast({
|
||||
key: OTHER_DEVICES_TOAST_KEY,
|
||||
title: _t("Review where you’re logged in"),
|
||||
icon: "verification_warning",
|
||||
component: sdk.getComponent("toasts.UnverifiedSessionToast"),
|
||||
});
|
||||
} else {
|
||||
ToastStore.sharedInstance().dismissToast(OTHER_DEVICES_TOAST_KEY);
|
||||
}
|
||||
this._activeNagToasts = newActiveToasts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { _t } from '../../../languageHandler';
|
||||
import Modal from "../../../Modal";
|
||||
import dis from "../../../dispatcher";
|
||||
import { MatrixClientPeg } from '../../../MatrixClientPeg';
|
||||
import DeviceListener from '../../../DeviceListener';
|
||||
import NewSessionReviewDialog from '../dialogs/NewSessionReviewDialog';
|
||||
|
@ -26,29 +27,17 @@ import { replaceableComponent } from '../../../utils/replaceableComponent';
|
|||
|
||||
@replaceableComponent("views.toasts.UnverifiedSessionToast")
|
||||
export default class UnverifiedSessionToast extends React.PureComponent {
|
||||
static propTypes = {
|
||||
toastKey: PropTypes.string.isRequired,
|
||||
device: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
_onLaterClick = () => {
|
||||
const { device } = this.props;
|
||||
DeviceListener.sharedInstance().dismissVerification(device.deviceId);
|
||||
DeviceListener.sharedInstance().dismissVerifications();
|
||||
};
|
||||
|
||||
_onReviewClick = async () => {
|
||||
const { device } = this.props;
|
||||
DeviceListener.sharedInstance().dismissVerifications();
|
||||
|
||||
Modal.createTrackedDialog('New Session Review', 'Starting dialog', NewSessionReviewDialog, {
|
||||
dis.dispatch({
|
||||
action: 'view_user_info',
|
||||
userId: MatrixClientPeg.get().getUserId(),
|
||||
device,
|
||||
onFinished: (r) => {
|
||||
if (!r) {
|
||||
/* This'll come back false if the user clicks "this wasn't me" and saw a warning dialog */
|
||||
this._onLaterClick();
|
||||
}
|
||||
},
|
||||
}, null, /* priority = */ false, /* static = */ true);
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -56,11 +45,7 @@ export default class UnverifiedSessionToast extends React.PureComponent {
|
|||
|
||||
return (<div>
|
||||
<div className="mx_Toast_description">
|
||||
<span className="mx_Toast_deviceName">
|
||||
{device.getDisplayName()}
|
||||
</span> <span className="mx_Toast_deviceID">
|
||||
({device.deviceId})
|
||||
</span>
|
||||
{_t("Verify your other sessions")}
|
||||
</div>
|
||||
<div className="mx_Toast_buttons" aria-live="off">
|
||||
<FormButton label={_t("Later")} kind="danger" onClick={this._onLaterClick} />
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
"Verify this session": "Verify this session",
|
||||
"Encryption upgrade available": "Encryption upgrade available",
|
||||
"Set up encryption": "Set up encryption",
|
||||
"Unverified login. Was this you?": "Unverified login. Was this you?",
|
||||
"Review where you’re logged in": "Review where you’re logged in",
|
||||
"Who would you like to add to this community?": "Who would you like to add to this community?",
|
||||
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID",
|
||||
"Invite new community members": "Invite new community members",
|
||||
|
@ -562,6 +562,7 @@
|
|||
"Upgrade": "Upgrade",
|
||||
"Verify": "Verify",
|
||||
"Later": "Later",
|
||||
"Verify your other sessions": "Verify your other sessions",
|
||||
"Review": "Review",
|
||||
"From %(deviceName)s (%(deviceId)s)": "From %(deviceName)s (%(deviceId)s)",
|
||||
"Decline (%(counter)s)": "Decline (%(counter)s)",
|
||||
|
|
Loading…
Reference in New Issue