mirror of
https://github.com/AikidoSec/safe-chain.git
synced 2026-05-26 12:10:49 +00:00
Merge pull request #27 from AikidoSec/bun-security-scanner
Implement basic bun security scanner for safe chain
This commit is contained in:
commit
8f6742504f
7 changed files with 421 additions and 5 deletions
5
.github/workflows/test-on-pr.yml
vendored
5
.github/workflows/test-on-pr.yml
vendored
|
|
@ -1,9 +1,6 @@
|
||||||
name: Run tests
|
name: Run tests
|
||||||
|
|
||||||
on:
|
on: pull_request
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
unit-test:
|
unit-test:
|
||||||
|
|
|
||||||
204
package-lock.json
generated
204
package-lock.json
generated
|
|
@ -23,6 +23,10 @@
|
||||||
"resolved": "packages/safe-chain",
|
"resolved": "packages/safe-chain",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@aikidosec/safe-chain-bun": {
|
||||||
|
"resolved": "packages/safe-chain-bun",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@aikidosec/safe-chain-e2e-tests": {
|
"node_modules/@aikidosec/safe-chain-e2e-tests": {
|
||||||
"resolved": "test/e2e",
|
"resolved": "test/e2e",
|
||||||
"link": true
|
"link": true
|
||||||
|
|
@ -738,6 +742,160 @@
|
||||||
"node": "^18.17.0 || >=20.5.0"
|
"node": "^18.17.0 || >=20.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@oven/bun-darwin-aarch64": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-SihfZ3czKeWz6Z3m5rUDrMlarwOXjnkUg+7tIiSB9VZCFSvWEItMfdAF170eCXxZmEh7A1dw20a3lW37lkmlrA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-darwin-x64": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-iXr4y2ap6EmME7/EDoLMxSRKAh9yswKfrHDb9sF+ExHbk1C+XsNGxMY73ckQe2w0SIH6NXz2cRMTORbZ8LNjig==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-darwin-x64-baseline": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-3KeslC5z3vpXxluYBqh6EDwojxTSyWJQeYPJFf7y/Z5QJuAN7g33l8jrx072X8P/G8CBzU1lJky14vhhnqWd7A==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-linux-aarch64": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-jpUFKGUpim4h4KOqI1VYYgvifZVrWNQZFrmVPfSqGb0ZzF/p5L2qc9Hy2aUL3Lo+zHMPylwbe0iLKElPYk0xoQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-linux-aarch64-musl": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-7UoUHKACYDin3iR6kdqUrF1AOCCjTHPTv1xmzlX4rzwNQvFYSAR83AMrY7hkatKGzLYkI8EjXDAvFJpwF+ZxoA==",
|
||||||
|
"cpu": [
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-linux-x64": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-6RuXFaVU2ve0TVw1vfFo7ix/jh9IX7mMAEhwE2odX8EdX/ea55upiivYQ/EKeXt+Ij3STc2bCeV4vvRoEJAHdg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-linux-x64-baseline": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-oZ5FUMfeghwbQcL9oxajsKjwVI+1GnVvxcJ3z+pifuXaLMZr25NCr5h0q2j+ZxEFL3RtL/Pyj8/HLfzGEIVAVg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-linux-x64-musl": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-ioZjU+2yyLJXaDA8FKoy+tj/fuZKovG9EMp+n9+EG7g3MULbe5nU8gdsS/dET28WzuPlDlSkqF8EUocvg4HajQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-linux-x64-musl-baseline": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-0NzMg4XdXgujDM2jZogiV6MgACXW0a0NfB+o6fxwmUzdmMBUk1ZMRzypUi4XKjGUe89mYcPJcVFQRRnNwzTK/Q==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-windows-x64": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-DZVCXrZGN/B4JnVnieZin1Kxse1wOkf+Fm2hDGpZHzs27ECbw5xPMFIc0r/oCpxTc/InxuvYO9UGoOmvhFaHsQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
|
"node_modules/@oven/bun-windows-x64-baseline": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-sTnkLdThgsa6X8ib6eb3+zgy+CGJOibK6Th4wV2wmZFi5af6TM+digEi9i+q/X3nabGwPXm0V4vBiVpvcFilsA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"peer": true
|
||||||
|
},
|
||||||
"node_modules/@pkgjs/parseargs": {
|
"node_modules/@pkgjs/parseargs": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||||
|
|
@ -1308,6 +1466,41 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bun": {
|
||||||
|
"version": "1.2.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/bun/-/bun-1.2.21.tgz",
|
||||||
|
"integrity": "sha512-y0lJ02dS90U3PJm+7KAKY8Se95AQvP5Xm77LouUwrpNOHpv59kBG4SK1+9iE1cAhpUaFipq+0EJ56S6MmE3row==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64",
|
||||||
|
"x64",
|
||||||
|
"aarch64"
|
||||||
|
],
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"os": [
|
||||||
|
"darwin",
|
||||||
|
"linux",
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"peer": true,
|
||||||
|
"bin": {
|
||||||
|
"bun": "bin/bun.exe",
|
||||||
|
"bunx": "bin/bunx.exe"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@oven/bun-darwin-aarch64": "1.2.21",
|
||||||
|
"@oven/bun-darwin-x64": "1.2.21",
|
||||||
|
"@oven/bun-darwin-x64-baseline": "1.2.21",
|
||||||
|
"@oven/bun-linux-aarch64": "1.2.21",
|
||||||
|
"@oven/bun-linux-aarch64-musl": "1.2.21",
|
||||||
|
"@oven/bun-linux-x64": "1.2.21",
|
||||||
|
"@oven/bun-linux-x64-baseline": "1.2.21",
|
||||||
|
"@oven/bun-linux-x64-musl": "1.2.21",
|
||||||
|
"@oven/bun-linux-x64-musl-baseline": "1.2.21",
|
||||||
|
"@oven/bun-windows-x64": "1.2.21",
|
||||||
|
"@oven/bun-windows-x64-baseline": "1.2.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/bytes": {
|
"node_modules/bytes": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
|
||||||
|
|
@ -5797,6 +5990,17 @@
|
||||||
"safe-chain": "bin/safe-chain.js"
|
"safe-chain": "bin/safe-chain.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"packages/safe-chain-bun": {
|
||||||
|
"name": "@aikidosec/safe-chain-bun",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"dependencies": {
|
||||||
|
"@aikidosec/safe-chain": "file:../safe-chain"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bun": ">=1.2.21"
|
||||||
|
}
|
||||||
|
},
|
||||||
"test/e2e": {
|
"test/e2e": {
|
||||||
"name": "@aikidosec/safe-chain-e2e-tests",
|
"name": "@aikidosec/safe-chain-e2e-tests",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
"test/e2e"
|
"test/e2e"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run test --workspace=packages/safe-chain",
|
"test": "npm run test --workspace=packages/safe-chain --workspace=packages/safe-chain-bun",
|
||||||
"test:e2e": "npm run test --workspace=test/e2e",
|
"test:e2e": "npm run test --workspace=test/e2e",
|
||||||
"lint": "npm run lint --workspace=packages/safe-chain"
|
"lint": "npm run lint --workspace=packages/safe-chain"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
30
packages/safe-chain-bun/package.json
Normal file
30
packages/safe-chain-bun/package.json
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "@aikidosec/safe-chain-bun",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"main": "src/index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "node --test --experimental-test-module-mocks 'src/**/*.spec.js'"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"bun": "./src/index.js",
|
||||||
|
"default": "./src/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"keywords": ["bun", "security", "scanner", "malware", "aikido"],
|
||||||
|
"author": "Aikido Security",
|
||||||
|
"license": "AGPL-3.0-or-later",
|
||||||
|
"description": "Aikido Security Scanner for Bun package manager - detects malware and security threats during package installation",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/AikidoSec/safe-chain.git",
|
||||||
|
"directory": "packages/safe-chain-bun"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@aikidosec/safe-chain": "file:../safe-chain"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bun": ">=1.2.21"
|
||||||
|
}
|
||||||
|
}
|
||||||
37
packages/safe-chain-bun/src/index.js
Normal file
37
packages/safe-chain-bun/src/index.js
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { auditChanges } from "@aikidosec/safe-chain/scanning";
|
||||||
|
|
||||||
|
// Bun Security Scanner for Safe-Chain
|
||||||
|
// This is the entry point for Bun's native security scanner integration
|
||||||
|
|
||||||
|
export const scanner = {
|
||||||
|
version: "1", // Our scanner is using version 1 of the bun security scanner API.
|
||||||
|
|
||||||
|
async scan({ packages }) {
|
||||||
|
const advisories = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const changes = packages.map((pkg) => ({
|
||||||
|
name: pkg.name,
|
||||||
|
version: pkg.version,
|
||||||
|
type: "add",
|
||||||
|
}));
|
||||||
|
|
||||||
|
const audit = await auditChanges(changes);
|
||||||
|
|
||||||
|
if (!audit.isAllowed) {
|
||||||
|
for (const change of audit.disallowedChanges) {
|
||||||
|
advisories.push({
|
||||||
|
level: "fatal", // Fatal will block the installation process, this is what we want for packages that contain malware.
|
||||||
|
package: change.name,
|
||||||
|
url: null,
|
||||||
|
description: `Package ${change.name}@${change.version} contains known security threats (${change.reason}). Installation blocked by Safe-Chain.`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`Safe-Chain security scan failed: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return advisories;
|
||||||
|
},
|
||||||
|
};
|
||||||
140
packages/safe-chain-bun/src/index.spec.js
Normal file
140
packages/safe-chain-bun/src/index.spec.js
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { describe, it, mock } from "node:test";
|
||||||
|
|
||||||
|
describe("Bun Scanner", async () => {
|
||||||
|
const mockAuditChanges = mock.fn();
|
||||||
|
|
||||||
|
// Mock the scanning module
|
||||||
|
mock.module("@aikidosec/safe-chain/scanning", {
|
||||||
|
namedExports: {
|
||||||
|
auditChanges: mockAuditChanges,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { scanner } = await import("./index.js");
|
||||||
|
|
||||||
|
it("should export scanner object with version", () => {
|
||||||
|
assert.strictEqual(scanner.version, "1");
|
||||||
|
assert.strictEqual(typeof scanner.scan, "function");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return empty advisories for clean packages", async () => {
|
||||||
|
mockAuditChanges.mock.mockImplementation(() => ({
|
||||||
|
allowedChanges: [{ name: "express", version: "4.18.2", type: "add" }],
|
||||||
|
disallowedChanges: [],
|
||||||
|
isAllowed: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const packages = [{ name: "express", version: "4.18.2" }];
|
||||||
|
const result = await scanner.scan({ packages });
|
||||||
|
|
||||||
|
assert.deepEqual(result, []);
|
||||||
|
assert.strictEqual(mockAuditChanges.mock.callCount(), 1);
|
||||||
|
assert.deepEqual(mockAuditChanges.mock.calls[0].arguments[0], [
|
||||||
|
{ name: "express", version: "4.18.2", type: "add" },
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return fatal advisory for malware packages", async () => {
|
||||||
|
mockAuditChanges.mock.mockImplementation(() => ({
|
||||||
|
allowedChanges: [],
|
||||||
|
disallowedChanges: [
|
||||||
|
{
|
||||||
|
name: "malicious-pkg",
|
||||||
|
version: "1.0.0",
|
||||||
|
type: "add",
|
||||||
|
reason: "MALWARE",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isAllowed: false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const packages = [{ name: "malicious-pkg", version: "1.0.0" }];
|
||||||
|
const result = await scanner.scan({ packages });
|
||||||
|
|
||||||
|
assert.strictEqual(result.length, 1);
|
||||||
|
assert.deepEqual(result[0], {
|
||||||
|
level: "fatal",
|
||||||
|
package: "malicious-pkg",
|
||||||
|
url: null,
|
||||||
|
description: "Package malicious-pkg@1.0.0 contains known security threats (MALWARE). Installation blocked by Safe-Chain.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle multiple packages with mixed results", async () => {
|
||||||
|
mockAuditChanges.mock.mockImplementation(() => ({
|
||||||
|
allowedChanges: [{ name: "express", version: "4.18.2", type: "add" }],
|
||||||
|
disallowedChanges: [
|
||||||
|
{
|
||||||
|
name: "malicious-pkg",
|
||||||
|
version: "1.0.0",
|
||||||
|
type: "add",
|
||||||
|
reason: "MALWARE",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "another-bad-pkg",
|
||||||
|
version: "2.1.0",
|
||||||
|
type: "add",
|
||||||
|
reason: "MALWARE",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
isAllowed: false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const packages = [
|
||||||
|
{ name: "express", version: "4.18.2" },
|
||||||
|
{ name: "malicious-pkg", version: "1.0.0" },
|
||||||
|
{ name: "another-bad-pkg", version: "2.1.0" },
|
||||||
|
];
|
||||||
|
const result = await scanner.scan({ packages });
|
||||||
|
|
||||||
|
assert.strictEqual(result.length, 2);
|
||||||
|
assert.strictEqual(result[0].package, "malicious-pkg");
|
||||||
|
assert.strictEqual(result[0].level, "fatal");
|
||||||
|
assert.strictEqual(result[1].package, "another-bad-pkg");
|
||||||
|
assert.strictEqual(result[1].level, "fatal");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle empty package list", async () => {
|
||||||
|
mockAuditChanges.mock.mockImplementation(() => ({
|
||||||
|
allowedChanges: [],
|
||||||
|
disallowedChanges: [],
|
||||||
|
isAllowed: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const result = await scanner.scan({ packages: [] });
|
||||||
|
|
||||||
|
assert.deepEqual(result, []);
|
||||||
|
assert.deepEqual(
|
||||||
|
mockAuditChanges.mock.calls[mockAuditChanges.mock.callCount() - 1]
|
||||||
|
.arguments[0],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should convert Bun package format to safe-chain format correctly", async () => {
|
||||||
|
mockAuditChanges.mock.mockImplementation(() => ({
|
||||||
|
allowedChanges: [],
|
||||||
|
disallowedChanges: [],
|
||||||
|
isAllowed: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
const bunPackages = [
|
||||||
|
{ name: "lodash", version: "4.17.21" },
|
||||||
|
{ name: "@types/node", version: "20.0.0" },
|
||||||
|
];
|
||||||
|
|
||||||
|
await scanner.scan({ packages: bunPackages });
|
||||||
|
|
||||||
|
const expectedChanges = [
|
||||||
|
{ name: "lodash", version: "4.17.21", type: "add" },
|
||||||
|
{ name: "@types/node", version: "20.0.0", type: "add" },
|
||||||
|
];
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
mockAuditChanges.mock.calls[mockAuditChanges.mock.callCount() - 1]
|
||||||
|
.arguments[0],
|
||||||
|
expectedChanges
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -15,6 +15,14 @@
|
||||||
"safe-chain": "bin/safe-chain.js"
|
"safe-chain": "bin/safe-chain.js"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"default": "./src/main.js"
|
||||||
|
},
|
||||||
|
"./scanning": {
|
||||||
|
"default": "./src/scanning/audit/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Aikido Security",
|
"author": "Aikido Security",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue