16812: Removed download attribute, fixed redirectTo
authorDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Tue, 13 Oct 2020 21:56:04 +0000 (23:56 +0200)
committerDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Tue, 13 Oct 2020 21:56:04 +0000 (23:56 +0200)
Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla@contractors.roche.com>

src/common/redirect-to.test.ts
src/common/redirect-to.ts
src/index.tsx
src/store/auth/auth-action.test.ts
src/store/auth/auth-middleware.test.ts
src/store/store.ts
src/views-components/context-menu/actions/collection-copy-to-clipboard-action.tsx
src/views-components/context-menu/actions/collection-file-viewer-action.tsx
src/views-components/context-menu/actions/download-collection-file-action.tsx
src/views-components/context-menu/actions/file-viewer-action.tsx
src/views-components/context-menu/actions/helpers.ts

index ad8ac9e0c2354680948848ff1ba35593a61ee010..177e16566896e6f6d723d457ce7850d6b70b3444 100644 (file)
@@ -6,7 +6,10 @@ import { storeRedirects, handleRedirects } from './redirect-to';
 
 describe('redirect-to', () => {
     const { location } = window;
-    const redirectTo = 'http://localhost/test123';
+    const config: any = {
+        keepWebServiceUrl: 'http://localhost'
+    };
+    const redirectTo = '/test123';
     const locationTemplate = {
         hash: '',
         hostname: '',
@@ -68,14 +71,11 @@ describe('redirect-to', () => {
         });
 
         it('should redirect to page when it is present in session storage', () => {
-            // given
-            const token = 'testToken';
-
             // when
-            handleRedirects(token);
+            handleRedirects(config);
 
             // then
-            expect(window.location.href).toBe(`${redirectTo}?api_token=${token}`);
+            expect(window.location.href).toBe(`${config.keepWebServiceUrl}${redirectTo}`);
         });
     });
 });
\ No newline at end of file
index 54268c24c8114052abb4faeeb880b5cd00b0ce2b..86fac71cbae8ab7adb27354ee7a351e34c7c72e3 100644 (file)
@@ -2,6 +2,8 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
+import { Config } from './config';
+
 const REDIRECT_TO_KEY = 'redirectTo';
 
 export const storeRedirects = () => {
@@ -15,12 +17,13 @@ export const storeRedirects = () => {
     }
 };
 
-export const handleRedirects = (token: string) => {
+export const handleRedirects = (config: Config) => {
     const { sessionStorage } = window;
+    const { keepWebServiceUrl } = config;
 
     if (sessionStorage && sessionStorage.getItem(REDIRECT_TO_KEY)) {
         const redirectUrl = sessionStorage.getItem(REDIRECT_TO_KEY);
         sessionStorage.removeItem(REDIRECT_TO_KEY);
-        window.location.href = `${redirectUrl}?api_token=${token}`;
+        window.location.href = `${keepWebServiceUrl}${redirectUrl}`;
     }
 };
\ No newline at end of file
index f87ff3843b2f904bc1697d3fd2f1f5521846700c..92a2716b6a7fbe6c24010e68994cfc7295680f51 100644 (file)
@@ -127,7 +127,7 @@ fetchConfig()
                 }
             }
         });
-        const store = configureStore(history, services);
+        const store = configureStore(history, services, config);
 
         store.subscribe(initListener(history, store, services, config));
         store.dispatch(initAuth(config));
