Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Introduce a default_server_name for aesthetics and rework .well-known
Browse files Browse the repository at this point in the history
Fixes element-hq/element-web#7724

The `default_server_name` from the config gets displayed in the "Login with my [server] matrix ID" dropdown when the default server is being used. At this point, we also discourage the use of the `default_hs_url` and `default_is_url` options because we do an implicit .well-known lookup to configure the client based on the `default_server_name`. If the URLs are still present in the config, we'll honour them and won't do a .well-known lookup when the URLs are mixed with the new server_name option. Users will be warned if the `default_server_name` does not match the `default_hs_url` if both are supplied. Users are additionally prevented from logging in, registering, and resetting their password if the implicit .well-known check fails - this is to prevent people from doing actions against the wrong homeserver.

This relies on matrix-org/matrix-js-sdk#799 as we now do auto discovery in two places. Instead of bringing the .well-known out to its own utility class in the react-sdk, we might as well drag it out to the js-sdk.
  • Loading branch information
turt2live committed Dec 5, 2018
1 parent c0ef2f7 commit 633be50
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 118 deletions.
7 changes: 7 additions & 0 deletions res/css/structures/login/_Login.scss
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ limitations under the License.
margin-bottom: 12px;
}

.mx_Login_subtext {
display: block;
font-size: 0.8em;
text-align: center;
margin: 10px;
}

