From a69155a97647c0017d609aeef2d4ff2b5488be00 Mon Sep 17 00:00:00 2001 From: Paul Bauriegel Date: Thu, 3 Sep 2026 05:33:06 +0000 Subject: [PATCH] fix(Jira Node): Strip trailing slashes from domain URL (#32163) Co-authored-by: RomanDavydchuk Co-authored-by: RomanDavydchuk --- .../JiraSoftwareCloudApi.credentials.ts | 2 +- .../JiraSoftwareServerApi.credentials.ts | 2 +- .../JiraSoftwareServerPatApi.credentials.ts | 2 +- packages/nodes-base/nodes/Jira/GenericFunctions.ts | 3 +++ .../nodes/Jira/__test__/GenericFunctions.test.ts | 14 ++++++++++++++ 5 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts b/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts index 83889b8afc0..25e6a09517e 100644 --- a/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts +++ b/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts @@ -48,7 +48,7 @@ export class JiraSoftwareCloudApi implements ICredentialType { test: ICredentialTestRequest = { request: { - baseURL: '={{$credentials?.domain}}', + baseURL: '={{$credentials.domain?.replace(/\\/+$/, "")}}', url: '/rest/api/2/myself', }, }; diff --git a/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts b/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts index 6a0ed10e265..9faa43c4a26 100644 --- a/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts +++ b/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts @@ -50,7 +50,7 @@ export class JiraSoftwareServerApi implements ICredentialType { test: ICredentialTestRequest = { request: { - baseURL: '={{$credentials?.domain}}', + baseURL: '={{$credentials.domain?.replace(/\\/+$/, "")}}', url: '/rest/api/2/myself', }, }; diff --git a/packages/nodes-base/credentials/JiraSoftwareServerPatApi.credentials.ts b/packages/nodes-base/credentials/JiraSoftwareServerPatApi.credentials.ts index e2b0df52a11..60cdec9e90f 100644 --- a/packages/nodes-base/credentials/JiraSoftwareServerPatApi.credentials.ts +++ b/packages/nodes-base/credentials/JiraSoftwareServerPatApi.credentials.ts @@ -40,7 +40,7 @@ export class JiraSoftwareServerPatApi implements ICredentialType { test: ICredentialTestRequest = { request: { - baseURL: '={{$credentials?.domain}}', + baseURL: '={{$credentials.domain?.replace(/\\/+$/, "")}}', url: '/rest/api/2/myself', }, }; diff --git a/packages/nodes-base/nodes/Jira/GenericFunctions.ts b/packages/nodes-base/nodes/Jira/GenericFunctions.ts index 852d802d160..cfd878efd2d 100644 --- a/packages/nodes-base/nodes/Jira/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Jira/GenericFunctions.ts @@ -66,6 +66,9 @@ export async function jiraSoftwareCloudApiRequest( credentialType = 'jiraSoftwareCloudApi'; } + // Strip trailing slashes from domain to prevent double slashes in URL construction + domain = domain.replace(/\/+$/, ''); + const options: IRequestOptions = { headers: { Accept: 'application/json', diff --git a/packages/nodes-base/nodes/Jira/__test__/GenericFunctions.test.ts b/packages/nodes-base/nodes/Jira/__test__/GenericFunctions.test.ts index 6a5117ad606..721317dcabf 100644 --- a/packages/nodes-base/nodes/Jira/__test__/GenericFunctions.test.ts +++ b/packages/nodes-base/nodes/Jira/__test__/GenericFunctions.test.ts @@ -92,6 +92,20 @@ describe('Jira -> GenericFunctions', () => { ); }); + it('should remove trailing slashes from the domain before making the request', async () => { + mockExecuteFunctions.getNodeParameter.mockReturnValue('cloud'); + mockExecuteFunctions.getCredentials.mockResolvedValue({ + domain: 'https://example.atlassian.net///', + }); + + await jiraSoftwareCloudApiRequest.call(mockExecuteFunctions, '/api/2/myself', 'GET'); + + expect(mockExecuteFunctions.helpers.requestWithAuthentication).toHaveBeenCalledWith( + 'jiraSoftwareCloudApi', + expect.objectContaining({ uri: 'https://example.atlassian.net/rest/api/2/myself' }), + ); + }); + it('should use jiraSoftwareCloudOAuth2Api credential for jiraVersion "cloudOAuth2" and look up cloudId', async () => { const cloudId = 'abc123-cloud-id'; mockExecuteFunctions.getNodeParameter.mockReturnValue('cloudOAuth2');