Files
2026-03-06 07:22:00 -05:00

58 lines
2.0 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JiraProvider = void 0;
const PRIORITY_MAP = {
critical: 'Highest',
high: 'High',
medium: 'Medium',
low: 'Low',
};
class JiraProvider {
constructor(host, token, username, projectKey) {
this.host = host;
this.token = token;
this.username = username;
this.projectKey = projectKey;
}
async sendFinding(finding) {
const stepsSection = finding.steps && finding.steps.length > 0
? `\n\nReproduction Steps:\n${finding.steps.map((s, i) => `${i + 1}. ${s}`).join('\n')}`
: '';
const body = {
fields: {
project: { key: this.projectKey },
summary: `[ABE] [${finding.severity.toUpperCase()}] ${finding.title}`,
description: {
type: 'doc',
version: 1,
content: [
{
type: 'paragraph',
content: [{ type: 'text', text: `${finding.description}${stepsSection}` }],
},
],
},
issuetype: { name: 'Bug' },
priority: { name: PRIORITY_MAP[finding.severity] ?? 'Medium' },
labels: ['abe-finding', `severity-${finding.severity}`],
},
};
const auth = Buffer.from(`${this.username}:${this.token}`).toString('base64');
const url = `${this.host.replace(/\/$/, '')}/rest/api/3/issue`;
const res = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`,
},
body: JSON.stringify(body),
signal: AbortSignal.timeout(15000),
});
if (!res.ok) {
const text = await res.text();
throw new Error(`Jira API error ${res.status}: ${text}`);
}
}
}
exports.JiraProvider = JiraProvider;