<commit_before>/**
 *
 * Auth
 *
 */

/* eslint-disable consistent-return */

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';

import ProgressBar from 'components/ProgressBar';
import injectSaga from 'utils/injectSaga';
import injectReducer from 'utils/injectReducer';
import { exist as tokenExist } from 'utils/token';

import { makeSelectAuthenticated } from './selectors';
import reducer from './reducer';
import saga from './saga';
import { authenticate, unauthenticate } from './actions';

export class Auth extends React.Component { // eslint-disable-line react/prefer-stateless-function
  componentDidMount() {
    if (!tokenExist()) {
      return this.props.unauthenticate();
    }

    if (this.props.authenticated === null) {
      this.props.authenticate();
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.authenticated === this.props.authenticated) {
      return;
    }

    if (nextProps.authenticated === false && nextProps.options.unauthenticated) {
      return this.props.redirect(nextProps.options.unauthenticated);
    }

    if (nextProps.authenticated === true && nextProps.options.authenticated) {
      return this.props.redirect(nextProps.options.authenticated);
    }
  }

  render() {
    if (this.props.authenticated === null) {
      return <ProgressBar />;
    }

    return this.props.children;
  }
}

Auth.propTypes = {
  children: PropTypes.node,
  redirect: PropTypes.func.isRequired,
  authenticate: PropTypes.func.isRequired,
  unauthenticate: PropTypes.func.isRequired,
  authenticated: PropTypes.bool,
  options: PropTypes.shape({
    authenticated: PropTypes.string,
    unauthenticated: PropTypes.string,
  }),
};

const mapStateToProps = createStructuredSelector({
  authenticated: makeSelectAuthenticated(),
});

function mapDispatchToProps(dispatch) {
  return {
    authenticate: () => dispatch(authenticate()),
    unauthenticate: () => dispatch(unauthenticate()),
    redirect: (endpoint) => dispatch(push(endpoint)),
  };
}

const withConnect = connect(mapStateToProps, mapDispatchToProps);

const withReducer = injectReducer({ key: 'auth', reducer });
const withSaga = injectSaga({ key: 'auth', saga });

export const AuthComponent = compose(
  withReducer,
  withSaga,
  withConnect,
)(Auth);

export default function withAuth(Component, options) {
  return (props) => (
    <AuthComponent options={options}>
      <Component {...props} />
    </AuthComponent><commit_msg>auth flow refactor and bugfix<commit_after>/**
 *
 * Auth
 *
 */

/* eslint-disable consistent-return */

import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { push } from 'react-router-redux';
import { createStructuredSelector } from 'reselect';
import { compose } from 'redux';

import ProgressBar from 'components/ProgressBar';
import injectSaga from 'utils/injectSaga';
import injectReducer from 'utils/injectReducer';
import { exist as tokenExist } from 'utils/token';

import { makeSelectAuthenticated } from './selectors';
import reducer from './reducer';
import saga from './saga';
import { authenticate, unauthenticate } from './actions';

export class Auth extends React.Component { // eslint-disable-line react/prefer-stateless-function
  componentDidMount() {
    if (!tokenExist()) {
      return this.props.unauthenticate();
    }

    this.authFlow(this.props.authenticated);
  }

  componentWillReceiveProps(nextProps) {
    this.authFlow(nextProps.authenticated);
  }

  authFlow(authenticated) {
    if (authenticated === null) {
      return this.props.authenticate();
    }

    if (authenticated === false && this.props.options.unauthenticated) {
      return this.props.redirect(this.props.options.unauthenticated);
    }

    if (authenticated === true && this.props.options.authenticated) {
      return this.props.redirect(this.props.options.authenticated);
    }
  }

  render() {
    if (this.props.authenticated === null) {
      return <ProgressBar />;
    }

    return this.props.children;
  }
}

Auth.propTypes = {
  children: PropTypes.node,
  redirect: PropTypes.func.isRequired,
  authenticate: PropTypes.func.isRequired,
  unauthenticate: PropTypes.func.isRequired,
  authenticated: PropTypes.bool,
  options: PropTypes.shape({
    authenticated: PropTypes.string,
    unauthenticated: PropTypes.string,
  }),
};

const mapStateToProps = createStructuredSelector({
  authenticated: makeSelectAuthenticated(),
});

function mapDispatchToProps(dispatch) {
  return {
    authenticate: () => dispatch(authenticate()),
    unauthenticate: () => dispatch(unauthenticate()),
    redirect: (endpoint) => dispatch(push(endpoint)),
  };
}

const withConnect = connect(mapStateToProps, mapDispatchToProps);

const withReducer = injectReducer({ key: 'auth', reducer });
const withSaga = injectSaga({ key: 'auth', saga });

export const AuthComponent = compose(
  withReducer,
  withSaga,
  withConnect,
)(Auth);

export default function withAuth(Component, options) {
  return (props) => (
    <AuthComponent options={options} {...props}>
      <Component {...props} />
    </AuthComponent>
{'fraction_non_alphanumeric': 0.13191168144933008, 'fraction_numerical': 0.0, 'mean_word_length': 4.2114060963618485, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5258412', 'n_tokens_mistral': 1609, 'n_tokens_neox': 1544, 'n_words': 348}