@orangemug/oops 0.1.3 → 0.2.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 +8 -2
- package/dist/npm/bin/index.js +8 -3
- package/dist/npm/cjs/index.js +4 -3
- package/dist/npm/es/index.js +4 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# `@orangemug/oops`
|
|
2
|
+
|
|
2
3
|
Have I got a compromised pacakge in my npm/pnpm/yarn cache?
|
|
3
4
|
|
|
4
5
|
## Usage
|
|
6
|
+
|
|
5
7
|
Find out with `oops`
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
10
|
npx @orangemug/oops --help
|
|
9
11
|
# ./oops <dangerous_package_versions>
|
|
10
|
-
#
|
|
12
|
+
#
|
|
11
13
|
# Example: npx @orangemug/oops @ctrl/tinycolor:4.1.1 @ctrl/tinycolor:4.1.2
|
|
12
14
|
```
|
|
13
15
|
|
|
@@ -19,8 +21,12 @@ You can attach this command to a bug tracker ticket somewhere in your company/or
|
|
|
19
21
|
> npx @orangemug/oops \
|
|
20
22
|
> @ctrl/tinycolor:4.1.1 \
|
|
21
23
|
> @ctrl/tinycolor:4.1.2
|
|
22
|
-
> ```
|
|
24
|
+
> ```
|
|
23
25
|
|
|
26
|
+
The examples are from <https://orca.security/resources/blog/npm-malware-campaign-tinycolor/>
|
|
27
|
+
|
|
28
|
+
It also support ranges such as `^4`
|
|
24
29
|
|
|
25
30
|
## Licence
|
|
31
|
+
|
|
26
32
|
MIT
|
package/dist/npm/bin/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import chalk from 'chalk';
|
|
|
3
3
|
import { exec as exec$1 } from 'child_process';
|
|
4
4
|
import { promisify } from 'util';
|
|
5
5
|
import semver from 'semver';
|
|
6
|
+
import validSemver from 'semver/ranges/valid.js';
|
|
6
7
|
import minimist from 'minimist';
|
|
7
8
|
|
|
8
9
|
const exec = promisify(exec$1);
|
|
@@ -28,7 +29,7 @@ async function npmDoesPackageExist(pkgName) {
|
|
|
28
29
|
}
|
|
29
30
|
async function yarnDoesPackageExist(pkgName) {
|
|
30
31
|
const result = await exec(`yarn cache list --pattern ${pkgName}`);
|
|
31
|
-
const items = result.stdout.split("\n").map(line => line.split(/\s+/));
|
|
32
|
+
const items = result.stdout.split("\n").map((line) => line.split(/\s+/));
|
|
32
33
|
const out = [];
|
|
33
34
|
for (const item of items) {
|
|
34
35
|
if (item[0] === pkgName) {
|
|
@@ -38,7 +39,7 @@ async function yarnDoesPackageExist(pkgName) {
|
|
|
38
39
|
return out;
|
|
39
40
|
}
|
|
40
41
|
async function doesPackageExistInCache(pkgName, version) {
|
|
41
|
-
if (!
|
|
42
|
+
if (!validSemver(version)) {
|
|
42
43
|
throw new Error(`Invalid version range "${version}"`);
|
|
43
44
|
}
|
|
44
45
|
const effectedVersions = {};
|
|
@@ -56,7 +57,7 @@ async function doesPackageExistInCache(pkgName, version) {
|
|
|
56
57
|
}
|
|
57
58
|
return 0;
|
|
58
59
|
});
|
|
59
|
-
const filteredVersions = sorted.filter(pkgVersion => {
|
|
60
|
+
const filteredVersions = sorted.filter((pkgVersion) => {
|
|
60
61
|
return semver.satisfies(pkgVersion, version);
|
|
61
62
|
});
|
|
62
63
|
effectedVersions[managerName] = filteredVersions;
|
|
@@ -68,6 +69,10 @@ async function run(packages) {
|
|
|
68
69
|
let hasErrors = false;
|
|
69
70
|
for (const pkg of packages) {
|
|
70
71
|
const [pkgName, version] = pkg.split(":");
|
|
72
|
+
if (version === undefined || version === "") {
|
|
73
|
+
console.error(chalk.red(`'${pkg}' doesn't contain a version, add a version, for example '${pkg}:^2' (change the semver version)`));
|
|
74
|
+
process.exit(2);
|
|
75
|
+
}
|
|
71
76
|
if (pkgName && version) {
|
|
72
77
|
const output = await doesPackageExistInCache(pkgName, version);
|
|
73
78
|
console.log(`${chalk.magenta(pkgName)}:${version}`);
|
package/dist/npm/cjs/index.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var child_process = require('child_process');
|
|
4
4
|
var util = require('util');
|
|
5
5
|
var semver = require('semver');
|
|
6
|
+
var validSemver = require('semver/ranges/valid.js');
|
|
6
7
|
|
|
7
8
|
const exec = util.promisify(child_process.exec);
|
|
8
9
|
async function pnpmDoesPackageExist(pkgName) {
|
|
@@ -27,7 +28,7 @@ async function npmDoesPackageExist(pkgName) {
|
|
|
27
28
|
}
|
|
28
29
|
async function yarnDoesPackageExist(pkgName) {
|
|
29
30
|
const result = await exec(`yarn cache list --pattern ${pkgName}`);
|
|
30
|
-
const items = result.stdout.split("\n").map(line => line.split(/\s+/));
|
|
31
|
+
const items = result.stdout.split("\n").map((line) => line.split(/\s+/));
|
|
31
32
|
const out = [];
|
|
32
33
|
for (const item of items) {
|
|
33
34
|
if (item[0] === pkgName) {
|
|
@@ -37,7 +38,7 @@ async function yarnDoesPackageExist(pkgName) {
|
|
|
37
38
|
return out;
|
|
38
39
|
}
|
|
39
40
|
async function doesPackageExistInCache(pkgName, version) {
|
|
40
|
-
if (!
|
|
41
|
+
if (!validSemver(version)) {
|
|
41
42
|
throw new Error(`Invalid version range "${version}"`);
|
|
42
43
|
}
|
|
43
44
|
const effectedVersions = {};
|
|
@@ -55,7 +56,7 @@ async function doesPackageExistInCache(pkgName, version) {
|
|
|
55
56
|
}
|
|
56
57
|
return 0;
|
|
57
58
|
});
|
|
58
|
-
const filteredVersions = sorted.filter(pkgVersion => {
|
|
59
|
+
const filteredVersions = sorted.filter((pkgVersion) => {
|
|
59
60
|
return semver.satisfies(pkgVersion, version);
|
|
60
61
|
});
|
|
61
62
|
effectedVersions[managerName] = filteredVersions;
|
package/dist/npm/es/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { exec as exec$1 } from 'child_process';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
3
|
import semver from 'semver';
|
|
4
|
+
import validSemver from 'semver/ranges/valid.js';
|
|
4
5
|
|
|
5
6
|
const exec = promisify(exec$1);
|
|
6
7
|
async function pnpmDoesPackageExist(pkgName) {
|
|
@@ -25,7 +26,7 @@ async function npmDoesPackageExist(pkgName) {
|
|
|
25
26
|
}
|
|
26
27
|
async function yarnDoesPackageExist(pkgName) {
|
|
27
28
|
const result = await exec(`yarn cache list --pattern ${pkgName}`);
|
|
28
|
-
const items = result.stdout.split("\n").map(line => line.split(/\s+/));
|
|
29
|
+
const items = result.stdout.split("\n").map((line) => line.split(/\s+/));
|
|
29
30
|
const out = [];
|
|
30
31
|
for (const item of items) {
|
|
31
32
|
if (item[0] === pkgName) {
|
|
@@ -35,7 +36,7 @@ async function yarnDoesPackageExist(pkgName) {
|
|
|
35
36
|
return out;
|
|
36
37
|
}
|
|
37
38
|
async function doesPackageExistInCache(pkgName, version) {
|
|
38
|
-
if (!
|
|
39
|
+
if (!validSemver(version)) {
|
|
39
40
|
throw new Error(`Invalid version range "${version}"`);
|
|
40
41
|
}
|
|
41
42
|
const effectedVersions = {};
|
|
@@ -53,7 +54,7 @@ async function doesPackageExistInCache(pkgName, version) {
|
|
|
53
54
|
}
|
|
54
55
|
return 0;
|
|
55
56
|
});
|
|
56
|
-
const filteredVersions = sorted.filter(pkgVersion => {
|
|
57
|
+
const filteredVersions = sorted.filter((pkgVersion) => {
|
|
57
58
|
return semver.satisfies(pkgVersion, version);
|
|
58
59
|
});
|
|
59
60
|
effectedVersions[managerName] = filteredVersions;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orangemug/oops",
|
|
3
3
|
"description": "Have I got a compromised pacakge in my cache?",
|
|
4
|
+
"version": "0.2.0",
|
|
4
5
|
"repository": {
|
|
5
6
|
"type": "git",
|
|
6
7
|
"url": "https://github.com/orangemug/oops"
|
|
@@ -52,6 +53,5 @@
|
|
|
52
53
|
"chalk": "^5.6.2",
|
|
53
54
|
"minimist": "^1.2.8",
|
|
54
55
|
"semver": "^7.7.4"
|
|
55
|
-
}
|
|
56
|
-
"version": "0.1.3"
|
|
56
|
+
}
|
|
57
57
|
}
|