Skip to content

Commit

Permalink
feat(Jira Software Node): Personal Access Token credential type (#11038)
Browse files Browse the repository at this point in the history
  • Loading branch information
GKdeVries authored Jan 22, 2025
1 parent 69c2153 commit 1c7a38f
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import type {
IAuthenticateGeneric,
ICredentialTestRequest,
ICredentialType,
INodeProperties,
} from 'n8n-workflow';

export class JiraSoftwareServerPatApi implements ICredentialType {
name = 'jiraSoftwareServerPatApi';

displayName = 'Jira SW Server (PAT) API';

documentationUrl = 'jira';

properties: INodeProperties[] = [
{
displayName: 'Personal Access Token',
name: 'personalAccessToken',
typeOptions: { password: true },
type: 'string',
default: '',
},
{
displayName: 'Domain',
name: 'domain',
type: 'string',
default: '',
placeholder: 'https://example.com',
},
];

authenticate: IAuthenticateGeneric = {
type: 'generic',
properties: {
headers: {
Authorization: '=Bearer {{$credentials.personalAccessToken}}',
},
},
};

test: ICredentialTestRequest = {
request: {
baseURL: '={{$credentials?.domain}}',
url: '/rest/api/2/project',
},
};
}
5 changes: 4 additions & 1 deletion packages/nodes-base/nodes/Jira/GenericFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ export async function jiraSoftwareCloudApiRequest(
if (jiraVersion === 'server') {
domain = (await this.getCredentials('jiraSoftwareServerApi')).domain as string;
credentialType = 'jiraSoftwareServerApi';
} else if (jiraVersion === 'serverPat') {
domain = (await this.getCredentials('jiraSoftwareServerPatApi')).domain as string;
credentialType = 'jiraSoftwareServerPatApi';
} else {
domain = (await this.getCredentials('jiraSoftwareCloudApi')).domain as string;
credentialType = 'jiraSoftwareCloudApi';
Expand Down Expand Up @@ -233,7 +236,7 @@ export async function getUsers(this: ILoadOptionsFunctions): Promise<INodeProper
const query: IDataObject = { maxResults };
let endpoint = '/api/2/users/search';

if (jiraVersion === 'server') {
if (jiraVersion === 'server' || jiraVersion === 'serverPat') {
endpoint = '/api/2/user/search';
query.username = "'";
}
Expand Down
36 changes: 26 additions & 10 deletions packages/nodes-base/nodes/Jira/Jira.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ export class Jira implements INodeType {
},
},
},
{
name: 'jiraSoftwareServerPatApi',
required: true,
displayOptions: {
show: {
jiraVersion: ['serverPat'],
},
},
},
],
properties: [
{
Expand All @@ -82,6 +91,10 @@ export class Jira implements INodeType {
name: 'Server (Self Hosted)',
value: 'server',
},
{
name: 'Server Pat (Self Hosted)',
value: 'serverPat',
},
],
default: 'cloud',
},
Expand Down Expand Up @@ -139,7 +152,7 @@ export class Jira implements INodeType {
let endpoint = '';
let projects;

if (jiraVersion === 'server') {
if (jiraVersion === 'server' || jiraVersion === 'serverPat') {
endpoint = '/api/2/project';
projects = await jiraSoftwareCloudApiRequest.call(this, endpoint, 'GET');
} else {
Expand Down Expand Up @@ -502,7 +515,7 @@ export class Jira implements INodeType {
};
}
if (additionalFields.assignee) {
if (jiraVersion === 'server') {
if (jiraVersion === 'server' || jiraVersion === 'serverPat') {
fields.assignee = {
name: additionalFields.assignee as string,
};
Expand All @@ -513,7 +526,7 @@ export class Jira implements INodeType {
}
}
if (additionalFields.reporter) {
if (jiraVersion === 'server') {
if (jiraVersion === 'server' || jiraVersion === 'serverPat') {
fields.reporter = {
name: additionalFields.reporter as string,
};
Expand Down Expand Up @@ -632,7 +645,7 @@ export class Jira implements INodeType {
};
}
if (updateFields.assignee) {
if (jiraVersion === 'server') {
if (jiraVersion === 'server' || jiraVersion === 'serverPat') {
fields.assignee = {
name: updateFields.assignee as string,
};
Expand All @@ -643,7 +656,7 @@ export class Jira implements INodeType {
}
}
if (updateFields.reporter) {
if (jiraVersion === 'server') {
if (jiraVersion === 'server' || jiraVersion === 'serverPat') {
fields.reporter = {
name: updateFields.reporter as string,
};
Expand Down Expand Up @@ -1025,7 +1038,8 @@ export class Jira implements INodeType {
}
}
if (resource === 'issueAttachment') {
const apiVersion = jiraVersion === 'server' ? '2' : ('3' as string);
const apiVersion =
jiraVersion === 'server' || jiraVersion === 'serverPat' ? '2' : ('3' as string);

//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments/#api-rest-api-3-issue-issueidorkey-attachments-post
if (operation === 'add') {
Expand Down Expand Up @@ -1183,7 +1197,8 @@ export class Jira implements INodeType {
}

if (resource === 'issueComment') {
let apiVersion = jiraVersion === 'server' ? '2' : ('3' as string);
let apiVersion =
jiraVersion === 'server' || jiraVersion === 'serverPat' ? '2' : ('3' as string);

//https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-post
if (operation === 'add') {
Expand All @@ -1205,7 +1220,7 @@ export class Jira implements INodeType {
Object.assign(body, options);
if (!jsonParameters) {
const comment = this.getNodeParameter('comment', i) as string;
if (jiraVersion === 'server' || options.wikiMarkup) {
if (jiraVersion === 'server' || jiraVersion === 'serverPat' || options.wikiMarkup) {
Object.assign(body, { body: comment });
} else {
Object.assign(body, {
Expand Down Expand Up @@ -1356,7 +1371,7 @@ export class Jira implements INodeType {
Object.assign(qs, options);
if (!jsonParameters) {
const comment = this.getNodeParameter('comment', i) as string;
if (jiraVersion === 'server' || options.wikiMarkup) {
if (jiraVersion === 'server' || jiraVersion === 'serverPat' || options.wikiMarkup) {
Object.assign(body, { body: comment });
} else {
Object.assign(body, {
Expand Down Expand Up @@ -1407,7 +1422,8 @@ export class Jira implements INodeType {
}

if (resource === 'user') {
const apiVersion = jiraVersion === 'server' ? '2' : ('3' as string);
const apiVersion =
jiraVersion === 'server' || jiraVersion === 'serverPat' ? '2' : ('3' as string);

if (operation === 'create') {
// https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-users/#api-rest-api-3-user-post
Expand Down
14 changes: 14 additions & 0 deletions packages/nodes-base/nodes/Jira/JiraTrigger.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ export class JiraTrigger implements INodeType {
},
},
},
{
displayName: 'Credentials to Connect to Jira',
name: 'jiraSoftwareServerPatApi',
required: true,
displayOptions: {
show: {
jiraVersion: ['serverPat'],
},
},
},
{
// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed
name: 'httpQueryAuth',
Expand Down Expand Up @@ -87,6 +97,10 @@ export class JiraTrigger implements INodeType {
name: 'Server (Self Hosted)',
value: 'server',
},
{
name: 'Server (Pat) (Self Hosted)',
value: 'serverPat',
},
],
default: 'cloud',
},
Expand Down
1 change: 1 addition & 0 deletions packages/nodes-base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"dist/credentials/JenkinsApi.credentials.js",
"dist/credentials/JiraSoftwareCloudApi.credentials.js",
"dist/credentials/JiraSoftwareServerApi.credentials.js",
"dist/credentials/JiraSoftwareServerPatApi.credentials.js",
"dist/credentials/JotFormApi.credentials.js",
"dist/credentials/JwtAuth.credentials.js",
"dist/credentials/Kafka.credentials.js",
Expand Down

0 comments on commit 1c7a38f

Please sign in to comment.