19079: Don't use collection specific url processing for search result clipboard actions
authorStephen Smith <stephen@curii.com>
Thu, 28 Jul 2022 20:02:44 +0000 (16:02 -0400)
committerStephen Smith <stephen@curii.com>
Thu, 28 Jul 2022 20:02:44 +0000 (16:02 -0400)
Arvados-DCO-1.1-Signed-off-by: Stephen Smith <stephen@curii.com>

cypress/integration/search.spec.js
src/routes/routes.ts
src/store/open-in-new-tab/open-in-new-tab.actions.ts
src/views-components/context-menu/actions/copy-to-clipboard-action.tsx
src/views-components/context-menu/actions/helpers.test.ts
src/views-components/context-menu/actions/helpers.ts

index 6f880e7fd6159acf269e5b746fb6f80ee962bb99..86d86877724cb1965367b916592739097987772c 100644 (file)
@@ -127,7 +127,7 @@ describe('Search tests', function() {
         });
     });
 
-    it.only('shows search context menu', function() {
+    it('shows search context menu', function() {
         const colName = `Collection ${Math.floor(Math.random() * Math.floor(999999))}`;
 
         cy.createCollection(adminUser.token, {
index 50689ec37c46ac1fba6d5ff985badeb233944031..22c8f4c8e52414b8d84c99cc439facc4d4f9ecdf 100644 (file)
@@ -66,7 +66,10 @@ export const getResourceUrl = (uuid: string) => {
     }
 };
 
-export const getNavUrl = (uuid: string, config: FederationConfig) => {
+/**
+ * @returns A relative or federated url for the given uuid, with a token for federated WB1 urls
+ */
+export const getNavUrl = (uuid: string, config: FederationConfig, includeToken: boolean = true): string => {
     const path = getResourceUrl(uuid) || "";
     const cls = uuid.substring(0, 5);
     if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
@@ -83,7 +86,9 @@ export const getNavUrl = (uuid: string, config: FederationConfig) => {
             u = new URL(config.remoteHostsConfig[cls].workbench2Url);
         } else {
             u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
-            u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
+            if (includeToken) {
+                u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
+            }
         }
         u.pathname = path;
         return u.toString();
index a363bc03c5c6b7b79527dcc87dcf9f86813cba53..c465aae8695a51291918aa0fd630e57fe8b327c6 100644 (file)
@@ -3,21 +3,25 @@
 // SPDX-License-Identifier: AGPL-3.0
 
 import copy from 'copy-to-clipboard';
-import { getResourceUrl } from 'routes/routes';
-import { getClipboardUrl } from 'views-components/context-menu/actions/helpers';
+import { Dispatch } from 'redux';
+import { getNavUrl } from 'routes/routes';
+import { RootState } from 'store/store';
 
-export const openInNewTabAction = (resource: any) => () => {
-    const url = getResourceUrl(resource.uuid);
+export const openInNewTabAction = (resource: any) => (dispatch: Dispatch, getState: () => RootState) => {
+    const url = getNavUrl(resource.uuid, getState().auth);
 
-    if (url) {
+    if (url[0] === '/') {
         window.open(`${window.location.origin}${url}`, '_blank');
+    } else if (url.length) {
+        window.open(url, '_blank');
     }
 };
 
-export const copyToClipboardAction = (resource: any) => () => {
-    const url = getResourceUrl(resource.uuid);
+export const copyToClipboardAction = (resource: any) => (dispatch: Dispatch, getState: () => RootState) => {
+    // Copy to clipboard omits token to avoid accidental sharing
+    const url = getNavUrl(resource.uuid, getState().auth, false);
 
     if (url) {
-        copy(getClipboardUrl(url, false));
+        copy(url);
     }
 };
index c34087400cf5223930b806b358163e470e60741a..50ed20fd7fb01d2dc0f0cacb8850bbc5bfcec71d 100644 (file)
@@ -6,12 +6,12 @@ import React from "react";
 import copy from 'copy-to-clipboard';
 import { ListItemIcon, ListItemText, ListItem } from "@material-ui/core";
 import { Link } from "components/icon/icon";
-import { getClipboardUrl } from "./helpers";
+import { getCollectionItemClipboardUrl } from "./helpers";
 
 export const CopyToClipboardAction = (props: { href?: any, download?: any, onClick?: () => void, kind?: string, currentCollectionUuid?: string; }) => {
     const copyToClipboard = () => {
         if (props.href) {
-            const clipboardUrl = getClipboardUrl(props.href, true, true);
+            const clipboardUrl = getCollectionItemClipboardUrl(props.href, true, true);
             copy(clipboardUrl);
         }
 
index b3b7f7f8dab5208cf05047d3322061e4a44d2fa6..7776d0e5aacdf976fe081ef9cbb964dd44e04b31 100644 (file)
@@ -2,7 +2,7 @@
 //
 // SPDX-License-Identifier: AGPL-3.0
 
-import { sanitizeToken, getClipboardUrl, getInlineFileUrl } from "./helpers";
+import { sanitizeToken, getCollectionItemClipboardUrl, getInlineFileUrl } from "./helpers";
 
 describe('helpers', () => {
     // given
@@ -22,7 +22,7 @@ describe('helpers', () => {
     describe('getClipboardUrl', () => {
         it('should add redirectTo query param', () => {
             // when
-            const result = getClipboardUrl(url);
+            const result = getCollectionItemClipboardUrl(url);
 
             // then
             expect(result).toBe('http://localhost?redirectToDownload=https://example.com/c=zzzzz-4zz18-0123456789abcde/LIMS/1.html');
index f196074d7e8770dde905e653be6e356c305ceaa5..9140e457afef89affcb573f0c84303640d4014e0 100644 (file)
@@ -14,7 +14,10 @@ export const sanitizeToken = (href: string, tokenAsQueryParam = true): string =>
     return `${[prefix, ...rest].join('/')}${tokenAsQueryParam ? `${sep}api_token=${token}` : ''}`;
 };
 
-export const getClipboardUrl = (href: string, shouldSanitizeToken = true, inline = false): string => {
+/**
+ * @returns A shareable token-free WB2 url that redirects to keep-web after login
+ */
+export const getCollectionItemClipboardUrl = (href: string, shouldSanitizeToken = true, inline = false): string => {
     const { origin } = window.location;
     const url = shouldSanitizeToken ? sanitizeToken(href, false) : href;
     const redirectKey = inline ? REDIRECT_TO_PREVIEW_KEY : REDIRECT_TO_DOWNLOAD_KEY;