retire 3.2.4 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## [3.2.4]
3
+ ## [4.0.0]
4
+
5
+ ### Breaking changes
6
+ - npm scanning no longer supported
7
+
8
+ ### Changes
9
+ - Complete rewrite to typescript
4
10
 
5
- - Bump vulnerable deps
6
11
 
7
12
  ## [3.2.3]
8
13
 
package/README.md CHANGED
@@ -13,22 +13,13 @@ Usage
13
13
  Usage: retire [options]
14
14
 
15
15
  Options:
16
-
17
- -h, --help output usage information
18
16
  -V, --version output the version number
19
-
20
- -p, --package limit node scan to packages where parent is mentioned in package.json (ignore node_modules)
21
- -n, --node Run node dependency scan only
22
- -j, --js Run scan of JavaScript files only
23
17
  -v, --verbose Show identified files (by default only vulnerable files are shown)
24
18
  -x, --dropexternal Don't include project provided vulnerability repository
25
19
  -c, --nocache Don't use local cache
26
-
27
20
  --jspath <path> Folder to scan for javascript files
28
- --nodepath <path> Folder to scan for node files
29
21
  --path <path> Folder to scan for both
30
22
  --jsrepo <path|url> Local or internal version of repo
31
- --noderepo <path|url> Local or internal version of repo
32
23
  --cachedir <path> Path to use for local cache instead of /tmp/.retire-cache