index 83a699a7d2121d7118c2a37ac08cec1f3dc9733c..4e4a85e39196fade0452b92e567d4acb44b3842a 100644 (file)
@@ -23,6 +23,7 @@ describe('auth-actions', () => {
 
     let store: RootStore;
     let services: ServiceRepository;
+    const config: any = {};
     const actions: ApiActions = {
         progressFn: (id: string, working: boolean) => { },
         errorFn: (id: string, message: string) => { }
@@ -32,7 +33,7 @@ describe('auth-actions', () => {
     beforeEach(() => {
         axiosMock.reset();
         services = createServices(mockConfig({}), actions, axiosInst);
-        store = configureStore(createBrowserHistory(), services);
+        store = configureStore(createBrowserHistory(), services, config);
         localStorage.clear();
         importMocks = [];
     });
index 1fe34381d941372a79b0b3835703895807cffc29..bcc942e1ee76e85f338ed34bc2db80437715d1ef 100644 (file)
@@ -18,6 +18,7 @@ describe("AuthMiddleware", () => {
     let store: RootStore;
     let services: ServiceRepository;
     let axiosInst: AxiosInstance;
+    const config: any = {};
     const actions: ApiActions = {
         progressFn: (id: string, working: boolean) => { },
         errorFn: (id: string, message: string) => { }
@@ -26,7 +27,7 @@ describe("AuthMiddleware", () => {
     beforeEach(() => {
         axiosInst = Axios.create({ headers: {} });
         services = createServices(mockConfig({}), actions, axiosInst);
-        store = configureStore(createBrowserHistory(), services);
+        store = configureStore(createBrowserHistory(), services, config);
         localStorage.clear();
     });
 
index 0bc351bbe4c6c6aebbc48f22688d78b258e31243..a6e0cbbe8556459a51abf0f004f6fd90145b9120 100644 (file)
@@ -69,6 +69,7 @@ import { ownerNameReducer } from '~/store/owner-name/owner-name-reducer';
 import { SubprocessMiddlewareService } from '~/store/subprocess-panel/subprocess-panel-middleware-service';
 import { SUBPROCESS_PANEL_ID } from '~/store/subprocess-panel/subprocess-panel-actions';
 import { ALL_PROCESSES_PANEL_ID } from './all-processes-panel/all-processes-panel-action';
+import { Config } from '~/common/config';
 
 const composeEnhancers =
     (process.env.NODE_ENV === 'development' &&
@@ -80,7 +81,7 @@ export type RootState = ReturnType<ReturnType<typeof createRootReducer>>;
 
 export type RootStore = Store<RootState, Action> & { dispatch: Dispatch<any> };
 
-export function configureStore(history: History, services: ServiceRepository): RootStore {
+export function configureStore(history: History, services: ServiceRepository, config: Config): RootStore {
     const rootReducer = createRootReducer(services);
 
     const projectPanelMiddleware = dataExplorerMiddleware(
@@ -135,8 +136,7 @@ export function configureStore(history: History, services: ServiceRepository): R
         const state = store.getState();
 
         if (state.auth && state.auth.apiToken) {
-            const { apiToken } = state.auth;
-            handleRedirects(apiToken);
+            handleRedirects(config);
         }
 
         return next(action);
index 4ecdef7019b1ad2c48284c9661a5fdb56fbb8236..f6038b80103d9e8b96bf5c63cd0a572298303492 100644 (file)
@@ -5,19 +5,18 @@
 import { connect } from "react-redux";
 import { RootState } from "../../../store/store";
 import { getNodeValue } from "~/models/tree";
-import { CollectionFileType } from "~/models/collection-file";
 import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
 import { CopyToClipboardAction } from "./copy-to-clipboard-action";
 
 const mapStateToProps = (state: RootState) => {
     const { resource } = state.contextMenu;
     const currentCollectionUuid = state.collectionPanel.item ? state.collectionPanel.item.uuid : '';
+    const { keepWebServiceUrl } = state.auth.config;
     if (resource && resource.menuKind === ContextMenuKind.COLLECTION_FILES_ITEM) {
         const file = getNodeValue(resource.uuid)(state.collectionPanelFiles);
         if (file) {
             return {
-                href: file.url,
-                download: file.type === CollectionFileType.DIRECTORY ? undefined : file.name,
+                href: file.url.replace(keepWebServiceUrl, ''),
                 kind: 'file',
                 currentCollectionUuid
             };
index 0a202daf21085513acc2ae62f00c43e866393d4c..cdc0c8294ca01f75e06ab59335633a1cab0ae304 100644 (file)
@@ -6,7 +6,6 @@ import { connect } from "react-redux";
 import { RootState } from "../../../store/store";
 import { FileViewerAction } from '~/views-components/context-menu/actions/file-viewer-action';
 import { getNodeValue } from "~/models/tree";
-import { CollectionFileType } from "~/models/collection-file";
 import { ContextMenuKind } from '~/views-components/context-menu/context-menu';
 
 const mapStateToProps = (state: RootState) => {
@@ -17,7 +16,6 @@ const mapStateToProps = (state: RootState) => {
         if (file) {
             return {
                 href: file.url,
-                download: file.type === CollectionFileType.DIRECTORY ? undefined : file.name,
                 kind: 'file',
                 currentCollectionUuid
             };
index aadc1d11a14c26c4aa89fccdf52fdf1d39d7f001..9332d170f82856bb714b7c05ff99c4377a6a67bf 100644 (file)
@@ -6,9 +6,9 @@ import { connect } from "react-redux";
 import { RootState } from "../../../store/store";
 import { DownloadAction } from "./download-action";
 import { getNodeValue } from "../../../models/tree";
-import { CollectionFileType } from "../../../models/collection-file";
 import { ContextMenuKind } from '../context-menu';
 import { filterCollectionFilesBySelection } from "~/store/collection-panel/collection-panel-files/collection-panel-files-state";
+import { sanitizeToken } from "./helpers";
 
 const mapStateToProps = (state: RootState) => {
     const { resource } = state.contextMenu;
@@ -17,8 +17,7 @@ const mapStateToProps = (state: RootState) => {
         const file = getNodeValue(resource.uuid)(state.collectionPanelFiles);
         if (file) {
             return {
-                href: file.url,
-                download: file.type === CollectionFileType.DIRECTORY ? undefined : file.name,
+                href: sanitizeToken(file.url, false),
                 kind: 'file',
                 currentCollectionUuid
             };
@@ -26,8 +25,7 @@ const mapStateToProps = (state: RootState) => {
     } else {
         const files = filterCollectionFilesBySelection(state.collectionPanelFiles, true);
         return {
-            href: files.map(file => file.url),
-            download: files.map(file => file.name),
+            href: files.map(file => sanitizeToken(file.url, false)),
             kind: 'files',
             currentCollectionUuid
         };
index a2c32bea875e32524be04532dd90957e6da06675..e58ea6a7888461599c8d45dd9dc663c0306b7710 100644 (file)
@@ -8,15 +8,13 @@ import { OpenIcon } from "~/components/icon/icon";
 import { sanitizeToken } from "./helpers";
 
 export const FileViewerAction = (props: { href?: any, download?: any, onClick?: () => void, kind?: string, currentCollectionUuid?: string; }) => {
-    const fileProps = props.download ? { download: props.download } : {};
 
     return props.href
         ? <a
             style={{ textDecoration: 'none' }}
-            href={sanitizeToken(props.href)}
+            href={sanitizeToken(props.href, false)}
             target="_blank"
-            onClick={props.onClick}
-            {...fileProps}>
+            onClick={props.onClick}>
             <ListItem button>
                     <ListItemIcon>
                         <OpenIcon />
index a8cc24b31eb982e7a36c559f99583fc37e78d40a..3836860626a8363554ae1df135975a7a07c204ba 100644 (file)
@@ -11,6 +11,7 @@ export const sanitizeToken = (href: string, tokenAsQueryParam: boolean = true):
 
 export const getClipboardUrl = (href: string): string => {
     const { origin } = window.location;
+    const url = sanitizeToken(href, false);
 
-    return `${origin}?redirectTo=${sanitizeToken(href, false)}`;
+    return `${origin}?redirectTo=${url}`;
 };
\ No newline at end of file