Merge pull request #3101 from matrix-org/dbkr/simplify_email_reg

Simplify email registration
This commit is contained in:
David Baker 2019-06-13 18:22:30 +01:00 committed by GitHub
commit 446b20c454
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 87 additions and 19 deletions

View file

@ -28,6 +28,7 @@ import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
import * as ServerType from '../../views/auth/ServerTypeSelector'; import * as ServerType from '../../views/auth/ServerTypeSelector';
import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils"; import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
import classNames from "classnames"; import classNames from "classnames";
import * as Lifecycle from '../../../Lifecycle';
// Phases // Phases
// Show controls to configure server details // Show controls to configure server details
@ -80,6 +81,9 @@ module.exports = React.createClass({
// Phase of the overall registration dialog. // Phase of the overall registration dialog.
phase: PHASE_REGISTRATION, phase: PHASE_REGISTRATION,
flows: null, flows: null,
// If set, we've registered but are not going to log
// the user in to their new account automatically.
completedNoSignin: false,
// We perform liveliness checks later, but for now suppress the errors. // We perform liveliness checks later, but for now suppress the errors.
// We also track the server dead errors independently of the regular errors so // We also track the server dead errors independently of the regular errors so
@ -209,6 +213,7 @@ module.exports = React.createClass({
errorText: _t("Registration has been disabled on this homeserver."), errorText: _t("Registration has been disabled on this homeserver."),
}); });
} else { } else {
console.log("Unable to query for supported registration methods.", e);
this.setState({ this.setState({
errorText: _t("Unable to query for supported registration methods."), errorText: _t("Unable to query for supported registration methods."),
}); });
@ -282,21 +287,27 @@ module.exports = React.createClass({
return; return;
} }
this.setState({ const newState = {
// we're still busy until we get unmounted: don't show the registration form again
busy: true,
doingUIAuth: false, doingUIAuth: false,
}); };
if (response.access_token) {
const cli = await this.props.onLoggedIn({
userId: response.user_id,
deviceId: response.device_id,
homeserverUrl: this.state.matrixClient.getHomeserverUrl(),
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(),
accessToken: response.access_token,
});
const cli = await this.props.onLoggedIn({ this._setupPushers(cli);
userId: response.user_id, // we're still busy until we get unmounted: don't show the registration form again
deviceId: response.device_id, newState.busy = true;
homeserverUrl: this.state.matrixClient.getHomeserverUrl(), } else {
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(), newState.busy = false;
accessToken: response.access_token, newState.completedNoSignin = true;
}); }
this._setupPushers(cli); this.setState(newState);
}, },
_setupPushers: function(matrixClient) { _setupPushers: function(matrixClient) {
@ -353,6 +364,12 @@ module.exports = React.createClass({
}, },
_makeRegisterRequest: function(auth) { _makeRegisterRequest: function(auth) {
// We inhibit login if we're trying to register with an email address: this
// avoids a lot of complex race conditions that can occur if we try to log
// the user in one one or both of the tabs they might end up with after
// clicking the email link.
let inhibitLogin = Boolean(this.state.formVals.email);
// Only send the bind params if we're sending username / pw params // Only send the bind params if we're sending username / pw params
// (Since we need to send no params at all to use the ones saved in the // (Since we need to send no params at all to use the ones saved in the
// session). // session).
@ -360,6 +377,8 @@ module.exports = React.createClass({
email: true, email: true,
msisdn: true, msisdn: true,
} : {}; } : {};
// Likewise inhibitLogin
if (!this.state.formVals.password) inhibitLogin = null;
return this.state.matrixClient.register( return this.state.matrixClient.register(
this.state.formVals.username, this.state.formVals.username,
@ -368,6 +387,7 @@ module.exports = React.createClass({
auth, auth,
bindThreepids, bindThreepids,
null, null,
inhibitLogin,
); );
}, },
@ -379,6 +399,19 @@ module.exports = React.createClass({
}; };
}, },
// Links to the login page shown after registration is completed are routed through this
// which checks the user hasn't already logged in somewhere else (perhaps we should do
// this more generally?)
_onLoginClickWithCheck: async function(ev) {
ev.preventDefault();
const sessionLoaded = await Lifecycle.loadSession({});
if (!sessionLoaded) {
// ok fine, there's still no session: really go to the login page
this.props.onLoginClick();
}
},
renderServerComponent() { renderServerComponent() {
const ServerTypeSelector = sdk.getComponent("auth.ServerTypeSelector"); const ServerTypeSelector = sdk.getComponent("auth.ServerTypeSelector");
const ServerConfig = sdk.getComponent("auth.ServerConfig"); const ServerConfig = sdk.getComponent("auth.ServerConfig");
@ -528,17 +561,49 @@ module.exports = React.createClass({
</a>; </a>;
} }
let body;
if (this.state.completedNoSignin) {
let regDoneText;
if (this.state.formVals.password) {
// We're the client that started the registration
regDoneText = _t(
"<a>Log in</a> to your new account.", {},
{
a: (sub) => <a href="#/login" onClick={this._onLoginClickWithCheck}>{sub}</a>,
},
);
} else {
// We're not the original client: the user probably got to us by clicking the
// email validation link. We can't offer a 'go straight to your account' link
// as we don't have the original creds.
regDoneText = _t(
"You can now close this window or <a>log in</a> to your new account.", {},
{
a: (sub) => <a href="#/login" onClick={this._onLoginClickWithCheck}>{sub}</a>,
},
);
}
body = <div>
<h2>{_t("Registration Successful")}</h2>
<h3>{ regDoneText }</h3>
</div>;
} else {
body = <div>
<h2>{ _t('Create your account') }</h2>
{ errorText }
{ serverDeadSection }
{ this.renderServerComponent() }
{ this.renderRegisterComponent() }
{ goBack }
{ signIn }
</div>;
}
return ( return (
<AuthPage> <AuthPage>
<AuthHeader /> <AuthHeader />
<AuthBody> <AuthBody>
<h2>{ _t('Create your account') }</h2> { body }
{ errorText }
{ serverDeadSection }
{ this.renderServerComponent() }
{ this.renderRegisterComponent() }
{ goBack }
{ signIn }
</AuthBody> </AuthBody>
</AuthPage> </AuthPage>
); );

View file

@ -1557,6 +1557,9 @@
"Registration has been disabled on this homeserver.": "Registration has been disabled on this homeserver.", "Registration has been disabled on this homeserver.": "Registration has been disabled on this homeserver.",
"Unable to query for supported registration methods.": "Unable to query for supported registration methods.", "Unable to query for supported registration methods.": "Unable to query for supported registration methods.",
"This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.", "This server does not support authentication with a phone number.": "This server does not support authentication with a phone number.",
"<a>Log in</a> to your new account.": "<a>Log in</a> to your new account.",
"You can now close this window or <a>log in</a> to your new account.": "You can now close this window or <a>log in</a> to your new account.",
"Registration Successful": "Registration Successful",
"Create your account": "Create your account", "Create your account": "Create your account",
"Commands": "Commands", "Commands": "Commands",
"Results from DuckDuckGo": "Results from DuckDuckGo", "Results from DuckDuckGo": "Results from DuckDuckGo",