Fix potential race condition causing ProxyHandler to not evaluate its redirect functions if the component doesn't get updated

This commit is contained in:
Brett Sun 2016-01-13 16:03:08 +01:00
parent cc9fa2378f
commit 1ffa1eb6aa
2 changed files with 34 additions and 8 deletions

View File

@ -34,8 +34,8 @@ export function AuthRedirect({to, when}) {
//
// So if when === 'loggedIn', we're checking if the user is logged in (and
// vice versa)
const exprToValidate = when === 'loggedIn' ? currentUser && currentUser.email
: currentUser && !currentUser.email;
const isLoggedIn = currentUser && Object.keys(currentUser).length && currentUser.email;
const exprToValidate = when === 'loggedIn' ? isLoggedIn : !isLoggedIn;
// and redirect if `true`.
if (exprToValidate) {
@ -80,7 +80,11 @@ export function ProxyHandler(...redirectFunctions) {
displayName: 'ProxyHandler',
propTypes: {
currentUser: object,
// Provided from AscribeApp
currentUser: React.PropTypes.object,
whitelabel: React.PropTypes.object,
// Provided from router
location: object
},
@ -88,10 +92,18 @@ export function ProxyHandler(...redirectFunctions) {
// to use the `Lifecycle` widget in further down nested components
mixins: [RouteContext],
componentDidUpdate() {
const { currentUser, location: { query } } = this.props;
componentDidMount() {
this.evaluateRedirectFunctions();
},
if (!UserStore.isLoading()) {
componentWillReceiveProps(nextProps) {
this.evaluateRedirectFunctions(nextProps);
},
evaluateRedirectFunctions(props = this.props) {
const { currentUser, location: { query } } = props;
if (UserStore.hasLoaded() && !UserStore.isLoading()) {
for (let i = 0; i < redirectFunctions.length; i++) {
// if a redirectFunction redirects the user,
// it should return `true` and therefore
@ -106,7 +118,7 @@ export function ProxyHandler(...redirectFunctions) {
render() {
return (
<Component {...this.props}/>
<Component {...this.props} />
);
}
});

View File

@ -12,12 +12,16 @@ class UserStore {
constructor() {
this.currentUser = {};
this.userMeta = {
hasLoaded: false,
invalidateCache: false,
err: null
};
this.bindActions(UserActions);
this.registerAsync(UserSource);
this.exportPublicMethods({
hasLoaded: this.hasLoaded.bind(this)
});
}
onFetchCurrentUser(invalidateCache) {
@ -28,7 +32,8 @@ class UserStore {
}
}
onSuccessFetchCurrentUser({users: [user = {}]}) {
onSuccessFetchCurrentUser({ users: [ user = {} ] = [] }) {
this.userMeta.hasLoaded = true;
this.userMeta.invalidateCache = false;
this.userMeta.err = null;
@ -50,6 +55,10 @@ class UserStore {
altWhitelabel.recycle();
altUser.recycle();
altThirdParty.recycle();
// Since we've just logged out, we can set this store's
// hasLoaded flag back to true as there is no current user.
this.userMeta.hasLoaded = true;
});
}
@ -59,8 +68,13 @@ class UserStore {
onErrorCurrentUser(err) {
console.logGlobal(err);
this.userMeta.hasLoaded = true;
this.userMeta.err = err;
}
hasLoaded() {
return this.userMeta.hasLoaded;
}
}
export default altUser.createStore(UserStore, 'UserStore');