mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 23:45:44 +01:00
reset the redux state if the token is expired and the user still uses the web ui
This commit is contained in:
@@ -155,9 +155,19 @@ export function createUrlWithIdentifiers(url: string): string {
|
|||||||
return createUrl(url) + "?X-SCM-Client=WUI&X-SCM-Session-ID=" + sessionId;
|
return createUrl(url) + "?X-SCM-Client=WUI&X-SCM-Session-ID=" + sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ErrorListener = (error: Error) => void;
|
||||||
|
|
||||||
class ApiClient {
|
class ApiClient {
|
||||||
|
constructor() {
|
||||||
|
this.notifyAndRethrow = this.notifyAndRethrow.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorListeners: ErrorListener[] = [];
|
||||||
|
|
||||||
get(url: string): Promise<Response> {
|
get(url: string): Promise<Response> {
|
||||||
return fetch(createUrl(url), applyFetchOptions({})).then(handleFailure);
|
return fetch(createUrl(url), applyFetchOptions({}))
|
||||||
|
.then(handleFailure)
|
||||||
|
.catch(this.notifyAndRethrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
post(url: string, payload?: any, contentType = "application/json", additionalHeaders: Record<string, string> = {}) {
|
post(url: string, payload?: any, contentType = "application/json", additionalHeaders: Record<string, string> = {}) {
|
||||||
@@ -193,7 +203,9 @@ class ApiClient {
|
|||||||
method: "HEAD"
|
method: "HEAD"
|
||||||
};
|
};
|
||||||
options = applyFetchOptions(options);
|
options = applyFetchOptions(options);
|
||||||
return fetch(createUrl(url), options).then(handleFailure);
|
return fetch(createUrl(url), options)
|
||||||
|
.then(handleFailure)
|
||||||
|
.catch(this.notifyAndRethrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(url: string): Promise<Response> {
|
delete(url: string): Promise<Response> {
|
||||||
@@ -201,7 +213,9 @@ class ApiClient {
|
|||||||
method: "DELETE"
|
method: "DELETE"
|
||||||
};
|
};
|
||||||
options = applyFetchOptions(options);
|
options = applyFetchOptions(options);
|
||||||
return fetch(createUrl(url), options).then(handleFailure);
|
return fetch(createUrl(url), options)
|
||||||
|
.then(handleFailure)
|
||||||
|
.catch(this.notifyAndRethrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
httpRequestWithJSONBody(
|
httpRequestWithJSONBody(
|
||||||
@@ -245,7 +259,9 @@ class ApiClient {
|
|||||||
options.headers["Content-Type"] = contentType;
|
options.headers["Content-Type"] = contentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch(createUrl(url), options).then(handleFailure);
|
return fetch(createUrl(url), options)
|
||||||
|
.then(handleFailure)
|
||||||
|
.catch(this.notifyAndRethrow);
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribe(url: string, argument: SubscriptionArgument): Cancel {
|
subscribe(url: string, argument: SubscriptionArgument): Cancel {
|
||||||
@@ -276,6 +292,15 @@ class ApiClient {
|
|||||||
|
|
||||||
return () => es.close();
|
return () => es.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onError(errorListener: ErrorListener) {
|
||||||
|
this.errorListeners.push(errorListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private notifyAndRethrow(error: Error): never {
|
||||||
|
this.errorListeners.forEach(errorListener => errorListener(error));
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const apiClient = new ApiClient();
|
export const apiClient = new ApiClient();
|
||||||
|
|||||||
@@ -64,6 +64,15 @@ class Index extends Component<Props, State> {
|
|||||||
this.props.fetchIndexResources();
|
this.props.fetchIndexResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate() {
|
||||||
|
const { indexResources, loading, error } = this.props;
|
||||||
|
const { pluginsLoaded } = this.state;
|
||||||
|
if (!indexResources && !loading && !error && pluginsLoaded) {
|
||||||
|
this.props.fetchIndexResources();
|
||||||
|
this.setState({ pluginsLoaded: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pluginLoaderCallback = () => {
|
pluginLoaderCallback = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
pluginsLoaded: true
|
pluginsLoaded: true
|
||||||
|
|||||||
@@ -24,14 +24,14 @@
|
|||||||
|
|
||||||
import thunk from "redux-thunk";
|
import thunk from "redux-thunk";
|
||||||
import logger from "redux-logger";
|
import logger from "redux-logger";
|
||||||
import { applyMiddleware, combineReducers, compose, createStore } from "redux";
|
import { AnyAction, applyMiddleware, combineReducers, compose, createStore } from "redux";
|
||||||
import users from "./users/modules/users";
|
import users from "./users/modules/users";
|
||||||
import repos from "./repos/modules/repos";
|
import repos from "./repos/modules/repos";
|
||||||
import repositoryTypes from "./repos/modules/repositoryTypes";
|
import repositoryTypes from "./repos/modules/repositoryTypes";
|
||||||
import changesets from "./repos/modules/changesets";
|
import changesets from "./repos/modules/changesets";
|
||||||
import sources from "./repos/sources/modules/sources";
|
import sources from "./repos/sources/modules/sources";
|
||||||
import groups from "./groups/modules/groups";
|
import groups from "./groups/modules/groups";
|
||||||
import auth from "./modules/auth";
|
import auth, { isAuthenticated } from "./modules/auth";
|
||||||
import pending from "./modules/pending";
|
import pending from "./modules/pending";
|
||||||
import failure from "./modules/failure";
|
import failure from "./modules/failure";
|
||||||
import permissions from "./repos/permissions/modules/permissions";
|
import permissions from "./repos/permissions/modules/permissions";
|
||||||
@@ -40,13 +40,15 @@ import roles from "./admin/roles/modules/roles";
|
|||||||
import namespaceStrategies from "./admin/modules/namespaceStrategies";
|
import namespaceStrategies from "./admin/modules/namespaceStrategies";
|
||||||
import indexResources from "./modules/indexResource";
|
import indexResources from "./modules/indexResource";
|
||||||
import plugins from "./admin/plugins/modules/plugins";
|
import plugins from "./admin/plugins/modules/plugins";
|
||||||
|
import { apiClient } from "@scm-manager/ui-components";
|
||||||
|
|
||||||
import branches from "./repos/branches/modules/branches";
|
import branches from "./repos/branches/modules/branches";
|
||||||
|
import { UnauthorizedError } from "@scm-manager/ui-components/src";
|
||||||
|
|
||||||
function createReduxStore() {
|
function createReduxStore() {
|
||||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||||
|
|
||||||
const reducer = combineReducers({
|
const appReducer = combineReducers({
|
||||||
pending,
|
pending,
|
||||||
failure,
|
failure,
|
||||||
indexResources,
|
indexResources,
|
||||||
@@ -65,7 +67,28 @@ function createReduxStore() {
|
|||||||
plugins
|
plugins
|
||||||
});
|
});
|
||||||
|
|
||||||
return createStore(reducer, composeEnhancers(applyMiddleware(thunk, logger)));
|
const reducer = (state: any, action: AnyAction) => {
|
||||||
|
console.log(action.type, state?.tokenExpired);
|
||||||
|
if (state?.tokenExpired && action.type.indexOf("FAILURE") === -1) {
|
||||||
|
console.log("reset state");
|
||||||
|
return appReducer({}, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.type === "API_CLIENT_UNAUTHORIZED" && isAuthenticated(state)) {
|
||||||
|
return { ...state, tokenExpired: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...appReducer(state, action), tokenExpired: state?.tokenExpired };
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk, logger)));
|
||||||
|
apiClient.onError(error => {
|
||||||
|
if (error instanceof UnauthorizedError) {
|
||||||
|
store.dispatch({ type: "API_CLIENT_UNAUTHORIZED", error });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default createReduxStore;
|
export default createReduxStore;
|
||||||
|
|||||||
Reference in New Issue
Block a user