Improve login

This commit is contained in:
cyril lopez 2018-09-25 17:11:14 +02:00
parent 98d89475d4
commit d96b888cc6
12 changed files with 116 additions and 136 deletions

View File

@ -11,6 +11,7 @@ import { findIndex } from 'lodash';
import 'sanitize.css/sanitize.css';
import 'whatwg-fetch';
import {
getAppPluginsSucceeded,
unsetHasUserPlugin,
} from 'containers/App/actions';
import { basename, store } from './createStore';
@ -27,8 +28,10 @@ if (window.location.port !== '4000') {
return response.json();
})
.then(plugins => {
dispatch(getAppPluginsSucceeded(plugins));
if (findIndex(plugins, ['id', 'users-permissions']) === -1) {
store.dispatch(unsetHasUserPlugin());
dispatch(unsetHasUserPlugin());
}
const $body = document.getElementsByTagName('body')[0];

View File

@ -7,6 +7,7 @@
import { findIndex } from 'lodash';
import {
getAppPluginsSucceeded,
unsetHasUserPlugin,
} from 'containers/App/actions';
import 'babel-polyfill';
@ -25,6 +26,8 @@ const plugins = (() => {
}
})();
dispatch(getAppPluginsSucceeded(plugins));
// Hot reloadable translation json files
if (module.hot) {
// modules.hot.accept does not accept dynamic dependencies,
@ -35,7 +38,7 @@ if (module.hot) {
}
if (findIndex(plugins, ['id', 'users-permissions']) === -1) {
store.dispatch(unsetHasUserPlugin());
dispatch(unsetHasUserPlugin());
}
export {

View File

@ -4,50 +4,19 @@
*
*/
import {
GET_CURR_ENV_SUCCEEDED,
GET_GA_STATUS,
GET_GA_STATUS_SUCCEEDED,
GET_LAYOUT,
GET_LAYOUT_SUCCEEDED,
GET_STRAPI_VERSION_SUCCEEDED,
GET_ADMIN_DATA,
GET_ADMIN_DATA_SUCCEEDED,
} from './constants';
export function getCurrEnvSucceeded(currentEnvironment) {
export function getAdminData() {
return {
type: GET_CURR_ENV_SUCCEEDED,
currentEnvironment,
type: GET_ADMIN_DATA,
};
}
export function getGaStatus() {
export function getAdminDataSucceeded(data) {
return {
type: GET_GA_STATUS,
type: GET_ADMIN_DATA_SUCCEEDED,
data,
};
}
export function getGaStatusSucceeded(allowGa) {
return {
type: GET_GA_STATUS_SUCCEEDED,
allowGa,
};
}
export function getLayout() {
return {
type: GET_LAYOUT,
};
}
export function getLayoutSucceeded(layout) {
return {
type: GET_LAYOUT_SUCCEEDED,
layout,
};
}
export function getStrapiVersionSucceeded(strapiVersion) {
return {
type: GET_STRAPI_VERSION_SUCCEEDED,
strapiVersion,
};
}
}

View File

@ -4,9 +4,5 @@
*
*/
export const GET_CURR_ENV_SUCCEEDED = 'app/Admin/GET_CURR_ENV_SUCCEEDED';
export const GET_GA_STATUS = 'app/Admin/GET_GA_STATUS';
export const GET_GA_STATUS_SUCCEEDED = 'app/Admin/GET_GA_STATUS_SUCCEEDED';
export const GET_LAYOUT = 'app/Admin/GET_LAYOUT';
export const GET_LAYOUT_SUCCEEDED = 'app/Admin/GET_LAYOUT_SUCCEEDED';
export const GET_STRAPI_VERSION_SUCCEEDED = 'app/Admin/GET_STRAPI_VERSION_SUCCEEDED';
export const GET_ADMIN_DATA = 'app/Admin/GET_ADMIN_DATA';
export const GET_ADMIN_DATA_SUCCEEDED = 'app/Admin/GET_ADMIN_DATA_SUCCEEDED';

View File

@ -16,21 +16,17 @@ import { connect } from 'react-redux';
import { createStructuredSelector } from 'reselect';
import { Switch, Route } from 'react-router-dom';
import { get, includes, isFunction, map, omit } from 'lodash';
import { compose } from 'redux';
import { bindActionCreators, compose } from 'redux';
// Actions required for disabling and enabling the OverlayBlocker
import { disableGlobalOverlayBlocker, enableGlobalOverlayBlocker } from 'actions/overlayBlocker';
import { pluginLoaded, updatePlugin } from 'containers/App/actions';
import {
makeSelectBlockApp,
makeSelectIsAppLoading,
makeSelectShowGlobalAppBlocker,
selectHasUserPlugin,
selectPlugins,
} from 'containers/App/selectors';
import { hideNotification } from 'containers/NotificationProvider/actions';
// Design
import ComingSoonPage from 'containers/ComingSoonPage';
import Content from 'containers/Content';
@ -41,21 +37,19 @@ import HomePage from 'containers/HomePage/Loadable';
import InstallPluginPage from 'containers/InstallPluginPage/Loadable';
import LeftMenu from 'containers/LeftMenu';
import ListPluginsPage from 'containers/ListPluginsPage/Loadable';
import LoadingIndicatorPage from 'components/LoadingIndicatorPage';
import Logout from 'components/Logout';
import NotFoundPage from 'containers/NotFoundPage/Loadable';
import OverlayBlocker from 'components/OverlayBlocker';
import PluginPage from 'containers/PluginPage';
// Utils
import auth from 'utils/auth';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import { getGaStatus, getLayout } from './actions';
import { getAdminData } from './actions';
import reducer from './reducer';
import saga from './saga';
import selectAdminPage from './selectors';
import styles from './styles.scss';
const PLUGINS_TO_BLOCK_PRODUCTION = ['content-type-builder', 'settings-manager'];
@ -72,30 +66,30 @@ export class AdminPage extends React.Component {
});
componentDidMount() {
this.props.getAdminData();
this.checkLogin(this.props);
this.props.getGaStatus();
this.props.getLayout();
ReactGA.initialize('UA-54313258-9');
}
componentWillReceiveProps(nextProps) {
if (nextProps.location.pathname !== this.props.location.pathname) {
this.checkLogin(nextProps);
componentDidUpdate(prevProps) {
const { adminPage: { allowGa }, location: { pathname }, plugins } = this.props;
if (nextProps.adminPage.allowGa) {
ReactGA.pageview(nextProps.location.pathname);
if (prevProps.location.pathname !== pathname) {
this.checkLogin(this.props);
if (allowGa) {
ReactGA.pageview(pathname);
}
}
if (
get(nextProps.plugins.toJS(), ['users-permissions', 'hasAdminUser']) !==
get(this.props.plugins.toJS(), ['users-permissions', 'hasAdminUser'])
) {
this.checkLogin(nextProps, true);
const hasAdminPath = ['users-permissions', 'hasAdminUser'];
if (get(prevProps.plugins.toJS(), hasAdminPath) !== get(plugins.toJS(), hasAdminPath)) {
this.checkLogin(this.props, true);
}
if (!this.hasUserPluginLoaded(this.props) && this.hasUserPluginLoaded(nextProps)) {
this.checkLogin(nextProps);
if (!this.hasUserPluginLoaded(prevProps) && this.hasUserPluginLoaded(this.props)) {
this.checkLogin(this.props);
}
}
@ -162,8 +156,18 @@ export class AdminPage extends React.Component {
shouldDisplayLogout = () => auth.getToken() && this.props.hasUserPlugin && this.isUrlProtected(this.props);
shouldCheckTokenValidity = () => {
return this.hasUserPlugin() && auth.getToken() !== null;
}
showLeftMenu = () => !includes(this.props.location.pathname, 'users-permissions/auth/');
showLoading = () => {
const { isAppLoading, adminPage: { isLoading } } = this.props;
return isAppLoading || isLoading;
}
retrievePlugins = () => {
const {
adminPage: { currentEnvironment },
@ -185,8 +189,8 @@ export class AdminPage extends React.Component {
const header = this.showLeftMenu() ? <Header /> : '';
const style = this.showLeftMenu() ? {} : { width: '100%' };
if (adminPage.isLoading) {
return <div />;
if (this.showLoading()) {
return <LoadingIndicatorPage />;
}
return (
@ -244,8 +248,6 @@ AdminPage.propTypes = {
blockApp: PropTypes.bool.isRequired,
disableGlobalOverlayBlocker: PropTypes.func.isRequired,
enableGlobalOverlayBlocker: PropTypes.func.isRequired,
getGaStatus: PropTypes.func.isRequired,
getLayout: PropTypes.func.isRequired,
hasUserPlugin: PropTypes.bool,
history: PropTypes.object.isRequired,
location: PropTypes.object.isRequired,
@ -257,37 +259,25 @@ AdminPage.propTypes = {
const mapStateToProps = createStructuredSelector({
adminPage: selectAdminPage(),
// appPlugins: makeSelectAppPlugins(),
blockApp: makeSelectBlockApp(),
hasUserPlugin: selectHasUserPlugin(),
isAppLoading: makeSelectIsAppLoading(),
plugins: selectPlugins(),
showGlobalAppBlocker: makeSelectShowGlobalAppBlocker(),
});
function mapDispatchToProps(dispatch) {
return {
disableGlobalOverlayBlocker: () => {
dispatch(disableGlobalOverlayBlocker());
},
enableGlobalOverlayBlocker: () => {
dispatch(enableGlobalOverlayBlocker());
},
getGaStatus: () => {
dispatch(getGaStatus());
},
getLayout: () => {
dispatch(getLayout());
},
onHideNotification: id => {
dispatch(hideNotification(id));
},
pluginLoaded: plugin => {
dispatch(pluginLoaded(plugin));
},
updatePlugin: (pluginId, updatedKey, updatedValue) => {
dispatch(updatePlugin(pluginId, updatedKey, updatedValue));
return bindActionCreators(
{
disableGlobalOverlayBlocker,
enableGlobalOverlayBlocker,
getAdminData,
pluginLoaded,
updatePlugin,
},
dispatch,
};
);
}
const withConnect = connect(mapStateToProps, mapDispatchToProps);

View File

@ -7,10 +7,7 @@
import { fromJS, Map } from 'immutable';
import {
GET_CURR_ENV_SUCCEEDED,
GET_GA_STATUS_SUCCEEDED,
GET_LAYOUT_SUCCEEDED,
GET_STRAPI_VERSION_SUCCEEDED,
GET_ADMIN_DATA_SUCCEEDED,
} from './constants';
const initialState = fromJS({
@ -23,16 +20,13 @@ const initialState = fromJS({
function adminPageReducer(state = initialState, action) {
switch (action.type) {
case GET_CURR_ENV_SUCCEEDED:
case GET_ADMIN_DATA_SUCCEEDED:
return state
.update('isLoading', () => false)
.update('currentEnvironment', () => action.currentEnvironment);
case GET_GA_STATUS_SUCCEEDED:
return state.update('allowGa', () => action.allowGa);
case GET_LAYOUT_SUCCEEDED:
return state.update('layout', () => Map(action.layout));
case GET_STRAPI_VERSION_SUCCEEDED:
return state.update('strapiVersion', () => action.strapiVersion);
.update('allowGa', () => action.data.allowGa)
.update('currentEnvironment', () => action.data.currentEnvironment)
.update('layout', () => Map(action.data.layout))
.update('strapiVersion', () => action.data.strapiVersion)
.update('isLoading', () => false);
default:
return state;
}

View File

@ -1,42 +1,38 @@
import { fork, call, put, takeLatest } from 'redux-saga/effects';
import { all, fork, call, put, select, takeLatest } from 'redux-saga/effects';
import auth from 'utils/auth';
import request from 'utils/request';
import { makeSelectAppPlugins } from 'containers/App/selectors';
import {
getCurrEnvSucceeded,
getGaStatusSucceeded,
getLayoutSucceeded,
getStrapiVersionSucceeded,
getAdminDataSucceeded,
} from './actions';
import { GET_GA_STATUS, GET_LAYOUT } from './constants';
import { GET_ADMIN_DATA } from './constants';
function* getGaStatus() {
function* getData() {
try {
const [{ allowGa }, { strapiVersion }, { currentEnvironment }] = yield [
const appPlugins = yield select(makeSelectAppPlugins());
const hasUserPlugin = appPlugins.indexOf('users-permissions') !== -1;
if (hasUserPlugin && auth.getToken() !== null) {
yield call(request, `${strapi.backendURL}/users/me`, { method: 'GET' });
}
const [{ allowGa }, { strapiVersion }, { currentEnvironment }, { layout }] = yield all([
call(request, '/admin/gaConfig', { method: 'GET' }),
call(request, '/admin/strapiVersion', { method: 'GET' }),
call(request, '/admin/currentEnvironment', { method: 'GET' }),
];
call(request, '/admin/layout', { method: 'GET' }),
]);
yield put(getAdminDataSucceeded({ allowGa, strapiVersion, currentEnvironment, layout }));
yield put(getCurrEnvSucceeded(currentEnvironment));
yield put(getGaStatusSucceeded(allowGa));
yield put(getStrapiVersionSucceeded(strapiVersion));
} catch(err) {
strapi.notification.error('notification.error');
}
}
function* getLayout() {
try {
const layout = yield call(request, '/admin/layout', { method: 'GET' });
yield put(getLayoutSucceeded(layout));
} catch(err) {
strapi.notification.error('notification.error.layout');
console.log(err); // eslint-disable-line no-console
}
}
function* defaultSaga() {
yield fork(takeLatest, GET_GA_STATUS, getGaStatus);
yield fork(takeLatest, GET_LAYOUT, getLayout);
yield all([
fork(takeLatest, GET_ADMIN_DATA, getData),
]);
}
export default defaultSaga;

View File

@ -6,6 +6,7 @@
import {
FREEZE_APP,
GET_APP_PLUGINS_SUCCEEDED,
LOAD_PLUGIN,
PLUGIN_DELETED,
PLUGIN_LOADED,
@ -20,6 +21,13 @@ export function freezeApp() {
};
}
export function getAppPluginsSucceeded(plugins) {
return {
type: GET_APP_PLUGINS_SUCCEEDED,
appPlugins: plugins.map(plugin => plugin.id),
};
}
export function loadPlugin(newPlugin) {
return {
type: LOAD_PLUGIN,

View File

@ -5,6 +5,7 @@
*/
export const FREEZE_APP = 'app/App/FREEZE_APP';
export const GET_APP_PLUGINS_SUCCEEDED = 'app/App/GET_APP_PLUGINS_SUCCEEDED';
export const LOAD_PLUGIN = 'app/App/LOAD_PLUGIN';
export const PLUGIN_LOADED = 'app/App/PLUGIN_LOADED';
export const PLUGIN_DELETED = 'app/App/PLUGIN_DELETED';

View File

@ -4,10 +4,11 @@ import {
ENABLE_GLOBAL_OVERLAY_BLOCKER,
} from 'constants/overlayBlocker';
import { fromJS } from 'immutable';
import { fromJS, List } from 'immutable';
import {
FREEZE_APP,
GET_APP_PLUGINS_SUCCEEDED,
PLUGIN_DELETED,
PLUGIN_LOADED,
UNFREEZE_APP,
@ -16,8 +17,10 @@ import {
} from './constants';
const initialState = fromJS({
appPlugins: List([]),
blockApp: false,
hasUserPlugin: true,
isAppLoading: true,
plugins: {},
showGlobalAppBlocker: true,
});
@ -30,6 +33,10 @@ function appReducer(state = initialState, action) {
return state.set('showGlobalAppBlocker', true);
case FREEZE_APP:
return state.set('blockApp', true);
case GET_APP_PLUGINS_SUCCEEDED:
return state
.update('appPlugins', () => List(action.appPlugins))
.update('isAppLoading', () => false);
case PLUGIN_LOADED:
return state.setIn(['plugins', action.plugin.id], fromJS(action.plugin));
case UPDATE_PLUGIN:

View File

@ -29,10 +29,22 @@ const makeSelectBlockApp = () => createSelector(
(appState) => appState.get('blockApp'),
);
const makeSelectIsAppLoading = () => createSelector(
selectApp(),
appState => appState.get('isAppLoading'),
);
const makeSelectAppPlugins = () => createSelector(
selectApp(),
appState => appState.get('appPlugins'),
);
export {
selectApp,
selectHasUserPlugin,
selectPlugins,
makeSelectAppPlugins,
makeSelectBlockApp,
makeSelectIsAppLoading,
makeSelectShowGlobalAppBlocker,
};

View File

@ -9,6 +9,7 @@ import {
unfreezeApp,
updatePlugin,
} from 'containers/App/actions';
import { showNotification } from 'containers/NotificationProvider/actions';
import auth from 'utils/auth';
import { history, store } from './createStore';
import { translationMessages, languages } from './i18n';