16812: Cleared token code 16812-token-appears-in-the-download-URL
authorDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Mon, 19 Oct 2020 19:37:24 +0000 (21:37 +0200)
committerDaniel Kutyła <daniel.kutyla@contractors.roche.com>
Mon, 19 Oct 2020 19:37:24 +0000 (21:37 +0200)
Arvados-DCO-1.1-Signed-off-by: Daniel Kutyła <daniel.kutyla@contractors.roche.com>

src/services/collection-service/collection-service.ts
src/store/open-in-new-tab/open-in-new-tab.actions.ts [new file with mode: 0644]
src/views-components/context-menu/actions/download-action.tsx
src/views-components/context-menu/actions/download-collection-file-action.tsx
src/views-components/context-menu/actions/helpers.test.ts
src/views-components/context-menu/actions/helpers.ts

index 90441a645f49d92d622fb0dd689fdaee9604bc51..0aa0aa84de4f476866c60cccb68b5dc2acc9bcb9 100644 (file)
@@ -65,8 +65,8 @@ export class CollectionService extends TrashableResourceService<CollectionResour
             ? this.webdavClient.defaults.baseURL.slice(0, -1)
             : this.webdavClient.defaults.baseURL;
         const apiToken = this.authService.getApiToken();
-        const splittedApiToken = apiToken ? apiToken.split('/') : [];
-        const userApiToken = `/t=${splittedApiToken[2]}/`;
+        const encodedApiToken = apiToken ? encodeURI(apiToken) : '';
+        const userApiToken = `/t=${encodedApiToken}/`;
         const splittedPrevFileUrl = file.url.split('/');
         const url = `${baseUrl}/${splittedPrevFileUrl[1]}${userApiToken}${splittedPrevFileUrl.slice(2).join('/')}`;
         return {
diff --git a/src/store/open-in-new-tab/open-in-new-tab.actions.ts b/src/store/open-in-new-tab/open-in-new-tab.actions.ts
new file mode 100644 (file)
index 0000000..42bdc4c
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Dispatch } from 'redux';
+import { ResourceKind } from '~/models/resource';
+import { unionize, ofType } from '~/common/unionize';
+
+export const openInNewTabActions = unionize({
+    COPY_STORE: ofType<{}>(),
+    OPEN_COLLECTION_IN_NEW_TAB: ofType<string>(),
+    OPEN_PROJECT_IN_NEW_TAB: ofType<string>()
+});
+
+export const openInNewTabAction = (resource: any) => (dispatch: Dispatch) => {
+    const { uuid, kind } = resource;
+
+    dispatch(openInNewTabActions.COPY_STORE());
+
+    if (kind === ResourceKind.COLLECTION) {
+        dispatch(openInNewTabActions.OPEN_COLLECTION_IN_NEW_TAB(uuid));
+    }
+    if (kind === ResourceKind.PROJECT) {
+        dispatch(openInNewTabActions.OPEN_PROJECT_IN_NEW_TAB(uuid));
+    }
+
+    console.log(uuid);
+};
\ No newline at end of file
index 7468954fdd97d293837dd8edfebbc0d5a62a241a..86694c8b5f7b1de7bfa179dd59e2e7b5a0790499 100644 (file)
@@ -47,7 +47,7 @@ export const DownloadAction = (props: { href?: any, download?: any, onClick?: ()
     return props.href || props.kind === 'files'
         ? <a
             style={{ textDecoration: 'none' }}
-            href={props.kind === 'files' ? undefined : `${props.href}?disposition=attachment`}
+            href={props.kind === 'files' ? undefined : `${props.href}&disposition=attachment`}
             onClick={props.onClick}
             {...downloadProps}>
             <ListItem button onClick={() => props.kind === 'files' ? createZip(props.href, props.download) : undefined}>
index 7849109d3467be508ad0dd67e3f43474490d3393..3e4e4a0ba7929418ebc80694768716eb072d4c4d 100644 (file)
@@ -8,6 +8,7 @@ import { DownloadAction } from "./download-action";
 import { getNodeValue } from "../../../models/tree";
 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;
@@ -16,7 +17,7 @@ const mapStateToProps = (state: RootState) => {
         const file = getNodeValue(resource.uuid)(state.collectionPanelFiles);
         if (file) {
             return {
-                href: file.url,
+                href: sanitizeToken(file.url, true),
                 kind: 'file',
                 currentCollectionUuid
             };
index 6aaacc2fc63c393eb4364d85daff240313d77dab..9750a1cc6c8203fd45bf2d7f72c03bbfccf89adf 100644 (file)
@@ -6,7 +6,7 @@ import { sanitizeToken, getClipboardUrl } from "./helpers";
 
 describe('helpers', () => {
     // given
-    const url = 'https://collections.ardev.roche.com/c=ardev-4zz18-k0hamvtwyit6q56/t=1ha4ykd3w14ed19b2gh3uyjrjup38vsx27x1utwdne0bxcfg5d/LIMS/1.html';
+    const url = 'https://collections.ardev.roche.com/c=ardev-4zz18-k0hamvtwyit6q56/t=v2/arlog-gj3su-stk5unu8570brvs/fryzaq6z1ow1npak5nngldtkoup918isrvlualf134uf1fbtd/LIMS/1.html';
 
     describe('sanitizeToken', () => {
         it('should sanitize token from the url', () => {
@@ -14,7 +14,7 @@ describe('helpers', () => {
             const result = sanitizeToken(url);
 
             // then
-            expect(result).toBe('https://collections.ardev.roche.com/c=ardev-4zz18-k0hamvtwyit6q56/LIMS/1.html?api_token=1ha4ykd3w14ed19b2gh3uyjrjup38vsx27x1utwdne0bxcfg5d');
+            expect(result).toBe('https://collections.ardev.roche.com/c=ardev-4zz18-k0hamvtwyit6q56/LIMS/1.html?api_token=v2/arlog-gj3su-stk5unu8570brvs/fryzaq6z1ow1npak5nngldtkoup918isrvlualf134uf1fbtd');
         });
     });
 
index 419c796d1a769f6a156d2c7c9aabc16be293fb60..8dfcaca0e30853d9f317f8aaa460d58dae25cbc5 100644 (file)
@@ -4,8 +4,8 @@
 
 export const sanitizeToken = (href: string, tokenAsQueryParam: boolean = true): string => {
     const [prefix, suffix] = href.split('/t=');
-    const [token, ...rest] = suffix.split('/');
-
+    const [token1, token2, token3, ...rest] = suffix.split('/');
+    const token = `${token1}/${token2}/${token3}`;
     const sep = href.indexOf("?") > -1 ? "&" : "?";
 
     return `${[prefix, ...rest].join('/')}${tokenAsQueryParam ? `${sep}api_token=${token}` : ''}`;