From 3b77d9eb97f2beb526a24329166e506cbea2db1a Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 1 Apr 2020 10:37:58 -0700 Subject: [PATCH 1/4] [Reporting] Fix URLs in job params when basePath includes namespace suffix --- .../public/lib/reporting_api_client.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts index cddfcd3ec855a..d262c2b030dcb 100644 --- a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts +++ b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts @@ -9,12 +9,7 @@ import rison from 'rison-node'; import { HttpSetup } from 'src/core/public'; import { add } from './job_completion_notifications'; -import { - API_LIST_URL, - API_BASE_URL, - API_BASE_GENERATE, - REPORTING_MANAGEMENT_HOME, -} from '../../constants'; +import { API_LIST_URL, API_BASE_GENERATE, REPORTING_MANAGEMENT_HOME } from '../../constants'; import { JobId, SourceJob } from '../..'; export interface JobQueueEntry { @@ -129,12 +124,17 @@ export class ReportingAPIClient { }); }; + /* + * Return a string to queue a job, with the job params encoded in the query string of the URL. Used for copying POST URL + */ public getReportingJobPath = (exportType: string, jobParams: JobParams) => { const params = stringify({ jobParams: rison.encode(jobParams) }); - - return `${this.http.basePath.prepend(API_BASE_URL)}/${exportType}?${params}`; + return `${this.http.basePath.prepend(API_BASE_GENERATE)}/${exportType}?${params}`; }; + /* + * Sends a request to queue a job, with the job params in the POST body + */ public createReportingJob = async (exportType: string, jobParams: any) => { const jobParamsRison = rison.encode(jobParams); const resp = await this.http.post(`${API_BASE_GENERATE}/${exportType}`, { @@ -154,5 +154,5 @@ export class ReportingAPIClient { public getDownloadLink = (jobId: JobId) => this.http.basePath.prepend(`${API_LIST_URL}/download/${jobId}`); - public getBasePath = () => this.http.basePath.get(); + public getBasePath = () => this.http.basePath.serverBasePath; // server basePath as configured, not including namespace suffix } From 19a7a0519c967ea1a737d3078b25136b28267380 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 1 Apr 2020 11:44:17 -0700 Subject: [PATCH 2/4] canvas fix --- .../workpad_header/workpad_export/index.ts | 4 ++-- .../workpad_header/workpad_export/utils.test.ts | 10 +++++++--- .../workpad_header/workpad_export/utils.ts | 12 ++++++------ 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts index 949264fcc9fdb..b0083eb4f87e2 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/index.ts @@ -57,7 +57,7 @@ export const WorkpadExport = compose( ({ workpad, pageCount, kibana }: Props & WithKibanaProps): ComponentProps => ({ getExportUrl: type => { if (type === 'pdf') { - const pdfUrl = getPdfUrl(workpad, { pageCount }, kibana.services.http.basePath.prepend); + const pdfUrl = getPdfUrl(workpad, { pageCount }, kibana.services.http.basePath); return getAbsoluteUrl(pdfUrl); } @@ -78,7 +78,7 @@ export const WorkpadExport = compose( onExport: type => { switch (type) { case 'pdf': - return createPdf(workpad, { pageCount }, kibana.services.http.basePath.prepend) + return createPdf(workpad, { pageCount }, kibana.services.http.basePath) .then(({ data }: { data: { job: { id: string } } }) => { notify.info(strings.getExportPDFMessage(), { title: strings.getExportPDFTitle(workpad.name), diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts index ceaf82c1c07d6..b856a1dd28f20 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts @@ -9,12 +9,16 @@ jest.mock('../../../../common/lib/fetch'); import { getPdfUrl, createPdf } from './utils'; import { workpads } from '../../../../__tests__/fixtures/workpads'; import { fetch } from '../../../../common/lib/fetch'; +import { IBasePath } from 'kibana/public'; -const addBasePath = jest.fn().mockImplementation(s => `basepath/${s}`); +const basePath = ({ + prepend: jest.fn().mockImplementation(s => `basepath/s/spacey/${s}`), + serverBasePath: `basepath`, +} as unknown) as IBasePath; const workpad = workpads[0]; test('getPdfUrl returns the correct url', () => { - const url = getPdfUrl(workpad, { pageCount: 2 }, addBasePath); + const url = getPdfUrl(workpad, { pageCount: 2 }, basePath); expect(url).toMatchInlineSnapshot( `"basepath//api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FPhoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas%20workpad',relativeUrls:!(%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F1,%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F2),title:'base%20workpad')"` @@ -22,7 +26,7 @@ test('getPdfUrl returns the correct url', () => { }); test('createPdf posts to create the pdf', () => { - createPdf(workpad, { pageCount: 2 }, addBasePath); + createPdf(workpad, { pageCount: 2 }, basePath); expect(fetch.post).toBeCalled(); diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.ts index 5adbf4ce66c13..dc99c0687f388 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.ts @@ -6,6 +6,7 @@ import rison from 'rison-node'; // @ts-ignore Untyped local. +import { IBasePath } from 'kibana/public'; import { fetch } from '../../../../common/lib/fetch'; import { CanvasWorkpad } from '../../../../types'; import { url } from '../../../../../../../../src/plugins/kibana_utils/public'; @@ -17,9 +18,7 @@ interface PageCount { pageCount: number; } -type AddBasePath = (url: string) => string; - -type Arguments = [CanvasWorkpad, PageCount, AddBasePath]; +type Arguments = [CanvasWorkpad, PageCount, IBasePath]; interface PdfUrlData { createPdfUri: string; @@ -29,10 +28,11 @@ interface PdfUrlData { function getPdfUrlParts( { id, name: title, width, height }: CanvasWorkpad, { pageCount }: PageCount, - addBasePath: (path: string) => string + basePath: IBasePath ): PdfUrlData { - const reportingEntry = addBasePath('/api/reporting/generate'); - const canvasEntry = '/app/canvas#'; + const reportingEntry = basePath.prepend('/api/reporting/generate'); + const urlPrefix = basePath.get().replace(basePath.serverBasePath, ''); // for Spaces prefix, which is included in basePath.get() + const canvasEntry = `${urlPrefix}/app/canvas#`; // The viewport in Reporting by specifying the dimensions. In order for things to work, // we need a viewport that will include all of the pages in the workpad. The viewport From d39c85c2154538e9308b0e00c921782abc60a335 Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 1 Apr 2020 12:02:49 -0700 Subject: [PATCH 3/4] cleanup --- .../components/workpad_header/workpad_export/utils.test.ts | 1 + .../plugins/reporting/public/lib/reporting_api_client.ts | 7 +++++-- .../share_context_menu/register_pdf_png_reporting.tsx | 5 +++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts index b856a1dd28f20..03639df8dea27 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts @@ -13,6 +13,7 @@ import { IBasePath } from 'kibana/public'; const basePath = ({ prepend: jest.fn().mockImplementation(s => `basepath/s/spacey/${s}`), + get: () => 'basepath/s/spacey', serverBasePath: `basepath`, } as unknown) as IBasePath; const workpad = workpads[0]; diff --git a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts index d262c2b030dcb..b6c33860752d6 100644 --- a/x-pack/plugins/reporting/public/lib/reporting_api_client.ts +++ b/x-pack/plugins/reporting/public/lib/reporting_api_client.ts @@ -125,7 +125,7 @@ export class ReportingAPIClient { }; /* - * Return a string to queue a job, with the job params encoded in the query string of the URL. Used for copying POST URL + * Return a URL to queue a job, with the job params encoded in the query string of the URL. Used for copying POST URL */ public getReportingJobPath = (exportType: string, jobParams: JobParams) => { const params = stringify({ jobParams: rison.encode(jobParams) }); @@ -154,5 +154,8 @@ export class ReportingAPIClient { public getDownloadLink = (jobId: JobId) => this.http.basePath.prepend(`${API_LIST_URL}/download/${jobId}`); - public getBasePath = () => this.http.basePath.serverBasePath; // server basePath as configured, not including namespace suffix + /* + * provides the raw server basePath to allow it to be stripped out from relativeUrls in job params + */ + public getServerBasePath = () => this.http.basePath.serverBasePath; } diff --git a/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx b/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx index e9eaa9c2ed2a1..2a955ea398bd4 100644 --- a/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx +++ b/x-pack/plugins/reporting/public/share_context_menu/register_pdf_png_reporting.tsx @@ -58,9 +58,10 @@ export const reportingPDFPNGProvider = ({ } const getReportingJobParams = () => { + // Relative URL must have URL prefix (Spaces ID prefix), but not server basePath // Replace hashes with original RISON values. const relativeUrl = shareableUrl.replace( - window.location.origin + apiClient.getBasePath(), + window.location.origin + apiClient.getServerBasePath(), '' ); @@ -80,7 +81,7 @@ export const reportingPDFPNGProvider = ({ const getPngJobParams = () => { // Replace hashes with original RISON values. const relativeUrl = shareableUrl.replace( - window.location.origin + apiClient.getBasePath(), + window.location.origin + apiClient.getServerBasePath(), '' ); From b25e24ed35ad04e261b9e69a91ce2111f7c1321d Mon Sep 17 00:00:00 2001 From: Timothy Sullivan Date: Wed, 1 Apr 2020 12:10:06 -0700 Subject: [PATCH 4/4] update snapshots in tests --- .../components/workpad_header/workpad_export/utils.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts index 03639df8dea27..6c7d7ddd0a793 100644 --- a/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts +++ b/x-pack/legacy/plugins/canvas/public/components/workpad_header/workpad_export/utils.test.ts @@ -22,7 +22,7 @@ test('getPdfUrl returns the correct url', () => { const url = getPdfUrl(workpad, { pageCount: 2 }, basePath); expect(url).toMatchInlineSnapshot( - `"basepath//api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FPhoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas%20workpad',relativeUrls:!(%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F1,%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F2),title:'base%20workpad')"` + `"basepath/s/spacey//api/reporting/generate/printablePdf?jobParams=(browserTimezone:America%2FPhoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas%20workpad',relativeUrls:!(%2Fs%2Fspacey%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F1,%2Fs%2Fspacey%2Fapp%2Fcanvas%23%2Fexport%2Fworkpad%2Fpdf%2Fbase-workpad%2Fpage%2F2),title:'base%20workpad')"` ); }); @@ -33,10 +33,10 @@ test('createPdf posts to create the pdf', () => { const args = (fetch.post as jest.MockedFunction).mock.calls[0]; - expect(args[0]).toMatchInlineSnapshot(`"basepath//api/reporting/generate/printablePdf"`); + expect(args[0]).toMatchInlineSnapshot(`"basepath/s/spacey//api/reporting/generate/printablePdf"`); expect(args[1]).toMatchInlineSnapshot(` Object { - "jobParams": "(browserTimezone:America/Phoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas workpad',relativeUrls:!(/app/canvas#/export/workpad/pdf/base-workpad/page/1,/app/canvas#/export/workpad/pdf/base-workpad/page/2),title:'base workpad')", + "jobParams": "(browserTimezone:America/Phoenix,layout:(dimensions:(height:0,width:0),id:preserve_layout),objectType:'canvas workpad',relativeUrls:!(/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/1,/s/spacey/app/canvas#/export/workpad/pdf/base-workpad/page/2),title:'base workpad')", } `); });