@nodesecure/scanner 3.7.0 → 3.8.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/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # NodeSecure Scanner
2
2
  ![version](https://img.shields.io/badge/dynamic/json.svg?url=https://raw.githubusercontent.com/NodeSecure/scanner/master/package.json&query=$.version&label=Version)
3
3
  [![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/NodeSecure/scanner/commit-activity)
4
- [![Security Responsible Disclosure](https://img.shields.io/badge/Security-Responsible%20Disclosure-yellow.svg)](https://github.com/nodejs/security-wg/blob/master/processes/responsible_disclosure_template.md
5
- )
6
4
  [![mit](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/NodeSecure/scanner/blob/master/LICENSE)
7
5
  ![build](https://img.shields.io/github/workflow/status/NodeSecure/scanner/Node.js%20CI)
8
6
 
@@ -71,7 +69,7 @@ interface Options {
71
69
  ## Contributors ✨
72
70
 
73
71
  <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
74
- [![All Contributors](https://img.shields.io/badge/all_contributors-6-orange.svg?style=flat-square)](#contributors-)
72
+ [![All Contributors](https://img.shields.io/badge/all_contributors-9-orange.svg?style=flat-square)](#contributors-)
75
73
  <!-- ALL-CONTRIBUTORS-BADGE:END -->
76
74
 
77
75
  Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
@@ -80,14 +78,21 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
80
78
  <!-- prettier-ignore-start -->
81
79
  <!-- markdownlint-disable -->
82
80
  <table>
83
- <tr>
84
- <td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Afraxken" title="Reviewed Pull Requests">👀</a> <a href="#security-fraxken" title="Security">🛡️</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Afraxken" title="Bug reports">🐛</a></td>
85
- <td align="center"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tony Gorez</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Atony-go" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Atony-go" title="Bug reports">🐛</a></td>
86
- <td align="center"><a href="https://mickaelcroquet.fr"><img src="https://avatars.githubusercontent.com/u/23740372?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Haze</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=CroquetMickael" title="Code">💻</a></td>
87
- <td align="center"><a href="https://github.com/mbalabash"><img src="https://avatars.githubusercontent.com/u/16868922?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maksim Balabash</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=mbalabash" title="Code">💻</a></td>
88
- <td align="center"><a href="https://dev.to/antoinecoulon"><img src="https://avatars.githubusercontent.com/u/43391199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoine Coulon</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=antoine-coulon" title="Code">💻</a> <a href="#security-antoine-coulon" title="Security">🛡️</a></td>
89
- <td align="center"><a href="https://www.linkedin.com/in/nicolas-hallaert/"><img src="https://avatars.githubusercontent.com/u/39910164?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolas Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=Rossb0b" title="Code">💻</a></td>
90
- </tr>
81
+ <tbody>
82
+ <tr>
83
+ <td align="center"><a href="https://www.linkedin.com/in/thomas-gentilhomme/"><img src="https://avatars.githubusercontent.com/u/4438263?v=4?s=100" width="100px;" alt="Gentilhomme"/><br /><sub><b>Gentilhomme</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=fraxken" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Afraxken" title="Reviewed Pull Requests">👀</a> <a href="#security-fraxken" title="Security">🛡️</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Afraxken" title="Bug reports">🐛</a></td>
84
+ <td align="center"><a href="http://tonygo.dev"><img src="https://avatars.githubusercontent.com/u/22824417?v=4?s=100" width="100px;" alt="Tony Gorez"/><br /><sub><b>Tony Gorez</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Code">💻</a> <a href="https://github.com/NodeSecure/scanner/commits?author=tony-go" title="Documentation">📖</a> <a href="https://github.com/NodeSecure/scanner/pulls?q=is%3Apr+reviewed-by%3Atony-go" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/NodeSecure/scanner/issues?q=author%3Atony-go" title="Bug reports">🐛</a></td>
85
+ <td align="center"><a href="https://mickaelcroquet.fr"><img src="https://avatars.githubusercontent.com/u/23740372?v=4?s=100" width="100px;" alt="Haze"/><br /><sub><b>Haze</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=CroquetMickael" title="Code">💻</a></td>
86
+ <td align="center"><a href="https://github.com/mbalabash"><img src="https://avatars.githubusercontent.com/u/16868922?v=4?s=100" width="100px;" alt="Maksim Balabash"/><br /><sub><b>Maksim Balabash</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=mbalabash" title="Code">💻</a></td>
87
+ <td align="center"><a href="https://dev.to/antoinecoulon"><img src="https://avatars.githubusercontent.com/u/43391199?v=4?s=100" width="100px;" alt="Antoine Coulon"/><br /><sub><b>Antoine Coulon</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=antoine-coulon" title="Code">💻</a> <a href="#security-antoine-coulon" title="Security">🛡️</a></td>
88
+ <td align="center"><a href="https://www.linkedin.com/in/nicolas-hallaert/"><img src="https://avatars.githubusercontent.com/u/39910164?v=4?s=100" width="100px;" alt="Nicolas Hallaert"/><br /><sub><b>Nicolas Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=Rossb0b" title="Code">💻</a></td>
89
+ <td align="center"><a href="http://sofiand.github.io/portfolio-client/"><img src="https://avatars.githubusercontent.com/u/39944043?v=4?s=100" width="100px;" alt="Yefis"/><br /><sub><b>Yefis</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=SofianD" title="Code">💻</a></td>
90
+ </tr>
91
+ <tr>
92
+ <td align="center"><a href="https://www.linkedin.com/in/franck-hallaert/"><img src="https://avatars.githubusercontent.com/u/110826655?v=4?s=100" width="100px;" alt="Franck Hallaert"/><br /><sub><b>Franck Hallaert</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=Aekk0" title="Code">💻</a></td>
93
+ <td align="center"><a href="https://www.linkedin.com/in/ange-tekeu-a155811b4/"><img src="https://avatars.githubusercontent.com/u/35274201?v=4?s=100" width="100px;" alt="Ange TEKEU"/><br /><sub><b>Ange TEKEU</b></sub></a><br /><a href="https://github.com/NodeSecure/scanner/commits?author=tekeuange23" title="Code">💻</a></td>
94
+ </tr>
95
+ </tbody>
91
96
  </table>
92
97
 
93
98
  <!-- markdownlint-restore -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nodesecure/scanner",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "description": "A package API to run a static analysis of your module's dependencies.",
5
5
  "exports": "./index.js",
6
6
  "engines": {
@@ -48,39 +48,39 @@
48
48
  },
49
49
  "homepage": "https://github.com/NodeSecure/scanner#readme",
50
50
  "devDependencies": {
51
- "@nodesecure/eslint-config": "^1.4.1",
51
+ "@nodesecure/eslint-config": "^1.5.0",
52
52
  "@slimio/is": "^1.5.1",
53
53
  "@small-tech/esm-tape-runner": "^2.0.0",
54
54
  "@small-tech/tap-monkey": "^1.4.0",
55
- "@types/node": "^18.0.0",
56
- "c8": "^7.11.3",
55
+ "@types/node": "^18.11.9",
56
+ "c8": "^7.12.0",
57
57
  "cross-env": "^7.0.3",
58
- "dotenv": "^16.0.1",
59
- "eslint": "^8.18.0",
60
- "get-folder-size": "^3.1.0",
58
+ "dotenv": "^16.0.3",
59
+ "eslint": "^8.27.0",
60
+ "get-folder-size": "^4.0.0",
61
61
  "pkg-ok": "^3.0.0",
62
- "sinon": "^14.0.0",
62
+ "sinon": "^14.0.1",
63
63
  "snap-shot-core": "^10.2.4",
64
- "tape": "^5.5.3"
64
+ "tape": "^5.6.1"
65
65
  },
66
66
  "dependencies": {
67
67
  "@nodesecure/flags": "^2.4.0",
68
68
  "@nodesecure/fs-walk": "^1.0.0",
69
69
  "@nodesecure/i18n": "^2.0.0",
70
- "@nodesecure/js-x-ray": "^5.0.1",
71
- "@nodesecure/npm-registry-sdk": "^1.4.0",
70
+ "@nodesecure/js-x-ray": "^5.1.0",
71
+ "@nodesecure/npm-registry-sdk": "^1.4.1",
72
72
  "@nodesecure/ntlp": "^2.1.0",
73
73
  "@nodesecure/utils": "^1.0.0",
74
74
  "@nodesecure/vuln": "^1.7.0",
75
75
  "@npm/types": "^1.0.2",
76
- "@npmcli/arborist": "^5.2.3",
76
+ "@npmcli/arborist": "^6.1.1",
77
77
  "@slimio/lock": "^1.0.0",
78
78
  "builtins": "^5.0.1",
79
79
  "combine-async-iterators": "^2.0.1",
80
80
  "itertools": "^1.7.1",
81
81
  "lodash.difference": "^4.5.0",
82
- "pacote": "^13.6.1",
83
- "semver": "^7.3.7"
82
+ "pacote": "^15.0.6",
83
+ "semver": "^7.3.8"
84
84
  },
85
85
  "type": "module"
86
86
  }
@@ -9,6 +9,8 @@ export default class Dependency {
9
9
  this.name = name;
10
10
  this.version = version;
11
11
  this.dev = false;
12
+ this.existOnRemoteRegistry = true;
13
+ this.alias = {};
12
14
 
13
15
  if (parent !== null) {
14
16
  parent.dependencyCount++;
@@ -62,6 +64,7 @@ export default class Dependency {
62
64
  id: typeof customId === "number" ? customId : Dependency.currentId++,
63
65
  usedBy: this.parent,
64
66
  isDevDependency: this.dev,
67
+ existOnRemoteRegistry: this.existOnRemoteRegistry,
65
68
  flags: this.flags,
66
69
  description: "",
67
70
  size: 0,
@@ -76,6 +79,7 @@ export default class Dependency {
76
79
  minified: [],
77
80
  unused: [],
78
81
  missing: [],
82
+ alias: this.alias,
79
83
  required_files: [],
80
84
  required_nodejs: [],
81
85
  required_thirdparty: [],
package/src/depWalker.js CHANGED
@@ -37,10 +37,24 @@ export async function* searchDeepDependencies(packageName, gitURL, options) {
37
37
  registry,
38
38
  cache: `${os.homedir()}/.npm`
39
39
  });
40
- const { dependencies, customResolvers } = mergeDependencies(pkg);
40
+ const { dependencies, customResolvers, alias } = mergeDependencies(pkg);
41
41
 
42
42
  const current = new Dependency(name, version, parent);
43
- gitURL !== null && current.isGit(gitURL);
43
+ current.alias = Object.fromEntries(alias);
44
+
45
+ if (gitURL !== null) {
46
+ current.isGit(gitURL);
47
+ try {
48
+ await pacote.manifest(`${name}@${version}`, {
49
+ ...NPM_TOKEN,
50
+ registry,
51
+ cache: `${os.homedir()}/.npm`
52
+ });
53
+ }
54
+ catch {
55
+ current.existOnRemoteRegistry = false;
56
+ }
57
+ }
44
58
  current.addFlag("isDeprecated", deprecated === true);
45
59
  current.addFlag("hasCustomResolver", customResolvers.size > 0);
46
60
  current.addFlag("hasDependencies", dependencies.size > 0);
@@ -88,11 +102,16 @@ export async function* deepReadEdges(currentPackageName, options) {
88
102
  registry,
89
103
  cache: `${os.homedir()}/.npm`
90
104
  });
91
- const { customResolvers } = mergeDependencies(pkg);
105
+ const { customResolvers, alias } = mergeDependencies(pkg);
92
106
 
107
+ current.alias = Object.fromEntries(alias);
93
108
  current.addFlag("hasValidIntegrity", _integrity === integrity);
94
109
  current.addFlag("isDeprecated");
95
110
  current.addFlag("hasCustomResolver", customResolvers.size > 0);
111
+
112
+ if (isGitDependency(to.resolved)) {
113
+ current.isGit(to.resolved);
114
+ }
96
115
  }
97
116
  current.addFlag("hasDependencies", to.edgesOut.size > 0);
98
117
 
@@ -121,8 +140,20 @@ export async function* getRootDependencies(manifest, options) {
121
140
  registry
122
141
  } = options;
123
142
 
124
- const { dependencies, customResolvers } = mergeDependencies(manifest, void 0);
143
+ const { dependencies, customResolvers, alias } = mergeDependencies(manifest, void 0);
125
144
  const parent = new Dependency(manifest.name, manifest.version);
145
+ parent.alias = Object.fromEntries(alias);
146
+
147
+ try {
148
+ await pacote.manifest(`${manifest.name}@${manifest.version}`, {
149
+ ...NPM_TOKEN,
150
+ registry,
151
+ cache: `${os.homedir()}/.npm`
152
+ });
153
+ }
154
+ catch {
155
+ parent.existOnRemoteRegistry = false;
156
+ }
126
157
  parent.addFlag("hasCustomResolver", customResolvers.size > 0);
127
158
  parent.addFlag("hasDependencies", dependencies.size > 0);
128
159
 
@@ -1,5 +1,3 @@
1
- const kGitVersionVariants = ["git:", "git+", "github:"];
2
-
3
1
  /**
4
2
  * @example isGitDependency("github:NodeSecure/scanner") // => true
5
3
  * @example isGitDependency("git+ssh://git@github.com:npm/cli#semver:^5.0") // => true
@@ -9,12 +7,5 @@ const kGitVersionVariants = ["git:", "git+", "github:"];
9
7
  * @returns {boolean}
10
8
  */
11
9
  export function isGitDependency(version) {
12
- for (const variant of kGitVersionVariants) {
13
- if (version.startsWith(variant)) {
14
- return true;
15
- }
16
- }
17
-
18
- return false;
10
+ return /^git(:|\+|hub:)/.test(version);
19
11
  }
20
-
@@ -1,6 +1,7 @@
1
1
  export function mergeDependencies(manifest, types = ["dependencies"]) {
2
2
  const dependencies = new Map();
3
3
  const customResolvers = new Map();
4
+ const alias = new Map();
4
5
 
5
6
  for (const fieldName of types) {
6
7
  if (!Reflect.has(manifest, fieldName)) {
@@ -15,12 +16,15 @@ export function mergeDependencies(manifest, types = ["dependencies"]) {
15
16
  */
16
17
  if (/^([a-zA-Z]+:|git\+|\.\\)/.test(version)) {
17
18
  customResolvers.set(name, version);
18
- continue;
19
+ if (!version.startsWith("npm:")) {
20
+ continue;
21
+ }
22
+ alias.set(name, version.slice(4));
19
23
  }
20
24
 
21
25
  dependencies.set(name, version);
22
26
  }
23
27
  }
24
28
 
25
- return { dependencies, customResolvers };
29
+ return { dependencies, customResolvers, alias };
26
30
  }
@@ -34,6 +34,11 @@ declare namespace Scanner {
34
34
  /** Id of the package (useful for usedBy relation) */
35
35
  id: number;
36
36
  isDevDependency: boolean;
37
+ /**
38
+ * Tell if the given package exist on the configured remote registry (npm by default)
39
+ * @default true
40
+ */
41
+ existOnRemoteRegistry: boolean;
37
42
  /** By whom (id) is used the package */
38
43
  usedBy: Record<string, string>;
39
44
  /** Size on disk of the extracted tarball (in bytes) */
@@ -56,7 +61,7 @@ declare namespace Scanner {
56
61
  *
57
62
  * @see https://github.com/NodeSecure/js-x-ray/blob/master/WARNINGS.md
58
63
  */
59
- warnings: JSXRay.Warning<JSXRay.BaseWarning>[];
64
+ warnings: JSXRay.Warning<JSXRay.WarningDefault>[];
60
65
  /** Tarball composition (files and dependencies) */
61
66
  composition: {
62
67
  /** Files extensions (.js, .md, .exe etc..) */
@@ -64,6 +69,7 @@ declare namespace Scanner {
64
69
  files: string[];
65
70
  /** Minified files (foo.min.js etc..) */
66
71
  minified: string[];
72
+ alias: Record<string, string>;
67
73
  required_files: string[];
68
74
  required_thirdparty: string[];
69
75
  required_nodejs: string[];
@@ -155,7 +161,7 @@ declare namespace Scanner {
155
161
  licenses: License[];
156
162
  ast: {
157
163
  dependencies: Record<string, JSXRay.Dependency>;
158
- warnings: JSXRay.Warning<JSXRay.BaseWarning>[];
164
+ warnings: JSXRay.Warning<JSXRay.WarningDefault>[];
159
165
  };
160
166
  }
161
167
 
@@ -1,63 +1,63 @@
1
- import ntlp from "@nodesecure/ntlp";
2
- import Locker from "@slimio/lock";
3
- import Logger from "../src/logger.class";
4
-
5
- export = tarball;
6
-
7
- declare namespace tarball {
8
- export interface ManifestData {
9
- /** Dependencies in package.json */
10
- packageDeps: string[];
11
- /** DevDependencies in package.json */
12
- packageDevDeps: string[];
13
- /** Does package.json contain a 'gypfile' property ? */
14
- packageGyp: boolean;
15
- }
16
-
17
- export interface ScannedFileResult {
18
- /** Dependencies in try/catch block (probably optional dependencies) */
19
- inTryDeps: string[];
20
- /** Dependencies required or imported */
21
- dependencies: string[];
22
- /** Required or imported javascript files */
23
- filesDependencies: string[];
24
- }
25
-
26
- export interface ScannedPackageResult {
27
- files: {
28
- /** Complete list of files for the given package */
29
- list: string[];
30
- /** Complete list of extensions (.js, .md etc.) */
31
- extensions: string[];
32
- /** List of minified javascript files */
33
- minified: string[];
34
- };
35
- /** Size of the directory in bytes */
36
- directorySize: number;
37
- /** Unique license contained in the tarball (MIT, ISC ..) */
38
- uniqueLicenseIds: string[];
39
- /** All licenses with their SPDX */
40
- licenses: ntlp.license[];
41
- ast: {
42
- dependencies: any;
43
- warnings: any[];
44
- };
45
- }
46
-
47
- export interface ScanDirOrArchiveOptions {
48
- ref: any;
49
- locker: Locker;
50
- tmpLocation: string;
51
- logger: Logger;
52
- }
53
-
54
- export interface ScanFileOptions {
55
- name: string;
56
- ref: any;
57
- }
58
-
59
- export function readManifest(dest: string, ref: any): Promise<ManifestData>;
60
- export function scanFile(dest: string, file: string, options: ScanFileOptions): Promise<ScannedFileResult | null>;
61
- export function scanPackage(dest: string, packageName: string): Promise<ScannedPackageResult>;
62
- export function scanDirOrArchive(name: string, version: string, options: ScanDirOrArchiveOptions): Promise<void>;
63
- }
1
+ import ntlp from "@nodesecure/ntlp";
2
+ import Locker from "@slimio/lock";
3
+ import Logger from "../src/logger.class";
4
+
5
+ export = tarball;
6
+
7
+ declare namespace tarball {
8
+ export interface ManifestData {
9
+ /** Dependencies in package.json */
10
+ packageDeps: string[];
11
+ /** DevDependencies in package.json */
12
+ packageDevDeps: string[];
13
+ /** Does package.json contain a 'gypfile' property ? */
14
+ packageGyp: boolean;
15
+ }
16
+
17
+ export interface ScannedFileResult {
18
+ /** Dependencies in try/catch block (probably optional dependencies) */
19
+ inTryDeps: string[];
20
+ /** Dependencies required or imported */
21
+ dependencies: string[];
22
+ /** Required or imported javascript files */
23
+ filesDependencies: string[];
24
+ }
25
+
26
+ export interface ScannedPackageResult {
27
+ files: {
28
+ /** Complete list of files for the given package */
29
+ list: string[];
30
+ /** Complete list of extensions (.js, .md etc.) */
31
+ extensions: string[];
32
+ /** List of minified javascript files */
33
+ minified: string[];
34
+ };
35
+ /** Size of the directory in bytes */
36
+ directorySize: number;
37
+ /** Unique license contained in the tarball (MIT, ISC ..) */
38
+ uniqueLicenseIds: string[];
39
+ /** All licenses with their SPDX */
40
+ licenses: ntlp.license[];
41
+ ast: {
42
+ dependencies: any;
43
+ warnings: any[];
44
+ };
45
+ }
46
+
47
+ export interface ScanDirOrArchiveOptions {
48
+ ref: any;
49
+ locker: Locker;
50
+ tmpLocation: string;
51
+ logger: Logger;
52
+ }
53
+
54
+ export interface ScanFileOptions {
55
+ name: string;
56
+ ref: any;
57
+ }
58
+
59
+ export function readManifest(dest: string, ref: any): Promise<ManifestData>;
60
+ export function scanFile(dest: string, file: string, options: ScanFileOptions): Promise<ScannedFileResult | null>;
61
+ export function scanPackage(dest: string, packageName?: string): Promise<ScannedPackageResult>;
62
+ export function scanDirOrArchive(name: string, version: string, options: ScanDirOrArchiveOptions): Promise<void>;
63
+ }