diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js
index 7cbad074bf..f21db12c51 100644
--- a/src/IdentityAuthClient.js
+++ b/src/IdentityAuthClient.js
@@ -17,7 +17,18 @@ limitations under the License.
import { createClient, SERVICE_TYPES } from 'matrix-js-sdk';
import MatrixClientPeg from './MatrixClientPeg';
+import Modal from './Modal';
+import sdk from './index';
+import { _t } from './languageHandler';
import { Service, startTermsFlow, TermsNotSignedError } from './Terms';
+import {
+ doesAccountDataHaveIdentityServer,
+ doesIdentityServerHaveTerms,
+ useDefaultIdentityServer,
+} from './utils/IdentityServerUtils';
+import { abbreviateUrl } from './utils/UrlUtils';
+
+export class AbortedIdentityActionError extends Error {}
export default class IdentityAuthClient {
/**
@@ -89,7 +100,10 @@ export default class IdentityAuthClient {
try {
await this._checkToken(token);
} catch (e) {
- if (e instanceof TermsNotSignedError) {
+ if (
+ e instanceof TermsNotSignedError ||
+ e instanceof AbortedIdentityActionError
+ ) {
// Retrying won't help this
throw e;
}
@@ -106,6 +120,8 @@ export default class IdentityAuthClient {
}
async _checkToken(token) {
+ const identityServerUrl = this._matrixClient.getIdentityServerUrl();
+
try {
await this._matrixClient.getIdentityAccount(token);
} catch (e) {
@@ -113,7 +129,7 @@ export default class IdentityAuthClient {
console.log("Identity Server requires new terms to be agreed to");
await startTermsFlow([new Service(
SERVICE_TYPES.IS,
- this._matrixClient.getIdentityServerUrl(),
+ identityServerUrl,
token,
)]);
return;
@@ -121,6 +137,42 @@ export default class IdentityAuthClient {
throw e;
}
+ if (
+ !this.tempClient &&
+ !doesAccountDataHaveIdentityServer() &&
+ !await doesIdentityServerHaveTerms(identityServerUrl)
+ ) {
+ const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
+ const { finished } = Modal.createTrackedDialog('Default identity server terms warning', '',
+ QuestionDialog, {
+ title: _t("Identity server has no terms of service"),
+ description: (
+
+
{_t(
+ "This action requires accessing the default identity server " +
+ " to validate an email address or phone number, " +
+ "but the server does not have any terms of service.", {},
+ {
+ server: () => {abbreviateUrl(identityServerUrl)},
+ },
+ )}
+
{_t(
+ "Only continue if you trust the owner of the server.",
+ )}
+
+ ),
+ button: _t("Trust"),
+ });
+ const [confirmed] = await finished;
+ if (confirmed) {
+ useDefaultIdentityServer();
+ } else {
+ throw new AbortedIdentityActionError(
+ "User aborted identity server action without terms",
+ );
+ }
+ }
+
// We should ensure the token in `localStorage` is cleared
// appropriately. We already clear storage on sign out, but we'll need
// additional clearing when changing ISes in settings as part of future
diff --git a/src/components/views/settings/SetIdServer.js b/src/components/views/settings/SetIdServer.js
index 7f4a50d391..126cdc9557 100644
--- a/src/components/views/settings/SetIdServer.js
+++ b/src/components/views/settings/SetIdServer.js
@@ -24,9 +24,8 @@ import Modal from '../../../Modal';
import dis from "../../../dispatcher";
import { getThreepidsWithBindStatus } from '../../../boundThreepids';
import IdentityAuthClient from "../../../IdentityAuthClient";
-import {SERVICE_TYPES} from "matrix-js-sdk";
import {abbreviateUrl, unabbreviateUrl} from "../../../utils/UrlUtils";
-import { getDefaultIdentityServerUrl } from '../../../utils/IdentityServerUtils';
+import { getDefaultIdentityServerUrl, doesIdentityServerHaveTerms } from '../../../utils/IdentityServerUtils';
// We'll wait up to this long when checking for 3PID bindings on the IS.
const REACHABILITY_TIMEOUT = 10000; // ms
@@ -162,19 +161,8 @@ export default class SetIdServer extends React.Component {
let save = true;
// Double check that the identity server even has terms of service.
- let terms;
- try {
- terms = await MatrixClientPeg.get().getTerms(SERVICE_TYPES.IS, fullUrl);
- } catch (e) {
- console.error(e);
- if (e.cors === "rejected" || e.httpStatus === 404) {
- terms = null;
- } else {
- throw e;
- }
- }
-
- if (!terms || !terms["policies"] || Object.keys(terms["policies"]).length <= 0) {
+ const hasTerms = await doesIdentityServerHaveTerms(fullUrl);
+ if (!hasTerms) {
const [confirmed] = await this._showNoTermsWarning(fullUrl);
save = confirmed;
}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 524a8a1abf..d6b7eb60a3 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -99,6 +99,10 @@
"Failed to invite users to %(groupId)s": "Failed to invite users to %(groupId)s",
"Failed to add the following rooms to %(groupId)s:": "Failed to add the following rooms to %(groupId)s:",
"Unnamed Room": "Unnamed Room",
+ "Identity server has no terms of service": "Identity server has no terms of service",
+ "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "This action requires accessing the default identity server to validate an email address or phone number, but the server 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.",
+ "Trust": "Trust",
"Error": "Error",
"Unable to load! Check your network connectivity and try again.": "Unable to load! Check your network connectivity and try again.",
"Dismiss": "Dismiss",
@@ -563,9 +567,7 @@
"Change identity server": "Change identity server",
"Disconnect from the identity server and connect to instead?": "Disconnect from the identity server and connect to instead?",
"Terms of service not accepted or the identity server is invalid.": "Terms of service not accepted or the identity server is invalid.",
- "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.",
- "Only continue if you trust the owner of the server.": "Only continue if you trust the owner of the server.",
"Disconnect identity server": "Disconnect identity server",
"Disconnect from the identity server ?": "Disconnect from the identity server ?",
"Disconnect": "Disconnect",
diff --git a/src/utils/IdentityServerUtils.js b/src/utils/IdentityServerUtils.js
index 883bd52149..cf180e3026 100644
--- a/src/utils/IdentityServerUtils.js
+++ b/src/utils/IdentityServerUtils.js
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
+import { SERVICE_TYPES } from 'matrix-js-sdk';
import SdkConfig from '../SdkConfig';
import MatrixClientPeg from '../MatrixClientPeg';
@@ -28,3 +29,24 @@ export function useDefaultIdentityServer() {
base_url: url,
});
}
+
+export async function doesIdentityServerHaveTerms(fullUrl) {
+ let terms;
+ try {
+ terms = await MatrixClientPeg.get().getTerms(SERVICE_TYPES.IS, fullUrl);
+ } catch (e) {
+ console.error(e);
+ if (e.cors === "rejected" || e.httpStatus === 404) {
+ terms = null;
+ } else {
+ throw e;
+ }
+ }
+
+ return terms && terms["policies"] && (Object.keys(terms["policies"]).length > 0);
+}
+
+export function doesAccountDataHaveIdentityServer() {
+ const event = MatrixClientPeg.get().getAccountData("m.identity_server");
+ return event && event.getContent() && event.getContent()['base_url'];
+}