diff --git a/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts b/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts index bb1d16be6b01c..2284cb8873de1 100644 --- a/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts +++ b/packages/nodes-base/credentials/JiraSoftwareCloudApi.credentials.ts @@ -1,4 +1,6 @@ import { + IAuthenticateGeneric, + ICredentialTestRequest, ICredentialType, INodeProperties, } from 'n8n-workflow'; @@ -29,4 +31,19 @@ export class JiraSoftwareCloudApi implements ICredentialType { placeholder: 'https://example.atlassian.net', }, ]; + authenticate: IAuthenticateGeneric = { + type: 'generic', + properties: { + auth:{ + username: '={{$credentials.email}}', + password: '={{$credentials.apiToken}}', + }, + }, + }; + test: ICredentialTestRequest = { + request: { + baseURL: '={{$credentials?.domain}}', + url: '/rest/api/2/project', + }, + }; } diff --git a/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts b/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts index 6817bacdc245b..f9d90d5448872 100644 --- a/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts +++ b/packages/nodes-base/credentials/JiraSoftwareServerApi.credentials.ts @@ -1,4 +1,6 @@ import { + IAuthenticateGeneric, + ICredentialTestRequest, ICredentialType, INodeProperties, } from 'n8n-workflow'; @@ -32,4 +34,19 @@ export class JiraSoftwareServerApi implements ICredentialType { placeholder: 'https://example.com', }, ]; + authenticate: IAuthenticateGeneric = { + type: 'generic', + properties: { + auth:{ + username: '={{$credentials.email}}', + password: '={{$credentials.password}}', + }, + }, + }; + test: ICredentialTestRequest = { + request: { + baseURL: '={{$credentials?.domain}}', + url: '/rest/api/2/project', + }, + }; } diff --git a/packages/nodes-base/nodes/Jira/GenericFunctions.ts b/packages/nodes-base/nodes/Jira/GenericFunctions.ts index 32e485247a1e5..b0a8b0d8e8b1d 100644 --- a/packages/nodes-base/nodes/Jira/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Jira/GenericFunctions.ts @@ -18,28 +18,22 @@ import { } from 'n8n-workflow'; export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, endpoint: string, method: string, body: any = {}, query?: IDataObject, uri?: string, option: IDataObject = {}): Promise { // tslint:disable-line:no-any - let data; let domain; const jiraVersion = this.getNodeParameter('jiraVersion', 0) as string; - let jiraCredentials: ICredentialDataDecryptedObject; - if (jiraVersion === 'server') { - jiraCredentials = await this.getCredentials('jiraSoftwareServerApi'); - } else { - jiraCredentials = await this.getCredentials('jiraSoftwareCloudApi'); - } + let domain = ''; + let credentialType: string; if (jiraVersion === 'server') { - domain = jiraCredentials!.domain; - data = Buffer.from(`${jiraCredentials!.email}:${jiraCredentials!.password}`).toString('base64'); + domain = (await this.getCredentials('jiraSoftwareServerApi')).domain as string; + credentialType = 'jiraSoftwareServerApi'; } else { - domain = jiraCredentials!.domain; - data = Buffer.from(`${jiraCredentials!.email}:${jiraCredentials!.apiToken}`).toString('base64'); + domain = (await this.getCredentials('jiraSoftwareCloudApi')).domain as string; + credentialType = 'jiraSoftwareCloudApi'; } const options: OptionsWithUri = { headers: { - Authorization: `Basic ${data}`, Accept: 'application/json', 'Content-Type': 'application/json', 'X-Atlassian-Token': 'no-check', @@ -64,7 +58,7 @@ export async function jiraSoftwareCloudApiRequest(this: IHookFunctions | IExecut } try { - return await this.helpers.request!(options); + return await this.helpers.requestWithAuthentication.call(this, credentialType, options); } catch (error) { throw new NodeApiError(this.getNode(), error as JsonObject); } diff --git a/packages/nodes-base/nodes/Jira/Jira.node.ts b/packages/nodes-base/nodes/Jira/Jira.node.ts index 0176ea16caf7a..a2d0a08eb6f9e 100644 --- a/packages/nodes-base/nodes/Jira/Jira.node.ts +++ b/packages/nodes-base/nodes/Jira/Jira.node.ts @@ -1,6 +1,7 @@ + import { - OptionsWithUri, -} from 'request'; + mergeWith, +} from 'lodash'; import { IExecuteFunctions, @@ -9,16 +10,12 @@ import { import { IBinaryData, IBinaryKeyData, - ICredentialsDecrypted, - ICredentialTestFunctions, IDataObject, ILoadOptionsFunctions, - INodeCredentialTestResult, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, - JsonObject, NodeOperationError, } from 'n8n-workflow'; @@ -82,7 +79,6 @@ export class Jira implements INodeType { ], }, }, - testedBy: 'jiraSoftwareApiTest', }, { name: 'jiraSoftwareServerApi', @@ -94,7 +90,6 @@ export class Jira implements INodeType { ], }, }, - testedBy: 'jiraSoftwareApiTest', }, ], properties: [ @@ -155,40 +150,6 @@ export class Jira implements INodeType { }; methods = { - credentialTest: { - async jiraSoftwareApiTest(this: ICredentialTestFunctions, credential: ICredentialsDecrypted): Promise { - const credentials = credential.data; - const data = Buffer.from(`${credentials!.email}:${credentials!.password || credentials!.apiToken}`).toString('base64'); - - const options: OptionsWithUri = { - headers: { - Authorization: `Basic ${data}`, - Accept: 'application/json', - 'Content-Type': 'application/json', - 'X-Atlassian-Token': 'no-check', - }, - method: 'GET', - uri: `${credentials!.domain}/rest/api/2/project`, - qs: { - recent: 0, - }, - json: true, - timeout: 5000, - }; - try { - await this.helpers.request!(options); - } catch (err) { - return { - status: 'Error', - message: `Connection details not valid: ${(err as JsonObject).message}`, - }; - } - return { - status: 'OK', - message: 'Authentication successful!', - }; - }, - }, loadOptions: { // Get all the projects to display them to user so that he can // select them easily @@ -651,6 +612,17 @@ export class Jira implements INodeType { responseData = await jiraSoftwareCloudApiRequest.call(this, `/api/2/issue/${issueKey}`, 'GET', {}, qs); if (simplifyOutput) { + // Use rendered fields if requested and available + qs.expand = qs.expand || ''; + if ( + (qs.expand as string).toLowerCase().indexOf('renderedfields') !== -1 && + responseData.renderedFields && Object.keys(responseData.renderedFields).length + ) { + responseData.fields = mergeWith( + responseData.fields, + responseData.renderedFields, + (a,b) => b === null ? a : b); + } returnData.push(simplifyIssueOutput(responseData)); } else { returnData.push(responseData);