Skip to content

Commit c3dc5ad

Browse files
committed
Cleanup code and update dependencies
1 parent c2cac9d commit c3dc5ad

File tree

15 files changed

+205
-161
lines changed

15 files changed

+205
-161
lines changed

CODE_OF_CONDUCT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
106106
### 4. Permanent Ban
107107

108108
**Community Impact**: Demonstrating a pattern of violation of community
109-
standards, including sustained inappropriate behavior, harassment of an
109+
standards, including sustained inappropriate behavior, harassment of an
110110
individual, or aggression toward or disparagement of classes of individuals.
111111

112112
**Consequence**: A permanent ban from any sort of public interaction within

package-lock.json

Lines changed: 105 additions & 81 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@
3333
"src/**/*.ejs"
3434
],
3535
"dependencies": {
36-
"axios": "^1.9.0",
36+
"axios": "^1.10.0",
3737
"ejs": "npm:neat-ejs@^3.1.10",
3838
"jsonpath-plus": "^10.3.0"
3939
},
4040
"devDependencies": {
41-
"@eslint/js": "^9.27.0",
41+
"@eslint/js": "^9.30.1",
4242
"c8": "^10.1.3",
43-
"eslint": "^9.27.0",
43+
"eslint": "^9.30.1",
4444
"express": "^5.1.0",
45-
"globals": "^16.2.0",
46-
"mocha": "^11.5.0",
45+
"globals": "^16.3.0",
46+
"mocha": "^11.7.1",
4747
"mocha-junit-reporter": "^2.2.1"
4848
},
4949
"engines": {

src/cli.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
* CLI and environment handling service
44
*/
55

6-
import { existsSync } from "fs";
7-
import { readFile } from "fs/promises";
6+
import { existsSync } from "node:fs";
7+
import { readFile } from "node:fs/promises";
8+
import { join } from "node:path";
89

910
/**
1011
* Statuses expected for the "status" CLI option
@@ -85,8 +86,8 @@ const expectedOptions = [
8586
*/
8687
export async function parseArgs() {
8788
// Read package metadata from package.json
88-
const npmPackageUrl = new URL("../package.json", import.meta.url);
89-
const npmPackage = JSON.parse(await readFile(npmPackageUrl, { encoding: "utf8" }));
89+
const npmPackagePath = join(import.meta.dirname, "../package.json");
90+
const npmPackage = JSON.parse(await readFile(npmPackagePath, { encoding: "utf8" }));
9091

9192
// Show the help message
9293
if (process.argv.some(a => a.match(/^--?h(elp)?$/))) {
@@ -113,7 +114,7 @@ export async function parseArgs() {
113114
// Extract options
114115
for (const opt of expectedOptions) {
115116
// From the command line
116-
const i = process.argv.findIndex(a => a == `--${opt.name}`);
117+
const i = process.argv.findIndex(a => a === `--${opt.name}`);
117118
let value = undefined;
118119
if (i >= 0 && i + 1 < process.argv.length) {
119120
value = process.argv[i + 1];
@@ -157,10 +158,9 @@ export class CliError extends Error {
157158
*
158159
* @param {number} exitCode Process exit code
159160
* @param {string} message Error message
160-
* @param {...any} args Other arguments
161161
*/
162-
constructor(exitCode = 1, message = "", ...args) {
163-
super(message, ...args);
162+
constructor(exitCode = 1, message = "") {
163+
super(message);
164164
this.exitCode = exitCode;
165165
}
166166

src/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Tool configuration service
44
*/
55

6-
import { readFile } from "fs/promises";
6+
import { readFile } from "node:fs/promises";
77
import { JSONPath } from "jsonpath-plus";
88

99
/**

src/defectdojo.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ export class DefectDojoApiClient {
5252
/**
5353
* Fetch engagements by product and name.
5454
*
55-
* @param {string} productId Product id
56-
* @param {string} name Engagement name (optional)
57-
* @returns Engagements
55+
* @param {string|number} productId Product id
56+
* @param {string} [name] Engagement name (optional)
57+
* @returns Promise<*> Engagements
5858
* @throws Request error
5959
*/
6060
async getEngagements(productId, name) {
@@ -66,8 +66,8 @@ export class DefectDojoApiClient {
6666
query.push("o=-updated", "limit=100");
6767
const response = await this.http.get("/engagements?" + query.join("&"));
6868
const engagements = response.data?.results
69-
?.filter(e => !name || e.name === name) // Exact match
70-
?.map(e => ({ ...e, url: `${this.url}/engagement/${e.id}` }))
69+
?.filter(e => !name || e.name === name) // Exact match
70+
?.map(e => ({ ...e, url: `${this.url}/engagement/${e.id}` }))
7171
?? [];
7272
console.log(`[info] Engagements count = ${engagements.length}`);
7373
return engagements;
@@ -81,7 +81,7 @@ export class DefectDojoApiClient {
8181
*
8282
* @param {string[]} engagements Engagements ids
8383
* @param {string[]} statuses Statuses to filter
84-
* @returns Vulnerabilities
84+
* @returns Promise<*> Vulnerabilities
8585
* @throws Request error
8686
*/
8787
async getFindings(engagements, statuses) {

src/exports.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
*/
55

66
import ejs from "ejs";
7-
import { readFile, writeFile } from "fs/promises";
8-
import { dirname, join } from "path";
9-
import { fileURLToPath } from "url";
7+
import { readFile, writeFile } from "node:fs/promises";
8+
import { join } from "node:path";
109
import { resolveField } from "./config.js";
1110

1211
/**
@@ -41,7 +40,7 @@ export async function exportToCSV(_products, _engagements, findings, path, confi
4140
*/
4241
export async function exportToHTML(products, engagements, findings, path, config) {
4342
// Load the template
44-
const templateFile = join(dirname(fileURLToPath(import.meta.url)), "template.ejs");
43+
const templateFile = join(import.meta.dirname, "template.ejs");
4544
const template = await readFile(templateFile, { encoding: "utf8" });
4645

4746
// Export vulnerabilities

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77

88
import { main } from "./main.js";
99

10-
main();
10+
await main();

src/main.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* Export a security debt from DefectDojo.
44
*/
55

6-
import { join } from "path";
6+
import assert from "node:assert/strict";
7+
import { join } from "node:path";
78
import { parseArgs } from "./cli.js";
89
import { loadConfig } from "./config.js";
910
import { DefectDojoApiClient } from "./defectdojo.js";
@@ -16,7 +17,10 @@ export async function main() {
1617

1718
// Load configuration
1819
const config = await loadConfig(opts.config)
19-
.catch((e) => { console.error(`[error] ${e.message}`); process.exit(1); });
20+
.catch((e) => {
21+
console.error(`[error] ${e.message}`);
22+
process.exit(1);
23+
});
2024

2125
// Initialise the DefectDojo API client
2226
const defectDojo = new DefectDojoApiClient(opts.url, opts.token);
@@ -27,38 +31,51 @@ export async function main() {
2731
.reduce(async (prevResults, p) => {
2832
const results = await prevResults;
2933
const product = await defectDojo.getProduct(p)
30-
.catch((e) => { console.error(`[error] ${e.message}`); process.exit(1); });
34+
.catch((e) => {
35+
console.error(`[error] ${e.message}`);
36+
process.exit(1);
37+
});
3138
return [...results, product];
3239
}, []);
3340

3441
// Fetch engagements
3542
const engagements = await products.reduce(async (prevResults, p) => {
3643
const results = await prevResults;
3744
const engagements = await defectDojo.getEngagements(p.id, opts.engagement)
38-
.catch((e) => { console.error(`[error] ${e.message}`); process.exit(1); });
45+
.catch((e) => {
46+
console.error(`[error] ${e.message}`);
47+
process.exit(1);
48+
});
3949
p.engagements = engagements;
4050
return [...results, ...engagements];
4151
}, []);
4252

53+
assert(engagements.length > 0, "No engagement found");
54+
4355
// Fetch vulnerabilities
4456
const findings = await defectDojo
4557
.getFindings(engagements.map(e => e.id), opts.status)
46-
.catch((e) => { console.error(`[error] ${e.message}`); process.exit(1); });
58+
.catch((e) => {
59+
console.error(`[error] ${e.message}`);
60+
process.exit(1);
61+
});
4762

4863
/*
4964
* Process vulnerabilities
5065
*/
5166

5267
console.log("[info] Processing findings");
5368

54-
const { impacts, eases, easeTags, criticities,
55-
criticityMatrix, originTags, serviceProviderTag } = config;
69+
const {
70+
impacts, eases, easeTags, criticities,
71+
criticityMatrix, originTags, serviceProviderTag
72+
} = config;
5673

5774
// Compute additional fields
5875
for (const finding of findings) {
5976
// Resultant criticity
6077
finding.severity = finding.severity?.toLowerCase();
61-
const i = Math.max(impacts.findIndex(i => i == finding.severity), 0);
78+
const i = Math.max(impacts.findIndex(i => i === finding.severity), 0);
6279
const e = easeTags.indexOf(finding.tags?.find(t => easeTags.includes(t)) ?? easeTags[0]);
6380
finding.ease_index = e;
6481
finding.ease = eases[e];
@@ -82,13 +99,13 @@ export async function main() {
8299
(f2.severity_index - f1.severity_index) || f1.title.localeCompare(f2.title));
83100

84101
console.log("[info] Vulnerabilities:", criticities.map(c =>
85-
findings.filter(f => f.criticity == c).length + " " + c).join(", "));
102+
findings.filter(f => f.criticity === c).length + " " + c).join(", "));
86103

87104
/*
88105
* Generate reports
89106
*/
90107

91-
const defaultReportName = "Security-Debt" + (products.length == 1 ? `_${products[0].name}` : "");
108+
const defaultReportName = "Security-Debt" + (products.length === 1 ? `_${products[0].name}` : "");
92109
const path = opts.output ?? join(process.cwd(), defaultReportName);
93110

94111
for (const format of opts.format) {

src/template.ejs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
td, th {
6565
padding: .3em .6em;
6666
border: 1px solid #dbdbdb;
67-
border-width: 1px;
6867
}
6968
thead th {
7069
border-width: 1px 1px 2px 1px;
@@ -130,9 +129,9 @@
130129
<%_ for (const finding of findings) { -%>
131130
<tr>
132131
<%_ for (const field of finding) { -%>
133-
<%_ if (field.type == "criticity") { -%>
132+
<%_ if (field.type === "criticity") { -%>
134133
<td class="criticity c<%= field.index %>"><%= field.value %></td>
135-
<%_ } else if (field.type == "boolean") { -%>
134+
<%_ } else if (field.type === "boolean") { -%>
136135
<td><%= field.value ? "Y" : "N" %></td>
137136
<%_ } else { -%>
138137
<td <%_ if (field.value?.length > 20) { %> title="<%= field.value %>" <% } %>><%= field.value -%></td>

0 commit comments

Comments
 (0)