33
24
  --proxy <url> Proxy url (http://some.host:8080)
34
25
  --outputformat <format> Valid formats: text, json, jsonsimple, depcheck (experimental), cyclonedx and cyclonedxJSON
@@ -41,6 +32,7 @@ Options:
41
32
  --insecure Enable fetching remote jsrepo/noderepo files from hosts using an insecure or self-signed SSL (TLS) certificate
42
33
  --ext <extensions> Comman separated list of file extensions for javascript files. The default is "js"
43
34
  --cacert <path> Use the specified certificate file to verify the peer used for fetching remote jsrepo/noderepo files
35
+ -h, --help display help for command
44
36
  ````
45
37
 
46
38
  The `depcheck` output format mimics the output of OWASP Dependency Check, but lacks some information compared to OWASP Dependency Check, because that information is not in the repo.
package/lib/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/lib/cli.js ADDED
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __importDefault = (this && this.__importDefault) || function (mod) {
27
+ return (mod && mod.__esModule) ? mod : { "default": mod };
28
+ };
29
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ const utils = __importStar(require("./utils"));
32
+ const commander_1 = require("commander");
33
+ const retire = __importStar(require("./retire"));
34
+ const repo = __importStar(require("./repo"));
35
+ const resolve = __importStar(require("./resolve"));
36
+ const scanner = __importStar(require("./scanner"));
37
+ const reporting = __importStar(require("./reporting"));
38
+ const os_1 = __importDefault(require("os"));
39
+ const path_1 = __importDefault(require("path"));
40
+ const fs_1 = __importDefault(require("fs"));
41
+ const ansi_colors_1 = __importDefault(require("ansi-colors"));
42
+ const events_1 = require("events");
43
+ const types_1 = require("./types");
44
+ const z = __importStar(require("zod"));
45
+ const events = new events_1.EventEmitter();
46
+ let failProcess = false;
47
+ const defaultIgnoreFiles = ['.retireignore', '.retireignore.json'];
48
+ if (process.argv.includes("--node") || process.argv.includes("-n")) {
49
+ console.log("Error: retire.js no longer supports scanning node packages. Use npm audit instead.");
50
+ process.exit(1);
51
+ }
52
+ /*
53
+ * Parse command line flags.
54
+ */
55
+ const prg = commander_1.program
56
+ .version(retire.version)
57
+ .option('-v, --verbose', 'Show identified files (by default only vulnerable files are shown)')
58
+ .option('-x, --dropexternal', "Don't include project provided vulnerability repository")
59
+ .option('-c, --nocache', "Don't use local cache")
60
+ .option('--jspath <path>', 'Folder to scan for javascript files')
61
+ .option('--path <path>', 'Folder to scan for both')
62
+ .option('--jsrepo <path|url>', 'Local or internal version of repo')
63
+ .option('--cachedir <path>', 'Path to use for local cache instead of /tmp/.retire-cache')
64
+ .option('--proxy <url>', 'Proxy url (http://some.host:8080)')
65
+ .option('--outputformat <format>', 'Valid formats: text, json, jsonsimple, depcheck (experimental), cyclonedx and cyclonedxJSON')
66
+ .option('--outputpath <path>', 'File to which output should be written')
67
+ .option('--ignore <paths>', 'Comma delimited list of paths to ignore')
68
+ .option('--ignorefile <path>', 'Custom ignore file, defaults to .retireignore / .retireignore.json')
69
+ .option('--severity <level>', 'Specify the bug severity level from which the process fails. Allowed levels none, low, medium, high, critical. Default: none')
70
+ .option('--exitwith <code>', 'Custom exit code (default: 13) when vulnerabilities are found')
71
+ .option('--colors', 'Enable color output (console output only)')
72
+ .option('--insecure', 'Enable fetching remote jsrepo/noderepo files from hosts using an insecure or self-signed SSL (TLS) certificate')
73
+ .option('--ext <extensions>', 'Comman separated list of file extensions for javascript files. The default is "js"')
74
+ .option('--cacert <path>', 'Use the specified certificate file to verify the peer used for fetching remote jsrepo/noderepo files')
75
+ .parse()
76
+ .opts();
77
+ const colorwarn = prg.colors ? ansi_colors_1.default.red : (x) => x;
78
+ const jsrepolocation = (_a = prg.jsrepo) !== null && _a !== void 0 ? _a : "https://raw.githubusercontent.com/RetireJS/retire.js/master/repository/jsrepository.json";
79
+ const ignorefile = (_b = prg.ignoreFile) !== null && _b !== void 0 ? _b : defaultIgnoreFiles.filter((x) => fs_1.default.existsSync(x))[0];
80
+ const scanpath = (_c = prg.path) !== null && _c !== void 0 ? _c : ".";
81
+ const log = reporting.open({
82
+ colors: !!prg.colors,
83
+ colorwarn,
84
+ jsRepo: jsrepolocation,
85
+ outputformat: prg.outputformat,
86
+ outputpath: prg.outputpath,
87
+ path: scanpath,
88
+ verbose: !!prg.verbose
89
+ });
90
+ const severity = (_d = prg.severity) !== null && _d !== void 0 ? _d : "none";
91
+ if (!(severity in types_1.severityLevels)) {
92
+ exitWithError(`Error: Invalid severity level (${severity}). Valid levels are: ${Object.keys(types_1.severityLevels).join(', ')}`);
93
+ }
94
+ const config = {
95
+ path: scanpath,
96
+ ignore: {
97
+ paths: (_g = (_f = (_e = prg.ignore) === null || _e === void 0 ? void 0 : _e.split(",")) === null || _f === void 0 ? void 0 : _f.map((x) => path_1.default.resolve(x))) !== null && _g !== void 0 ? _g : [],
98
+ pathsAsString: [],
99
+ descriptors: []
100
+ },
101
+ colorwarn,
102
+ nocache: prg.nocache ? true : false,
103
+ cachedir: (_h = prg.cachedir) !== null && _h !== void 0 ? _h : path_1.default.resolve(os_1.default.tmpdir(), '.retire-cache/'),
104
+ log: log,
105
+ severity: severity,
106
+ exitwith: (_j = prg.exitwith) !== null && _j !== void 0 ? _j : 13
107
+ };
108
+ log.info(`retire.js v${retire.version}`);
109
+ function exitWithError(msg) {
110
+ log.error(config.colorwarn(msg));
111
+ process.exitCode = 1;
112
+ log.close();
113
+ }
114
+ if (prg.cacert) {
115
+ if (!fs_1.default.existsSync(prg.cacert)) {
116
+ exitWithError(`Error: Could not read cacert file: ${prg.cacert}`);
117
+ }
118
+ config.cacertbuf = fs_1.default.readFileSync(prg.cacert);
119
+ }
120
+ const ignoreFileParser = z.array(z.object({
121
+ justification: z.string()
122
+ }).and(z.object({
123
+ path: z.string(),
124
+ }).or(z.object({
125
+ component: z.string(),
126
+ version: z.string().optional(),
127
+ identifiers: z.record(z.string(), z.string()).optional(),
128
+ }))));
129
+ if (ignorefile) {
130
+ if (!fs_1.default.existsSync(ignorefile)) {
131
+ exitWithError(`Error: Could not read ignore file: ${ignorefile}`);
132
+ }
133
+ if (ignorefile.substr(-5) === ".json") {
134
+ try {
135
+ config.ignore.descriptors = ignoreFileParser.parse(JSON.parse(fs_1.default.readFileSync(ignorefile, "utf-8")));
136
+ }
137
+ catch (e) {
138
+ exitWithError(`Error: Invalid ignore file: ${ignorefile}`);
139
+ }
140
+ const ignoredPaths = (_m = (_l = (_k = config.ignore.descriptors) === null || _k === void 0 ? void 0 : _k.map((x) => "path" in x ? x.path : undefined)) === null || _l === void 0 ? void 0 : _l.filter((x) => x != undefined)) !== null && _m !== void 0 ? _m : [];
141
+ config.ignore.pathsAsString = config.ignore.pathsAsString.concat(ignoredPaths);
142
+ }
143
+ else {
144
+ const lines = fs_1.default.readFileSync(ignorefile, "utf-8").split(/\r\n|\n/g).filter((e) => e !== '');
145
+ const ignored = lines.map(e => { return e[0] === '@' ? e.slice(1) : path_1.default.resolve(e); });
146
+ config.ignore.pathsAsString = config.ignore.pathsAsString.concat(ignored);
147
+ }
148
+ }
149
+ config.ignore.paths = config.ignore.pathsAsString
150
+ .map(p => p.replace(/[.+?^${}()|[\]\\]/g, '\\$&'))
151
+ .map(p => p.replace(/[*]{1,2}/g, (a) => a.length == 2 ? ".*" : "[^/]*"))
152
+ .map(s => new RegExp(s));
153
+ scanner.on('vulnerable-dependency-found', (result) => {
154
+ const levels = result.results
155
+ .map((r) => {
156
+ return r.vulnerabilities ? r.vulnerabilities.map((v) => {
157
+ var _a;
158
+ return types_1.severityLevels[(_a = v.severity) !== null && _a !== void 0 ? _a : 'critical'];
159
+ }) : [];
160
+ });
161
+ const severity = utils.flatten(levels).reduce((x, y) => x > y ? x : y);
162
+ if (severity >= types_1.severityLevels[config.severity]) {
163
+ failProcess = true;
164
+ }
165
+ });
166
+ scanner.on('vulnerable-dependency-found', log.logVulnerableDependency);
167
+ scanner.on('dependency-found', log.logDependency);
168
+ events.on('scan-done', () => {
169
+ process.exitCode = failProcess ? config.exitwith : 0;
170
+ log.close();
171
+ });
172
+ process.on('uncaughtException', (err, ...rest) => {
173
+ console.warn('Exception caught: ', err, rest);
174
+ console.warn(err.stack);
175
+ process.exit(1);
176
+ });
177
+ events.on('stop', (err) => {
178
+ exitWithError(err);
179
+ });
180
+ (jsrepolocation.match(/^https?:\/\//)
181
+ ? repo.loadrepository(jsrepolocation, config)
182
+ : repo.loadrepositoryFromFile(jsrepolocation, config))
183
+ .then((jsRepo) => {
184
+ resolve.scanJsFiles(config.path, config)
185
+ .on('jsfile', (file) => {
186
+ scanner.scanJsFile(file, jsRepo, config);
187
+ })
188
+ .on('bowerfile', (bowerfile) => {
189
+ const bowerRepo = repo.asbowerrepo(jsRepo);
190
+ scanner.scanBowerFile(bowerfile, bowerRepo, config);
191
+ })
192
+ .on('end', () => {
193
+ events.emit('scan-done');
194
+ });
195
+ }).catch((e) => events.emit('stop', e));
package/lib/repo.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { Options, Repository } from "./types";
2
+ export declare function asbowerrepo(jsRepo: Repository): Repository;
3
+ export declare function loadrepository(repoUrl: string, options: Options): Promise<Repository>;
4
+ export declare function loadrepositoryFromFile(filepath: string, options: Options): Promise<Repository>;
package/lib/repo.js CHANGED
@@ -1,112 +1,157 @@
1
- /* global require, exports */
2
- /*jshint esversion: 6 */
3
- var utils = require('./utils'),
4
- fs = require('fs'),
5
- path = require('path'),
6
- forward = require('../lib/utils').forwardEvent,
7
- http = require('http'),
8
- https = require('https'),
9
- retire = require('./retire'),
10
- URL = require('url'),
11
- ProxyAgent = require('proxy-agent');
12
-
13
- var emitter = require('events').EventEmitter;
14
-
15
-
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
+ return new (P || (P = Promise))(function (resolve, reject) {
28
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
32
+ });
33
+ };
34
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ exports.loadrepositoryFromFile = exports.loadrepository = exports.asbowerrepo = void 0;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const http = __importStar(require("http"));
42
+ const https = __importStar(require("https"));
43
+ const retire = __importStar(require("./retire"));
44
+ const URL = __importStar(require("url"));
45
+ const proxy_agent_1 = __importDefault(require("proxy-agent"));
16
46
  function loadJson(url, options) {
17
- var events = new emitter();
18
- options.log.info('Downloading ' + url + ' ...');
19
- var reqOptions = Object.assign({}, URL.parse(url), { method: 'GET' });
20
- var proxyUri = options.proxy || process.env.http_proxy;
21
- if (proxyUri) {
22
- reqOptions.agent = new ProxyAgent(proxyUri);
23
- }
24
- if (options.insecure) {
25
- reqOptions.rejectUnauthorized = false;
26
- }
27
- if (options.cacertbuf) {
28
- reqOptions.ca = [ options.cacertbuf ];
29
- }
30
- var req = (url.startsWith("http:") ? http : https).get(reqOptions, function (res) {
31
- if (res.statusCode != 200) return events.emit('stop', 'Error downloading: ' + url + ": HTTP " + res.statusCode + " " + res.statusText);
32
- var data = [];
33
- res.on('data', c => data.push(c));
34
- res.on('end', () => {
35
- var d = Buffer.concat(data).toString();
36
- d = options.process ? options.process(d) : d;
37
- events.emit('done', JSON.parse(d));
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ return new Promise((resolve, reject) => {
49
+ options.log.info('Downloading ' + url + ' ...');
50
+ const reqOptions = Object.assign(Object.assign({}, URL.parse(url)), { method: 'GET' });
51
+ const proxyUri = options.proxy || process.env.http_proxy;
52
+ if (proxyUri) {
53
+ reqOptions.agent = new proxy_agent_1.default(proxyUri);
54
+ }
55
+ if (options.insecure) {
56
+ reqOptions.rejectUnauthorized = false;
57
+ }
58
+ if (options.cacertbuf) {
59
+ reqOptions.ca = [options.cacertbuf];
60
+ }
61
+ const req = (url.startsWith("http:") ? http : https).get(reqOptions, (res) => {
62
+ if (res.statusCode != 200)
63
+ return reject(`Error downloading: ${url}: HTTP ${res.statusCode} ${res.statusMessage}`);
64
+ const data = [];
65
+ res.on('data', c => data.push(c));
66
+ res.on('end', () => {
67
+ let d = Buffer.concat(data).toString();
68
+ d = options.process ? options.process(d) : d;
69
+ resolve(JSON.parse(d));
70
+ });
71
+ });
72
+ req.on('error', e => reject(`Error downloading: ${url}: ${e}`));
73
+ req.end();
74
+ });
38
75
  });
39
- });
40
- req.on('error', e => events.emit('stop', 'Error downloading: ' + url + ": " + e.toString()));
41
- req.end();
42
- return events;
43
76
  }
44
-
45
77
  function loadJsonFromFile(file, options) {
46
- options.log.debug('Reading ' + file + ' ...');
47
- var events = new emitter();
48
- fs.readFile(file, { encoding : 'utf8'}, function(err, data) {
49
- if (err) { return events.emit('stop', err.toString()); }
50
- data = options.process ? options.process(data) : data;
51
- var obj = JSON.parse(data);
52
- events.emit('done', obj);
53
- });
54
- return events;
78
+ return __awaiter(this, void 0, void 0, function* () {
79
+ options.log.debug('Reading ' + file + ' ...');
80
+ return new Promise((resolve, reject) => {
81
+ fs.readFile(file, { encoding: 'utf8' }, (err, data) => {
82
+ if (err) {
83
+ return reject(err.toString());
84
+ }
85
+ data = options.process ? options.process(data) : data;
86
+ resolve(JSON.parse(data));
87
+ });
88
+ });
89
+ });
55
90
  }
56
-
57
91
  function loadFromCache(url, cachedir, options) {
58
- var cacheIndex = path.resolve(cachedir, 'index.json');
59
- if (!fs.existsSync(cachedir)) fs.mkdirSync(cachedir);
60
- var cache = fs.existsSync(cacheIndex) ? JSON.parse(fs.readFileSync(cacheIndex)) : {};
61
- var now = new Date().getTime();
62
- if (cache[url]) {
63
- if (now - cache[url].date < 60*60*1000) {
64
- options.log.info('Loading from cache: ' + url);
65
- return loadJsonFromFile(path.resolve(cachedir, cache[url].file), options);
66
- } else {
67
- if (fs.existsSync(path.resolve(cachedir, cache[url].date + '.json'))) {
68
- try {
69
- fs.unlinkSync(path.resolve(cachedir, cache[url].date + '.json'));
70
- } catch (error) {
71
- if (error.code !== 'ENOENT') {
72
- throw error;
73
- } else {
74
- console.warn("Could not delete cache. Ignore this error if you are running multiple retire.js in parallel");
75
- }
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ const cacheIndex = path.resolve(cachedir, 'index.json');
94
+ if (!fs.existsSync(cachedir))
95
+ fs.mkdirSync(cachedir);
96
+ const cache = fs.existsSync(cacheIndex) ? JSON.parse(fs.readFileSync(cacheIndex, "utf-8")) : {};
97
+ const now = new Date().getTime();
98
+ if (cache[url]) {
99
+ if (now - cache[url].date < 60 * 60 * 1000) {
100
+ options.log.info('Loading from cache: ' + url);
101
+ return loadJsonFromFile(path.resolve(cachedir, cache[url].file), options);
102
+ }
103
+ else {
104
+ if (fs.existsSync(path.resolve(cachedir, cache[url].date + '.json'))) {
105
+ try {
106
+ fs.unlinkSync(path.resolve(cachedir, cache[url].date + '.json'));
107
+ }
108
+ catch (error) {
109
+ if (error != null && typeof error == "object" && "code" in error && error.code !== 'ENOENT') {
110
+ throw error;
111
+ }
112
+ else {
113
+ console.warn("Could not delete cache. Ignore this error if you are running multiple retire.js in parallel");
114
+ }
115
+ }
116
+ }
117
+ }
76
118
  }
77
- }
78
- }
79
- }
80
- var events = new emitter();
81
- loadJson(url, options).on('done', function(data) {
82
- cache[url] = { date : now, file : now + '.json' };
83
- fs.writeFileSync(path.resolve(cachedir, cache[url].file), JSON.stringify(data), { encoding : 'utf8' });
84
- fs.writeFileSync(cacheIndex, JSON.stringify(cache), { encoding : 'utf8' });
85
- events.emit('done', data);
86
- }).on('stop', forward(events, 'stop'));
87
- return events;
119
+ const data = yield loadJson(url, options);
120
+ cache[url] = { date: now, file: now + '.json' };
121
+ fs.writeFileSync(path.resolve(cachedir, cache[url].file), JSON.stringify(data), { encoding: 'utf8' });
122
+ fs.writeFileSync(cacheIndex, JSON.stringify(cache), { encoding: 'utf8' });
123
+ return data;
124
+ });
88
125
  }
