Merge remote-tracking branch 'origin/develop' into travis/terms/inline-is-only

This commit is contained in:
Travis Ralston 2019-08-16 09:41:00 -06:00
commit 2456912ec7
5 changed files with 105 additions and 70 deletions

52
src/boundThreepids.js Normal file
View file

@ -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;
}

View file

@ -22,6 +22,7 @@ import MatrixClientPeg from "../../../MatrixClientPeg";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import Modal from '../../../Modal'; import Modal from '../../../Modal';
import dis from "../../../dispatcher"; import dis from "../../../dispatcher";
import { getThreepidBindStatus } from '../../../boundThreepids';
import IdentityAuthClient from "../../../IdentityAuthClient"; import IdentityAuthClient from "../../../IdentityAuthClient";
import {SERVICE_TYPES} from "matrix-js-sdk"; import {SERVICE_TYPES} from "matrix-js-sdk";
@ -100,6 +101,7 @@ export default class SetIdServer extends React.Component {
idServer: defaultIdServer, idServer: defaultIdServer,
error: null, error: null,
busy: false, busy: false,
disconnectBusy: false,
checking: false, checking: false,
}; };
} }
@ -193,24 +195,45 @@ export default class SetIdServer extends React.Component {
}); });
}; };
_onDisconnectClicked = () => { _onDisconnectClicked = async () => {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); this.setState({disconnectBusy: true});
Modal.createTrackedDialog('Identity Server Disconnect Warning', '', QuestionDialog, { try {
title: _t("Disconnect Identity Server"), const threepids = await getThreepidBindStatus(MatrixClientPeg.get());
description:
<div> const boundThreepids = threepids.filter(tp => tp.bound);
{_t( let message;
"Disconnect from the identity server <idserver />?", {}, if (boundThreepids.length) {
{idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>}, message = _t(
)}, "You are currently sharing email addresses or phone numbers on the identity " +
</div>, "server <idserver />. You will need to reconnect to <idserver2 /> to stop " +
button: _t("Disconnect"), "sharing them.", {},
onFinished: (confirmed) => { {
if (confirmed) { idserver: sub => <b>{abbreviateUrl(this.state.currentClientIdServer)}</b>,
this._disconnectIdServer(); // 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 = () => { _disconnectIdServer = () => {
@ -258,6 +281,11 @@ export default class SetIdServer extends React.Component {
let discoSection; let discoSection;
if (idServerUrl) { if (idServerUrl) {
let discoButtonContent = _t("Disconnect");
if (this.state.disconnectBusy) {
const InlineSpinner = sdk.getComponent('views.elements.InlineSpinner');
discoButtonContent = <InlineSpinner />;
}
discoSection = <div> discoSection = <div>
<span className="mx_SettingsTab_subsectionText">{_t( <span className="mx_SettingsTab_subsectionText">{_t(
"Disconnecting from your identity server will mean you " + "Disconnecting from your identity server will mean you " +
@ -265,7 +293,7 @@ export default class SetIdServer extends React.Component {
"able to invite others by email or phone.", "able to invite others by email or phone.",
)}</span> )}</span>
<AccessibleButton onClick={this._onDisconnectClicked} kind="danger"> <AccessibleButton onClick={this._onDisconnectClicked} kind="danger">
{_t("Disconnect")} {discoButtonContent}
</AccessibleButton> </AccessibleButton>
</div>; </div>;
} }

View file

@ -22,8 +22,8 @@ import { _t } from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg"; import MatrixClientPeg from "../../../../MatrixClientPeg";
import sdk from '../../../../index'; import sdk from '../../../../index';
import Modal from '../../../../Modal'; import Modal from '../../../../Modal';
import IdentityAuthClient from '../../../../IdentityAuthClient';
import AddThreepid from '../../../../AddThreepid'; import AddThreepid from '../../../../AddThreepid';
import { getThreepidBindStatus } from '../../../../boundThreepids';
/* /*
TODO: Improve the UX for everything in here. TODO: Improve the UX for everything in here.
@ -198,31 +198,8 @@ export default class EmailAddresses extends React.Component {
async componentWillMount() { async componentWillMount() {
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
const userId = client.getUserId();
const { threepids } = await client.getThreePids(); const emails = await getThreepidBindStatus(client, 'email');
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;
}
}
this.setState({ emails }); this.setState({ emails });
} }

View file

@ -22,8 +22,8 @@ import { _t } from "../../../../languageHandler";
import MatrixClientPeg from "../../../../MatrixClientPeg"; import MatrixClientPeg from "../../../../MatrixClientPeg";
import sdk from '../../../../index'; import sdk from '../../../../index';
import Modal from '../../../../Modal'; import Modal from '../../../../Modal';
import IdentityAuthClient from '../../../../IdentityAuthClient';
import AddThreepid from '../../../../AddThreepid'; import AddThreepid from '../../../../AddThreepid';
import { getThreepidBindStatus } from '../../../../boundThreepids';
/* /*
TODO: Improve the UX for everything in here. TODO: Improve the UX for everything in here.
@ -217,31 +217,8 @@ export default class PhoneNumbers extends React.Component {
async componentWillMount() { async componentWillMount() {
const client = MatrixClientPeg.get(); const client = MatrixClientPeg.get();
const userId = client.getUserId();
const { threepids } = await client.getThreePids(); const msisdns = await getThreepidBindStatus(client, 'msisdn');
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;
}
}
this.setState({ msisdns }); this.setState({ msisdns });
} }

View file

@ -548,12 +548,13 @@
"Not a valid Identity Server (status code %(code)s)": "Not a valid Identity Server (status code %(code)s)", "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", "Could not connect to Identity Server": "Could not connect to Identity Server",
"Checking server": "Checking server", "Checking server": "Checking 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 />?",
"Identity server has no terms of service": "Identity server has no terms of service", "Identity server has no terms of service": "Identity server has no terms of service",
"The identity server you have chosen does not have any terms of service.": "The identity server you have chosen does not have any terms of service.", "The identity server you have chosen does not have any terms of service.": "The identity server you have chosen does not have any terms of service.",
"Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.", "Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.",
"Terms of service not accepted or the identity server is invalid.": "Terms of service not accepted or the identity server is invalid.", "Terms of service not accepted or the identity server is invalid.": "Terms of service not accepted or the identity server is invalid.",
"Disconnect Identity Server": "Disconnect Identity Server", "Disconnect Identity Server": "Disconnect Identity Server",
"Disconnect from the identity server <idserver />?": "Disconnect from the identity server <idserver />?",
"Disconnect": "Disconnect", "Disconnect": "Disconnect",
"Identity Server (%(server)s)": "Identity Server (%(server)s)", "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.", "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.",