do not show login error, when redirecting

This commit is contained in:
Sebastian Sdorra
2019-04-17 11:45:44 +02:00
parent 20cf0507a2
commit 2b2d7ea0e9
3 changed files with 66 additions and 24 deletions

View File

@@ -3,13 +3,12 @@ import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { translate } from "react-i18next"; import { translate } from "react-i18next";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
import type { History } from "history";
import { import {
logout, logout,
isAuthenticated, isAuthenticated,
isLogoutPending, isLogoutPending,
getLogoutFailure getLogoutFailure, isRedirecting
} from "../modules/auth"; } from "../modules/auth";
import { Loading, ErrorPage } from "@scm-manager/ui-components"; import { Loading, ErrorPage } from "@scm-manager/ui-components";
import { getLogoutLink } from "../modules/indexResource"; import { getLogoutLink } from "../modules/indexResource";
@@ -17,24 +16,24 @@ import { getLogoutLink } from "../modules/indexResource";
type Props = { type Props = {
authenticated: boolean, authenticated: boolean,
loading: boolean, loading: boolean,
redirecting: boolean,
error: Error, error: Error,
logoutLink: string, logoutLink: string,
// dispatcher functions // dispatcher functions
logout: (link: string, history: History) => void, logout: (link: string) => void,
// context props // context props
history: History,
t: string => string t: string => string
}; };
class Logout extends React.Component<Props> { class Logout extends React.Component<Props> {
componentDidMount() { componentDidMount() {
this.props.logout(this.props.logoutLink, this.props.history); this.props.logout(this.props.logoutLink);
} }
render() { render() {
const { authenticated, loading, error, t } = this.props; const { authenticated, redirecting, loading, error, t } = this.props;
if (error) { if (error) {
return ( return (
<ErrorPage <ErrorPage
@@ -43,7 +42,7 @@ class Logout extends React.Component<Props> {
error={error} error={error}
/> />
); );
} else if (loading || authenticated) { } else if (loading || authenticated || redirecting) {
return <Loading />; return <Loading />;
} else { } else {
return <Redirect to="/login" />; return <Redirect to="/login" />;
@@ -54,11 +53,13 @@ class Logout extends React.Component<Props> {
const mapStateToProps = state => { const mapStateToProps = state => {
const authenticated = isAuthenticated(state); const authenticated = isAuthenticated(state);
const loading = isLogoutPending(state); const loading = isLogoutPending(state);
const redirecting = isRedirecting(state);
const error = getLogoutFailure(state); const error = getLogoutFailure(state);
const logoutLink = getLogoutLink(state); const logoutLink = getLogoutLink(state);
return { return {
authenticated, authenticated,
loading, loading,
redirecting,
error, error,
logoutLink logoutLink
}; };
@@ -66,7 +67,7 @@ const mapStateToProps = state => {
const mapDispatchToProps = dispatch => { const mapDispatchToProps = dispatch => {
return { return {
logout: (link: string, history: History) => dispatch(logout(link, history)) logout: (link: string) => dispatch(logout(link))
}; };
}; };

View File

@@ -11,7 +11,6 @@ import {
fetchIndexResourcesPending, fetchIndexResourcesPending,
fetchIndexResourcesSuccess fetchIndexResourcesSuccess
} from "./indexResource"; } from "./indexResource";
import type { History } from "history";
// Action // Action
@@ -30,10 +29,7 @@ export const LOGOUT = "scm/auth/LOGOUT";
export const LOGOUT_PENDING = `${LOGOUT}_${types.PENDING_SUFFIX}`; export const LOGOUT_PENDING = `${LOGOUT}_${types.PENDING_SUFFIX}`;
export const LOGOUT_SUCCESS = `${LOGOUT}_${types.SUCCESS_SUFFIX}`; export const LOGOUT_SUCCESS = `${LOGOUT}_${types.SUCCESS_SUFFIX}`;
export const LOGOUT_FAILURE = `${LOGOUT}_${types.FAILURE_SUFFIX}`; export const LOGOUT_FAILURE = `${LOGOUT}_${types.FAILURE_SUFFIX}`;
export const LOGOUT_REDIRECT = `${LOGOUT}_REDIRECT`;
type LogoutRedirection = {
logoutRedirect: string
};
// Reducer // Reducer
@@ -59,6 +55,13 @@ export default function reducer(
case LOGOUT_SUCCESS: case LOGOUT_SUCCESS:
return initialState; return initialState;
case LOGOUT_REDIRECT: {
// we keep the current state until we are redirected to the new page
return {
...state,
redirecting: true
};
}
default: default:
return state; return state;
} }
@@ -94,10 +97,16 @@ export const logoutPending = () => {
export const logoutSuccess = () => { export const logoutSuccess = () => {
return { return {
type: LOGOUT_SUCCESS type: LOGOUT_SUCCESS,
}; };
}; };
export const redirectAfterLogout = () => {
return {
type: LOGOUT_REDIRECT
}
};
export const logoutFailure = (error: Error) => { export const logoutFailure = (error: Error) => {
return { return {
type: LOGOUT_FAILURE, type: LOGOUT_FAILURE,
@@ -190,7 +199,7 @@ export const fetchMe = (link: string) => {
}; };
}; };
export const logout = (link: string, history: History) => { export const logout = (link: string) => {
return function(dispatch: any) { return function(dispatch: any) {
dispatch(logoutPending()); dispatch(logoutPending());
return apiClient return apiClient
@@ -199,17 +208,24 @@ export const logout = (link: string, history: History) => {
return response.status === 200 return response.status === 200
? response.json() ? response.json()
: new Promise(function(resolve) { : new Promise(function(resolve) {
resolve(undefined); resolve();
}); });
}) })
.then(json => { .then(json => {
let fetchIndex = true;
if (json && json.logoutRedirect) { if (json && json.logoutRedirect) {
dispatch(redirectAfterLogout());
window.location.assign(json.logoutRedirect); window.location.assign(json.logoutRedirect);
fetchIndex = false;
} else {
dispatch(logoutSuccess());
} }
dispatch(logoutSuccess()); return fetchIndex;
}) })
.then(() => { .then((fetchIndex: boolean) => {
dispatch(fetchIndexResources()); if (fetchIndex) {
dispatch(fetchIndexResources());
}
}) })
.catch(error => { .catch(error => {
dispatch(logoutFailure(error)); dispatch(logoutFailure(error));
@@ -257,3 +273,8 @@ export const isLogoutPending = (state: Object) => {
export const getLogoutFailure = (state: Object) => { export const getLogoutFailure = (state: Object) => {
return getFailure(state, LOGOUT); return getFailure(state, LOGOUT);
}; };
export const isRedirecting = (state: Object) => {
return !!stateAuth(state).redirecting;
};

View File

@@ -26,7 +26,7 @@ import reducer, {
FETCH_ME, FETCH_ME,
LOGOUT, LOGOUT,
getLoginFailure, getLoginFailure,
getLogoutFailure, getLogoutFailure, isRedirecting, LOGOUT_REDIRECT, redirectAfterLogout,
} from "./auth"; } from "./auth";
import configureMockStore from "redux-mock-store"; import configureMockStore from "redux-mock-store";
@@ -70,6 +70,17 @@ describe("auth reducer", () => {
expect(state.authenticated).toBeUndefined(); expect(state.authenticated).toBeUndefined();
}); });
it("should keep state and set redirecting to true", () => {
const initialState = {
authenticated: true,
me
};
const state = reducer(initialState, redirectAfterLogout());
expect(state.me).toBe(initialState.me);
expect(state.authenticated).toBe(initialState.authenticated);
expect(state.redirecting).toBe(true);
});
it("should set state authenticated and me after login", () => { it("should set state authenticated and me after login", () => {
const state = reducer(undefined, loginSuccess(me)); const state = reducer(undefined, loginSuccess(me));
expect(state.me).toBe(me); expect(state.me).toBe(me);
@@ -246,8 +257,7 @@ describe("auth actions", () => {
const expectedActions = [ const expectedActions = [
{ type: LOGOUT_PENDING }, { type: LOGOUT_PENDING },
{ type: LOGOUT_SUCCESS }, { type: LOGOUT_REDIRECT }
{ type: FETCH_INDEXRESOURCES_PENDING }
]; ];
const store = mockStore({}); const store = mockStore({});
@@ -257,8 +267,6 @@ describe("auth actions", () => {
"http://example.com/cas/logout" "http://example.com/cas/logout"
); );
expect(store.getActions()).toEqual(expectedActions); expect(store.getActions()).toEqual(expectedActions);
// expect(window.location.href).toEqual("http://example.com/cas/logout");
}); });
}); });
@@ -345,4 +353,16 @@ describe("auth selectors", () => {
it("should return unknown, if failure state is not set for LOGOUT", () => { it("should return unknown, if failure state is not set for LOGOUT", () => {
expect(getLogoutFailure({})).toBeUndefined(); expect(getLogoutFailure({})).toBeUndefined();
}); });
it("should return false, if redirecting is not set", () => {
expect(isRedirecting({})).toBe(false);
});
it("should return false, if redirecting is false", () => {
expect(isRedirecting({auth: { redirecting: false }})).toBe(false);
});
it("should return true, if redirecting is true", () => {
expect(isRedirecting({auth: { redirecting: true }})).toBe(true);
});
}); });