89
-
90
- exports.asbowerrepo = function(jsRepo) {
91
- var result = {};
92
- Object.keys(jsRepo).map(function(k) {
93
- (jsRepo[k].bowername || [k]).map(function(b) {
94
- result[b] = result[b] || { vulnerabilities: [] };
95
- result[b].vulnerabilities = result[b].vulnerabilities.concat(jsRepo[k].vulnerabilities);
126
+ function asbowerrepo(jsRepo) {
127
+ const result = {};
128
+ Object.keys(jsRepo).map((k) => {
129
+ ([jsRepo[k].bowername || k]).map((b) => {
130
+ result[b] = result[b] || { vulnerabilities: [] };
131
+ result[b].vulnerabilities = result[b].vulnerabilities.concat(jsRepo[k].vulnerabilities);
132
+ });
96
133
  });
97
- });
98
- return result;
99
- };
100
-
101
- exports.loadrepository = function(repoUrl, options) {
102
- options = utils.extend(options, { process : retire.replaceVersion });
103
- if (options.nocache) {
104
- return loadJson(repoUrl, options);
105
- }
106
- return loadFromCache(repoUrl, options.cachedir, options);
107
- };
108
-
109
- exports.loadrepositoryFromFile = function(filepath, options) {
110
- options = utils.extend(options, { process : retire.replaceVersion });
111
- return loadJsonFromFile(filepath, options);
112
- };
134
+ return result;
135
+ }
136
+ exports.asbowerrepo = asbowerrepo;
137
+ ;
138
+ function loadrepository(repoUrl, options) {
139
+ return __awaiter(this, void 0, void 0, function* () {
140
+ //options = utils.extend(options, { process : retire.replaceVersion });
141
+ options = Object.assign(Object.assign({}, options), { process: retire.replaceVersion });
142
+ if (options.nocache) {
143
+ return yield loadJson(repoUrl, options);
144
+ }
145
+ return yield loadFromCache(repoUrl, options.cachedir, options);
146
+ });
147
+ }
148
+ exports.loadrepository = loadrepository;
149
+ ;
150
+ function loadrepositoryFromFile(filepath, options) {
151
+ return __awaiter(this, void 0, void 0, function* () {
152
+ options = Object.assign(Object.assign({}, options), { process: retire.replaceVersion });
153
+ return yield loadJsonFromFile(filepath, options);
154
+ });
155
+ }
156
+ exports.loadrepositoryFromFile = loadrepositoryFromFile;
157
+ ;
@@ -0,0 +1,3 @@
1
+ import { type ConfigurableLogger } from "../reporting";
2
+ declare const _default: ConfigurableLogger;
3
+ export default _default;
@@ -1,43 +1,70 @@
1
- var retire = require('../retire');
2
- var utils = require('../utils');
3
-
4
-
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ const retire = __importStar(require("../retire"));
27
+ const utils = __importStar(require("../utils"));
5
28
  function printResults(logger, finding, config) {
6
- if (finding.results && finding.results.length > 0) {
7
- var logFunc = retire.isVulnerable(finding.results) ? logger.warn : logger.info;
8
- var printed = {};
9
- finding.results.forEach(function(elm) {
10
- if (!config.verbose && !retire.isVulnerable([elm])) return;
11
- var key = elm.component + ' ' + elm.version;
12
- logFunc(finding.file);
13
- logFunc(' ' + String.fromCharCode(8627) + ' ' + key);
14
- if (printed[key]) return;
15
- if (retire.isVulnerable([elm])) {
16
- logFunc(key + ' has known vulnerabilities:' + printVulnerability(logger, elm, config));
17
- }
18
- printed[key] = true;
29
+ if (finding.results && finding.results.length > 0) {
30
+ const logFunc = retire.isVulnerable(finding.results) ? logger.warn : logger.info;
31
+ const printed = new Set();
32
+ finding.results.forEach((elm) => {
33
+ if (!config.verbose && !retire.isVulnerable([elm]))
34
+ return;
35
+ const key = `${elm.component} ${elm.version}`;
36
+ logFunc(finding.file);
37
+ logFunc(` ${String.fromCharCode(8627)} ${key}`);
38
+ if (printed.has(key))
39
+ return;
40
+ if (retire.isVulnerable([elm])) {
41
+ logFunc(`${key} has known vulnerabilities:${printVulnerability(elm, config)}`);
42
+ }
43
+ printed.add(key);
44
+ });
45
+ }
46
+ }
47
+ function printVulnerability(component, config) {
48
+ var _a;
49
+ let string = '';
50
+ (_a = component.vulnerabilities) === null || _a === void 0 ? void 0 : _a.forEach((vulnerability) => {
51
+ string += config.outputformat === 'clean' ? '\n ' : ' ';
52
+ if (vulnerability.severity) {
53
+ string += `severity: ${vulnerability.severity}; `;
54
+ }
55
+ if (vulnerability.identifiers) {
56
+ string += Object.entries(vulnerability.identifiers).map(([id, name]) => {
57
+ return `${name}: ${utils.flatten([[id]]).join(' ')}`;
58
+ }).join(', ') + '; ';
59
+ }
60
+ string += vulnerability.info.join(config.outputformat === 'clean' ? '\n' : ' ');
19
61
  });
20
- }
62
+ return string;
21
63
  }
22
-
23
- function printVulnerability(logger, component, config) {
24
- var string = '';
25
- component.vulnerabilities.forEach(function(vulnerability){
26
- string += config.outputformat === 'clean' ? '\n ' : ' ';
27
- if (vulnerability.severity) {
28
- string += 'severity: ' + vulnerability.severity + '; ';
64
+ exports.default = {
65
+ configure: (logger, _, config) => {
66
+ logger.logDependency = (finding) => { if (config.verbose)
67
+ printResults(logger, finding, config); };
68
+ logger.logVulnerableDependency = (component) => { printResults(logger, component, config); };
29
69
  }
30
- if (vulnerability.identifiers) {
31
- string += utils.map(vulnerability.identifiers, function(id, name) {
32
- return name + ': ' + utils.flatten([id]).join(' ');
33
- }).join(', ') + '; ';
34
- }
35
- string += vulnerability.info.join(config.outputformat === 'clean' ? '\n' : ' ');
36
- });
37
- return string;
38
- }
39
-
40
- exports.configure = function(logger, writer, config, hash) {
41
- logger.logDependency = function(finding) { if (config.verbose) printResults(logger, finding, config); };
42
- logger.logVulnerableDependency = function(component) { printResults(logger, component, config); };
43
- };
70
+ };
@@ -0,0 +1,3 @@
1
+ import { ConfigurableLogger } from "../reporting";
2
+ declare const _default: ConfigurableLogger;
3
+ export default _default;