mirror of https://github.com/vector-im/riot-web
Refactor login token
move the logic for handling login tokens into Lifecycle.loadSession This means it needs access to the (real) query parmeters, so it depends on corresponding changes in vector-web.pull/21833/head
parent
6802db05bd
commit
bbfb9291f8
|
@ -15,6 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import q from 'q';
|
import q from 'q';
|
||||||
|
import Matrix from 'matrix-js-sdk';
|
||||||
|
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import Notifier from './Notifier'
|
import Notifier from './Notifier'
|
||||||
|
@ -29,20 +30,28 @@ import dis from './dispatcher';
|
||||||
* 0. if it looks like we are in the middle of a registration process, it does
|
* 0. if it looks like we are in the middle of a registration process, it does
|
||||||
* nothing.
|
* nothing.
|
||||||
*
|
*
|
||||||
* 1. if we have a guest access token in the query params, it uses that.
|
* 1. if we have a loginToken in the (real) query params, it uses that to log
|
||||||
|
* in.
|
||||||
*
|
*
|
||||||
* 2. if an access token is stored in local storage (from a previous session),
|
* 2. if we have a guest access token in the fragment query params, it uses
|
||||||
|
* that.
|
||||||
|
*
|
||||||
|
* 3. if an access token is stored in local storage (from a previous session),
|
||||||
* it uses that.
|
* it uses that.
|
||||||
*
|
*
|
||||||
* 3. it attempts to auto-register as a guest user.
|
* 4. it attempts to auto-register as a guest user.
|
||||||
*
|
*
|
||||||
* If any of steps 1-3 are successful, it will call {setLoggedIn}, which in
|
* If any of steps 1-4 are successful, it will call {setLoggedIn}, which in
|
||||||
* turn will raise on_logged_in and will_start_client events.
|
* turn will raise on_logged_in and will_start_client events.
|
||||||
*
|
*
|
||||||
* It returns a promise which resolves when the above process completes.
|
* It returns a promise which resolves when the above process completes.
|
||||||
*
|
*
|
||||||
* @param {object} opts.queryParams: string->string map of the query-parameters
|
* @param {object} opts.realQueryParams: string->string map of the
|
||||||
* extracted from the #-fragment of the starting URI.
|
* query-parameters extracted from the real query-string of the starting
|
||||||
|
* URI.
|
||||||
|
*
|
||||||
|
* @param {object} opts.fragmentQueryParams: string->string map of the
|
||||||
|
* query-parameters extracted from the #-fragment of the starting URI.
|
||||||
*
|
*
|
||||||
* @param {boolean} opts.enableGuest: set to true to enable guest access tokens
|
* @param {boolean} opts.enableGuest: set to true to enable guest access tokens
|
||||||
* and auto-guest registrations.
|
* and auto-guest registrations.
|
||||||
|
@ -55,12 +64,13 @@ import dis from './dispatcher';
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export function loadSession(opts) {
|
export function loadSession(opts) {
|
||||||
const queryParams = opts.queryParams || {};
|
const realQueryParams = opts.realQueryParams || {};
|
||||||
|
const fragmentQueryParams = opts.fragmentQueryParams || {};
|
||||||
let enableGuest = opts.enableGuest || false;
|
let enableGuest = opts.enableGuest || false;
|
||||||
const guestHsUrl = opts.guestHsUrl;
|
const guestHsUrl = opts.guestHsUrl;
|
||||||
const guestIsUrl = opts.guestIsUrl;
|
const guestIsUrl = opts.guestIsUrl;
|
||||||
|
|
||||||
if (queryParams.client_secret && queryParams.sid) {
|
if (fragmentQueryParams.client_secret && fragmentQueryParams.sid) {
|
||||||
// this happens during email validation: the email contains a link to the
|
// this happens during email validation: the email contains a link to the
|
||||||
// IS, which in turn redirects back to vector. We let MatrixChat create a
|
// IS, which in turn redirects back to vector. We let MatrixChat create a
|
||||||
// Registration component which completes the next stage of registration.
|
// Registration component which completes the next stage of registration.
|
||||||
|
@ -73,14 +83,22 @@ export function loadSession(opts) {
|
||||||
enableGuest = false;
|
enableGuest = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (realQueryParams.loginToken) {
|
||||||
|
if (!realQueryParams.homeserver) {
|
||||||
|
console.warn("Cannot log in with token: can't determine HS URL to use");
|
||||||
|
} else {
|
||||||
|
return _loginWithToken(realQueryParams);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (enableGuest &&
|
if (enableGuest &&
|
||||||
queryParams.guest_user_id &&
|
fragmentQueryParams.guest_user_id &&
|
||||||
queryParams.guest_access_token
|
fragmentQueryParams.guest_access_token
|
||||||
) {
|
) {
|
||||||
console.log("Using guest access credentials");
|
console.log("Using guest access credentials");
|
||||||
setLoggedIn({
|
setLoggedIn({
|
||||||
userId: queryParams.guest_user_id,
|
userId: fragmentQueryParams.guest_user_id,
|
||||||
accessToken: queryParams.guest_access_token,
|
accessToken: fragmentQueryParams.guest_access_token,
|
||||||
homeserverUrl: guestHsUrl,
|
homeserverUrl: guestHsUrl,
|
||||||
identityServerUrl: guestIsUrl,
|
identityServerUrl: guestIsUrl,
|
||||||
guest: true,
|
guest: true,
|
||||||
|
@ -100,6 +118,27 @@ export function loadSession(opts) {
|
||||||
return q();
|
return q();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _loginWithToken(queryParams) {
|
||||||
|
// create a temporary MatrixClient to do the login
|
||||||
|
var client = Matrix.createClient({
|
||||||
|
baseUrl: queryParams.homeserver,
|
||||||
|
});
|
||||||
|
|
||||||
|
return client.loginWithToken(queryParams.loginToken).then(function(data) {
|
||||||
|
console.log("Logged in with token");
|
||||||
|
setLoggedIn({
|
||||||
|
userId: data.user_id,
|
||||||
|
accessToken: data.access_token,
|
||||||
|
homeserverUrl: queryParams.homeserver,
|
||||||
|
identityServerUrl: queryParams.identityServer,
|
||||||
|
guest: false,
|
||||||
|
})
|
||||||
|
}, (err) => {
|
||||||
|
console.error("Failed to log in with login token: " + err + " " +
|
||||||
|
err.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function _registerAsGuest(hsUrl, isUrl) {
|
function _registerAsGuest(hsUrl, isUrl) {
|
||||||
console.log("Doing guest login on %s", hsUrl);
|
console.log("Doing guest login on %s", hsUrl);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var Matrix = require("matrix-js-sdk");
|
var Matrix = require("matrix-js-sdk");
|
||||||
var url = require('url');
|
|
||||||
var Favico = require('favico.js');
|
var Favico = require('favico.js');
|
||||||
|
|
||||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||||
|
@ -50,7 +49,15 @@ module.exports = React.createClass({
|
||||||
onNewScreen: React.PropTypes.func,
|
onNewScreen: React.PropTypes.func,
|
||||||
registrationUrl: React.PropTypes.string,
|
registrationUrl: React.PropTypes.string,
|
||||||
enableGuest: React.PropTypes.bool,
|
enableGuest: React.PropTypes.bool,
|
||||||
startingQueryParams: React.PropTypes.object
|
|
||||||
|
// the queryParams extracted from the [real] query-string of the URI
|
||||||
|
realQueryParams: React.PropTypes.object,
|
||||||
|
|
||||||
|
// the initial queryParams extracted from the hash-fragment of the URI
|
||||||
|
startingFragmentQueryParams: React.PropTypes.object,
|
||||||
|
|
||||||
|
// called when the session load completes
|
||||||
|
onLoadCompleted: React.PropTypes.func,
|
||||||
},
|
},
|
||||||
|
|
||||||
PageTypes: {
|
PageTypes: {
|
||||||
|
@ -89,8 +96,10 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
getDefaultProps: function() {
|
getDefaultProps: function() {
|
||||||
return {
|
return {
|
||||||
startingQueryParams: {},
|
realQueryParams: {},
|
||||||
|
startingFragmentQueryParams: {},
|
||||||
config: {},
|
config: {},
|
||||||
|
onLoadCompleted: () => {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -171,7 +180,8 @@ module.exports = React.createClass({
|
||||||
this.handleResize();
|
this.handleResize();
|
||||||
|
|
||||||
Lifecycle.loadSession({
|
Lifecycle.loadSession({
|
||||||
queryParams: this.props.startingQueryParams,
|
realQueryParams: this.props.realQueryParams,
|
||||||
|
fragmentQueryParams: this.props.startingFragmentQueryParams,
|
||||||
enableGuest: this.props.enableGuest,
|
enableGuest: this.props.enableGuest,
|
||||||
guestHsUrl: this.getCurrentHsUrl(),
|
guestHsUrl: this.getCurrentHsUrl(),
|
||||||
guestIsUrl: this.getCurrentIsUrl(),
|
guestIsUrl: this.getCurrentIsUrl(),
|
||||||
|
@ -284,41 +294,6 @@ module.exports = React.createClass({
|
||||||
screen: 'forgot_password'
|
screen: 'forgot_password'
|
||||||
});
|
});
|
||||||
this.notifyNewScreen('forgot_password');
|
this.notifyNewScreen('forgot_password');
|
||||||
break;
|
|
||||||
case 'token_login':
|
|
||||||
if (this.state.logged_in) return;
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
MatrixClientPeg.replaceUsingUrls(
|
|
||||||
payload.params.homeserver,
|
|
||||||
payload.params.identityServer
|
|
||||||
);
|
|
||||||
|
|
||||||
var client = MatrixClientPeg.get();
|
|
||||||
client.loginWithToken(payload.params.loginToken).done(function(data) {
|
|
||||||
MatrixClientPeg.replaceUsingCreds({
|
|
||||||
homeserverUrl: client.getHomeserverUrl(),
|
|
||||||
identityServerUrl: client.getIdentityServerUrl(),
|
|
||||||
userId: data.user_id,
|
|
||||||
accessToken: data.access_token,
|
|
||||||
guest: false,
|
|
||||||
});
|
|
||||||
self.setState({
|
|
||||||
screen: undefined,
|
|
||||||
logged_in: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// We're left with the login token, hs and is url as query params
|
|
||||||
// in the url, a little nasty but let's redirect to clear them
|
|
||||||
var parsedUrl = url.parse(window.location.href);
|
|
||||||
parsedUrl.search = "";
|
|
||||||
window.location.href = url.format(parsedUrl);
|
|
||||||
|
|
||||||
}, function(error) {
|
|
||||||
self.notifyNewScreen('login');
|
|
||||||
self.setState({errorText: 'Login failed.'});
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 'leave_room':
|
case 'leave_room':
|
||||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||||
|
@ -552,6 +527,7 @@ module.exports = React.createClass({
|
||||||
* Called when the sessionloader has finished
|
* Called when the sessionloader has finished
|
||||||
*/
|
*/
|
||||||
_onLoadCompleted: function() {
|
_onLoadCompleted: function() {
|
||||||
|
this.props.onLoadCompleted();
|
||||||
this.setState({loading: false});
|
this.setState({loading: false});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -734,11 +710,6 @@ module.exports = React.createClass({
|
||||||
action: 'start_login',
|
action: 'start_login',
|
||||||
params: params
|
params: params
|
||||||
});
|
});
|
||||||
} else if (screen == 'token_login') {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'token_login',
|
|
||||||
params: params
|
|
||||||
});
|
|
||||||
} else if (screen == 'forgot_password') {
|
} else if (screen == 'forgot_password') {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'start_password_recovery',
|
action: 'start_password_recovery',
|
||||||
|
@ -994,8 +965,8 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
// work out the HS URL prompts we should show for
|
// work out the HS URL prompts we should show for
|
||||||
|
|
||||||
// console.log("rendering; loading="+this.state.loading+"; screen="+this.state.screen +
|
console.log("rendering; loading="+this.state.loading+"; screen="+this.state.screen +
|
||||||
// "; logged_in="+this.state.logged_in+"; ready="+this.state.ready);
|
"; logged_in="+this.state.logged_in+"; ready="+this.state.ready);
|
||||||
|
|
||||||
if (this.state.loading) {
|
if (this.state.loading) {
|
||||||
var Spinner = sdk.getComponent('elements.Spinner');
|
var Spinner = sdk.getComponent('elements.Spinner');
|
||||||
|
@ -1099,7 +1070,7 @@ module.exports = React.createClass({
|
||||||
clientSecret={this.state.register_client_secret}
|
clientSecret={this.state.register_client_secret}
|
||||||
sessionId={this.state.register_session_id}
|
sessionId={this.state.register_session_id}
|
||||||
idSid={this.state.register_id_sid}
|
idSid={this.state.register_id_sid}
|
||||||
email={this.props.startingQueryParams.email}
|
email={this.props.startingFragmentQueryParams.email}
|
||||||
username={this.state.upgradeUsername}
|
username={this.state.upgradeUsername}
|
||||||
guestAccessToken={this.state.guestAccessToken}
|
guestAccessToken={this.state.guestAccessToken}
|
||||||
defaultHsUrl={this.getDefaultHsUrl()}
|
defaultHsUrl={this.getDefaultHsUrl()}
|
||||||
|
|
Loading…
Reference in New Issue