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

Simplify email registration #3101

Merged
merged 2 commits into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 88 additions & 20 deletions src/components/structures/auth/Registration.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
import * as ServerType from '../../views/auth/ServerTypeSelector';
import AutoDiscoveryUtils, {ValidatedServerConfig} from "../../../utils/AutoDiscoveryUtils";
import classNames from "classnames";
import * as Lifecycle from '../../../Lifecycle';

// Phases
// Show controls to configure server details
Expand Down Expand Up @@ -80,6 +81,9 @@ module.exports = React.createClass({
// Phase of the overall registration dialog.
phase: PHASE_REGISTRATION,
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 also track the server dead errors independently of the regular errors so
Expand Down Expand Up @@ -209,6 +213,7 @@ module.exports = React.createClass({
errorText: _t("Registration has been disabled on this homeserver."),
});
} else {
console.log("Unable to query for supported registration methods.", e);
this.setState({
errorText: _t("Unable to query for supported registration methods."),
});
Expand Down Expand Up @@ -282,21 +287,27 @@ module.exports = React.createClass({
return;
}

this.setState({
// we're still busy until we get unmounted: don't show the registration form again
busy: true,
const newState = {
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({
userId: response.user_id,
deviceId: response.device_id,
homeserverUrl: this.state.matrixClient.getHomeserverUrl(),
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(),
accessToken: response.access_token,
});
this._setupPushers(cli);
// we're still busy until we get unmounted: don't show the registration form again
newState.busy = true;
} else {
newState.busy = false;
newState.completedNoSignin = true;
}

this._setupPushers(cli);
this.setState(newState);
},

_setupPushers: function(matrixClient) {
Expand Down Expand Up @@ -352,14 +363,25 @@ module.exports = React.createClass({
});
},

_makeRegisterRequest: function(auth) {
_makeRegisterRequest: function(auth, inhibitLogin) {
// default is to inhibit login if we're trying to register with an email address
// We do this so that the client that gets spawned when clicking on the email
// verification link doesn't get logged in (it can't choose different params
// because it doesn't have the password and it can only supply a complete
// set of parameters). If the original client is still around when the
// registration completes, it can resubmit with inhibitLogin=false to
// log itself in!
if (inhibitLogin === undefined) inhibitLogin = Boolean(this.state.formVals.email);

// 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
// session).
const bindThreepids = this.state.formVals.password ? {
email: true,
msisdn: true,
} : {};
// Likewise inhibitLogin
if (!this.state.formVals.password) inhibitLogin = null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the render method, I guess this means the client that was opened from the e-mail. If so, could you clarify in the comment above? Also, I thought that if you also had to click "Log in" in the browser that was opened from the e-mail? Probably misunderstanding something ...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, sorry - this was from when I was going to put a button in the original client to re-submit the request, which we've now decided not to do.


return this.state.matrixClient.register(
this.state.formVals.username,
Expand All @@ -368,6 +390,7 @@ module.exports = React.createClass({
auth,
bindThreepids,
null,
inhibitLogin,
);
},

Expand All @@ -379,6 +402,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() {
const ServerTypeSelector = sdk.getComponent("auth.ServerTypeSelector");
const ServerConfig = sdk.getComponent("auth.ServerConfig");
Expand Down Expand Up @@ -528,17 +564,49 @@ module.exports = React.createClass({
</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 (
<AuthPage>
<AuthHeader />
<AuthBody>
<h2>{ _t('Create your account') }</h2>
{ errorText }
{ serverDeadSection }
{ this.renderServerComponent() }
{ this.renderRegisterComponent() }
{ goBack }
{ signIn }
{ body }
</AuthBody>
</AuthPage>
);
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1557,6 +1557,9 @@
"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.",
"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",
"Commands": "Commands",
"Results from DuckDuckGo": "Results from DuckDuckGo",
Expand Down