Skip to content

Commit 73b1421

Browse files
committed
Add Fix column to security report
1 parent 1f02783 commit 73b1421

7 files changed

Lines changed: 194 additions & 28 deletions

File tree

src/types/general.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ export interface v7Vulnerability {
4242
readonly name: string;
4343
readonly via: v7VulnerabilityVia[] | string[];
4444
readonly nodes: string[];
45+
readonly fixAvailable?: boolean | { name: string; version: string; isSemVerMajor: boolean };
4546
}
4647

4748
export interface v7VulnerabilityVia {

src/types/table.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
export type SecurityReportHeader = 'ID' | 'Module' | 'Title' | 'Paths' | 'Severity' | 'URL' | 'Ex.';
1+
export type SecurityReportHeader = 'ID' | 'Module' | 'Title' | 'Paths' | 'Severity' | 'URL' | 'Ex.' | 'Fix';
22
export type ExceptionReportHeader = 'ID' | 'Status' | 'Expiry' | 'Notes';

src/utils/print.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import get from 'lodash.get';
22
import { table, TableUserConfig } from 'table';
33
import { SecurityReportHeader, ExceptionReportHeader } from 'src/types';
44

5-
const SECURITY_REPORT_HEADER: SecurityReportHeader[] = ['ID', 'Module', 'Title', 'Paths', 'Severity', 'URL', 'Ex.'];
5+
const SECURITY_REPORT_HEADER: SecurityReportHeader[] = ['ID', 'Module', 'Title', 'Paths', 'Severity', 'URL', 'Ex.', 'Fix'];
66
const EXCEPTION_REPORT_HEADER: ExceptionReportHeader[] = ['ID', 'Status', 'Expiry', 'Notes'];
77

88
// TODO: Add unit tests

src/utils/vulnerability.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export function processAuditJson(
174174
{ key: 'Severity', value: cur.severity },
175175
{ key: 'URL', value: cur.url },
176176
{ key: 'Ex.', value: isExcepted ? 'y' : 'n' },
177+
{ key: 'Fix', value: 'N/A' },
177178
]
178179
.filter(({ key }) => (columnsToInclude.length ? columnsToInclude.includes(key) : true))
179180
.map(({ key, value }) =>
@@ -245,6 +246,16 @@ export function processAuditJson(
245246
{ key: 'Severity', value: vul.severity, bgColor: getSeverityBgColor(vul.severity) },
246247
{ key: 'URL', value: vul.url },
247248
{ key: 'Ex.', value: isExcepted ? 'y' : 'n' },
249+
{
250+
key: 'Fix',
251+
value: (() => {
252+
const fixAvailable = get(cur, 'fixAvailable');
253+
if (typeof fixAvailable === 'object' && fixAvailable !== null && fixAvailable.isSemVerMajor) {
254+
return 'major';
255+
}
256+
return String(Boolean(fixAvailable));
257+
})(),
258+
},
248259
]
249260
.filter(({ key }) => (columnsToInclude.length ? columnsToInclude.includes(key) : true))
250261
.map(({ key, value, bgColor }) => color(value, isExcepted ? '' : 'yellow', key === 'Severity' ? bgColor : undefined));
@@ -340,7 +351,8 @@ export function processExceptions(nsprc: NsprcFile, cmdExceptions: string[] = []
340351
}
341352

342353
// Color the date accordingly
343-
let expiryDate = get(details, 'expiry') ? new Date(get(details, 'expiry')).toUTCString() : '';
354+
const expiry: string | number | undefined = get(details, 'expiry');
355+
let expiryDate = expiry !== undefined && expiry !== null ? new Date(expiry).toUTCString() : '';
344356
// If it was expired for more than 5 years ago, warn by coloring the date in red
345357
if (years && years <= -5) {
346358
expiryDate = color(expiryDate, 'red');
@@ -368,7 +380,10 @@ export function processExceptions(nsprc: NsprcFile, cmdExceptions: string[] = []
368380
* @param {Array} unusedExceptionIds List of unused exception IDs
369381
* @param {Array} unusedExceptionModules List of unused exception module names
370382
*/
371-
export function handleUnusedExceptions(unusedExceptionIds: string[], unusedExceptionModules: string[]): void {
383+
export function handleUnusedExceptions(
384+
unusedExceptionIds: (string | null | undefined)[],
385+
unusedExceptionModules: (string | null | undefined)[],
386+
): void {
372387
const cleanedUnusedExceptionIds = unusedExceptionIds.filter(Boolean);
373388
const cleanedUnusedExceptionModules = unusedExceptionModules.filter(Boolean);
374389
const message = [

test/__mocks__/v6-security-report-table-data.json

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"\u001b[33mloopback-component-explorer>swagger-ui\u001b[0m",
77
"\u001b[33mmoderate\u001b[0m",
88
"\u001b[33mhttps://npmjs.com/advisories/975\u001b[0m",
9-
"\u001b[33mn\u001b[0m"
9+
"\u001b[33mn\u001b[0m",
10+
"\u001b[33mN/A\u001b[0m"
1011
],
1112
[
1213
"\u001b[33m976\u001b[0m",
@@ -15,7 +16,8 @@
1516
"\u001b[33mloopback-component-explorer>swagger-ui\u001b[0m",
1617
"\u001b[33mmoderate\u001b[0m",
1718
"\u001b[33mhttps://npmjs.com/advisories/976\u001b[0m",
18-
"\u001b[33mn\u001b[0m"
19+
"\u001b[33mn\u001b[0m",
20+
"\u001b[33mN/A\u001b[0m"
1921
],
2022
[
2123
"\u001b[33m985\u001b[0m",
@@ -24,7 +26,8 @@
2426
"\u001b[33mloopback-component-explorer>swagger-ui\u001b[0m",
2527
"\u001b[33mmoderate\u001b[0m",
2628
"\u001b[33mhttps://npmjs.com/advisories/985\u001b[0m",
27-
"\u001b[33mn\u001b[0m"
29+
"\u001b[33mn\u001b[0m",
30+
"\u001b[33mN/A\u001b[0m"
2831
],
2932
[
3033
"\u001b[33m1084\u001b[0m",
@@ -33,7 +36,8 @@
3336
"\u001b[33mloopback-connector-rest>strong-globalize>os-locale>mem\u001b[0m",
3437
"\u001b[33mlow\u001b[0m",
3538
"\u001b[33mhttps://npmjs.com/advisories/1084\u001b[0m",
36-
"\u001b[33mn\u001b[0m"
39+
"\u001b[33mn\u001b[0m",
40+
"\u001b[33mN/A\u001b[0m"
3741
],
3842
[
3943
"\u001b[33m1179\u001b[0m",
@@ -42,7 +46,8 @@
4246
"\u001b[33mmocha>mkdirp>minimist\u001b[0m",
4347
"\u001b[33mlow\u001b[0m",
4448
"\u001b[33mhttps://npmjs.com/advisories/1179\u001b[0m",
45-
"\u001b[33mn\u001b[0m"
49+
"\u001b[33mn\u001b[0m",
50+
"\u001b[33mN/A\u001b[0m"
4651
],
4752
[
4853
"\u001b[33m1213\u001b[0m",
@@ -51,7 +56,8 @@
5156
"\u001b[33mnodemon>update-notifier>configstore>dot-prop\u001b[0m",
5257
"\u001b[33m\u001b[41mhigh\u001b[0m",
5358
"\u001b[33mhttps://npmjs.com/advisories/1213\u001b[0m",
54-
"\u001b[33mn\u001b[0m"
59+
"\u001b[33mn\u001b[0m",
60+
"\u001b[33mN/A\u001b[0m"
5561
],
5662
[
5763
"\u001b[33m1500\u001b[0m",
@@ -60,7 +66,8 @@
6066
"\u001b[33mmocha>yargs-parser\nmocha>yargs-unparser>yargs>yargs-parser\u001b[0m",
6167
"\u001b[33mlow\u001b[0m",
6268
"\u001b[33mhttps://npmjs.com/advisories/1500\u001b[0m",
63-
"\u001b[33mn\u001b[0m"
69+
"\u001b[33mn\u001b[0m",
70+
"\u001b[33mN/A\u001b[0m"
6471
],
6572
[
6673
"\u001b[33m1523\u001b[0m",
@@ -69,7 +76,8 @@
6976
"\u001b[33mlodash\nloopback>async>lodash\nloopback>loopback-connector-remote>loopback-datasource-juggler>async>lodash\nloopback>loopback-datasource-juggler>async>lodash\nloopback>loopback-connector-remote>strong-remoting>loopback-phase>async>lodash\n...and 40 more\u001b[0m",
7077
"\u001b[33mlow\u001b[0m",
7178
"\u001b[33mhttps://npmjs.com/advisories/1523\u001b[0m",
72-
"\u001b[33mn\u001b[0m"
79+
"\u001b[33mn\u001b[0m",
80+
"\u001b[33mN/A\u001b[0m"
7381
],
7482
[
7583
"\u001b[33m1555\u001b[0m",
@@ -78,7 +86,8 @@
7886
"\u001b[33mloopback>loopback-connector-remote>loopback-datasource-juggler>loopback-connector>msgpack5>bl\nloopback>loopback-datasource-juggler>loopback-connector>msgpack5>bl\nloopback-connector-mongodb>loopback-connector>msgpack5>bl\u001b[0m",
7987
"\u001b[33m\u001b[41mcritical\u001b[0m",
8088
"\u001b[33mhttps://npmjs.com/advisories/1555\u001b[0m",
81-
"\u001b[33mn\u001b[0m"
89+
"\u001b[33mn\u001b[0m",
90+
"\u001b[33mN/A\u001b[0m"
8291
],
8392
[
8493
"\u001b[33m1556\u001b[0m",
@@ -87,7 +96,8 @@
8796
"\u001b[33mloopback-connector-rest>strong-globalize>g11n-pipeline>swagger-client>cross-fetch>node-fetch\u001b[0m",
8897
"\u001b[33mlow\u001b[0m",
8998
"\u001b[33mhttps://npmjs.com/advisories/1556\u001b[0m",
90-
"\u001b[33mn\u001b[0m"
99+
"\u001b[33mn\u001b[0m",
100+
"\u001b[33mN/A\u001b[0m"
91101
],
92102
[
93103
"\u001b[33m1589\u001b[0m",
@@ -96,6 +106,7 @@
96106
"\u001b[33mnodemon>chokidar>fsevents>node-pre-gyp>rc>ini\nnodemon>update-notifier>is-installed-globally>global-dirs>ini\nnodemon>update-notifier>latest-version>package-json>registry-auth-token>rc>ini\nnodemon>update-notifier>latest-version>package-json>registry-url>rc>ini\u001b[0m",
97107
"\u001b[33mlow\u001b[0m",
98108
"\u001b[33mhttps://npmjs.com/advisories/1589\u001b[0m",
99-
"\u001b[33mn\u001b[0m"
109+
"\u001b[33mn\u001b[0m",
110+
"\u001b[33mN/A\u001b[0m"
100111
]
101112
]

test/__mocks__/v7-security-report-table-data.json

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"\u001b[33mbl\u001b[0m",
77
"\u001b[33m\u001b[41mcritical\u001b[0m",
88
"\u001b[33mhttps://npmjs.com/advisories/1555\u001b[0m",
9-
"\u001b[33mn\u001b[0m"
9+
"\u001b[33mn\u001b[0m",
10+
"\u001b[33mtrue\u001b[0m"
1011
],
1112
[
1213
"\u001b[33m1213\u001b[0m",
@@ -15,7 +16,8 @@
1516
"\u001b[33mdot-prop\u001b[0m",
1617
"\u001b[33m\u001b[41mhigh\u001b[0m",
1718
"\u001b[33mhttps://npmjs.com/advisories/1213\u001b[0m",
18-
"\u001b[33mn\u001b[0m"
19+
"\u001b[33mn\u001b[0m",
20+
"\u001b[33mtrue\u001b[0m"
1921
],
2022
[
2123
"\u001b[33m1589\u001b[0m",
@@ -24,7 +26,8 @@
2426
"\u001b[33mfsevents>ini\nini\u001b[0m",
2527
"\u001b[33mlow\u001b[0m",
2628
"\u001b[33mhttps://npmjs.com/advisories/1589\u001b[0m",
27-
"\u001b[33mn\u001b[0m"
29+
"\u001b[33mn\u001b[0m",
30+
"\u001b[33mtrue\u001b[0m"
2831
],
2932
[
3033
"\u001b[33m1523\u001b[0m",
@@ -33,7 +36,8 @@
3336
"\u001b[33mlodash\u001b[0m",
3437
"\u001b[33mlow\u001b[0m",
3538
"\u001b[33mhttps://npmjs.com/advisories/1523\u001b[0m",
36-
"\u001b[33mn\u001b[0m"
39+
"\u001b[33mn\u001b[0m",
40+
"\u001b[33mtrue\u001b[0m"
3741
],
3842
[
3943
"\u001b[33m1084\u001b[0m",
@@ -42,7 +46,8 @@
4246
"\u001b[33mloopback-connector-rest>mem\u001b[0m",
4347
"\u001b[33mlow\u001b[0m",
4448
"\u001b[33mhttps://npmjs.com/advisories/1084\u001b[0m",
45-
"\u001b[33mn\u001b[0m"
49+
"\u001b[33mn\u001b[0m",
50+
"\u001b[33mtrue\u001b[0m"
4651
],
4752
[
4853
"\u001b[33m1179\u001b[0m",
@@ -51,7 +56,8 @@
5156
"\u001b[33mmocha>minimist\u001b[0m",
5257
"\u001b[33mlow\u001b[0m",
5358
"\u001b[33mhttps://npmjs.com/advisories/1179\u001b[0m",
54-
"\u001b[33mn\u001b[0m"
59+
"\u001b[33mn\u001b[0m",
60+
"\u001b[33mtrue\u001b[0m"
5561
],
5662
[
5763
"\u001b[33m1556\u001b[0m",
@@ -60,7 +66,8 @@
6066
"\u001b[33mnode-fetch\u001b[0m",
6167
"\u001b[33mlow\u001b[0m",
6268
"\u001b[33mhttps://npmjs.com/advisories/1556\u001b[0m",
63-
"\u001b[33mn\u001b[0m"
69+
"\u001b[33mn\u001b[0m",
70+
"\u001b[33mtrue\u001b[0m"
6471
],
6572
[
6673
"\u001b[33m975\u001b[0m",
@@ -69,7 +76,8 @@
6976
"\u001b[33mswagger-ui\u001b[0m",
7077
"\u001b[33mmoderate\u001b[0m",
7178
"\u001b[33mhttps://npmjs.com/advisories/975\u001b[0m",
72-
"\u001b[33mn\u001b[0m"
79+
"\u001b[33mn\u001b[0m",
80+
"\u001b[33mmajor\u001b[0m"
7381
],
7482
[
7583
"\u001b[33m976\u001b[0m",
@@ -78,7 +86,8 @@
7886
"\u001b[33mswagger-ui\u001b[0m",
7987
"\u001b[33mmoderate\u001b[0m",
8088
"\u001b[33mhttps://npmjs.com/advisories/976\u001b[0m",
81-
"\u001b[33mn\u001b[0m"
89+
"\u001b[33mn\u001b[0m",
90+
"\u001b[33mmajor\u001b[0m"
8291
],
8392
[
8493
"\u001b[33m985\u001b[0m",
@@ -87,7 +96,8 @@
8796
"\u001b[33mswagger-ui\u001b[0m",
8897
"\u001b[33mmoderate\u001b[0m",
8998
"\u001b[33mhttps://npmjs.com/advisories/985\u001b[0m",
90-
"\u001b[33mn\u001b[0m"
99+
"\u001b[33mn\u001b[0m",
100+
"\u001b[33mmajor\u001b[0m"
91101
],
92102
[
93103
"\u001b[33m1500\u001b[0m",
@@ -96,6 +106,7 @@
96106
"\u001b[33mmocha>yargs-parser\nyargs-unparser>yargs-parser\u001b[0m",
97107
"\u001b[33mlow\u001b[0m",
98108
"\u001b[33mhttps://npmjs.com/advisories/1500\u001b[0m",
99-
"\u001b[33mn\u001b[0m"
109+
"\u001b[33mn\u001b[0m",
110+
"\u001b[33mtrue\u001b[0m"
100111
]
101112
]

0 commit comments

Comments
 (0)