window.location.assign(`https://${homeClusterHost}/login?${(uuidPrefix !== homeCluster && homeCluster !== loginCluster) ? "remote=" + uuidPrefix + "&" : ""}return_to=${currentUrl}`);
}
- public logout(expireToken: string) {
- const currentUrl = `${window.location.protocol}//${window.location.host}`;
- window.location.assign(`${this.baseUrl || ""}/logout?api_token=${expireToken}&return_to=${currentUrl}`);
+ public logout(expireToken: string, preservePath: boolean) {
+ const fullUrl = new URL(window.location.href);
+ const wbBase = `${fullUrl.protocol}//${fullUrl.host}`;
+ const wbPath = fullUrl.pathname + fullUrl.search;
+ const returnTo = `${wbBase}${preservePath ? wbPath : ''}`
+
+ window.location.assign(`${this.baseUrl || ""}/logout?api_token=${expireToken}&return_to=${returnTo}`);
}
public getUserDetails = (showErrors?: boolean): Promise<User> => {
export const authActions = unionize({
LOGIN: {},
- LOGOUT: ofType<{ deleteLinkData: boolean }>(),
+ LOGOUT: ofType<{ deleteLinkData: boolean, preservePath: boolean }>(),
SET_CONFIG: ofType<{ config: Config }>(),
SET_EXTRA_TOKEN: ofType<{ extraApiToken: string, extraApiTokenExpiration?: Date }>(),
RESET_EXTRA_TOKEN: {},
const tokenLocation = await svc.authService.getStorageType();
dispatch(authActions.INIT_USER({ user, token, tokenExpiration, tokenLocation }));
} catch (e) {
- dispatch(authActions.LOGOUT({ deleteLinkData: false }));
+ dispatch(authActions.LOGOUT({ deleteLinkData: false, preservePath: false }));
}
};
dispatch(authActions.LOGIN());
};
-export const logout = (deleteLinkData: boolean = false) =>
+export const logout = (deleteLinkData: boolean = false, preservePath: boolean = false) =>
(dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) =>
- dispatch(authActions.LOGOUT({ deleteLinkData }));
+ dispatch(authActions.LOGOUT({ deleteLinkData, preservePath }))
export type AuthAction = UnionOf<typeof authActions>;
window.location.assign = jest.fn();
const next = jest.fn();
const middleware = authMiddleware(services)(store)(next);
- middleware(authActions.LOGOUT({deleteLinkData: false}));
+ middleware(authActions.LOGOUT({deleteLinkData: false, preservePath: false}));
expect(window.location.assign).toBeCalledWith(
`/logout?api_token=someToken&return_to=${location.protocol}//${location.host}`
);
expect(localStorage.getItem(API_TOKEN_KEY)).toBeFalsy();
});
-});
\ No newline at end of file
+});
document.title = `Arvados Workbench (${config.uuidPrefix})`;
next(action);
},
- LOGOUT: ({ deleteLinkData }) => {
+ LOGOUT: ({ deleteLinkData, preservePath }) => {
next(action);
if (deleteLinkData) {
services.linkAccountService.removeAccountToLink();
services.authService.removeSessions();
services.authService.removeUser();
removeAuthorizationHeader(services);
- services.authService.logout(token || '');
+ services.authService.logout(token || '', preservePath);
},
default: () => next(action)
});
});
const mapDispatchToProps = (dispatch: Dispatch): AutoLogoutActionProps => ({
- doLogout: () => dispatch<any>(logout(true)),
+ doLogout: () => dispatch<any>(logout(true, true)),
doWarn: (message: string, duration: number) =>
dispatch(snackbarActions.OPEN_SNACKBAR({
message, hideDuration: duration, kind: SnackbarKind.WARNING })),
{user.isActive && accountMenuItems}
<Divider />
<MenuItem data-cy="logout-menuitem"
- onClick={() => dispatch(authActions.LOGOUT({ deleteLinkData: true }))}>
+ onClick={() => dispatch(authActions.LOGOUT({ deleteLinkData: true, preservePath: false }))}>
Logout
</MenuItem>
</DropdownMenu>