project-shield 1.0.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 +440 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +151 -0
- package/dist/index.js.map +1 -0
- package/dist/integrity/failsafe.d.ts +17 -0
- package/dist/integrity/failsafe.d.ts.map +1 -0
- package/dist/integrity/failsafe.js +45 -0
- package/dist/integrity/failsafe.js.map +1 -0
- package/dist/integrity/ruleset.d.ts +12 -0
- package/dist/integrity/ruleset.d.ts.map +1 -0
- package/dist/integrity/ruleset.js +77 -0
- package/dist/integrity/ruleset.js.map +1 -0
- package/dist/integrity/seal.d.ts +12 -0
- package/dist/integrity/seal.d.ts.map +1 -0
- package/dist/integrity/seal.js +77 -0
- package/dist/integrity/seal.js.map +1 -0
- package/dist/output/badge.d.ts +16 -0
- package/dist/output/badge.d.ts.map +1 -0
- package/dist/output/badge.js +112 -0
- package/dist/output/badge.js.map +1 -0
- package/dist/output/evidence.d.ts +18 -0
- package/dist/output/evidence.d.ts.map +1 -0
- package/dist/output/evidence.js +205 -0
- package/dist/output/evidence.js.map +1 -0
- package/dist/output/fixit.d.ts +32 -0
- package/dist/output/fixit.d.ts.map +1 -0
- package/dist/output/fixit.js +387 -0
- package/dist/output/fixit.js.map +1 -0
- package/dist/output/terminal.d.ts +10 -0
- package/dist/output/terminal.d.ts.map +1 -0
- package/dist/output/terminal.js +190 -0
- package/dist/output/terminal.js.map +1 -0
- package/dist/scanner/engine.d.ts +6 -0
- package/dist/scanner/engine.d.ts.map +1 -0
- package/dist/scanner/engine.js +155 -0
- package/dist/scanner/engine.js.map +1 -0
- package/dist/scanner/ignore.d.ts +20 -0
- package/dist/scanner/ignore.d.ts.map +1 -0
- package/dist/scanner/ignore.js +125 -0
- package/dist/scanner/ignore.js.map +1 -0
- package/dist/scanner/injection.d.ts +15 -0
- package/dist/scanner/injection.d.ts.map +1 -0
- package/dist/scanner/injection.js +234 -0
- package/dist/scanner/injection.js.map +1 -0
- package/dist/scanner/mcp.d.ts +6 -0
- package/dist/scanner/mcp.d.ts.map +1 -0
- package/dist/scanner/mcp.js +322 -0
- package/dist/scanner/mcp.js.map +1 -0
- package/dist/scanner/pii.d.ts +21 -0
- package/dist/scanner/pii.d.ts.map +1 -0
- package/dist/scanner/pii.js +161 -0
- package/dist/scanner/pii.js.map +1 -0
- package/dist/scanner/secrets.d.ts +10 -0
- package/dist/scanner/secrets.d.ts.map +1 -0
- package/dist/scanner/secrets.js +224 -0
- package/dist/scanner/secrets.js.map +1 -0
- package/dist/scoring/lock.d.ts +12 -0
- package/dist/scoring/lock.d.ts.map +1 -0
- package/dist/scoring/lock.js +58 -0
- package/dist/scoring/lock.js.map +1 -0
- package/dist/scoring/score.d.ts +14 -0
- package/dist/scoring/score.d.ts.map +1 -0
- package/dist/scoring/score.js +74 -0
- package/dist/scoring/score.js.map +1 -0
- package/dist/types/index.d.ts +205 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +52 -0
- package/rules/v1.0.0.json +248 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.computeRulesetHash = computeRulesetHash;
|
|
37
|
+
exports.loadRuleset = loadRuleset;
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
const crypto = __importStar(require("node:crypto"));
|
|
41
|
+
const failsafe_js_1 = require("./failsafe.js");
|
|
42
|
+
/**
|
|
43
|
+
* Compute SHA-256 hash of the ruleset content (excluding the sha256 field itself).
|
|
44
|
+
*/
|
|
45
|
+
function computeRulesetHash(content) {
|
|
46
|
+
const parsed = JSON.parse(content);
|
|
47
|
+
// Remove the sha256 field before hashing
|
|
48
|
+
const { sha256: _hash, ...rest } = parsed;
|
|
49
|
+
const canonical = JSON.stringify(rest, null, 2);
|
|
50
|
+
return crypto.createHash('sha256').update(canonical).digest('hex');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Load and verify a ruleset file.
|
|
54
|
+
* Throws RulesetNotFoundError if file doesn't exist.
|
|
55
|
+
* Throws RulesetIntegrityError if hash doesn't match.
|
|
56
|
+
*/
|
|
57
|
+
function loadRuleset(rulesetPath) {
|
|
58
|
+
const resolvedPath = rulesetPath ?? path.join(process.cwd(), 'rules', 'v1.0.0.json');
|
|
59
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
60
|
+
throw new failsafe_js_1.RulesetNotFoundError(resolvedPath);
|
|
61
|
+
}
|
|
62
|
+
const content = fs.readFileSync(resolvedPath, 'utf-8');
|
|
63
|
+
let parsed;
|
|
64
|
+
try {
|
|
65
|
+
parsed = JSON.parse(content);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
throw new failsafe_js_1.RulesetIntegrityError();
|
|
69
|
+
}
|
|
70
|
+
const expectedHash = parsed.sha256;
|
|
71
|
+
const actualHash = computeRulesetHash(content);
|
|
72
|
+
if (actualHash !== expectedHash) {
|
|
73
|
+
throw new failsafe_js_1.RulesetIntegrityError();
|
|
74
|
+
}
|
|
75
|
+
return parsed;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=ruleset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleset.js","sourceRoot":"","sources":["../../src/integrity/ruleset.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,gDAMC;AAOD,kCAwBC;AA9CD,4CAA8B;AAC9B,gDAAkC;AAClC,oDAAsC;AAEtC,+CAA4E;AAE5E;;GAEG;AACH,SAAgB,kBAAkB,CAAC,OAAe;IAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,yCAAyC;IACzC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACrE,CAAC;AAED;;;;GAIG;AACH,SAAgB,WAAW,CAAC,WAAoB;IAC9C,MAAM,YAAY,GAAG,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAErF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,kCAAoB,CAAC,YAAY,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACvD,IAAI,MAAe,CAAC;IAEpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,mCAAqB,EAAE,CAAC;IACpC,CAAC;IAED,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACnC,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE/C,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;QAChC,MAAM,IAAI,mCAAqB,EAAE,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ScanResult, ScanScore, SealedResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Seal scan results with a SHA-256 hash for tamper detection.
|
|
4
|
+
*
|
|
5
|
+
* The hash covers: findings + score + timestamp + rulesetVersion.
|
|
6
|
+
* Same inputs (with same timestamp) produce the same hash.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sealResult(scanResult: ScanResult, score: ScanScore, rulesetVersion: string, options?: {
|
|
9
|
+
isPro?: boolean;
|
|
10
|
+
timestamp?: string;
|
|
11
|
+
}): SealedResult;
|
|
12
|
+
//# sourceMappingURL=seal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seal.d.ts","sourceRoot":"","sources":["../../src/integrity/seal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,SAAS,EAChB,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD,YAAY,CAqCd"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.sealResult = sealResult;
|
|
37
|
+
const crypto = __importStar(require("node:crypto"));
|
|
38
|
+
/**
|
|
39
|
+
* Seal scan results with a SHA-256 hash for tamper detection.
|
|
40
|
+
*
|
|
41
|
+
* The hash covers: findings + score + timestamp + rulesetVersion.
|
|
42
|
+
* Same inputs (with same timestamp) produce the same hash.
|
|
43
|
+
*/
|
|
44
|
+
function sealResult(scanResult, score, rulesetVersion, options) {
|
|
45
|
+
const timestamp = options?.timestamp ?? new Date().toISOString();
|
|
46
|
+
const isPro = options?.isPro ?? false;
|
|
47
|
+
const payload = {
|
|
48
|
+
findings: {
|
|
49
|
+
secrets: scanResult.secrets,
|
|
50
|
+
pii: scanResult.pii,
|
|
51
|
+
mcp: scanResult.mcp,
|
|
52
|
+
injection: scanResult.injection,
|
|
53
|
+
},
|
|
54
|
+
score: {
|
|
55
|
+
numericScore: score.numericScore,
|
|
56
|
+
grade: score.grade,
|
|
57
|
+
isLocked: score.isLocked,
|
|
58
|
+
},
|
|
59
|
+
timestamp,
|
|
60
|
+
rulesetVersion,
|
|
61
|
+
};
|
|
62
|
+
const resultHash = crypto
|
|
63
|
+
.createHash('sha256')
|
|
64
|
+
.update(JSON.stringify(payload))
|
|
65
|
+
.digest('hex');
|
|
66
|
+
const seal = {
|
|
67
|
+
resultHash,
|
|
68
|
+
timestamp,
|
|
69
|
+
rulesetVersion,
|
|
70
|
+
};
|
|
71
|
+
if (isPro) {
|
|
72
|
+
seal.badgeUUID = crypto.randomUUID();
|
|
73
|
+
seal.verifyURL = `https://shield.verify/${seal.badgeUUID}`;
|
|
74
|
+
}
|
|
75
|
+
return seal;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=seal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seal.js","sourceRoot":"","sources":["../../src/integrity/seal.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,gCA0CC;AAnDD,oDAAsC;AAGtC;;;;;GAKG;AACH,SAAgB,UAAU,CACxB,UAAsB,EACtB,KAAgB,EAChB,cAAsB,EACtB,OAAiD;IAEjD,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAC;IAEtC,MAAM,OAAO,GAAG;QACd,QAAQ,EAAE;YACR,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,GAAG,EAAE,UAAU,CAAC,GAAG;YACnB,GAAG,EAAE,UAAU,CAAC,GAAG;YACnB,SAAS,EAAE,UAAU,CAAC,SAAS;SAChC;QACD,KAAK,EAAE;YACL,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ;SACzB;QACD,SAAS;QACT,cAAc;KACf,CAAC;IAEF,MAAM,UAAU,GAAG,MAAM;SACtB,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;SAC/B,MAAM,CAAC,KAAK,CAAC,CAAC;IAEjB,MAAM,IAAI,GAAiB;QACzB,UAAU;QACV,SAAS;QACT,cAAc;KACf,CAAC;IAEF,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,yBAAyB,IAAI,CAAC,SAAS,EAAE,CAAC;IAC7D,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ScanScore, LockStatus } from '../types/index.js';
|
|
2
|
+
export declare class BadgeLockedError extends Error {
|
|
3
|
+
constructor(message: string);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Generate an SVG badge in shields.io style.
|
|
7
|
+
* Throws BadgeLockedError if score is F (locked).
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateBadge(score: ScanScore, lockStatus: LockStatus, options?: {
|
|
10
|
+
isPro: boolean;
|
|
11
|
+
}): string;
|
|
12
|
+
/**
|
|
13
|
+
* Save an SVG badge to disk.
|
|
14
|
+
*/
|
|
15
|
+
export declare function saveBadge(svgContent: string, outputPath: string): void;
|
|
16
|
+
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/output/badge.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/D,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAcD;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAqB,GAC7C,MAAM,CAwCR;AAYD;;GAEG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAEtE"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.BadgeLockedError = void 0;
|
|
37
|
+
exports.generateBadge = generateBadge;
|
|
38
|
+
exports.saveBadge = saveBadge;
|
|
39
|
+
const fs = __importStar(require("node:fs"));
|
|
40
|
+
class BadgeLockedError extends Error {
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(message);
|
|
43
|
+
this.name = 'BadgeLockedError';
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.BadgeLockedError = BadgeLockedError;
|
|
47
|
+
/**
|
|
48
|
+
* Badge color mapping by grade.
|
|
49
|
+
*/
|
|
50
|
+
const BADGE_COLORS = {
|
|
51
|
+
A: '#4c1', // green
|
|
52
|
+
B: '#97CA00', // brightgreen
|
|
53
|
+
C: '#dfb317', // yellow
|
|
54
|
+
D: '#fe7d37', // orange
|
|
55
|
+
E: '#e05d44', // red-orange
|
|
56
|
+
F: '#e05d44', // red
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Generate an SVG badge in shields.io style.
|
|
60
|
+
* Throws BadgeLockedError if score is F (locked).
|
|
61
|
+
*/
|
|
62
|
+
function generateBadge(score, lockStatus, options = { isPro: false }) {
|
|
63
|
+
if (lockStatus.isLocked) {
|
|
64
|
+
throw new BadgeLockedError(`Badge generation is locked: ${lockStatus.message}`);
|
|
65
|
+
}
|
|
66
|
+
const color = BADGE_COLORS[score.grade] ?? '#9f9f9f';
|
|
67
|
+
const label = 'Project Shield';
|
|
68
|
+
const value = `${score.grade} (${score.numericScore}/100)`;
|
|
69
|
+
const labelWidth = label.length * 7 + 10;
|
|
70
|
+
const valueWidth = value.length * 7 + 10;
|
|
71
|
+
const totalWidth = labelWidth + valueWidth;
|
|
72
|
+
const watermark = options.isPro ? '' : generateWatermark(labelWidth, totalWidth);
|
|
73
|
+
const disclaimer = 'This badge is informational only. It does not guarantee the absence of security vulnerabilities.';
|
|
74
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${value}">
|
|
75
|
+
<metadata>${disclaimer}</metadata>
|
|
76
|
+
<title>${label}: ${value}</title>
|
|
77
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
78
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
79
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
80
|
+
</linearGradient>
|
|
81
|
+
<clipPath id="r">
|
|
82
|
+
<rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
|
|
83
|
+
</clipPath>
|
|
84
|
+
<g clip-path="url(#r)">
|
|
85
|
+
<rect width="${labelWidth}" height="20" fill="#555"/>
|
|
86
|
+
<rect x="${labelWidth}" width="${valueWidth}" height="20" fill="${color}"/>
|
|
87
|
+
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
88
|
+
</g>
|
|
89
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
90
|
+
<text aria-hidden="true" x="${labelWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${label}</text>
|
|
91
|
+
<text x="${labelWidth / 2}" y="14">${label}</text>
|
|
92
|
+
<text aria-hidden="true" x="${labelWidth + valueWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${value}</text>
|
|
93
|
+
<text x="${labelWidth + valueWidth / 2}" y="14">${value}</text>
|
|
94
|
+
</g>${watermark}
|
|
95
|
+
</svg>`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Generate watermark text for free tier badges.
|
|
99
|
+
*/
|
|
100
|
+
function generateWatermark(labelWidth, totalWidth) {
|
|
101
|
+
return `
|
|
102
|
+
<g fill="#fff" fill-opacity="0.15" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="8" transform="rotate(-20, ${totalWidth / 2}, 10)">
|
|
103
|
+
<text x="${totalWidth / 2}" y="12">FREE</text>
|
|
104
|
+
</g>`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Save an SVG badge to disk.
|
|
108
|
+
*/
|
|
109
|
+
function saveBadge(svgContent, outputPath) {
|
|
110
|
+
fs.writeFileSync(outputPath, svgContent, 'utf-8');
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.js","sourceRoot":"","sources":["../../src/output/badge.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,sCA4CC;AAeD,8BAEC;AAvFD,4CAA8B;AAG9B,MAAa,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AALD,4CAKC;AAED;;GAEG;AACH,MAAM,YAAY,GAA2B;IAC3C,CAAC,EAAE,MAAM,EAAO,QAAQ;IACxB,CAAC,EAAE,SAAS,EAAI,cAAc;IAC9B,CAAC,EAAE,SAAS,EAAI,SAAS;IACzB,CAAC,EAAE,SAAS,EAAI,SAAS;IACzB,CAAC,EAAE,SAAS,EAAI,aAAa;IAC7B,CAAC,EAAE,SAAS,EAAI,MAAM;CACvB,CAAC;AAEF;;;GAGG;AACH,SAAgB,aAAa,CAC3B,KAAgB,EAChB,UAAsB,EACtB,UAA8B,EAAE,KAAK,EAAE,KAAK,EAAE;IAE9C,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,gBAAgB,CACxB,+BAA+B,UAAU,CAAC,OAAO,EAAE,CACpD,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC;IACrD,MAAM,KAAK,GAAG,gBAAgB,CAAC;IAC/B,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,YAAY,OAAO,CAAC;IAE3D,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,UAAU,GAAG,UAAU,CAAC;IAE3C,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACjF,MAAM,UAAU,GAAG,kGAAkG,CAAC;IAEtH,OAAO,kDAAkD,UAAU,wCAAwC,KAAK,KAAK,KAAK;cAC9G,UAAU;WACb,KAAK,KAAK,KAAK;;;;;;mBAMP,UAAU;;;mBAGV,UAAU;eACd,UAAU,YAAY,UAAU,uBAAuB,KAAK;mBACxD,UAAU;;;kCAGK,UAAU,GAAG,CAAC,6CAA6C,KAAK;eACnF,UAAU,GAAG,CAAC,YAAY,KAAK;kCACZ,UAAU,GAAG,UAAU,GAAG,CAAC,6CAA6C,KAAK;eAChG,UAAU,GAAG,UAAU,GAAG,CAAC,YAAY,KAAK;QACnD,SAAS;OACV,CAAC;AACR,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,UAAkB,EAAE,UAAkB;IAC/D,OAAO;qJAC4I,UAAU,GAAG,CAAC;eACpJ,UAAU,GAAG,CAAC;OACtB,CAAC;AACR,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,UAAkB,EAAE,UAAkB;IAC9D,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ScanResult, ScanScore, LockStatus, SealedResult, EvidencePack } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generate an EvidencePack JSON object from scan results.
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateEvidenceJSON(result: ScanResult, score: ScanScore, lockStatus: LockStatus, seal: SealedResult, config: {
|
|
6
|
+
scanTarget: string;
|
|
7
|
+
rulesetHash: string;
|
|
8
|
+
rulesetVersion: string;
|
|
9
|
+
}): EvidencePack;
|
|
10
|
+
/**
|
|
11
|
+
* Save EvidencePack as JSON file.
|
|
12
|
+
*/
|
|
13
|
+
export declare function saveEvidenceJSON(pack: EvidencePack, outputPath: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Generate a PDF Evidence Pack using pdfkit.
|
|
16
|
+
*/
|
|
17
|
+
export declare function generateEvidencePDF(pack: EvidencePack, outputPath: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/output/evidence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACb,MAAM,mBAAmB,CAAC;AAQ3B;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAC1E,YAAY,CAqCd;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAE7E;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,YAAY,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAyHf"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.generateEvidenceJSON = generateEvidenceJSON;
|
|
37
|
+
exports.saveEvidenceJSON = saveEvidenceJSON;
|
|
38
|
+
exports.generateEvidencePDF = generateEvidencePDF;
|
|
39
|
+
const fs = __importStar(require("node:fs"));
|
|
40
|
+
const fixit_js_1 = require("./fixit.js");
|
|
41
|
+
const DISCLAIMER = 'This scan covers: secret exposure, config checks, PII patterns, prompt injection patterns. ' +
|
|
42
|
+
'This is NOT a penetration test. Results do not guarantee complete security. ' +
|
|
43
|
+
'Generated by Project Shield v1.0.0.';
|
|
44
|
+
/**
|
|
45
|
+
* Generate an EvidencePack JSON object from scan results.
|
|
46
|
+
*/
|
|
47
|
+
function generateEvidenceJSON(result, score, lockStatus, seal, config) {
|
|
48
|
+
const guides = (0, fixit_js_1.getFixitGuides)(result, { isPro: true });
|
|
49
|
+
const criticalGuides = guides.filter(g => g.severity === 'critical');
|
|
50
|
+
return {
|
|
51
|
+
generatedAt: new Date().toISOString(),
|
|
52
|
+
toolVersion: '1.0.0',
|
|
53
|
+
rulesetVersion: config.rulesetVersion,
|
|
54
|
+
scanTarget: config.scanTarget,
|
|
55
|
+
filesScanned: result.summary.filesScanned,
|
|
56
|
+
filesExcluded: result.summary.filesExcluded,
|
|
57
|
+
scanDuration: `${(result.summary.timeMs / 1000).toFixed(1)}s`,
|
|
58
|
+
score,
|
|
59
|
+
lockStatus,
|
|
60
|
+
findings: {
|
|
61
|
+
secrets: result.secrets,
|
|
62
|
+
pii: result.pii,
|
|
63
|
+
mcp: result.mcp,
|
|
64
|
+
injection: result.injection,
|
|
65
|
+
},
|
|
66
|
+
fixitSummary: {
|
|
67
|
+
totalIssues: result.secrets.length +
|
|
68
|
+
result.pii.length +
|
|
69
|
+
result.mcp.length +
|
|
70
|
+
result.injection.length,
|
|
71
|
+
criticalIssues: criticalGuides.length,
|
|
72
|
+
fixitGuidesAvailable: guides.length,
|
|
73
|
+
},
|
|
74
|
+
integrity: {
|
|
75
|
+
rulesetHash: config.rulesetHash,
|
|
76
|
+
resultHash: seal.resultHash,
|
|
77
|
+
badgeUUID: seal.badgeUUID,
|
|
78
|
+
verifyURL: seal.verifyURL,
|
|
79
|
+
},
|
|
80
|
+
disclaimer: DISCLAIMER,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Save EvidencePack as JSON file.
|
|
85
|
+
*/
|
|
86
|
+
function saveEvidenceJSON(pack, outputPath) {
|
|
87
|
+
fs.writeFileSync(outputPath, JSON.stringify(pack, null, 2), 'utf-8');
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Generate a PDF Evidence Pack using pdfkit.
|
|
91
|
+
*/
|
|
92
|
+
async function generateEvidencePDF(pack, outputPath) {
|
|
93
|
+
// Dynamic import for pdfkit (CJS module)
|
|
94
|
+
const PDFDocumentModule = await import('pdfkit');
|
|
95
|
+
const PDFDocument = PDFDocumentModule.default ?? PDFDocumentModule;
|
|
96
|
+
return new Promise((resolve, reject) => {
|
|
97
|
+
const doc = new PDFDocument({
|
|
98
|
+
size: 'A4',
|
|
99
|
+
margins: { top: 60, bottom: 60, left: 50, right: 50 },
|
|
100
|
+
});
|
|
101
|
+
const stream = fs.createWriteStream(outputPath);
|
|
102
|
+
doc.pipe(stream);
|
|
103
|
+
// ─── Cover Page ───────────────────────────────────────
|
|
104
|
+
doc.fontSize(28).font('Helvetica-Bold').text('Project Shield', { align: 'center' });
|
|
105
|
+
doc.moveDown(0.5);
|
|
106
|
+
doc.fontSize(16).font('Helvetica').text('Security Scan Report', { align: 'center' });
|
|
107
|
+
doc.moveDown(1);
|
|
108
|
+
doc.fontSize(12).text(`Date: ${pack.generatedAt}`, { align: 'center' });
|
|
109
|
+
doc.text(`Target: ${pack.scanTarget}`, { align: 'center' });
|
|
110
|
+
doc.text(`Grade: ${pack.score.grade} (${pack.score.numericScore}/100)`, { align: 'center' });
|
|
111
|
+
doc.moveDown(2);
|
|
112
|
+
// ─── Executive Summary ────────────────────────────────
|
|
113
|
+
doc.fontSize(18).font('Helvetica-Bold').text('Executive Summary');
|
|
114
|
+
doc.moveDown(0.5);
|
|
115
|
+
doc.fontSize(11).font('Helvetica');
|
|
116
|
+
doc.text(`Score: ${pack.score.numericScore}/100 (Grade ${pack.score.grade})`);
|
|
117
|
+
doc.text(`Ruleset Version: ${pack.rulesetVersion}`);
|
|
118
|
+
doc.text(`Files Scanned: ${pack.filesScanned}`);
|
|
119
|
+
doc.text(`Files Excluded: ${pack.filesExcluded}`);
|
|
120
|
+
doc.text(`Scan Duration: ${pack.scanDuration}`);
|
|
121
|
+
doc.text(`Lock Status: ${pack.lockStatus.isLocked ? 'LOCKED' : 'Unlocked'}`);
|
|
122
|
+
doc.moveDown(0.5);
|
|
123
|
+
const { fixitSummary } = pack;
|
|
124
|
+
doc.text(`Total Issues: ${fixitSummary.totalIssues}`);
|
|
125
|
+
doc.text(`Critical Issues: ${fixitSummary.criticalIssues}`);
|
|
126
|
+
doc.text(`Fix-it Guides Available: ${fixitSummary.fixitGuidesAvailable}`);
|
|
127
|
+
doc.moveDown(1);
|
|
128
|
+
// ─── Findings Detail ──────────────────────────────────
|
|
129
|
+
doc.fontSize(18).font('Helvetica-Bold').text('Findings Detail');
|
|
130
|
+
doc.moveDown(0.5);
|
|
131
|
+
doc.fontSize(11).font('Helvetica');
|
|
132
|
+
// Secrets
|
|
133
|
+
doc.fontSize(14).font('Helvetica-Bold').text(`Secrets (${pack.findings.secrets.length})`);
|
|
134
|
+
doc.fontSize(10).font('Helvetica');
|
|
135
|
+
if (pack.findings.secrets.length === 0) {
|
|
136
|
+
doc.text(' No secrets detected.');
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
for (const s of pack.findings.secrets) {
|
|
140
|
+
doc.text(` [${s.severity.toUpperCase()}] ${s.file}:${s.line} — ${s.description} (${s.matched})`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
doc.moveDown(0.5);
|
|
144
|
+
// PII
|
|
145
|
+
doc.fontSize(14).font('Helvetica-Bold').text(`PII (${pack.findings.pii.length})`);
|
|
146
|
+
doc.fontSize(10).font('Helvetica');
|
|
147
|
+
if (pack.findings.pii.length === 0) {
|
|
148
|
+
doc.text(' No PII detected.');
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
for (const p of pack.findings.pii) {
|
|
152
|
+
doc.text(` [${p.severity.toUpperCase()}] ${p.file}:${p.line} — ${p.description} (${p.matched})`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
doc.moveDown(0.5);
|
|
156
|
+
// MCP
|
|
157
|
+
doc.fontSize(14).font('Helvetica-Bold').text(`MCP Config (${pack.findings.mcp.length})`);
|
|
158
|
+
doc.fontSize(10).font('Helvetica');
|
|
159
|
+
if (pack.findings.mcp.length === 0) {
|
|
160
|
+
doc.text(' No MCP configuration issues.');
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
for (const m of pack.findings.mcp) {
|
|
164
|
+
doc.text(` [${m.overallSeverity.toUpperCase()}] ${m.file} — ${m.failedCount}/5 checks failed`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
doc.moveDown(0.5);
|
|
168
|
+
// Injection
|
|
169
|
+
doc.fontSize(14).font('Helvetica-Bold').text(`Injection (${pack.findings.injection.length})`);
|
|
170
|
+
doc.fontSize(10).font('Helvetica');
|
|
171
|
+
if (pack.findings.injection.length === 0) {
|
|
172
|
+
doc.text(' No injection patterns detected.');
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
for (const inj of pack.findings.injection) {
|
|
176
|
+
doc.text(` [${inj.severity.toUpperCase()}] ${inj.file}:${inj.line} — ${inj.description}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
doc.moveDown(1);
|
|
180
|
+
// ─── Integrity Verification ───────────────────────────
|
|
181
|
+
doc.fontSize(18).font('Helvetica-Bold').text('Integrity Verification');
|
|
182
|
+
doc.moveDown(0.5);
|
|
183
|
+
doc.fontSize(10).font('Helvetica');
|
|
184
|
+
doc.text(`Result Hash: ${pack.integrity.resultHash}`);
|
|
185
|
+
doc.text(`Ruleset Hash: ${pack.integrity.rulesetHash}`);
|
|
186
|
+
if (pack.integrity.badgeUUID) {
|
|
187
|
+
doc.text(`Badge UUID: ${pack.integrity.badgeUUID}`);
|
|
188
|
+
}
|
|
189
|
+
if (pack.integrity.verifyURL) {
|
|
190
|
+
doc.text(`Verify URL: ${pack.integrity.verifyURL}`);
|
|
191
|
+
}
|
|
192
|
+
doc.moveDown(1);
|
|
193
|
+
// ─── Disclaimer ───────────────────────────────────────
|
|
194
|
+
doc.fontSize(18).font('Helvetica-Bold').text('Disclaimer');
|
|
195
|
+
doc.moveDown(0.5);
|
|
196
|
+
doc.fontSize(9).font('Helvetica').text(pack.disclaimer, {
|
|
197
|
+
width: 500,
|
|
198
|
+
align: 'left',
|
|
199
|
+
});
|
|
200
|
+
doc.end();
|
|
201
|
+
stream.on('finish', resolve);
|
|
202
|
+
stream.on('error', reject);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../../src/output/evidence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ScanResult, FixitGuide } from '../types/index.js';
|
|
2
|
+
export interface FixitEntry {
|
|
3
|
+
findingType: string;
|
|
4
|
+
file: string;
|
|
5
|
+
line: number;
|
|
6
|
+
severity: 'critical' | 'warning';
|
|
7
|
+
guide: FixitGuide;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Get fix-it guides for all findings in the scan result.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getFixitGuides(result: ScanResult, options: {
|
|
13
|
+
isPro: boolean;
|
|
14
|
+
}): FixitEntry[];
|
|
15
|
+
/**
|
|
16
|
+
* Format fix-it guides for terminal output.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatFixitTerminal(guides: FixitEntry[], isPro: boolean): string;
|
|
19
|
+
/**
|
|
20
|
+
* Format fix-it guides as JSON-compatible objects.
|
|
21
|
+
*/
|
|
22
|
+
export declare function formatFixitJson(guides: FixitEntry[], isPro: boolean): Array<{
|
|
23
|
+
findingType: string;
|
|
24
|
+
file: string;
|
|
25
|
+
line: number;
|
|
26
|
+
severity: string;
|
|
27
|
+
title: string;
|
|
28
|
+
steps: string[];
|
|
29
|
+
code?: string;
|
|
30
|
+
references?: string[];
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=fixit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixit.d.ts","sourceRoot":"","sources":["../../src/output/fixit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAC;IACjC,KAAK,EAAE,UAAU,CAAC;CACnB;AA6ND;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAC1B,UAAU,EAAE,CA0Fd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CA2DhF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAAE,EACpB,KAAK,EAAE,OAAO,GACb,KAAK,CAAC;IACP,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC,CAuBD"}
|