mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 20:20:49 +00:00
593 lines
20 KiB
JavaScript
593 lines
20 KiB
JavaScript
import { describe, it, mock } from "node:test";
|
|
import assert from "node:assert";
|
|
|
|
describe("npmInterceptor minimum package age", async () => {
|
|
let minimumPackageAgeSettings = 48;
|
|
let skipMinimumPackageAgeSetting = false;
|
|
let minimumPackageAgeExclusionsSetting = [];
|
|
|
|
mock.module("../../../config/settings.js", {
|
|
namedExports: {
|
|
getMinimumPackageAgeHours: () => minimumPackageAgeSettings,
|
|
skipMinimumPackageAge: () => skipMinimumPackageAgeSetting,
|
|
getNpmCustomRegistries: () => [],
|
|
getNpmMinimumPackageAgeExclusions: () => minimumPackageAgeExclusionsSetting,
|
|
},
|
|
});
|
|
|
|
mock.module("../../../scanning/audit/index.js", {
|
|
namedExports: {
|
|
isMalwarePackage: async () => {
|
|
return false;
|
|
},
|
|
},
|
|
});
|
|
mock.module("../../../environment/userInteraction.js", {
|
|
namedExports: {
|
|
ui: {
|
|
startProcess: () => {},
|
|
writeError: () => {},
|
|
writeInformation: () => {},
|
|
writeWarning: () => {},
|
|
writeVerbose: () => {},
|
|
writeExitWithoutInstallingMaliciousPackages: () => {},
|
|
emptyLine: () => {},
|
|
},
|
|
},
|
|
});
|
|
const { npmInterceptorForUrl } = await import("./npmInterceptor.js");
|
|
|
|
for (const packageInfoUrl of [
|
|
// Basic package metadata
|
|
"https://registry.npmjs.org/lodash",
|
|
"https://registry.npmjs.org/express",
|
|
// Scoped packages
|
|
"https://registry.npmjs.org/@vercel/functions",
|
|
"https://registry.npmjs.org/@babel/core",
|
|
"https://registry.npmjs.org/@types/node",
|
|
// With query parameters
|
|
"https://registry.npmjs.org/lodash?write=true",
|
|
"https://registry.npmjs.org/@babel/core?param=value&other=test",
|
|
// With fragments
|
|
"https://registry.npmjs.org/lodash#readme",
|
|
"https://registry.npmjs.org/@babel/core#installation",
|
|
// Version-specific metadata
|
|
"https://registry.npmjs.org/lodash/4.17.21",
|
|
"https://registry.npmjs.org/lodash/latest",
|
|
"https://registry.npmjs.org/@babel/core/7.21.4",
|
|
// URL-encoded scoped packages
|
|
"https://registry.npmjs.org/@types%2Fnode",
|
|
"https://registry.npmjs.org/@babel%2Fcore",
|
|
// With trailing slashes
|
|
"https://registry.npmjs.org/lodash/",
|
|
"https://registry.npmjs.org/@babel/core/",
|
|
]) {
|
|
it(`modifyResponse should be true for package info requests: ${packageInfoUrl}`, async () => {
|
|
const interceptor = npmInterceptorForUrl(packageInfoUrl);
|
|
const requestInterceptor = await interceptor.handleRequest(
|
|
packageInfoUrl
|
|
);
|
|
|
|
assert.equal(requestInterceptor.modifiesResponse(), true);
|
|
});
|
|
}
|
|
|
|
for (const packageUrl of [
|
|
// Regular package tarballs
|
|
"https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
"https://registry.npmjs.org/express/-/express-4.18.2.tgz",
|
|
// Scoped package tarballs
|
|
"https://registry.npmjs.org/@babel/core/-/core-8.0.0-alpha.1.tgz",
|
|
"https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz",
|
|
// Tarballs with query parameters (integrity checks)
|
|
"https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz?integrity=sha512-abc123",
|
|
"https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz?integrity=sha512-def456&cache=false",
|
|
// Tarballs with fragments
|
|
"https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#sha512-abc123",
|
|
"https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz#hash",
|
|
// Prerelease versions
|
|
"https://registry.npmjs.org/react/-/react-18.3.0-canary-abc123.tgz",
|
|
"https://registry.npmjs.org/lodash/-/lodash-5.0.0-beta.1.tgz",
|
|
]) {
|
|
it(`modifyResponse should be false for package downloads: ${packageUrl}`, async () => {
|
|
const interceptor = npmInterceptorForUrl(packageUrl);
|
|
const requestInterceptor = await interceptor.handleRequest(packageUrl);
|
|
|
|
assert.equal(requestInterceptor.modifiesResponse(), false);
|
|
});
|
|
}
|
|
|
|
for (const specialEndpoint of [
|
|
// Security advisory endpoints
|
|
"https://registry.npmjs.org/-/npm/v1/security/advisories/bulk",
|
|
"https://registry.npmjs.org/-/npm/v1/security/audits",
|
|
"https://registry.npmjs.org/-/npm/v1/security/audits/quick",
|
|
// Search endpoints
|
|
"https://registry.npmjs.org/-/v1/search?text=lodash&size=20",
|
|
"https://registry.npmjs.org/-/v1/search?text=react&from=0",
|
|
// Package access/collaboration endpoints
|
|
"https://registry.npmjs.org/-/package/lodash/access",
|
|
"https://registry.npmjs.org/-/package/@babel/core/collaborators",
|
|
"https://registry.npmjs.org/-/package/lodash/dist-tags",
|
|
"https://registry.npmjs.org/-/package/@babel/core/dist-tags/latest",
|
|
// User/organization endpoints
|
|
"https://registry.npmjs.org/-/user/org.couchdb.user:username",
|
|
"https://registry.npmjs.org/-/org/myorg/package",
|
|
// Anonymous metrics
|
|
"https://registry.npmjs.org/-/npm/anon-metrics/v1/",
|
|
// Ping/health check
|
|
"https://registry.npmjs.org/-/ping",
|
|
]) {
|
|
it(`modifyResponse should be false for special endpoints: ${specialEndpoint}`, async () => {
|
|
const interceptor = npmInterceptorForUrl(specialEndpoint);
|
|
const requestInterceptor = await interceptor.handleRequest(
|
|
specialEndpoint
|
|
);
|
|
|
|
assert.equal(requestInterceptor.modifiesResponse(), false);
|
|
});
|
|
}
|
|
|
|
it("Should remove packages older than the treshold", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "3.0.0",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-3),
|
|
["1.0.0"]: getDate(-7),
|
|
// cutoff-date here
|
|
["2.0.0"]: getDate(-4),
|
|
["3.0.0"]: getDate(-3),
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
assert.equal(Object.keys(modifiedJson.time).length, 3);
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 1);
|
|
assert.ok(Object.keys(modifiedJson.time).includes("1.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.time).includes("2.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.versions).includes("2.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.time).includes("3.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.versions).includes("3.0.0"));
|
|
});
|
|
|
|
it("Should set the package to the new latest non-preview release", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "3.0.0",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-3),
|
|
["1.0.0"]: getDate(-7),
|
|
["0.0.1"]: getDate(-8), // package order: this package is older than 1.0.0, it should not be considered latest
|
|
["2.0.0-alpha"]: getDate(-6), //package is a pre-release, it should not be latest
|
|
// cutoff-date here
|
|
["2.0.0"]: getDate(-4),
|
|
["3.0.0"]: getDate(-3),
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
assert.equal(modifiedJson["dist-tags"]["latest"], "1.0.0");
|
|
});
|
|
|
|
it("Should remove dist-tags if version was removed", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "3.0.0",
|
|
alpha: "2.0.0-alpha",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-4),
|
|
["1.0.0"]: getDate(-7),
|
|
// cutoff-date here
|
|
["2.0.0-alpha"]: getDate(-4),
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
console.log(modifiedJson);
|
|
|
|
assert.equal(modifiedJson["dist-tags"]["alpha"], undefined);
|
|
});
|
|
|
|
it("Should not filter packages when skipMinimumPackageAge is enabled", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = true;
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const originalBody = JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "3.0.0",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-3),
|
|
["1.0.0"]: getDate(-7),
|
|
// cutoff-date here
|
|
["2.0.0"]: getDate(-4),
|
|
["3.0.0"]: getDate(-3),
|
|
},
|
|
});
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
originalBody
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// All versions should remain unchanged
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 3);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("2.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("3.0.0"));
|
|
|
|
// Latest should remain unchanged
|
|
assert.equal(modifiedJson["dist-tags"]["latest"], "3.0.0");
|
|
});
|
|
|
|
it("Should use custom minimum package age of 48 hours", async () => {
|
|
minimumPackageAgeSettings = 48;
|
|
skipMinimumPackageAgeSetting = false;
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "4.0.0",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
["4.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-24),
|
|
["1.0.0"]: getDate(-72), // 3 days old - should remain
|
|
["2.0.0"]: getDate(-50), // ~2 days old - should remain
|
|
// 48-hour cutoff here
|
|
["3.0.0"]: getDate(-40), // ~1.7 days old - should be removed
|
|
["4.0.0"]: getDate(-24), // 1 day old - should be removed
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// Versions older than 48 hours should remain
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("2.0.0"));
|
|
|
|
// Versions newer than 48 hours should be removed
|
|
assert.ok(!Object.keys(modifiedJson.versions).includes("3.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.versions).includes("4.0.0"));
|
|
|
|
// Latest should be recalculated to 2.0.0
|
|
assert.equal(modifiedJson["dist-tags"]["latest"], "2.0.0");
|
|
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 2);
|
|
});
|
|
|
|
it("Should use very small minimum package age of 1 hour", async () => {
|
|
minimumPackageAgeSettings = 1;
|
|
skipMinimumPackageAgeSetting = false;
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "3.0.0",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-48),
|
|
modified: getDate(0),
|
|
["1.0.0"]: getDate(-3), // 3 hours old - should remain
|
|
["2.0.0"]: getDate(-2), // 2 hours old - should remain
|
|
// 1-hour cutoff here
|
|
["3.0.0"]: getDate(0), // just published - should be removed
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 2);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("2.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.versions).includes("3.0.0"));
|
|
assert.equal(modifiedJson["dist-tags"]["latest"], "2.0.0");
|
|
});
|
|
|
|
it("Should not filter packages when package is in exclusion list", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = ["lodash"];
|
|
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const originalBody = JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: {
|
|
latest: "3.0.0",
|
|
},
|
|
versions: {
|
|
["1.0.0"]: {},
|
|
["2.0.0"]: {},
|
|
["3.0.0"]: {},
|
|
},
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-3),
|
|
["1.0.0"]: getDate(-7),
|
|
// cutoff-date here
|
|
["2.0.0"]: getDate(-4),
|
|
["3.0.0"]: getDate(-3), // Would normally be filtered
|
|
},
|
|
});
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(packageUrl, originalBody);
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// All versions should remain unchanged since lodash is excluded
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 3);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("2.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("3.0.0"));
|
|
assert.equal(modifiedJson["dist-tags"]["latest"], "3.0.0");
|
|
});
|
|
|
|
it("Should filter packages when package is NOT in exclusion list", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = ["react"]; // Different package
|
|
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: { latest: "3.0.0" },
|
|
versions: { ["1.0.0"]: {}, ["3.0.0"]: {} },
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-3),
|
|
["1.0.0"]: getDate(-7),
|
|
["3.0.0"]: getDate(-3),
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// lodash should still be filtered since it's not in exclusions
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 1);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(!Object.keys(modifiedJson.versions).includes("3.0.0"));
|
|
});
|
|
|
|
it("Should handle scoped packages in exclusion list", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = ["@babel/core"];
|
|
|
|
const packageUrl = "https://registry.npmjs.org/@babel/core";
|
|
|
|
const originalBody = JSON.stringify({
|
|
name: "@babel/core",
|
|
["dist-tags"]: { latest: "7.0.0" },
|
|
versions: { ["6.0.0"]: {}, ["7.0.0"]: {} },
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-1),
|
|
["6.0.0"]: getDate(-100),
|
|
["7.0.0"]: getDate(-1), // Would normally be filtered
|
|
},
|
|
});
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(packageUrl, originalBody);
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// All versions should remain for excluded scoped package
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 2);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("6.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("7.0.0"));
|
|
});
|
|
|
|
it("Should handle multiple packages in exclusion list", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = ["react", "lodash", "@types/node"];
|
|
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const originalBody = JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: { latest: "2.0.0" },
|
|
versions: { ["1.0.0"]: {}, ["2.0.0"]: {} },
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-1),
|
|
["1.0.0"]: getDate(-100),
|
|
["2.0.0"]: getDate(-1),
|
|
},
|
|
});
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(packageUrl, originalBody);
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// All versions should remain since lodash is in the exclusion list
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 2);
|
|
});
|
|
|
|
it("Should exclude packages matching wildcard pattern @scope/*", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = ["@aikidosec/*"];
|
|
|
|
const packageUrl = "https://registry.npmjs.org/@aikidosec/safe-chain";
|
|
|
|
const originalBody = JSON.stringify({
|
|
name: "@aikidosec/safe-chain",
|
|
["dist-tags"]: { latest: "2.0.0" },
|
|
versions: { ["1.0.0"]: {}, ["2.0.0"]: {} },
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-1),
|
|
["1.0.0"]: getDate(-100),
|
|
["2.0.0"]: getDate(-1), // Would normally be filtered
|
|
},
|
|
});
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(packageUrl, originalBody);
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// All versions should remain since @aikidosec/* matches @aikidosec/safe-chain
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 2);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("2.0.0"));
|
|
});
|
|
|
|
it("Should NOT exclude packages that don't match wildcard pattern", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = ["@aikidosec/*"];
|
|
|
|
const packageUrl = "https://registry.npmjs.org/@other/package";
|
|
|
|
const originalBody = JSON.stringify({
|
|
name: "@other/package",
|
|
["dist-tags"]: { latest: "2.0.0" },
|
|
versions: { ["1.0.0"]: {}, ["2.0.0"]: {} },
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-1),
|
|
["1.0.0"]: getDate(-100),
|
|
["2.0.0"]: getDate(-1),
|
|
},
|
|
});
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(packageUrl, originalBody);
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// Version 2.0.0 should be filtered since @other/package doesn't match @aikidosec/*
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 1);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
});
|
|
|
|
it("Should reset exclusions between tests", async () => {
|
|
minimumPackageAgeSettings = 5;
|
|
skipMinimumPackageAgeSetting = false;
|
|
minimumPackageAgeExclusionsSetting = []; // Reset to empty
|
|
|
|
const packageUrl = "https://registry.npmjs.org/lodash";
|
|
|
|
const modifiedBody = await runModifyNpmInfoRequest(
|
|
packageUrl,
|
|
JSON.stringify({
|
|
name: "lodash",
|
|
["dist-tags"]: { latest: "2.0.0" },
|
|
versions: { ["1.0.0"]: {}, ["2.0.0"]: {} },
|
|
time: {
|
|
created: getDate(-365 * 24),
|
|
modified: getDate(-1),
|
|
["1.0.0"]: getDate(-100),
|
|
["2.0.0"]: getDate(-1),
|
|
},
|
|
})
|
|
);
|
|
|
|
const modifiedJson = JSON.parse(modifiedBody);
|
|
|
|
// Version 2.0.0 should be filtered since exclusions are empty
|
|
assert.equal(Object.keys(modifiedJson.versions).length, 1);
|
|
assert.ok(Object.keys(modifiedJson.versions).includes("1.0.0"));
|
|
});
|
|
|
|
function getDate(plusHours) {
|
|
const date = new Date();
|
|
date.setHours(date.getHours() + plusHours);
|
|
|
|
return date;
|
|
}
|
|
|
|
/**
|
|
* @param {import("../interceptorBuilder.js").Interceptor} interceptor
|
|
* @param {string} body
|
|
* @returns {Promise<string>}
|
|
*/
|
|
async function runModifyNpmInfoRequest(url, body) {
|
|
const interceptor = npmInterceptorForUrl(url);
|
|
const requestHandler = await interceptor.handleRequest(url);
|
|
|
|
if (requestHandler.modifiesResponse()) {
|
|
const modifiedBuffer = requestHandler.modifyBody(Buffer.from(body), {
|
|
["content-type"]: "application/json",
|
|
});
|
|
return modifiedBuffer.toString("utf8");
|
|
}
|
|
|
|
return body;
|
|
}
|
|
});
|