Skip to content

Commit

Permalink
Merge pull request #3314 from matrix-org/dbkr/warn_if_bound_threepids
Browse files Browse the repository at this point in the history
Warn on disconnecting from IS
  • Loading branch information
dbkr committed Aug 16, 2019
2 parents ded2297 + 7d96cc9 commit cde1944
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 71 deletions.
52 changes: 52 additions & 0 deletions src/boundThreepids.js
@@ -0,0 +1,52 @@
/*
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import IdentityAuthClient from './IdentityAuthClient';

export async function getThreepidBindStatus(client, filterMedium) {
const userId = client.getUserId();

let { threepids } = await client.getThreePids();
if (filterMedium) {
threepids = threepids.filter((a) => a.medium === filterMedium);
}

if (threepids.length > 0) {
// TODO: Handle terms agreement
// See https://github.com/vector-im/riot-web/issues/10522
const authClient = new IdentityAuthClient();
const identityAccessToken = await authClient.getAccessToken();

// Restructure for lookup query
const query = threepids.map(({ medium, address }) => [medium, address]);
const lookupResults = await client.bulkLookupThreePids(query, identityAccessToken);

// Record which are already bound
for (const [medium, address, mxid] of lookupResults.threepids) {
if (mxid !== userId) {
continue;
}
if (filterMedium && medium !== filterMedium) {
continue;
}
const threepid = threepids.find(e => e.medium === medium && e.address === address);
if (!threepid) continue;
threepid.bound = true;
}
}

return threepids;
}
66 changes: 47 additions & 19 deletions src/components/views/settings/SetIdServer.js
Expand Up @@ -22,6 +22,7 @@ import MatrixClientPeg from "../../../MatrixClientPeg";
import SdkConfig from "../../../SdkConfig";
import Modal from '../../../Modal';
import dis from "../../../dispatcher";
import { getThreepidBindStatus } from '../../../boundThreepids';

/**
* If a url has no path component, etc. abbreviate it to just the hostname
Expand Down Expand Up @@ -98,6 +99,7 @@ export default class SetIdServer extends React.Component {
idServer: defaultIdServer,
error: null,
busy: false,
disconnectBusy: false,
};
}

Expand Down Expand Up @@ -150,24 +152,45 @@ export default class SetIdServer extends React.Component {
});
};

_onDisconnectClicked = () => {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('Identity Server Disconnect Warning', '', QuestionDialog, {
title: _t("Disconnect Identity Server"),
description:
<div>
{_t(
"Disconnect from the identity server <idserver />?", {},
{idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>},
)},
</div>,
button: _t("Disconnect"),
onFinished: (confirmed) => {
if (confirmed) {
this._disconnectIdServer();
}
},
});
_onDisconnectClicked = async () => {
this.setState({disconnectBusy: true});
try {
const threepids = await getThreepidBindStatus(MatrixClientPeg.get());

const boundThreepids = threepids.filter(tp => tp.bound);
let message;
if (boundThreepids.length) {
message = _t(
"You are currently sharing email addresses or phone numbers on the identity " +
"server <idserver />. You will need to reconnect to <idserver2 /> to stop " +
"sharing them.", {},
{
idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>,
// XXX: https://github.com/vector-im/riot-web/issues/9086
idserver2: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>,
},
);
} else {
message = _t(
"Disconnect from the identity server <idserver />?", {},
{idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>},
);
}

const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
Modal.createTrackedDialog('Identity Server Disconnect Warning', '', QuestionDialog, {
title: _t("Disconnect Identity Server"),
description: message,
button: _t("Disconnect"),
onFinished: (confirmed) => {
if (confirmed) {
this._disconnectIdServer();
}
},
});
} finally {
this.setState({disconnectBusy: false});
}
};

_disconnectIdServer = () => {
Expand Down Expand Up @@ -215,14 +238,19 @@ export default class SetIdServer extends React.Component {

let discoSection;
if (idServerUrl) {
let discoButtonContent = _t("Disconnect");
if (this.state.disconnectBusy) {
const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
discoButtonContent = <InlineSpinner />;
}
discoSection = <div>
<span className="mx_SettingsTab_subsectionText">{_t(
"Disconnecting from your identity server will mean you " +
"won't be discoverable by other users and you won't be " +
"able to invite others by email or phone.",
)}</span>
<AccessibleButton onClick={this._onDisconnectClicked} kind="danger">
{_t("Disconnect")}
{discoButtonContent}
</AccessibleButton>
</div>;
}
Expand Down
29 changes: 3 additions & 26 deletions src/components/views/settings/discovery/EmailAddresses.js
Expand Up @@ -22,8 +22,8 @@ import { _t } from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import sdk from '../../../../index';
import Modal from '../../../../Modal';
import IdentityAuthClient from '../../../../IdentityAuthClient';
import AddThreepid from '../../../../AddThreepid';
import { getThreepidBindStatus } from '../../../../boundThreepids';

/*
TODO: Improve the UX for everything in here.
Expand Down Expand Up @@ -198,31 +198,8 @@ export default class EmailAddresses extends React.Component {

async componentWillMount() {
const client = MatrixClientPeg.get();
const userId = client.getUserId();

const { threepids } = await client.getThreePids();
const emails = threepids.filter((a) => a.medium === 'email');

if (emails.length > 0) {
// TODO: Handle terms agreement
// See https://github.com/vector-im/riot-web/issues/10522
const authClient = new IdentityAuthClient();
const identityAccessToken = await authClient.getAccessToken();

// Restructure for lookup query
const query = emails.map(({ medium, address }) => [medium, address]);
const lookupResults = await client.bulkLookupThreePids(query, identityAccessToken);

// Record which are already bound
for (const [medium, address, mxid] of lookupResults.threepids) {
if (medium !== "email" || mxid !== userId) {
continue;
}
const email = emails.find(e => e.address === address);
if (!email) continue;
email.bound = true;
}
}

const emails = await getThreepidBindStatus(client, 'email');

this.setState({ emails });
}
Expand Down
27 changes: 2 additions & 25 deletions src/components/views/settings/discovery/PhoneNumbers.js
Expand Up @@ -22,8 +22,8 @@ import { _t } from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg";
import sdk from '../../../../index';
import Modal from '../../../../Modal';
import IdentityAuthClient from '../../../../IdentityAuthClient';
import AddThreepid from '../../../../AddThreepid';
import { getThreepidBindStatus } from '../../../../boundThreepids';

/*
TODO: Improve the UX for everything in here.
Expand Down Expand Up @@ -217,31 +217,8 @@ export default class PhoneNumbers extends React.Component {

async componentWillMount() {
const client = MatrixClientPeg.get();
const userId = client.getUserId();

const { threepids } = await client.getThreePids();
const msisdns = threepids.filter((a) => a.medium === 'msisdn');

if (msisdns.length > 0) {
// TODO: Handle terms agreement
// See https://github.com/vector-im/riot-web/issues/10522
const authClient = new IdentityAuthClient();
const identityAccessToken = await authClient.getAccessToken();

// Restructure for lookup query
const query = msisdns.map(({ medium, address }) => [medium, address]);
const lookupResults = await client.bulkLookupThreePids(query, identityAccessToken);

// Record which are already bound
for (const [medium, address, mxid] of lookupResults.threepids) {
if (medium !== "msisdn" || mxid !== userId) {
continue;
}
const msisdn = msisdns.find(e => e.address === address);
if (!msisdn) continue;
msisdn.bound = true;
}
}
const msisdns = await getThreepidBindStatus(client, 'msisdn');

this.setState({ msisdns });
}
Expand Down
3 changes: 2 additions & 1 deletion src/i18n/strings/en_EN.json
Expand Up @@ -548,8 +548,9 @@
"Not a valid Identity Server (status code %(code)s)": "Not a valid Identity Server (status code %(code)s)",
"Could not connect to Identity Server": "Could not connect to Identity Server",
"Checking server": "Checking server",
"Disconnect Identity Server": "Disconnect Identity Server",
"You are currently sharing email addresses or phone numbers on the identity server <idserver />. You will need to reconnect to <idserver2 /> to stop sharing them.": "You are currently sharing email addresses or phone numbers on the identity server <idserver />. You will need to reconnect to <idserver2 /> to stop sharing them.",
"Disconnect from the identity server <idserver />?": "Disconnect from the identity server <idserver />?",
"Disconnect Identity Server": "Disconnect Identity Server",
"Disconnect": "Disconnect",
"Identity Server (%(server)s)": "Identity Server (%(server)s)",
"You are currently using <server></server> to discover and be discoverable by existing contacts you know. You can change your identity server below.": "You are currently using <server></server> to discover and be discoverable by existing contacts you know. You can change your identity server below.",
Expand Down

0 comments on commit cde1944

Please sign in to comment.