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

Commit

Permalink
Merge pull request #200 from matrix-org/matthew/loginfixes
Browse files Browse the repository at this point in the history
Bring back lost functionality on login/register/password-reset screens
  • Loading branch information
ara4n committed Mar 15, 2016
2 parents 836f7ca + 59866a2 commit 672a5cb
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 86 deletions.
14 changes: 8 additions & 6 deletions src/MatrixClientPeg.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ var matrixClient = null;
var localStorage = window.localStorage;

function deviceId() {
// XXX: is Math.random()'s deterministicity a problem here?
var id = Math.floor(Math.random()*16777215).toString(16);
id = "W" + "000000".substring(id.length) + id;
if (localStorage) {
Expand All @@ -34,7 +35,7 @@ function deviceId() {
return id;
}

function createClient(hs_url, is_url, user_id, access_token, guestAccess) {
function createClientForPeg(hs_url, is_url, user_id, access_token, guestAccess) {
var opts = {
baseUrl: hs_url,
idBaseUrl: is_url,
Expand Down Expand Up @@ -68,7 +69,7 @@ if (localStorage) {
var guestAccess = new GuestAccess(localStorage);
if (access_token && user_id && hs_url) {
console.log("Restoring session for %s", user_id);
createClient(hs_url, is_url, user_id, access_token, guestAccess);
createClientForPeg(hs_url, is_url, user_id, access_token, guestAccess);
}
else {
console.log("Session not found.");
Expand All @@ -91,7 +92,7 @@ class MatrixClient {

// FIXME, XXX: this all seems very convoluted :(
//
// if we replace the singleton using URLs we bypass our createClient()
// if we replace the singleton using URLs we bypass our createClientForPeg()
// global helper function... but if we replace it using
// an access_token we don't?
//
Expand All @@ -105,6 +106,7 @@ class MatrixClient {
baseUrl: hs_url,
idBaseUrl: is_url
});

// XXX: factor this out with the localStorage setting in replaceUsingAccessToken
if (localStorage) {
try {
Expand All @@ -123,11 +125,11 @@ class MatrixClient {
try {
localStorage.clear();
} catch (e) {
console.warn("Error using local storage");
console.warn("Error clearing local storage", e);
}
}
this.guestAccess.markAsGuest(Boolean(isGuest));
createClient(hs_url, is_url, user_id, access_token, this.guestAccess);
createClientForPeg(hs_url, is_url, user_id, access_token, this.guestAccess);
if (localStorage) {
try {
localStorage.setItem("mx_hs_url", hs_url);
Expand All @@ -136,7 +138,7 @@ class MatrixClient {
localStorage.setItem("mx_access_token", access_token);
console.log("Session persisted for %s", user_id);
} catch (e) {
console.warn("Error using local storage: can't persist session!");
console.warn("Error using local storage: can't persist session!", e);
}
} else {
console.warn("No local storage available: can't persist session!");
Expand Down
75 changes: 57 additions & 18 deletions src/components/structures/MatrixChat.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,41 @@ module.exports = React.createClass({
};
},

getCurrentHsUrl: function() {
if (MatrixClientPeg.get()) {
return MatrixClientPeg.get().getHomeserverUrl();
}
else if (window.localStorage && window.localStorage.getItem("mx_hs_url")) {
return window.localStorage.getItem("mx_hs_url");
}
else if (this.props.config) {
return this.props.config.default_hs_url
}
return "https://matrix.org";
},

getCurrentIsUrl: function() {
if (MatrixClientPeg.get()) {
return MatrixClientPeg.get().getIdentityServerUrl();
}
else if (window.localStorage && window.localStorage.getItem("mx_is_url")) {
return window.localStorage.getItem("mx_is_url");
}
else if (this.props.config) {
return this.props.config.default_is_url
}
return "https://matrix.org";
},

componentWillMount: function() {
this.favicon = new Favico({animation: 'none'});
},

componentDidMount: function() {
this._autoRegisterAsGuest = false;
if (this.props.enableGuest) {
if (!this.props.config || !this.props.config.default_hs_url) {
console.error("Cannot enable guest access: No supplied config prop for HS/IS URLs");
if (!this.getCurrentHsUrl()) {
console.error("Cannot enable guest access: can't determine HS URL to use");
}
else if (this.props.startingQueryParams.client_secret && this.props.startingQueryParams.sid) {
console.log("Not registering as guest; registration.");
Expand Down Expand Up @@ -167,19 +193,19 @@ module.exports = React.createClass({

_registerAsGuest: function() {
var self = this;
var config = this.props.config;
console.log("Doing guest login on %s", config.default_hs_url);
MatrixClientPeg.replaceUsingUrls(
config.default_hs_url, config.default_is_url
);
console.log("Doing guest login on %s", this.getCurrentHsUrl());
var hsUrl = this.getCurrentHsUrl();
var isUrl = this.getCurrentIsUrl();

MatrixClientPeg.replaceUsingUrls(hsUrl, isUrl);
MatrixClientPeg.get().registerGuest().done(function(creds) {
console.log("Registered as guest: %s", creds.user_id);
self._setAutoRegisterAsGuest(false);
self.onLoggedIn({
userId: creds.user_id,
accessToken: creds.access_token,
homeserverUrl: config.default_hs_url,
identityServerUrl: config.default_is_url,
homeserverUrl: hsUrl,
identityServerUrl: isUrl,
guest: true
});
}, function(err) {
Expand All @@ -201,6 +227,9 @@ module.exports = React.createClass({
case 'logout':
if (window.localStorage) {
window.localStorage.clear();
// preserve our HS & IS URLs for convenience
window.localStorage.setItem("mx_hs_url", this.getCurrentHsUrl());
window.localStorage.setItem("mx_is_url", this.getCurrentIsUrl());
}
Notifier.stop();
UserActivity.stop();
Expand Down Expand Up @@ -744,7 +773,7 @@ module.exports = React.createClass({
}
}
else {
console.error("Unknown screen : %s", screen);
console.info("Ignoring showScreen for '%s'", screen);
}
},

Expand Down Expand Up @@ -908,6 +937,8 @@ module.exports = React.createClass({
var NewVersionBar = sdk.getComponent('globals.NewVersionBar');
var ForgotPassword = sdk.getComponent('structures.login.ForgotPassword');

// work out the HS URL prompts we should show for

// needs to be before normal PageTypes as you are logged in technically
if (this.state.screen == 'post_registration') {
return (
Expand Down Expand Up @@ -1004,26 +1035,34 @@ module.exports = React.createClass({
username={this.state.upgradeUsername}
disableUsernameChanges={Boolean(this.state.upgradeUsername)}
guestAccessToken={this.state.guestAccessToken}
hsUrl={this.props.config.default_hs_url}
isUrl={this.props.config.default_is_url}
defaultHsUrl={this.props.config.default_hs_url}
defaultIsUrl={this.props.config.default_is_url}
customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()}
registrationUrl={this.props.registrationUrl}
onLoggedIn={this.onRegistered}
onLoginClick={this.onLoginClick} />
onLoginClick={this.onLoginClick}
onRegisterClick={this.onRegisterClick} />
);
} else if (this.state.screen == 'forgot_password') {
return (
<ForgotPassword
homeserverUrl={this.props.config.default_hs_url}
identityServerUrl={this.props.config.default_is_url}
onComplete={this.onLoginClick} />
defaultHsUrl={this.props.config.default_hs_url}
defaultIsUrl={this.props.config.default_is_url}
customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()}
onComplete={this.onLoginClick}
onLoginClick={this.onLoginClick} />
);
} else {
return (
<Login
onLoggedIn={this.onLoggedIn}
onRegisterClick={this.onRegisterClick}
homeserverUrl={this.props.config.default_hs_url}
identityServerUrl={this.props.config.default_is_url}
defaultHsUrl={this.props.config.default_hs_url}
defaultIsUrl={this.props.config.default_is_url}
customHsUrl={this.getCurrentHsUrl()}
customIsUrl={this.getCurrentIsUrl()}
onForgotPasswordClick={this.onForgotPasswordClick}
onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest: undefined}
/>
Expand Down
27 changes: 21 additions & 6 deletions src/components/structures/login/ForgotPassword.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ module.exports = React.createClass({
displayName: 'ForgotPassword',

propTypes: {
homeserverUrl: React.PropTypes.string,
identityServerUrl: React.PropTypes.string,
defaultHsUrl: React.PropTypes.string,
defaultIsUrl: React.PropTypes.string,
customHsUrl: React.PropTypes.string,
customIsUrl: React.PropTypes.string,
onLoginClick: React.PropTypes.func,
onRegisterClick: React.PropTypes.func,
onComplete: React.PropTypes.func.isRequired
},

Expand Down Expand Up @@ -152,8 +156,9 @@ module.exports = React.createClass({
else {
resetPasswordJsx = (
<div>
To reset your password, enter the email address linked to your account:
<br />
<div className="mx_Login_prompt">
To reset your password, enter the email address linked to your account:
</div>
<div>
<form onSubmit={this.onSubmitForm}>
<input className="mx_Login_field" ref="user" type="text"
Expand All @@ -175,11 +180,21 @@ module.exports = React.createClass({
</form>
<ServerConfig ref="serverConfig"
withToggleButton={true}
defaultHsUrl={this.props.homeserverUrl}
defaultIsUrl={this.props.identityServerUrl}
defaultHsUrl={this.props.defaultHsUrl}
defaultIsUrl={this.props.defaultIsUrl}
customHsUrl={this.props.customHsUrl}
customIsUrl={this.props.customIsUrl}
onHsUrlChanged={this.onHsUrlChanged}
onIsUrlChanged={this.onIsUrlChanged}
delayTimeMs={0}/>
<div className="mx_Login_error">
</div>
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
Return to login
</a>
<a className="mx_Login_create" onClick={this.props.onRegisterClick} href="#">
Create a new account
</a>
<LoginFooter />
</div>
</div>
Expand Down
50 changes: 34 additions & 16 deletions src/components/structures/login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,29 @@ var ServerConfig = require("../../views/login/ServerConfig");
module.exports = React.createClass({displayName: 'Login',
propTypes: {
onLoggedIn: React.PropTypes.func.isRequired,
homeserverUrl: React.PropTypes.string,
identityServerUrl: React.PropTypes.string,

customHsUrl: React.PropTypes.string,
customIsUrl: React.PropTypes.string,
defaultHsUrl: React.PropTypes.string,
defaultIsUrl: React.PropTypes.string,

// login shouldn't know or care how registration is done.
onRegisterClick: React.PropTypes.func.isRequired,

// login shouldn't care how password recovery is done.
onForgotPasswordClick: React.PropTypes.func,
onLoginAsGuestClick: React.PropTypes.func,
},

getDefaultProps: function() {
return {
homeserverUrl: 'https://matrix.org/',
identityServerUrl: 'https://matrix.org'
};
},

getInitialState: function() {
return {
busy: false,
errorText: null,
enteredHomeserverUrl: this.props.homeserverUrl,
enteredIdentityServerUrl: this.props.identityServerUrl
enteredHomeserverUrl: this.props.customHsUrl || this.props.defaultHsUrl,
enteredIdentityServerUrl: this.props.customIsUrl || this.props.defaultIsUrl,

// used for preserving username when changing homeserver
username: "",
};
},

Expand All @@ -76,12 +77,26 @@ module.exports = React.createClass({displayName: 'Login',
});
},

onUsernameChanged: function(username) {
this.setState({ username: username });
},

onHsUrlChanged: function(newHsUrl) {
this._initLoginLogic(newHsUrl);
var self = this;
this.setState({
enteredHomeserverUrl: newHsUrl
}, function() {
self._initLoginLogic(newHsUrl);
});
},

onIsUrlChanged: function(newIsUrl) {
this._initLoginLogic(null, newIsUrl);
var self = this;
this.setState({
enteredIdentityServerUrl: newIsUrl
}, function() {
self._initLoginLogic(null, newIsUrl);
});
},

_initLoginLogic: function(hsUrl, isUrl) {
Expand Down Expand Up @@ -162,6 +177,8 @@ module.exports = React.createClass({displayName: 'Login',
return (
<PasswordLogin
onSubmit={this.onPasswordLogin}
initialUsername={this.state.username}
onUsernameChanged={this.onUsernameChanged}
onForgotPasswordClick={this.props.onForgotPasswordClick} />
);
case 'm.login.cas':
Expand Down Expand Up @@ -203,8 +220,10 @@ module.exports = React.createClass({displayName: 'Login',
{ this.componentForStep(this._getCurrentFlowStep()) }
<ServerConfig ref="serverConfig"
withToggleButton={true}
defaultHsUrl={this.props.homeserverUrl}
defaultIsUrl={this.props.identityServerUrl}
customHsUrl={this.props.customHsUrl}
customIsUrl={this.props.customIsUrl}
defaultHsUrl={this.props.defaultHsUrl}
defaultIsUrl={this.props.defaultIsUrl}
onHsUrlChanged={this.onHsUrlChanged}
onIsUrlChanged={this.onIsUrlChanged}
delayTimeMs={1000}/>
Expand All @@ -216,7 +235,6 @@ module.exports = React.createClass({displayName: 'Login',
Create a new account
</a>
{ loginAsGuestJsx }
<br/>
<LoginFooter />
</div>
</div>
Expand Down
Loading

0 comments on commit 672a5cb

Please sign in to comment.