Make SessionLoader a function
There's no point in it being a React component.
This commit is contained in:
parent
24841cc5c4
commit
26c7c9e994
4 changed files with 123 additions and 179 deletions
115
src/Lifecycle.js
115
src/Lifecycle.js
|
@ -14,19 +14,120 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import q from 'q';
|
||||||
|
|
||||||
import MatrixClientPeg from './MatrixClientPeg';
|
import MatrixClientPeg from './MatrixClientPeg';
|
||||||
import Notifier from './Notifier'
|
import Notifier from './Notifier'
|
||||||
import UserActivity from './UserActivity';
|
import UserActivity from './UserActivity';
|
||||||
import Presence from './Presence';
|
import Presence from './Presence';
|
||||||
import dis from './dispatcher';
|
import dis from './dispatcher';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called at startup, to attempt to build a logged-in Matrix session. It tries
|
||||||
|
* a number of things:
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* 2. 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.
|
||||||
|
*
|
||||||
|
* If any of steps 1-3 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 {boolean} opts.enableGuest: set to true to enable guest access tokens
|
||||||
|
* and auto-guest registrations.
|
||||||
|
*
|
||||||
|
* @params {string} opts.hsUrl: homeserver URL. Only used if enableGuest is
|
||||||
|
* true; defines the HS to register against.
|
||||||
|
*
|
||||||
|
* @params {string} opts.isUrl: homeserver URL. Only used if enableGuest is
|
||||||
|
* true; defines the IS to use.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export function loadSession(opts) {
|
||||||
|
const queryParams = opts.queryParams || {};
|
||||||
|
let enableGuest = opts.enableGuest || false;
|
||||||
|
const hsUrl = opts.hsUrl;
|
||||||
|
const isUrl = opts.isUrl;
|
||||||
|
|
||||||
|
if (queryParams.client_secret && queryParams.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.
|
||||||
|
console.log("Not registering as guest: registration already in progress.");
|
||||||
|
return q();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hsUrl) {
|
||||||
|
console.warn("Cannot enable guest access: can't determine HS URL to use");
|
||||||
|
enableGuest = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableGuest &&
|
||||||
|
queryParams.guest_user_id &&
|
||||||
|
queryParams.guest_access_token
|
||||||
|
) {
|
||||||
|
console.log("Using guest access credentials");
|
||||||
|
setLoggedIn({
|
||||||
|
userId: queryParams.guest_user_id,
|
||||||
|
accessToken: queryParams.guest_access_token,
|
||||||
|
homeserverUrl: hsUrl,
|
||||||
|
identityServerUrl: isUrl,
|
||||||
|
guest: true,
|
||||||
|
});
|
||||||
|
return q();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MatrixClientPeg.get() && MatrixClientPeg.get().credentials) {
|
||||||
|
console.log("Using existing credentials");
|
||||||
|
setLoggedIn(MatrixClientPeg.getCredentials());
|
||||||
|
return q();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enableGuest) {
|
||||||
|
return _registerAsGuest(hsUrl, isUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fall back to login screen
|
||||||
|
return q();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _registerAsGuest(hsUrl, isUrl) {
|
||||||
|
console.log("Doing guest login on %s", hsUrl);
|
||||||
|
|
||||||
|
MatrixClientPeg.replaceUsingUrls(hsUrl, isUrl);
|
||||||
|
return MatrixClientPeg.get().registerGuest().then((creds) => {
|
||||||
|
console.log("Registered as guest: %s", creds.user_id);
|
||||||
|
setLoggedIn({
|
||||||
|
userId: creds.user_id,
|
||||||
|
accessToken: creds.access_token,
|
||||||
|
homeserverUrl: hsUrl,
|
||||||
|
identityServerUrl: isUrl,
|
||||||
|
guest: true,
|
||||||
|
});
|
||||||
|
}, (err) => {
|
||||||
|
console.error("Failed to register as guest: " + err + " " + err.data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitions to a logged-in state using the given credentials
|
* Transitions to a logged-in state using the given credentials
|
||||||
* @param {MatrixClientCreds} credentials The credentials to use
|
* @param {MatrixClientCreds} credentials The credentials to use
|
||||||
*/
|
*/
|
||||||
function setLoggedIn(credentials) {
|
export function setLoggedIn(credentials) {
|
||||||
credentials.guest = Boolean(credentials.guest);
|
credentials.guest = Boolean(credentials.guest);
|
||||||
console.log("onLoggedIn => %s (guest=%s) hs=%s",
|
console.log("setLoggedIn => %s (guest=%s) hs=%s",
|
||||||
credentials.userId, credentials.guest,
|
credentials.userId, credentials.guest,
|
||||||
credentials.homeserverUrl);
|
credentials.homeserverUrl);
|
||||||
MatrixClientPeg.replaceUsingCreds(credentials);
|
MatrixClientPeg.replaceUsingCreds(credentials);
|
||||||
|
@ -39,7 +140,7 @@ function setLoggedIn(credentials) {
|
||||||
/**
|
/**
|
||||||
* Logs the current session out and transitions to the logged-out state
|
* Logs the current session out and transitions to the logged-out state
|
||||||
*/
|
*/
|
||||||
function logout() {
|
export function logout() {
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
// logout doesn't work for guest sessions
|
// logout doesn't work for guest sessions
|
||||||
// Also we sometimes want to re-log in a guest session
|
// Also we sometimes want to re-log in a guest session
|
||||||
|
@ -67,7 +168,7 @@ function logout() {
|
||||||
* Starts the matrix client and all other react-sdk services that
|
* Starts the matrix client and all other react-sdk services that
|
||||||
* listen for events while a session is logged in.
|
* listen for events while a session is logged in.
|
||||||
*/
|
*/
|
||||||
function startMatrixClient() {
|
export function startMatrixClient() {
|
||||||
// dispatch this before starting the matrix client: it's used
|
// dispatch this before starting the matrix client: it's used
|
||||||
// to add listeners for the 'sync' event so otherwise we'd have
|
// to add listeners for the 'sync' event so otherwise we'd have
|
||||||
// a race condition (and we need to dispatch synchronously for this
|
// a race condition (and we need to dispatch synchronously for this
|
||||||
|
@ -85,7 +186,7 @@ function startMatrixClient() {
|
||||||
* Stops a running client and all related services, used after
|
* Stops a running client and all related services, used after
|
||||||
* a session has been logged out / ended.
|
* a session has been logged out / ended.
|
||||||
*/
|
*/
|
||||||
function onLoggedOut() {
|
export function onLoggedOut() {
|
||||||
if (window.localStorage) {
|
if (window.localStorage) {
|
||||||
const hsUrl = window.localStorage.getItem("mx_hs_url");
|
const hsUrl = window.localStorage.getItem("mx_hs_url");
|
||||||
const isUrl = window.localStorage.getItem("mx_is_url");
|
const isUrl = window.localStorage.getItem("mx_is_url");
|
||||||
|
@ -112,7 +213,3 @@ function _stopMatrixClient() {
|
||||||
MatrixClientPeg.get().removeAllListeners();
|
MatrixClientPeg.get().removeAllListeners();
|
||||||
MatrixClientPeg.unset();
|
MatrixClientPeg.unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
setLoggedIn, logout, startMatrixClient, onLoggedOut
|
|
||||||
};
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ module.exports.components['structures.login.ForgotPassword'] = require('./compon
|
||||||
module.exports.components['structures.login.Login'] = require('./components/structures/login/Login');
|
module.exports.components['structures.login.Login'] = require('./components/structures/login/Login');
|
||||||
module.exports.components['structures.login.PostRegistration'] = require('./components/structures/login/PostRegistration');
|
module.exports.components['structures.login.PostRegistration'] = require('./components/structures/login/PostRegistration');
|
||||||
module.exports.components['structures.login.Registration'] = require('./components/structures/login/Registration');
|
module.exports.components['structures.login.Registration'] = require('./components/structures/login/Registration');
|
||||||
module.exports.components['structures.login.SessionLoader'] = require('./components/structures/login/SessionLoader');
|
|
||||||
module.exports.components['views.avatars.BaseAvatar'] = require('./components/views/avatars/BaseAvatar');
|
module.exports.components['views.avatars.BaseAvatar'] = require('./components/views/avatars/BaseAvatar');
|
||||||
module.exports.components['views.avatars.MemberAvatar'] = require('./components/views/avatars/MemberAvatar');
|
module.exports.components['views.avatars.MemberAvatar'] = require('./components/views/avatars/MemberAvatar');
|
||||||
module.exports.components['views.avatars.RoomAvatar'] = require('./components/views/avatars/RoomAvatar');
|
module.exports.components['views.avatars.RoomAvatar'] = require('./components/views/avatars/RoomAvatar');
|
||||||
|
|
|
@ -26,7 +26,6 @@ var UserActivity = require("../../UserActivity");
|
||||||
var Presence = require("../../Presence");
|
var Presence = require("../../Presence");
|
||||||
var dis = require("../../dispatcher");
|
var dis = require("../../dispatcher");
|
||||||
|
|
||||||
var SessionLoader = require("./login/SessionLoader");
|
|
||||||
var Login = require("./login/Login");
|
var Login = require("./login/Login");
|
||||||
var Registration = require("./login/Registration");
|
var Registration = require("./login/Registration");
|
||||||
var PostRegistration = require("./login/PostRegistration");
|
var PostRegistration = require("./login/PostRegistration");
|
||||||
|
@ -145,14 +144,11 @@ module.exports = React.createClass({
|
||||||
if (this.props.config.sync_timeline_limit) {
|
if (this.props.config.sync_timeline_limit) {
|
||||||
MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit;
|
MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// register our dispatcher listener here rather than in
|
|
||||||
// componentDidMount so that we hear about any actions raised during
|
|
||||||
// the loading process.
|
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
|
|
||||||
this.focusComposer = false;
|
this.focusComposer = false;
|
||||||
// scrollStateMap is a map from room id to the scroll state returned by
|
// scrollStateMap is a map from room id to the scroll state returned by
|
||||||
// RoomView.getScrollState()
|
// RoomView.getScrollState()
|
||||||
|
@ -171,6 +167,17 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
window.addEventListener('resize', this.handleResize);
|
window.addEventListener('resize', this.handleResize);
|
||||||
this.handleResize();
|
this.handleResize();
|
||||||
|
|
||||||
|
Lifecycle.loadSession({
|
||||||
|
queryParams: this.props.startingQueryParams,
|
||||||
|
enableGuest: this.props.enableGuest,
|
||||||
|
hsUrl: this.getDefaultHsUrl(),
|
||||||
|
isUrl: this.getDefaultIsUrl(),
|
||||||
|
}).done(()=>{
|
||||||
|
// stuff this through the dispatcher so that it happens
|
||||||
|
// after the on_logged_in action.
|
||||||
|
dis.dispatch({action: 'load_completed'});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
|
@ -990,18 +997,11 @@ module.exports = React.createClass({
|
||||||
// "; 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');
|
||||||
return (
|
return (
|
||||||
<SessionLoader
|
<div className="mx_MatrixChat_splash">
|
||||||
queryParams={this.props.startingQueryParams}
|
<Spinner />
|
||||||
enableGuest={this.props.enableGuest}
|
</div>
|
||||||
hsUrl={this.getCurrentHsUrl()}
|
|
||||||
isUrl={this.getCurrentIsUrl()}
|
|
||||||
onLoggedIn={Lifecycle.setLoggedIn}
|
|
||||||
|
|
||||||
// stuff this through the dispatcher so that it happens
|
|
||||||
// after the on_logged_in action.
|
|
||||||
onComplete={()=>{dis.dispatch({action: 'load_completed'});}}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// needs to be before normal PageTypes as you are logged in technically
|
// needs to be before normal PageTypes as you are logged in technically
|
||||||
|
|
|
@ -1,152 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2016 OpenMarket Ltd
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import q from 'q';
|
|
||||||
|
|
||||||
import dis from '../../../dispatcher';
|
|
||||||
import sdk from '../../../index';
|
|
||||||
import MatrixClientPeg from '../../../MatrixClientPeg';
|
|
||||||
import Lifecycle from '../../../Lifecycle';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A react component which is only used when the application first starts.
|
|
||||||
*
|
|
||||||
* Its job is to attempt to build a logged-in Matrix session. It tries a number
|
|
||||||
* of things:
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* 2. 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.
|
|
||||||
*
|
|
||||||
* If any of steps 1-3 are successful, it will call onLoggedIn (which is
|
|
||||||
* typically Lifecycle.setLoggedIn, which in turn will raise on_logged_in and
|
|
||||||
* will_start_client events).
|
|
||||||
*
|
|
||||||
* Finally, it calls onComplete, which makes MatrixChat move into its normal processing.
|
|
||||||
*/
|
|
||||||
export default class SessionLoader extends React.Component {
|
|
||||||
constructor(props, context) {
|
|
||||||
super(props, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this._loadSession().done(() => {
|
|
||||||
this.props.onComplete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
|
||||||
if (nextProps.hsUrl != this.props.hsUrl ||
|
|
||||||
nextProps.isUrl != this.props.isUrl
|
|
||||||
) {
|
|
||||||
throw new Error("changing servers on a SessionLoader is not supported");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
_loadSession() {
|
|
||||||
if (this.props.queryParams.client_secret && this.props.queryParams.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.
|
|
||||||
console.log("Not registering as guest: registration already in progress.");
|
|
||||||
return q();
|
|
||||||
}
|
|
||||||
|
|
||||||
let enableGuest = false;
|
|
||||||
if (this.props.enableGuest) {
|
|
||||||
if (!this.props.hsUrl) {
|
|
||||||
console.warn("Cannot enable guest access: can't determine HS URL to use");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
enableGuest = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enableGuest &&
|
|
||||||
this.props.queryParams.guest_user_id &&
|
|
||||||
this.props.queryParams.guest_access_token
|
|
||||||
) {
|
|
||||||
console.log("Using guest access credentials");
|
|
||||||
this.props.onLoggedIn({
|
|
||||||
userId: this.props.queryParams.guest_user_id,
|
|
||||||
accessToken: this.props.queryParams.guest_access_token,
|
|
||||||
homeserverUrl: this.props.hsUrl,
|
|
||||||
identityServerUrl: this.props.isUrl,
|
|
||||||
guest: true,
|
|
||||||
});
|
|
||||||
return q();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MatrixClientPeg.get() && MatrixClientPeg.get().credentials) {
|
|
||||||
console.log("Using existing credentials");
|
|
||||||
this.props.onLoggedIn(MatrixClientPeg.getCredentials());
|
|
||||||
return q();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (enableGuest) {
|
|
||||||
return this._registerAsGuest();
|
|
||||||
}
|
|
||||||
|
|
||||||
// fall back to login screen
|
|
||||||
return q();
|
|
||||||
}
|
|
||||||
|
|
||||||
_registerAsGuest() {
|
|
||||||
var hsUrl = this.props.hsUrl;
|
|
||||||
var isUrl = this.props.isUrl;
|
|
||||||
console.log("Doing guest login on %s", hsUrl);
|
|
||||||
|
|
||||||
MatrixClientPeg.replaceUsingUrls(hsUrl, isUrl);
|
|
||||||
return MatrixClientPeg.get().registerGuest().then((creds) => {
|
|
||||||
console.log("Registered as guest: %s", creds.user_id);
|
|
||||||
this.props.onLoggedIn({
|
|
||||||
userId: creds.user_id,
|
|
||||||
accessToken: creds.access_token,
|
|
||||||
homeserverUrl: hsUrl,
|
|
||||||
identityServerUrl: isUrl,
|
|
||||||
guest: true,
|
|
||||||
});
|
|
||||||
}, (err) => {
|
|
||||||
console.error("Failed to register as guest: " + err + " " + err.data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const Spinner = sdk.getComponent('elements.Spinner');
|
|
||||||
return (
|
|
||||||
<div className="mx_MatrixChat_splash">
|
|
||||||
<Spinner />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SessionLoader.propTypes = {
|
|
||||||
queryParams: React.PropTypes.object.isRequired,
|
|
||||||
enableGuest: React.PropTypes.bool,
|
|
||||||
hsUrl: React.PropTypes.string,
|
|
||||||
isUrl: React.PropTypes.string,
|
|
||||||
onLoggedIn: React.PropTypes.func.isRequired,
|
|
||||||
onComplete: React.PropTypes.func.isRequired,
|
|
||||||
};
|
|
Loading…
Reference in a new issue