mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 11:47:23 +03:00
brings back the functionality in login/register/screens that got lost in @kegsay's refactor. specifically:
1) custom HS/IS urls are now persisted in HTML5 local storage. As a result, all the login components now distinguish between default HS/IS URLs and custom specified ones again. ( 2) custom HS/IS urls are synchronised between the instances of ServerConfig found in the Login, Registration and Forgot Password screens. 3) username are persisted over changing homeserver (but not password, to stop accidentally leaking passwords to the wrong server) 4) correctly interpret a blank URL field as meaning the placeholder text 5) when toggling custom URLs on and off, remember what the custom values were, and use the default URLs if custom mode is not engaged also, guest access now upholds custom HS/IS URLs found in local storage rather than being limited to the server config () also adds assorted comments and improved console debug and a few minor cosmetic changes to the login components. this commit sponsored by VS27...
This commit is contained in:
parent
b66ca74ede
commit
0bb58dd60c
8 changed files with 177 additions and 75 deletions
|
@ -25,6 +25,7 @@ var matrixClient = null;
|
||||||
var localStorage = window.localStorage;
|
var localStorage = window.localStorage;
|
||||||
|
|
||||||
function deviceId() {
|
function deviceId() {
|
||||||
|
// XXX: is Math.random()'s deterministicity a problem here?
|
||||||
var id = Math.floor(Math.random()*16777215).toString(16);
|
var id = Math.floor(Math.random()*16777215).toString(16);
|
||||||
id = "W" + "000000".substring(id.length) + id;
|
id = "W" + "000000".substring(id.length) + id;
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
|
@ -101,10 +102,12 @@ class MatrixClient {
|
||||||
// -matthew
|
// -matthew
|
||||||
|
|
||||||
replaceUsingUrls(hs_url, is_url) {
|
replaceUsingUrls(hs_url, is_url) {
|
||||||
|
// ...not to be confused with MatrixClientPeg's createClient...
|
||||||
matrixClient = Matrix.createClient({
|
matrixClient = Matrix.createClient({
|
||||||
baseUrl: hs_url,
|
baseUrl: hs_url,
|
||||||
idBaseUrl: is_url
|
idBaseUrl: is_url
|
||||||
});
|
});
|
||||||
|
|
||||||
// XXX: factor this out with the localStorage setting in replaceUsingAccessToken
|
// XXX: factor this out with the localStorage setting in replaceUsingAccessToken
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
try {
|
try {
|
||||||
|
@ -123,10 +126,11 @@ class MatrixClient {
|
||||||
try {
|
try {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Error using local storage");
|
console.warn("Error clearing local storage", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.guestAccess.markAsGuest(Boolean(isGuest));
|
this.guestAccess.markAsGuest(Boolean(isGuest));
|
||||||
|
// ...not to be confused with Matrix.createClient()...
|
||||||
createClient(hs_url, is_url, user_id, access_token, this.guestAccess);
|
createClient(hs_url, is_url, user_id, access_token, this.guestAccess);
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
try {
|
try {
|
||||||
|
@ -136,7 +140,7 @@ class MatrixClient {
|
||||||
localStorage.setItem("mx_access_token", access_token);
|
localStorage.setItem("mx_access_token", access_token);
|
||||||
console.log("Session persisted for %s", user_id);
|
console.log("Session persisted for %s", user_id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("Error using local storage: can't persist session!");
|
console.warn("Error using local storage: can't persist session!", e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.warn("No local storage available: can't persist session!");
|
console.warn("No local storage available: can't persist session!");
|
||||||
|
|
|
@ -85,6 +85,32 @@ 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() {
|
componentWillMount: function() {
|
||||||
this.favicon = new Favico({animation: 'none'});
|
this.favicon = new Favico({animation: 'none'});
|
||||||
},
|
},
|
||||||
|
@ -92,8 +118,8 @@ module.exports = React.createClass({
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
this._autoRegisterAsGuest = false;
|
this._autoRegisterAsGuest = false;
|
||||||
if (this.props.enableGuest) {
|
if (this.props.enableGuest) {
|
||||||
if (!this.props.config || !this.props.config.default_hs_url) {
|
if (!this.getCurrentHsUrl() || !this.getCurrentIsUrl()) {
|
||||||
console.error("Cannot enable guest access: No supplied config prop for HS/IS URLs");
|
console.error("Cannot enable guest access: can't determine HS/IS URLs to use");
|
||||||
}
|
}
|
||||||
else if (this.props.startingQueryParams.client_secret && this.props.startingQueryParams.sid) {
|
else if (this.props.startingQueryParams.client_secret && this.props.startingQueryParams.sid) {
|
||||||
console.log("Not registering as guest; registration.");
|
console.log("Not registering as guest; registration.");
|
||||||
|
@ -155,10 +181,10 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
_registerAsGuest: function() {
|
_registerAsGuest: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var config = this.props.config;
|
console.log("Doing guest login on %s", this.getCurrentHsUrl());
|
||||||
console.log("Doing guest login on %s", config.default_hs_url);
|
|
||||||
MatrixClientPeg.replaceUsingUrls(
|
MatrixClientPeg.replaceUsingUrls(
|
||||||
config.default_hs_url, config.default_is_url
|
this.getCurrentHsUrl(),
|
||||||
|
this.getCurrentIsUrl()
|
||||||
);
|
);
|
||||||
MatrixClientPeg.get().registerGuest().done(function(creds) {
|
MatrixClientPeg.get().registerGuest().done(function(creds) {
|
||||||
console.log("Registered as guest: %s", creds.user_id);
|
console.log("Registered as guest: %s", creds.user_id);
|
||||||
|
@ -166,8 +192,8 @@ module.exports = React.createClass({
|
||||||
self.onLoggedIn({
|
self.onLoggedIn({
|
||||||
userId: creds.user_id,
|
userId: creds.user_id,
|
||||||
accessToken: creds.access_token,
|
accessToken: creds.access_token,
|
||||||
homeserverUrl: config.default_hs_url,
|
homeserverUrl: self.getCurrentHsUrl(),
|
||||||
identityServerUrl: config.default_is_url,
|
identityServerUrl: self.getCurrentIsUrl(),
|
||||||
guest: true
|
guest: true
|
||||||
});
|
});
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
|
@ -188,7 +214,12 @@ module.exports = React.createClass({
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
case 'logout':
|
case 'logout':
|
||||||
if (window.localStorage) {
|
if (window.localStorage) {
|
||||||
|
// preserve our HS & IS URLs for convenience
|
||||||
|
var hsUrl = this.getCurrentHsUrl();
|
||||||
|
var isUrl = this.getCurrentIsUrl();
|
||||||
window.localStorage.clear();
|
window.localStorage.clear();
|
||||||
|
window.localStorage.setItem("mx_hs_url", hsUrl);
|
||||||
|
window.localStorage.setItem("mx_is_url", isUrl);
|
||||||
}
|
}
|
||||||
Notifier.stop();
|
Notifier.stop();
|
||||||
UserActivity.stop();
|
UserActivity.stop();
|
||||||
|
@ -711,7 +742,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
console.error("Unknown screen : %s", screen);
|
console.info("Ignoring showScreen for '%s'", screen);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -875,6 +906,8 @@ module.exports = React.createClass({
|
||||||
var NewVersionBar = sdk.getComponent('globals.NewVersionBar');
|
var NewVersionBar = sdk.getComponent('globals.NewVersionBar');
|
||||||
var ForgotPassword = sdk.getComponent('structures.login.ForgotPassword');
|
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
|
// needs to be before normal PageTypes as you are logged in technically
|
||||||
if (this.state.screen == 'post_registration') {
|
if (this.state.screen == 'post_registration') {
|
||||||
return (
|
return (
|
||||||
|
@ -970,26 +1003,34 @@ module.exports = React.createClass({
|
||||||
username={this.state.upgradeUsername}
|
username={this.state.upgradeUsername}
|
||||||
disableUsernameChanges={Boolean(this.state.upgradeUsername)}
|
disableUsernameChanges={Boolean(this.state.upgradeUsername)}
|
||||||
guestAccessToken={this.state.guestAccessToken}
|
guestAccessToken={this.state.guestAccessToken}
|
||||||
hsUrl={this.props.config.default_hs_url}
|
defaultHsUrl={this.props.config.default_hs_url}
|
||||||
isUrl={this.props.config.default_is_url}
|
defaultIsUrl={this.props.config.default_is_url}
|
||||||
|
initialHsUrl={this.getCurrentHsUrl()}
|
||||||
|
initialIsUrl={this.getCurrentIsUrl()}
|
||||||
registrationUrl={this.props.registrationUrl}
|
registrationUrl={this.props.registrationUrl}
|
||||||
onLoggedIn={this.onRegistered}
|
onLoggedIn={this.onRegistered}
|
||||||
onLoginClick={this.onLoginClick} />
|
onLoginClick={this.onLoginClick}
|
||||||
|
onRegisterClick={this.onRegisterClick} />
|
||||||
);
|
);
|
||||||
} else if (this.state.screen == 'forgot_password') {
|
} else if (this.state.screen == 'forgot_password') {
|
||||||
return (
|
return (
|
||||||
<ForgotPassword
|
<ForgotPassword
|
||||||
homeserverUrl={this.props.config.default_hs_url}
|
defaultHsUrl={this.props.config.default_hs_url}
|
||||||
identityServerUrl={this.props.config.default_is_url}
|
defaultIsUrl={this.props.config.default_is_url}
|
||||||
onComplete={this.onLoginClick} />
|
initialHsUrl={this.getCurrentHsUrl()}
|
||||||
|
initialIsUrl={this.getCurrentIsUrl()}
|
||||||
|
onComplete={this.onLoginClick}
|
||||||
|
onLoginClick={this.onLoginClick} />
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Login
|
<Login
|
||||||
onLoggedIn={this.onLoggedIn}
|
onLoggedIn={this.onLoggedIn}
|
||||||
onRegisterClick={this.onRegisterClick}
|
onRegisterClick={this.onRegisterClick}
|
||||||
homeserverUrl={this.props.config.default_hs_url}
|
defaultHsUrl={this.props.config.default_hs_url}
|
||||||
identityServerUrl={this.props.config.default_is_url}
|
defaultIsUrl={this.props.config.default_is_url}
|
||||||
|
initialHsUrl={this.getCurrentHsUrl()}
|
||||||
|
initialIsUrl={this.getCurrentIsUrl()}
|
||||||
onForgotPasswordClick={this.onForgotPasswordClick}
|
onForgotPasswordClick={this.onForgotPasswordClick}
|
||||||
onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest: undefined}
|
onLoginAsGuestClick={this.props.enableGuest && this.props.config && this.props.config.default_hs_url ? this._registerAsGuest: undefined}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -27,8 +27,12 @@ module.exports = React.createClass({
|
||||||
displayName: 'ForgotPassword',
|
displayName: 'ForgotPassword',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
homeserverUrl: React.PropTypes.string,
|
defaultHsUrl: React.PropTypes.string,
|
||||||
identityServerUrl: React.PropTypes.string,
|
defaultIsUrl: React.PropTypes.string,
|
||||||
|
initialHsUrl: React.PropTypes.string,
|
||||||
|
initialIsUrl: React.PropTypes.string,
|
||||||
|
onLoginClick: React.PropTypes.func,
|
||||||
|
onRegisterClick: React.PropTypes.func,
|
||||||
onComplete: React.PropTypes.func.isRequired
|
onComplete: React.PropTypes.func.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -152,8 +156,9 @@ module.exports = React.createClass({
|
||||||
else {
|
else {
|
||||||
resetPasswordJsx = (
|
resetPasswordJsx = (
|
||||||
<div>
|
<div>
|
||||||
|
<div className="mx_Login_prompt">
|
||||||
To reset your password, enter the email address linked to your account:
|
To reset your password, enter the email address linked to your account:
|
||||||
<br />
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<form onSubmit={this.onSubmitForm}>
|
<form onSubmit={this.onSubmitForm}>
|
||||||
<input className="mx_Login_field" ref="user" type="text"
|
<input className="mx_Login_field" ref="user" type="text"
|
||||||
|
@ -175,11 +180,21 @@ module.exports = React.createClass({
|
||||||
</form>
|
</form>
|
||||||
<ServerConfig ref="serverConfig"
|
<ServerConfig ref="serverConfig"
|
||||||
withToggleButton={true}
|
withToggleButton={true}
|
||||||
defaultHsUrl={this.props.homeserverUrl}
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
defaultIsUrl={this.props.identityServerUrl}
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
|
initialHsUrl={this.props.initialHsUrl}
|
||||||
|
initialIsUrl={this.props.initialIsUrl}
|
||||||
onHsUrlChanged={this.onHsUrlChanged}
|
onHsUrlChanged={this.onHsUrlChanged}
|
||||||
onIsUrlChanged={this.onIsUrlChanged}
|
onIsUrlChanged={this.onIsUrlChanged}
|
||||||
delayTimeMs={0}/>
|
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 />
|
<LoginFooter />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -30,28 +30,29 @@ var ServerConfig = require("../../views/login/ServerConfig");
|
||||||
module.exports = React.createClass({displayName: 'Login',
|
module.exports = React.createClass({displayName: 'Login',
|
||||||
propTypes: {
|
propTypes: {
|
||||||
onLoggedIn: React.PropTypes.func.isRequired,
|
onLoggedIn: React.PropTypes.func.isRequired,
|
||||||
homeserverUrl: React.PropTypes.string,
|
|
||||||
identityServerUrl: React.PropTypes.string,
|
initialHsUrl: React.PropTypes.string,
|
||||||
|
initialIsUrl: React.PropTypes.string,
|
||||||
|
defaultHsUrl: React.PropTypes.string,
|
||||||
|
defaultIsUrl: React.PropTypes.string,
|
||||||
|
|
||||||
// login shouldn't know or care how registration is done.
|
// login shouldn't know or care how registration is done.
|
||||||
onRegisterClick: React.PropTypes.func.isRequired,
|
onRegisterClick: React.PropTypes.func.isRequired,
|
||||||
|
|
||||||
// login shouldn't care how password recovery is done.
|
// login shouldn't care how password recovery is done.
|
||||||
onForgotPasswordClick: React.PropTypes.func,
|
onForgotPasswordClick: React.PropTypes.func,
|
||||||
onLoginAsGuestClick: React.PropTypes.func,
|
onLoginAsGuestClick: React.PropTypes.func,
|
||||||
},
|
},
|
||||||
|
|
||||||
getDefaultProps: function() {
|
|
||||||
return {
|
|
||||||
homeserverUrl: 'https://matrix.org/',
|
|
||||||
identityServerUrl: 'https://matrix.org'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
busy: false,
|
busy: false,
|
||||||
errorText: null,
|
errorText: null,
|
||||||
enteredHomeserverUrl: this.props.homeserverUrl,
|
enteredHomeserverUrl: this.props.initialHsUrl || this.props.defaultHsUrl,
|
||||||
enteredIdentityServerUrl: this.props.identityServerUrl
|
enteredIdentityServerUrl: this.props.initialIsUrl || this.props.defaultIsUrl,
|
||||||
|
|
||||||
|
// used for preserving username when changing homeserver
|
||||||
|
username: "",
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -76,12 +77,26 @@ module.exports = React.createClass({displayName: 'Login',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onUsernameChanged: function(username) {
|
||||||
|
this.setState({ username: username });
|
||||||
|
},
|
||||||
|
|
||||||
onHsUrlChanged: function(newHsUrl) {
|
onHsUrlChanged: function(newHsUrl) {
|
||||||
this._initLoginLogic(newHsUrl);
|
var self = this;
|
||||||
|
this.setState({
|
||||||
|
enteredHomeserverUrl: newHsUrl
|
||||||
|
}, function() {
|
||||||
|
self._initLoginLogic(newHsUrl);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onIsUrlChanged: function(newIsUrl) {
|
onIsUrlChanged: function(newIsUrl) {
|
||||||
this._initLoginLogic(null, newIsUrl);
|
var self = this;
|
||||||
|
this.setState({
|
||||||
|
enteredIdentityServerUrl: newIsUrl
|
||||||
|
}, function() {
|
||||||
|
self._initLoginLogic(null, newIsUrl);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_initLoginLogic: function(hsUrl, isUrl) {
|
_initLoginLogic: function(hsUrl, isUrl) {
|
||||||
|
@ -162,6 +177,8 @@ module.exports = React.createClass({displayName: 'Login',
|
||||||
return (
|
return (
|
||||||
<PasswordLogin
|
<PasswordLogin
|
||||||
onSubmit={this.onPasswordLogin}
|
onSubmit={this.onPasswordLogin}
|
||||||
|
initialUsername={this.state.username}
|
||||||
|
onUsernameChanged={this.onUsernameChanged}
|
||||||
onForgotPasswordClick={this.props.onForgotPasswordClick} />
|
onForgotPasswordClick={this.props.onForgotPasswordClick} />
|
||||||
);
|
);
|
||||||
case 'm.login.cas':
|
case 'm.login.cas':
|
||||||
|
@ -203,8 +220,10 @@ module.exports = React.createClass({displayName: 'Login',
|
||||||
{ this.componentForStep(this._getCurrentFlowStep()) }
|
{ this.componentForStep(this._getCurrentFlowStep()) }
|
||||||
<ServerConfig ref="serverConfig"
|
<ServerConfig ref="serverConfig"
|
||||||
withToggleButton={true}
|
withToggleButton={true}
|
||||||
defaultHsUrl={this.props.homeserverUrl}
|
initialHsUrl={this.props.initialHsUrl}
|
||||||
defaultIsUrl={this.props.identityServerUrl}
|
initialIsUrl={this.props.initialIsUrl}
|
||||||
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
onHsUrlChanged={this.onHsUrlChanged}
|
onHsUrlChanged={this.onHsUrlChanged}
|
||||||
onIsUrlChanged={this.onIsUrlChanged}
|
onIsUrlChanged={this.onIsUrlChanged}
|
||||||
delayTimeMs={1000}/>
|
delayTimeMs={1000}/>
|
||||||
|
@ -216,7 +235,6 @@ module.exports = React.createClass({displayName: 'Login',
|
||||||
Create a new account
|
Create a new account
|
||||||
</a>
|
</a>
|
||||||
{ loginAsGuestJsx }
|
{ loginAsGuestJsx }
|
||||||
<br/>
|
|
||||||
<LoginFooter />
|
<LoginFooter />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,8 +36,10 @@ module.exports = React.createClass({
|
||||||
sessionId: React.PropTypes.string,
|
sessionId: React.PropTypes.string,
|
||||||
registrationUrl: React.PropTypes.string,
|
registrationUrl: React.PropTypes.string,
|
||||||
idSid: React.PropTypes.string,
|
idSid: React.PropTypes.string,
|
||||||
hsUrl: React.PropTypes.string,
|
initialHsUrl: React.PropTypes.string,
|
||||||
isUrl: React.PropTypes.string,
|
initialIsUrl: React.PropTypes.string,
|
||||||
|
defaultHsUrl: React.PropTypes.string,
|
||||||
|
defaultIsUrl: React.PropTypes.string,
|
||||||
email: React.PropTypes.string,
|
email: React.PropTypes.string,
|
||||||
username: React.PropTypes.string,
|
username: React.PropTypes.string,
|
||||||
guestAccessToken: React.PropTypes.string,
|
guestAccessToken: React.PropTypes.string,
|
||||||
|
@ -50,8 +52,6 @@ module.exports = React.createClass({
|
||||||
return {
|
return {
|
||||||
busy: false,
|
busy: false,
|
||||||
errorText: null,
|
errorText: null,
|
||||||
enteredHomeserverUrl: this.props.hsUrl,
|
|
||||||
enteredIdentityServerUrl: this.props.isUrl
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ module.exports = React.createClass({
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
// attach this to the instance rather than this.state since it isn't UI
|
// attach this to the instance rather than this.state since it isn't UI
|
||||||
this.registerLogic = new Signup.Register(
|
this.registerLogic = new Signup.Register(
|
||||||
this.props.hsUrl, this.props.isUrl
|
this.props.initialHsUrl, this.props.initialIsUrl
|
||||||
);
|
);
|
||||||
this.registerLogic.setClientSecret(this.props.clientSecret);
|
this.registerLogic.setClientSecret(this.props.clientSecret);
|
||||||
this.registerLogic.setSessionId(this.props.sessionId);
|
this.registerLogic.setSessionId(this.props.sessionId);
|
||||||
|
@ -242,11 +242,15 @@ module.exports = React.createClass({
|
||||||
{busySpinner}
|
{busySpinner}
|
||||||
<ServerConfig ref="serverConfig"
|
<ServerConfig ref="serverConfig"
|
||||||
withToggleButton={true}
|
withToggleButton={true}
|
||||||
defaultHsUrl={this.state.enteredHomeserverUrl}
|
initialHsUrl={this.props.initialHsUrl}
|
||||||
defaultIsUrl={this.state.enteredIdentityServerUrl}
|
initialIsUrl={this.props.initialIsUrl}
|
||||||
|
defaultHsUrl={this.props.defaultHsUrl}
|
||||||
|
defaultIsUrl={this.props.defaultIsUrl}
|
||||||
onHsUrlChanged={this.onHsUrlChanged}
|
onHsUrlChanged={this.onHsUrlChanged}
|
||||||
onIsUrlChanged={this.onIsUrlChanged}
|
onIsUrlChanged={this.onIsUrlChanged}
|
||||||
delayTimeMs={1000} />
|
delayTimeMs={1000} />
|
||||||
|
<div className="mx_Login_error">
|
||||||
|
</div>
|
||||||
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
|
<a className="mx_Login_create" onClick={this.props.onLoginClick} href="#">
|
||||||
I already have an account
|
I already have an account
|
||||||
</a>
|
</a>
|
||||||
|
@ -256,11 +260,13 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var LoginHeader = sdk.getComponent('login.LoginHeader');
|
var LoginHeader = sdk.getComponent('login.LoginHeader');
|
||||||
|
var LoginFooter = sdk.getComponent('login.LoginFooter');
|
||||||
return (
|
return (
|
||||||
<div className="mx_Login">
|
<div className="mx_Login">
|
||||||
<div className="mx_Login_box">
|
<div className="mx_Login_box">
|
||||||
<LoginHeader />
|
<LoginHeader />
|
||||||
{this._getRegisterContentJsx()}
|
{this._getRegisterContentJsx()}
|
||||||
|
<LoginFooter />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -31,12 +31,11 @@ module.exports = React.createClass({
|
||||||
servers by specifying a different Home server URL.
|
servers by specifying a different Home server URL.
|
||||||
<br/>
|
<br/>
|
||||||
This allows you to use this app with an existing Matrix account on
|
This allows you to use this app with an existing Matrix account on
|
||||||
a different Home server.
|
a different home server.
|
||||||
<br/>
|
<br/>
|
||||||
<br/>
|
<br/>
|
||||||
You can also set a custom Identity server but this will affect
|
You can also set a custom identity server but this will typically prevent
|
||||||
people's ability to find you if you use a server in a group other
|
interaction with users based on email address.
|
||||||
than the main Matrix.org group.
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_Dialog_buttons">
|
<div className="mx_Dialog_buttons">
|
||||||
|
|
|
@ -23,13 +23,24 @@ var ReactDOM = require('react-dom');
|
||||||
module.exports = React.createClass({displayName: 'PasswordLogin',
|
module.exports = React.createClass({displayName: 'PasswordLogin',
|
||||||
propTypes: {
|
propTypes: {
|
||||||
onSubmit: React.PropTypes.func.isRequired, // fn(username, password)
|
onSubmit: React.PropTypes.func.isRequired, // fn(username, password)
|
||||||
onForgotPasswordClick: React.PropTypes.func // fn()
|
onForgotPasswordClick: React.PropTypes.func, // fn()
|
||||||
|
initialUsername: React.PropTypes.string,
|
||||||
|
initialPassword: React.PropTypes.string,
|
||||||
|
onUsernameChanged: React.PropTypes.func,
|
||||||
|
onPasswordChanged: React.PropTypes.func,
|
||||||
|
},
|
||||||
|
|
||||||
|
getDefaultProps: function() {
|
||||||
|
return {
|
||||||
|
onUsernameChanged: function() {},
|
||||||
|
onPasswordChanged: function() {},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
username: "",
|
username: this.props.initialUsername,
|
||||||
password: ""
|
password: this.props.initialPassword,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -40,10 +51,12 @@ module.exports = React.createClass({displayName: 'PasswordLogin',
|
||||||
|
|
||||||
onUsernameChanged: function(ev) {
|
onUsernameChanged: function(ev) {
|
||||||
this.setState({username: ev.target.value});
|
this.setState({username: ev.target.value});
|
||||||
|
this.props.onUsernameChanged(ev.target.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
onPasswordChanged: function(ev) {
|
onPasswordChanged: function(ev) {
|
||||||
this.setState({password: ev.target.value});
|
this.setState({password: ev.target.value});
|
||||||
|
this.props.onPasswordChanged(ev.target.value);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
|
@ -29,8 +29,10 @@ module.exports = React.createClass({
|
||||||
propTypes: {
|
propTypes: {
|
||||||
onHsUrlChanged: React.PropTypes.func,
|
onHsUrlChanged: React.PropTypes.func,
|
||||||
onIsUrlChanged: React.PropTypes.func,
|
onIsUrlChanged: React.PropTypes.func,
|
||||||
defaultHsUrl: React.PropTypes.string,
|
initialHsUrl: React.PropTypes.string, // whatever the current value is when we create the component
|
||||||
defaultIsUrl: React.PropTypes.string,
|
initialIsUrl: React.PropTypes.string, // whatever the current value is when we create the component
|
||||||
|
defaultHsUrl: React.PropTypes.string, // e.g. https://matrix.org
|
||||||
|
defaultIsUrl: React.PropTypes.string, // e.g. https://vector.im
|
||||||
withToggleButton: React.PropTypes.bool,
|
withToggleButton: React.PropTypes.bool,
|
||||||
delayTimeMs: React.PropTypes.number // time to wait before invoking onChanged
|
delayTimeMs: React.PropTypes.number // time to wait before invoking onChanged
|
||||||
},
|
},
|
||||||
|
@ -46,19 +48,21 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
hs_url: this.props.defaultHsUrl,
|
hs_url: this.props.initialHsUrl,
|
||||||
is_url: this.props.defaultIsUrl,
|
is_url: this.props.initialIsUrl,
|
||||||
original_hs_url: this.props.defaultHsUrl,
|
// if withToggleButton is false, then show the config all the time given we have no way otherwise of making it visible
|
||||||
original_is_url: this.props.defaultIsUrl,
|
configVisible: !this.props.withToggleButton ||
|
||||||
// no toggle button = show, toggle button = hide
|
(this.props.initialHsUrl !== this.props.defaultHsUrl) ||
|
||||||
configVisible: !this.props.withToggleButton
|
(this.props.initialIsUrl !== this.props.defaultIsUrl)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onHomeserverChanged: function(ev) {
|
onHomeserverChanged: function(ev) {
|
||||||
this.setState({hs_url: ev.target.value}, function() {
|
this.setState({hs_url: ev.target.value}, function() {
|
||||||
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, function() {
|
this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, function() {
|
||||||
this.props.onHsUrlChanged(this.state.hs_url.replace(/\/$/, ""));
|
var hsUrl = this.state.hs_url.trim().replace(/\/$/, "");
|
||||||
|
if (hsUrl === "") hsUrl = this.props.defaultHsUrl;
|
||||||
|
this.props.onHsUrlChanged(hsUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -66,7 +70,9 @@ module.exports = React.createClass({
|
||||||
onIdentityServerChanged: function(ev) {
|
onIdentityServerChanged: function(ev) {
|
||||||
this.setState({is_url: ev.target.value}, function() {
|
this.setState({is_url: ev.target.value}, function() {
|
||||||
this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, function() {
|
this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, function() {
|
||||||
this.props.onIsUrlChanged(this.state.is_url.replace(/\/$/, ""));
|
var isUrl = this.state.is_url.trim().replace(/\/$/, "");
|
||||||
|
if (isUrl === "") isUrl = this.props.defaultIsUrl;
|
||||||
|
this.props.onIsUrlChanged(isUrl);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -78,18 +84,18 @@ module.exports = React.createClass({
|
||||||
return setTimeout(fn.bind(this), this.props.delayTimeMs);
|
return setTimeout(fn.bind(this), this.props.delayTimeMs);
|
||||||
},
|
},
|
||||||
|
|
||||||
getHsUrl: function() {
|
|
||||||
return this.state.hs_url;
|
|
||||||
},
|
|
||||||
|
|
||||||
getIsUrl: function() {
|
|
||||||
return this.state.is_url;
|
|
||||||
},
|
|
||||||
|
|
||||||
onServerConfigVisibleChange: function(ev) {
|
onServerConfigVisibleChange: function(ev) {
|
||||||
this.setState({
|
this.setState({
|
||||||
configVisible: ev.target.checked
|
configVisible: ev.target.checked
|
||||||
});
|
});
|
||||||
|
if (!ev.target.checked) {
|
||||||
|
this.props.onHsUrlChanged(this.props.defaultHsUrl);
|
||||||
|
this.props.onIsUrlChanged(this.props.defaultIsUrl);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.props.onHsUrlChanged(this.state.hs_url);
|
||||||
|
this.props.onIsUrlChanged(this.state.is_url);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showHelpPopup: function() {
|
showHelpPopup: function() {
|
||||||
|
@ -124,14 +130,14 @@ module.exports = React.createClass({
|
||||||
Home server URL
|
Home server URL
|
||||||
</label>
|
</label>
|
||||||
<input className="mx_Login_field" id="hsurl" type="text"
|
<input className="mx_Login_field" id="hsurl" type="text"
|
||||||
placeholder={this.state.original_hs_url}
|
placeholder={this.props.defaultHsUrl}
|
||||||
value={this.state.hs_url}
|
value={this.state.hs_url}
|
||||||
onChange={this.onHomeserverChanged} />
|
onChange={this.onHomeserverChanged} />
|
||||||
<label className="mx_Login_label mx_ServerConfig_islabel" htmlFor="isurl">
|
<label className="mx_Login_label mx_ServerConfig_islabel" htmlFor="isurl">
|
||||||
Identity server URL
|
Identity server URL
|
||||||
</label>
|
</label>
|
||||||
<input className="mx_Login_field" id="isurl" type="text"
|
<input className="mx_Login_field" id="isurl" type="text"
|
||||||
placeholder={this.state.original_is_url}
|
placeholder={this.props.defaultIsUrl}
|
||||||
value={this.state.is_url}
|
value={this.state.is_url}
|
||||||
onChange={this.onIdentityServerChanged} />
|
onChange={this.onIdentityServerChanged} />
|
||||||
<a className="mx_ServerConfig_help" href="#" onClick={this.showHelpPopup}>
|
<a className="mx_ServerConfig_help" href="#" onClick={this.showHelpPopup}>
|
||||||
|
|
Loading…
Reference in a new issue