()
| 25 | } |
| 26 | |
| 27 | async run () { |
| 28 | const start = process.hrtime.bigint() |
| 29 | const { default: pMap } = await import('p-map') |
| 30 | |
| 31 | // Find all deps in tree |
| 32 | const { edges, registries } = this.getEdgesOut(this.tree.inventory.values(), this.filterSet) |
| 33 | if (edges.size === 0) { |
| 34 | throw new Error('found no installed dependencies to audit') |
| 35 | } |
| 36 | |
| 37 | const tuf = await tufClient.initTUF({ |
| 38 | cachePath: this.opts.tufCache, |
| 39 | retry: this.opts.retry, |
| 40 | timeout: this.opts.timeout, |
| 41 | }) |
| 42 | await Promise.all([...registries].map(registry => this.setKeys({ registry, tuf }))) |
| 43 | |
| 44 | log.verbose('verifying registry signatures') |
| 45 | await pMap(edges, (e) => this.getVerifiedInfo(e), { concurrency: 20, stopOnError: true }) |
| 46 | |
| 47 | // Didn't find any dependencies that could be verified, e.g. only local deps, missing version, not on a registry etc. |
| 48 | if (!this.auditedWithKeysCount && !this.verifiedAttestationCount) { |
| 49 | throw new Error('found no dependencies to audit that were installed from ' + |
| 50 | 'a supported registry') |
| 51 | } |
| 52 | |
| 53 | const invalid = this.invalid.sort(sortAlphabetically) |
| 54 | const missing = this.missing.sort(sortAlphabetically) |
| 55 | |
| 56 | const hasNoInvalidOrMissing = invalid.length === 0 && missing.length === 0 |
| 57 | |
| 58 | if (!hasNoInvalidOrMissing) { |
| 59 | process.exitCode = 1 |
| 60 | } |
| 61 | |
| 62 | if (this.npm.config.get('json')) { |
| 63 | const result = { invalid, missing } |
| 64 | if (this.npm.config.get('include-attestations')) { |
| 65 | result.verified = this.verified |
| 66 | } |
| 67 | output.buffer(result) |
| 68 | return |
| 69 | } |
| 70 | const end = process.hrtime.bigint() |
| 71 | const elapsed = end - start |
| 72 | |
| 73 | const auditedPlural = this.auditedWithKeysCount > 1 ? 's' : '' |
| 74 | const timing = `audited ${this.auditedWithKeysCount} package${auditedPlural} in ` + |
| 75 | `${Math.floor(Number(elapsed) / 1e9)}s` |
| 76 | output.standard(timing) |
| 77 | output.standard() |
| 78 | |
| 79 | const verifiedBold = this.npm.chalk.bold('verified') |
| 80 | if (this.verifiedSignatureCount) { |
| 81 | if (this.verifiedSignatureCount === 1) { |
| 82 | output.standard(`${this.verifiedSignatureCount} package has a ${verifiedBold} registry signature`) |
| 83 | } else { |
| 84 | output.standard(`${this.verifiedSignatureCount} packages have ${verifiedBold} registry signatures`) |
no test coverage detected