Merge pull request #406 from matrix-org/rav/refactor_token_login
Refactor login tokenpull/21833/head
commit
3b317eb15d
|
@ -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