diff --git a/README.md b/README.md index 3fea9815..29c9d84e 100644 --- a/README.md +++ b/README.md @@ -109,25 +109,31 @@ You can configure the app by copying `config.sample.json` to For a good example, see https://riot.im/develop/config.json. -1. `default_server_name` sets the default server name to use for authentication. - This will trigger Riot to ask - `https:///.well-known/matrix/client` for the homeserver and - identity server URLs to use. This is the recommended approach for setting a - default server. However, it is also possible to use the following to directly - configure each of the URLs: - * `default_hs_url` sets the default homeserver URL. - * `default_is_url` sets the default identity server URL (this is the server used - for verifying third party identifiers like email addresses). If this is blank, - registering with an email address, adding an email address to your account, - or inviting users via email address will not work. Matrix identity servers are - very simple web services which map third party identifiers (currently only email - addresses) to matrix IDs: see http://matrix.org/docs/spec/identity_service/unstable.html - for more details. Currently the only public matrix identity servers are https://matrix.org - and https://vector.im. In the future, identity servers will be decentralised. - * Riot will report an error if you accidentally configure both `default_server_name` _and_ `default_hs_url` since it's unclear which should take priority. +1. `default_server_config` sets the default homeserver and identity server URL for + Riot to use. The object is the same as returned by [https:///.well-known/matrix/client](https://matrix.org/docs/spec/client_server/latest.html#get-well-known-matrix-client), + with added support for a `server_name` under the `m.homeserver` section to display + a custom homeserver name. Alternatively, the config can contain a `default_server_name` + instead which is where Riot will go to get that same object - see the `.well-known` + link above for more information. Note that the `default_server_name` is used to get + a complete server configuration whereas the `server_name` in the `default_server_config` + is for display purposes only. + * *Note*: The URLs can also be individually specified as `default_hs_url` and + `default_is_url`, however these are deprecated. They are maintained for backwards + compatibility with older configurations. `default_is_url` is respected only + if `default_hs_url` is used. + * The identity server is used for verifying third party identifiers like emails + and phone numbers. It is not used to store your password or account information. + If not provided, the identity server defaults to vector.im unless `disable_identity_server` + is set to true in the config. Currently the only two public identity servers + are https://matrix.org and https://vector.im, however in future identity servers + will be decentralised. + * Riot will fail to load if a mix of `default_server_config`, `default_server_name`, or + `default_hs_url` is specified. When multiple sources are specified, it is unclear + which should take priority and therefore the application cannot continue. 1. `features`: Lookup of optional features that may be `enable`d, `disable`d, or exposed to the user in the `labs` section of settings. The available optional experimental features vary from - release to release. + release to release. Some of the available features are described in the Labs Feature section + of this README. 1. `brand`: String to pass to your homeserver when configuring email notifications, to let the homeserver know what email template to use when talking to you. 1. `branding`: Configures various branding and logo details, such as: diff --git a/config.sample.json b/config.sample.json index c80c46fb..beb9c9f0 100644 --- a/config.sample.json +++ b/config.sample.json @@ -1,6 +1,14 @@ { - "default_hs_url": "https://matrix.org", - "default_is_url": "https://vector.im", + "default_server_config": { + "m.homeserver": { + "base_url": "https://matrix.org", + "server_name": "matrix.org" + }, + "m.identity_server": { + "base_url": "https://vector.im" + } + }, + "disable_identity_server": false, "disable_custom_urls": false, "disable_guests": false, "disable_login_language_selector": false, diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9c467cfc..10e57592 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1,4 +1,7 @@ { + "Unexpected error preparing the app. See console for details.": "Unexpected error preparing the app. See console for details.", + "Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.", + "Invalid configuration: no default server specified.": "Invalid configuration: no default server specified.", "Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s", "Unknown device": "Unknown device", "%(appName)s via %(browserName)s on %(osName)s": "%(appName)s via %(browserName)s on %(osName)s", @@ -15,7 +18,5 @@ "Need help?": "Need help?", "Chat with Riot Bot": "Chat with Riot Bot", "Explore rooms": "Explore rooms", - "Room Directory": "Room Directory", - "Search the room directory": "Search the room directory", - "Get started with some tips from Riot Bot!": "Get started with some tips from Riot Bot!" + "Room Directory": "Room Directory" } diff --git a/src/vector/index.js b/src/vector/index.js index 9d5c1dd4..98ba2edf 100644 --- a/src/vector/index.js +++ b/src/vector/index.js @@ -1,7 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd -Copyright 2018 New Vector Ltd +Copyright 2018, 2019 New Vector Ltd Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -45,6 +45,9 @@ import VectorConferenceHandler from 'matrix-react-sdk/lib/VectorConferenceHandle import Promise from 'bluebird'; import request from 'browser-request'; import * as languageHandler from 'matrix-react-sdk/lib/languageHandler'; +import {_t, _td, newTranslatableError} from 'matrix-react-sdk/lib/languageHandler'; +import AutoDiscoveryUtils from 'matrix-react-sdk/lib/utils/AutoDiscoveryUtils'; +import {AutoDiscovery} from "matrix-js-sdk/lib/autodiscovery"; import url from 'url'; @@ -341,22 +344,37 @@ async function loadApp() { const platform = PlatformPeg.get(); platform.startUpdater(); - const MatrixChat = sdk.getComponent('structures.MatrixChat'); - window.matrixChat = ReactDOM.render( - , - document.getElementById('matrixchat'), - ); + // Don't bother loading the app until the config is verified + verifyServerConfig().then((newConfig) => { + const MatrixChat = sdk.getComponent('structures.MatrixChat'); + window.matrixChat = ReactDOM.render( + , + document.getElementById('matrixchat'), + ); + }).catch(err => { + console.error(err); + + const errorMessage = err.translatedMessage + || _t("Unexpected error preparing the app. See console for details."); + + // Like the compatibility page, AWOOOOOGA at the user + const GenericErrorPage = sdk.getComponent("structures.GenericErrorPage"); + window.matrixChat = ReactDOM.render( + , + document.getElementById('matrixchat'), + ); + }); } else { console.error("Browser is missing required features."); // take to a different landing page to AWOOOOOGA at the user @@ -428,4 +446,68 @@ async function loadLanguage() { } } +async function verifyServerConfig() { + console.log("Verifying homeserver configuration"); + + // Note: the query string may include is_url and hs_url - we only respect these in the + // context of email validation. Because we don't respect them otherwise, we do not need + // to parse or consider them here. + + const config = SdkConfig.get(); + let wkConfig = config['default_server_config']; // overwritten later under some conditions + const serverName = config['default_server_name']; + const hsUrl = config['default_hs_url']; + const isUrl = config['default_is_url']; + + const incompatibleOptions = [wkConfig, serverName, hsUrl].filter(i => !!i); + if (incompatibleOptions.length > 1) { + throw newTranslatableError(_td( + "Invalid configuration: can only specify one of default_server_config, default_server_name, " + + "or default_hs_url.", + )); + } + if (incompatibleOptions.length < 1) { + throw newTranslatableError(_td("Invalid configuration: no default server specified.")); + } + + if (hsUrl) { + console.log("Config uses a default_hs_url - constructing a default_server_config using this information"); + + wkConfig = { + "m.homeserver": { + "base_url": hsUrl, + }, + }; + if (isUrl) { + wkConfig["m.identity_server"] = { + "base_url": isUrl, + }; + } + } + + let result = null; + + if (wkConfig) { + console.log("Config uses a default_server_config - validating object"); + result = await AutoDiscovery.fromDiscoveryConfig(wkConfig); + } + + if (serverName) { + console.log("Config uses a default_server_name - doing .well-known lookup"); + result = await AutoDiscovery.findClientConfig(serverName); + } + + const validatedConfig = AutoDiscoveryUtils.buildValidatedConfigFromDiscovery(serverName, result); + validatedConfig.isDefault = true; + + // Just in case we ever have to debug this + console.log("Using homeserver config:", validatedConfig); + + // Add the newly built config to the actual config for use by the app + console.log("Updating SdkConfig with validated discovery information"); + SdkConfig.add({"validated_server_config": validatedConfig}); + + return SdkConfig.get(); +} + loadApp(); diff --git a/src/vector/mobile_guide/index.html b/src/vector/mobile_guide/index.html index b2b14df3..dc14c979 100644 --- a/src/vector/mobile_guide/index.html +++ b/src/vector/mobile_guide/index.html @@ -4,6 +4,11 @@