.mx_Login_type_container {
display: flex;
margin-bottom: 14px;
Expand Down
46 changes: 43 additions & 3 deletions src/components/structures/MatrixChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
import { startAnyRegistrationFlow } from "../../Registration.js";
import { messageForSyncError } from '../../utils/ErrorUtils';

const AutoDiscovery = Matrix.AutoDiscovery;

// Disable warnings for now: we use deprecated bluebird functions
// and need to migrate, but they spam the console with warnings.
Promise.config({warnings: false});
Expand Down Expand Up @@ -181,6 +183,12 @@ export default React.createClass({
register_is_url: null,
register_id_sid: null,

// Parameters used for setting up the login/registration views
defaultServerName: this.props.config.default_server_name,
defaultHsUrl: this.props.config.default_hs_url,
defaultIsUrl: this.props.config.default_is_url,
defaultServerDiscoveryError: null,

// When showing Modal dialogs we need to set aria-hidden on the root app element
// and disable it when there are no dialogs
hideToSRUsers: false,
Expand All @@ -199,6 +207,10 @@ export default React.createClass({
};
},

getDefaultServerName: function() {
return this.state.defaultServerName;
},

getCurrentHsUrl: function() {
if (this.state.register_hs_url) {
return this.state.register_hs_url;
Expand All @@ -211,8 +223,10 @@ export default React.createClass({
}
},

getDefaultHsUrl() {
return this.props.config.default_hs_url || "https://matrix.org";
getDefaultHsUrl(defaultToMatrixDotOrg) {
defaultToMatrixDotOrg = typeof(defaultToMatrixDotOrg) !== 'boolean' ? true : defaultToMatrixDotOrg;
if (!this.state.defaultHsUrl && defaultToMatrixDotOrg) return "https://matrix.org";
return this.state.defaultHsUrl;
},

getFallbackHsUrl: function() {
Expand All @@ -232,7 +246,7 @@ export default React.createClass({
},

getDefaultIsUrl() {
return this.props.config.default_is_url || "https://vector.im";
return this.state.defaultIsUrl || "https://vector.im";
},

componentWillMount: function() {
Expand Down Expand Up @@ -282,6 +296,11 @@ export default React.createClass({
console.info(`Team token set to ${this._teamToken}`);
}

// Set up the default URLs (async)
if (this.getDefaultServerName() && !this.getDefaultHsUrl(false)) {
this._tryDiscoverDefaultHomeserver(this.getDefaultServerName());
}

// Set a default HS with query param `hs_url`
const paramHs = this.props.startingFragmentQueryParams.hs_url;
if (paramHs) {
Expand Down Expand Up @@ -1732,6 +1751,21 @@ export default React.createClass({
this.setState(newState);
},

_tryDiscoverDefaultHomeserver: async function(serverName) {
const discovery = await AutoDiscovery.findClientConfig(serverName);
const state = discovery["m.homeserver"].state;
if (state !== AutoDiscovery.SUCCESS) {
console.error("Failed to discover homeserver on startup:", discovery);
this.setState({defaultServerDiscoveryError: discovery["m.homeserver"].error});
} else {
const hsUrl = discovery["m.homeserver"].base_url;
const isUrl = discovery["m.identity_server"].state === AutoDiscovery.SUCCESS
? discovery["m.identity_server"].base_url
: "https://vector.im";
this.setState({defaultHsUrl: hsUrl, defaultIsUrl: isUrl});
}
},

_makeRegistrationUrl: function(params) {
if (this.props.startingFragmentQueryParams.referrer) {
params.referrer = this.props.startingFragmentQueryParams.referrer;
Expand Down Expand Up @@ -1820,6 +1854,8 @@ export default React.createClass({
idSid={this.state.register_id_sid}
email={this.props.startingFragmentQueryParams.email}
referrer={this.props.startingFragmentQueryParams.referrer}
defaultServerName={this.getDefaultServerName()}
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
defaultHsUrl={this.getDefaultHsUrl()}
defaultIsUrl={this.getDefaultIsUrl()}
brand={this.props.config.brand}
Expand All @@ -1842,6 +1878,8 @@ export default React.createClass({
const ForgotPassword = sdk.getComponent('structures.login.ForgotPassword');
return (
<ForgotPassword
defaultServerName={this.getDefaultServerName()}
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
defaultHsUrl={this.getDefaultHsUrl()}
defaultIsUrl={this.getDefaultIsUrl()}
customHsUrl={this.getCurrentHsUrl()}
Expand All @@ -1858,6 +1896,8 @@ export default React.createClass({
<Login
onLoggedIn={Lifecycle.setLoggedIn}
onRegisterClick={this.onRegisterClick}
defaultServerName={this.getDefaultServerName()}
defaultServerDiscoveryError={this.state.defaultServerDiscoveryError}
defaultHsUrl={this.getDefaultHsUrl()}
defaultIsUrl={this.getDefaultIsUrl()}
customHsUrl={this.getCurrentHsUrl()}
Expand Down
23 changes: 23 additions & 0 deletions src/components/structures/login/ForgotPassword.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ module.exports = React.createClass({
onLoginClick: PropTypes.func,
onRegisterClick: PropTypes.func,
onComplete: PropTypes.func.isRequired,

// The default server name to use when the user hasn't specified
// one. This is used when displaying the defaultHsUrl in the UI.
defaultServerName: PropTypes.string,

// An error passed along from higher up explaining that something
// went wrong when finding the defaultHsUrl.
defaultServerDiscoveryError: PropTypes.string,
},

getInitialState: function() {
Expand All @@ -45,6 +53,7 @@ module.exports = React.createClass({
progress: null,
password: null,
password2: null,
errorText: null,
};
},

Expand Down Expand Up @@ -81,6 +90,13 @@ module.exports = React.createClass({
onSubmitForm: function(ev) {
ev.preventDefault();

// Don't allow the user to register if there's a discovery error
// Without this, the user could end up registering on the wrong homeserver.
if (this.props.defaultServerDiscoveryError) {
this.setState({errorText: this.props.defaultServerDiscoveryError});
return;
}

if (!this.state.email) {
this.showErrorDialog(_t('The email address linked to your account must be entered.'));
} else if (!this.state.password || !this.state.password2) {
Expand Down Expand Up @@ -200,6 +216,12 @@ module.exports = React.createClass({
);
}

let errorText = null;
const err = this.state.errorText || this.props.defaultServerDiscoveryError;
if (err) {
errorText = <div className="mx_Login_error">{ err }</div>;
}

const LanguageSelector = sdk.getComponent('structures.login.LanguageSelector');

resetPasswordJsx = (
Expand Down Expand Up @@ -230,6 +252,7 @@ module.exports = React.createClass({
<input className="mx_Login_submit" type="submit" value={_t('Send Reset Email')} />
</form>
{ serverConfigSection }
{ errorText }
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
{ _t('Return to login screen') }
</a>
Expand Down
Loading

0 comments on commit 633be50

Please sign in to comment.