mirror of
https://github.com/element-hq/element-web
synced 2024-11-27 19:56:47 +03:00
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.
This commit is contained in:
parent
6802db05bd
commit
bbfb9291f8
2 changed files with 69 additions and 59 deletions
|
@ -15,6 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import q from 'q';
|
||||
import Matrix from 'matrix-js-sdk';
|
||||
|
||||
import MatrixClientPeg from './MatrixClientPeg';
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* It returns a promise which resolves when the above process completes.
|
||||
*
|
||||
* @param {object} opts.queryParams: string->string map of the query-parameters
|
||||
* extracted from the #-fragment of the starting URI.
|
||||
* @param {object} opts.realQueryParams: string->string map of the
|
||||
* 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
|
||||
* and auto-guest registrations.
|
||||
|
@ -55,12 +64,13 @@ import dis from './dispatcher';
|
|||
*
|
||||
*/
|
||||
export function loadSession(opts) {
|
||||
const queryParams = opts.queryParams || {};
|
||||
const realQueryParams = opts.realQueryParams || {};
|
||||
const fragmentQueryParams = opts.fragmentQueryParams || {};
|
||||
let enableGuest = opts.enableGuest || false;
|
||||
const guestHsUrl = opts.guestHsUrl;
|
||||
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
|
||||
// IS, which in turn redirects back to vector. We let MatrixChat create a
|
||||
// Registration component which completes the next stage of registration.
|
||||
|
@ -73,14 +83,22 @@ export function loadSession(opts) {
|
|||
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 &&
|
||||
queryParams.guest_user_id &&
|
||||
queryParams.guest_access_token
|
||||
fragmentQueryParams.guest_user_id &&
|
||||
fragmentQueryParams.guest_access_token
|
||||
) {
|
||||
console.log("Using guest access credentials");
|
||||
setLoggedIn({
|
||||
userId: queryParams.guest_user_id,
|
||||
accessToken: queryParams.guest_access_token,
|
||||
userId: fragmentQueryParams.guest_user_id,
|
||||
accessToken: fragmentQueryParams.guest_access_token,
|
||||
homeserverUrl: guestHsUrl,
|
||||
identityServerUrl: guestIsUrl,
|
||||
guest: true,
|
||||
|
@ -100,6 +118,27 @@ export function loadSession(opts) {
|
|||
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) {
|
||||
console.log("Doing guest login on %s", hsUrl);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ limitations under the License.
|
|||
*/
|
||||
var React = require('react');
|
||||
var Matrix = require("matrix-js-sdk");
|
||||
var url = require('url');
|
||||
var Favico = require('favico.js');
|
||||
|
||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||
|
@ -50,7 +49,15 @@ module.exports = React.createClass({
|
|||
onNewScreen: React.PropTypes.func,
|
||||
registrationUrl: React.PropTypes.string,
|
||||
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: {
|
||||
|
@ -89,8 +96,10 @@ module.exports = React.createClass({
|
|||
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
startingQueryParams: {},
|
||||
realQueryParams: {},
|
||||
startingFragmentQueryParams: {},
|
||||
config: {},
|
||||
onLoadCompleted: () => {},
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -171,7 +180,8 @@ module.exports = React.createClass({
|
|||
this.handleResize();
|
||||
|
||||
Lifecycle.loadSession({
|
||||
queryParams: this.props.startingQueryParams,
|
||||
realQueryParams: this.props.realQueryParams,
|
||||
fragmentQueryParams: this.props.startingFragmentQueryParams,
|
||||
enableGuest: this.props.enableGuest,
|
||||
guestHsUrl: this.getCurrentHsUrl(),
|
||||
guestIsUrl: this.getCurrentIsUrl(),
|
||||
|
@ -284,41 +294,6 @@ module.exports = React.createClass({
|
|||
screen: '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;
|
||||
case 'leave_room':
|
||||
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
|
||||
|
@ -552,6 +527,7 @@ module.exports = React.createClass({
|
|||
* Called when the sessionloader has finished
|
||||
*/
|
||||
_onLoadCompleted: function() {
|
||||
this.props.onLoadCompleted();
|
||||
this.setState({loading: false});
|
||||
},
|
||||
|
||||
|
@ -734,11 +710,6 @@ module.exports = React.createClass({
|
|||
action: 'start_login',
|
||||
params: params
|
||||
});
|
||||
} else if (screen == 'token_login') {
|
||||
dis.dispatch({
|
||||
action: 'token_login',
|
||||
params: params
|
||||
});
|
||||
} else if (screen == 'forgot_password') {
|
||||
dis.dispatch({
|
||||
action: 'start_password_recovery',
|
||||
|
@ -994,8 +965,8 @@ module.exports = React.createClass({
|
|||
|
||||
// work out the HS URL prompts we should show for
|
||||
|
||||
// console.log("rendering; loading="+this.state.loading+"; screen="+this.state.screen +
|
||||
// "; logged_in="+this.state.logged_in+"; ready="+this.state.ready);
|
||||
console.log("rendering; loading="+this.state.loading+"; screen="+this.state.screen +
|
||||
"; logged_in="+this.state.logged_in+"; ready="+this.state.ready);
|
||||
|
||||
if (this.state.loading) {
|
||||
var Spinner = sdk.getComponent('elements.Spinner');
|
||||
|
@ -1099,7 +1070,7 @@ module.exports = React.createClass({
|
|||
clientSecret={this.state.register_client_secret}
|
||||
sessionId={this.state.register_session_id}
|
||||
idSid={this.state.register_id_sid}
|
||||
email={this.props.startingQueryParams.email}
|
||||
email={this.props.startingFragmentQueryParams.email}
|
||||
username={this.state.upgradeUsername}
|
||||
guestAccessToken={this.state.guestAccessToken}
|
||||
defaultHsUrl={this.getDefaultHsUrl()}
|
||||
|
|
Loading…
Reference in a new issue