@fortressjs/cli 0.1.2 → 0.1.4

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.
@@ -0,0 +1,5 @@
1
+ import { AuditScanner, ScanResult } from "./scanner";
2
+ export declare class ASTScanner implements AuditScanner {
3
+ name: string;
4
+ scan(fileContent: string): ScanResult;
5
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ASTScanner = void 0;
7
+ const typescript_1 = __importDefault(require("typescript"));
8
+ class ASTScanner {
9
+ name = "ASTScanner";
10
+ scan(fileContent) {
11
+ const sourceFile = typescript_1.default.createSourceFile("temp.ts", fileContent, typescript_1.default.ScriptTarget.Latest, true);
12
+ const result = {
13
+ hasCSP: false,
14
+ hasRateLimiting: false,
15
+ hasRequestSizeLimiting: false,
16
+ hasLogger: false,
17
+ hasThreatDetection: false,
18
+ hasHTTPS: false
19
+ };
20
+ const visit = (node) => {
21
+ if (typescript_1.default.isImportDeclaration(node)) {
22
+ const moduleName = node.moduleSpecifier.getText(sourceFile);
23
+ if (moduleName.includes("@fortressjs/core")) {
24
+ result.hasCSP = true;
25
+ }
26
+ }
27
+ if (typescript_1.default.isCallExpression(node)) {
28
+ const expression = node.expression;
29
+ if (typescript_1.default.isPropertyAccessExpression(expression)) {
30
+ if (expression.expression.getText(sourceFile) ===
31
+ "fortress") {
32
+ switch (expression.name.getText(sourceFile)) {
33
+ case "headers":
34
+ result.hasCSP = true;
35
+ break;
36
+ case "rateLimit":
37
+ result.hasRateLimiting = true;
38
+ break;
39
+ case "requestLimit":
40
+ result.hasRequestSizeLimiting = true;
41
+ break;
42
+ case "logger":
43
+ result.hasLogger = true;
44
+ break;
45
+ case "threatDetector":
46
+ result.hasThreatDetection = true;
47
+ break;
48
+ }
49
+ }
50
+ }
51
+ }
52
+ typescript_1.default.forEachChild(node, visit);
53
+ };
54
+ visit(sourceFile);
55
+ return result;
56
+ }
57
+ }
58
+ exports.ASTScanner = ASTScanner;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ast_scanner_1 = require("./ast-scanner");
4
+ describe("ASTScanner", () => {
5
+ it("should parse valid code", () => {
6
+ const scanner = new ast_scanner_1.ASTScanner();
7
+ const result = scanner.scan(`
8
+ import express from "express";
9
+
10
+ const app = express();
11
+
12
+ app.get("/", () => {});
13
+ `);
14
+ expect(result).toBeDefined();
15
+ });
16
+ it("should detect fortress imports", () => {
17
+ const scanner = new ast_scanner_1.ASTScanner();
18
+ const result = scanner.scan(`
19
+ import fortress
20
+ from "@fortressjs/core";
21
+ `);
22
+ expect(result.hasCSP).toBe(true);
23
+ });
24
+ });
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export declare function runAudit(targetPath?: string): void;
1
+ export declare function runAudit(targetPath?: string, jsonOutput?: boolean, reportOutput?: boolean): void;
package/dist/index.js CHANGED
@@ -6,7 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.runAudit = runAudit;
7
7
  const fs_1 = __importDefault(require("fs"));
8
8
  const path_1 = __importDefault(require("path"));
9
- const scanner_1 = require("./scanner");
9
+ const report_generator_1 = require("./report-generator");
10
+ const ast_scanner_1 = require("./ast-scanner");
10
11
  // ANSI Terminal Colors
11
12
  const C = {
12
13
  reset: "\x1b[0m",
@@ -58,9 +59,7 @@ function getFilesRecursively(dir, fileList = []) {
58
59
  }
59
60
  return fileList;
60
61
  }
61
- function runAudit(targetPath) {
62
- console.log(`\n${C.bold}${C.cyan}🛡️ FortressJS Security Audit CLI${C.reset}`);
63
- console.log(`${C.dim}=========================================${C.reset}\n`);
62
+ function runAudit(targetPath, jsonOutput = false, reportOutput = false) {
64
63
  const target = path_1.default.resolve(targetPath || process.cwd());
65
64
  let files;
66
65
  try {
@@ -71,12 +70,26 @@ function runAudit(targetPath) {
71
70
  process.exit(1);
72
71
  }
73
72
  if (files.length === 0) {
73
+ if (jsonOutput) {
74
+ console.log(JSON.stringify({
75
+ target,
76
+ score: 0,
77
+ missing: [],
78
+ recommendations: [],
79
+ message: "No JavaScript or TypeScript files found"
80
+ }, null, 2));
81
+ return;
82
+ }
74
83
  console.log(`${C.yellow}No JavaScript or TypeScript files found to scan in: ${target}${C.reset}`);
75
84
  return;
76
85
  }
77
- console.log(`${C.dim}Target: ${target}${C.reset}`);
78
- console.log(`${C.dim}Scanning ${files.length} file(s)...${C.reset}`);
79
- const scanner = new scanner_1.RegexScanner();
86
+ if (!jsonOutput && !reportOutput) {
87
+ console.log(`\n${C.bold}${C.cyan}🛡️ FortressJS Security Audit CLI${C.reset}`);
88
+ console.log(`${C.dim}=========================================${C.reset}\n`);
89
+ console.log(`${C.dim}Target: ${target}${C.reset}`);
90
+ console.log(`${C.dim}Scanning ${files.length} file(s)...${C.reset}\n`);
91
+ }
92
+ const scanner = new ast_scanner_1.ASTScanner();
80
93
  // Aggregate results across all files in the project
81
94
  const aggregated = {
82
95
  hasCSP: false,
@@ -142,6 +155,22 @@ function runAudit(targetPath) {
142
155
  recommendations.push("Configure fortress.headers({ strictTransportSecurity: ... }) for HSTS");
143
156
  }
144
157
  score = Math.max(0, score);
158
+ const auditResult = {
159
+ target,
160
+ score,
161
+ missing,
162
+ recommendations
163
+ };
164
+ if (reportOutput) {
165
+ const markdown = (0, report_generator_1.generateMarkdownReport)(auditResult);
166
+ fs_1.default.writeFileSync("fortress-report.md", markdown);
167
+ console.log("Report generated: fortress-report.md");
168
+ return;
169
+ }
170
+ if (jsonOutput) {
171
+ console.log(JSON.stringify(auditResult, null, 2));
172
+ return;
173
+ }
145
174
  // Pick color based on score
146
175
  let scoreColor = C.red;
147
176
  if (score >= 90)
@@ -166,8 +195,12 @@ function runAudit(targetPath) {
166
195
  // CLI entry point
167
196
  const args = process.argv.slice(2);
168
197
  if (args[0] === "audit") {
169
- const target = args[1];
170
- runAudit(target);
198
+ const jsonOutput = args.includes("--json");
199
+ const reportOutput = args.includes("--report");
200
+ const target = args.find((arg) => arg !== "audit" &&
201
+ arg !== "--json" &&
202
+ arg !== "--report");
203
+ runAudit(target, jsonOutput, reportOutput);
171
204
  }
172
205
  else {
173
206
  console.log(`\n${C.bold}FortressJS CLI${C.reset}`);
@@ -175,5 +208,7 @@ else {
175
208
  console.log(` fortress audit`);
176
209
  console.log(` fortress audit .`);
177
210
  console.log(` fortress audit ./src`);
178
- console.log(` fortress audit ./src/app.ts\n`);
211
+ console.log(` fortress audit ./src/app.ts`);
212
+ console.log(` fortress audit --json`);
213
+ console.log(` fortress audit --report\n`);
179
214
  }
@@ -0,0 +1,8 @@
1
+ interface AuditResult {
2
+ target: string;
3
+ score: number;
4
+ missing: string[];
5
+ recommendations: string[];
6
+ }
7
+ export declare function generateMarkdownReport(auditResult: AuditResult): string;
8
+ export {};
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMarkdownReport = generateMarkdownReport;
4
+ function generateMarkdownReport(auditResult) {
5
+ const date = new Date()
6
+ .toISOString()
7
+ .split("T")[0];
8
+ return `# FortressJS Security Report
9
+
10
+ Generated: ${date}
11
+
12
+ ## Target
13
+
14
+ ${auditResult.target}
15
+
16
+ ## Security Score
17
+
18
+ ${auditResult.score}/100
19
+
20
+ ## Missing Protections
21
+
22
+ ${auditResult.missing
23
+ .map(item => `- ${item}`)
24
+ .join("\n")}
25
+
26
+ ## Recommendations
27
+
28
+ ${auditResult.recommendations
29
+ .map(item => `- ${item}`)
30
+ .join("\n")}
31
+ `;
32
+ }
package/package.json CHANGED
@@ -1,47 +1,48 @@
1
- {
2
- "name": "@fortressjs/cli",
3
- "version": "0.1.2",
4
- "description": "Security audit CLI for Express applications. Detect missing security headers, rate limits, request validation, and threat protection.",
5
- "license": "MIT",
6
- "author": "Davanesh Saminathan",
7
- "homepage": "https://github.com/davanesh/fortressjs",
8
- "bugs": {
9
- "url": "https://github.com/davanesh/fortressjs/issues"
10
- },
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/davanesh/fortressjs.git"
14
- },
15
- "keywords": [
16
- "security",
17
- "cli",
18
- "audit",
19
- "express",
20
- "nodejs",
21
- "middleware",
22
- "api-security",
23
- "fortressjs"
24
- ],
25
- "engines": {
26
- "node": ">=18"
27
- },
28
- "bin": {
29
- "fortress": "bin/fortress.js"
30
- },
31
- "main": "dist/index.js",
32
- "types": "dist/index.d.ts",
33
- "files": [
34
- "dist",
35
- "bin",
36
- "README.md"
37
- ],
38
- "scripts": {
39
- "build": "tsc"
40
- },
41
- "dependencies": {
42
- "@fortressjs/core": "^0.1.2"
43
- },
44
- "devDependencies": {
45
- "typescript": "^5.0.0"
46
- }
47
- }
1
+ {
2
+ "name": "@fortressjs/cli",
3
+ "version": "0.1.4",
4
+ "description": "Security audit CLI for Express applications. Detect missing security headers, rate limits, request validation, and threat protection.",
5
+ "license": "MIT",
6
+ "author": "Davanesh Saminathan",
7
+ "homepage": "https://github.com/davanesh/fortressjs",
8
+ "bugs": {
9
+ "url": "https://github.com/davanesh/fortressjs/issues"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/davanesh/fortressjs.git"
14
+ },
15
+ "keywords": [
16
+ "security",
17
+ "cli",
18
+ "audit",
19
+ "express",
20
+ "nodejs",
21
+ "middleware",
22
+ "api-security",
23
+ "fortressjs"
24
+ ],
25
+ "engines": {
26
+ "node": ">=18"
27
+ },
28
+ "bin": {
29
+ "fortress": "bin/fortress.js"
30
+ },
31
+ "main": "dist/index.js",
32
+ "types": "dist/index.d.ts",
33
+ "files": [
34
+ "dist",
35
+ "bin",
36
+ "README.md"
37
+ ],
38
+ "scripts": {
39
+ "build": "tsc",
40
+ "test": "jest"
41
+ },
42
+ "dependencies": {
43
+ "@fortressjs/core": "^0.1.2"
44
+ },
45
+ "devDependencies": {
46
+ "typescript": "^5.0.0"
47
+ }
48
+ }