Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

💄 Use Jira rendered fields with simplify option #3323

Merged
merged 8 commits into from
Jul 4, 2022
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';
Expand Down Expand Up @@ -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',
},
};
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';
Expand Down Expand Up @@ -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',
},
};
}
20 changes: 7 additions & 13 deletions packages/nodes-base/nodes/Jira/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<any> { // 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',
Expand All @@ -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);
}
Expand Down
56 changes: 14 additions & 42 deletions packages/nodes-base/nodes/Jira/Jira.node.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

import {
OptionsWithUri,
} from 'request';
mergeWith,
} from 'lodash';

import {
IExecuteFunctions,
Expand All @@ -9,16 +10,12 @@ import {
import {
IBinaryData,
IBinaryKeyData,
ICredentialsDecrypted,
ICredentialTestFunctions,
IDataObject,
ILoadOptionsFunctions,
INodeCredentialTestResult,
INodeExecutionData,
INodePropertyOptions,
INodeType,
INodeTypeDescription,
JsonObject,
NodeOperationError,
} from 'n8n-workflow';

Expand Down Expand Up @@ -82,7 +79,6 @@ export class Jira implements INodeType {
],
},
},
testedBy: 'jiraSoftwareApiTest',
},
{
name: 'jiraSoftwareServerApi',
Expand All @@ -94,7 +90,6 @@ export class Jira implements INodeType {
],
},
},
testedBy: 'jiraSoftwareApiTest',
},
],
properties: [
Expand Down Expand Up @@ -155,40 +150,6 @@ export class Jira implements INodeType {
};

methods = {
credentialTest: {
async jiraSoftwareApiTest(this: ICredentialTestFunctions, credential: ICredentialsDecrypted): Promise<INodeCredentialTestResult> {
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
Expand Down Expand Up @@ -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);
Expand Down