remove trailing slashes and fix test failures

This commit is contained in:
123Haynes 2026-04-01 07:08:30 +00:00
parent 1abe5932ad
commit f01d935bb1
7 changed files with 61 additions and 8 deletions

View file

@ -97,12 +97,13 @@ export async function fetchNewPackagesList() {
const ecosystem = getEcoSystem(); const ecosystem = getEcoSystem();
const baseUrl = getMalwareListBaseUrl(); const baseUrl = getMalwareListBaseUrl();
const path = newPackagesListPaths[/** @type {keyof typeof newPackagesListPaths} */ (ecosystem)]; const path = newPackagesListPaths[/** @type {keyof typeof newPackagesListPaths} */ (ecosystem)];
const url = `${baseUrl}/${path}`;
if (!url) { if (!path) {
return { newPackagesList: [], version: undefined }; return { newPackagesList: [], version: undefined };
} }
const url = `${baseUrl}/${path}`;
const response = await fetch(url); const response = await fetch(url);
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(
@ -130,12 +131,13 @@ export async function fetchNewPackagesListVersion() {
const ecosystem = getEcoSystem(); const ecosystem = getEcoSystem();
const baseUrl = getMalwareListBaseUrl(); const baseUrl = getMalwareListBaseUrl();
const path = newPackagesListPaths[/** @type {keyof typeof newPackagesListPaths} */ (ecosystem)]; const path = newPackagesListPaths[/** @type {keyof typeof newPackagesListPaths} */ (ecosystem)];
const url = `${baseUrl}/${path}`;
if (!url) { if (!path) {
return undefined; return undefined;
} }
const url = `${baseUrl}/${path}`;
const response = await fetch(url, { method: "HEAD" }); const response = await fetch(url, { method: "HEAD" });
if (!response.ok) { if (!response.ok) {
throw new Error( throw new Error(

View file

@ -185,6 +185,15 @@ describe("aikido API", async () => {
assert.deepStrictEqual(result.newPackagesList, []); assert.deepStrictEqual(result.newPackagesList, []);
assert.strictEqual(result.version, undefined); assert.strictEqual(result.version, undefined);
}); });
it("should return undefined version without fetching for unsupported ecosystems", async () => {
ecosystem = "ruby";
const result = await fetchNewPackagesListVersion();
assert.strictEqual(mockFetch.mock.calls.length, 0);
assert.strictEqual(result, undefined);
});
}); });
describe("fetchNewPackagesListVersion", () => { describe("fetchNewPackagesListVersion", () => {

View file

@ -207,21 +207,34 @@ export function getMalwareListBaseUrl() {
// Priority 1: CLI argument // Priority 1: CLI argument
const cliValue = cliArguments.getMalwareListBaseUrl(); const cliValue = cliArguments.getMalwareListBaseUrl();
if (cliValue) { if (cliValue) {
return cliValue; return removeTrailingSlashes(cliValue);
} }
// Priority 2: Environment variable // Priority 2: Environment variable
const envValue = environmentVariables.getMalwareListBaseUrl(); const envValue = environmentVariables.getMalwareListBaseUrl();
if (envValue) { if (envValue) {
return envValue; return removeTrailingSlashes(envValue);
} }
// Priority 3: Config file // Priority 3: Config file
const configValue = configFile.getMalwareListBaseUrl(); const configValue = configFile.getMalwareListBaseUrl();
if (configValue) { if (configValue) {
return configValue; return removeTrailingSlashes(configValue);
} }
// Default // Default
return "https://malware-list.aikido.dev"; return removeTrailingSlashes("https://malware-list.aikido.dev");
}
/**
* Removes trailing slashes from a URL-like string.
* @param {string} value
* @returns {string}
*/
function removeTrailingSlashes(value) {
if (!value || typeof value !== "string") {
return value;
}
return value.replace(/\/+$/, "");
} }

View file

@ -562,6 +562,32 @@ describe("getMalwareListBaseUrl", () => {
assert.strictEqual(url, "https://malware-list.aikido.dev"); assert.strictEqual(url, "https://malware-list.aikido.dev");
}); });
it("should trim trailing slash from CLI argument", () => {
initializeCliArguments(["--safe-chain-malware-list-base-url=https://cli-mirror.com/"]);
const url = getMalwareListBaseUrl();
assert.strictEqual(url, "https://cli-mirror.com");
});
it("should trim trailing slash from environment variable", () => {
process.env[envVarName] = "https://env-mirror.com/";
const url = getMalwareListBaseUrl();
assert.strictEqual(url, "https://env-mirror.com");
});
it("should trim trailing slash from config file value", () => {
configFileContent = JSON.stringify({
malwareListBaseUrl: "https://config-mirror.com/",
});
const url = getMalwareListBaseUrl();
assert.strictEqual(url, "https://config-mirror.com");
});
it("should return CLI argument value with highest priority", () => { it("should return CLI argument value with highest priority", () => {
initializeCliArguments(["--safe-chain-malware-list-base-url=https://cli-mirror.com"]); initializeCliArguments(["--safe-chain-malware-list-base-url=https://cli-mirror.com"]);

View file

@ -51,6 +51,7 @@ mock.module("../config/settings.js", {
namedExports: { namedExports: {
getMinimumPackageAgeHours: () => minimumPackageAgeHours, getMinimumPackageAgeHours: () => minimumPackageAgeHours,
getEcoSystem: () => ecosystem, getEcoSystem: () => ecosystem,
getMalwareListBaseUrl: () => "https://malware-list.aikido.dev",
ECOSYSTEM_JS: "js", ECOSYSTEM_JS: "js",
ECOSYSTEM_PY: "py", ECOSYSTEM_PY: "py",
}, },

View file

@ -8,6 +8,7 @@ mock.module("../config/settings.js", {
namedExports: { namedExports: {
getMinimumPackageAgeHours: () => minimumPackageAgeHours, getMinimumPackageAgeHours: () => minimumPackageAgeHours,
getEcoSystem: () => ecosystem, getEcoSystem: () => ecosystem,
getMalwareListBaseUrl: () => "https://malware-list.aikido.dev",
ECOSYSTEM_JS: "js", ECOSYSTEM_JS: "js",
ECOSYSTEM_PY: "py", ECOSYSTEM_PY: "py",
}, },

View file

@ -20,6 +20,7 @@ mock.module("../config/settings.js", {
namedExports: { namedExports: {
getEcoSystem: () => ecosystem, getEcoSystem: () => ecosystem,
getMinimumPackageAgeHours: () => 24, getMinimumPackageAgeHours: () => 24,
getMalwareListBaseUrl: () => "https://malware-list.aikido.dev",
ECOSYSTEM_JS: "js", ECOSYSTEM_JS: "js",
ECOSYSTEM_PY: "py", ECOSYSTEM_PY: "py",
}, },