@fortressjs/cli 0.1.3 → 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, jsonOutput?: boolean): 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,7 +59,7 @@ function getFilesRecursively(dir, fileList = []) {
58
59
  }
59
60
  return fileList;
60
61
  }
61
- function runAudit(targetPath, jsonOutput = false) {
62
+ function runAudit(targetPath, jsonOutput = false, reportOutput = false) {
62
63
  const target = path_1.default.resolve(targetPath || process.cwd());
63
64
  let files;
64
65
  try {
@@ -82,13 +83,13 @@ function runAudit(targetPath, jsonOutput = false) {
82
83
  console.log(`${C.yellow}No JavaScript or TypeScript files found to scan in: ${target}${C.reset}`);
83
84
  return;
84
85
  }
85
- if (!jsonOutput) {
86
+ if (!jsonOutput && !reportOutput) {
86
87
  console.log(`\n${C.bold}${C.cyan}🛡️ FortressJS Security Audit CLI${C.reset}`);
87
88
  console.log(`${C.dim}=========================================${C.reset}\n`);
88
89
  console.log(`${C.dim}Target: ${target}${C.reset}`);
89
90
  console.log(`${C.dim}Scanning ${files.length} file(s)...${C.reset}\n`);
90
91
  }
91
- const scanner = new scanner_1.RegexScanner();
92
+ const scanner = new ast_scanner_1.ASTScanner();
92
93
  // Aggregate results across all files in the project
93
94
  const aggregated = {
94
95
  hasCSP: false,
@@ -160,6 +161,12 @@ function runAudit(targetPath, jsonOutput = false) {
160
161
  missing,
161
162
  recommendations
162
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
+ }
163
170
  if (jsonOutput) {
164
171
  console.log(JSON.stringify(auditResult, null, 2));
165
172
  return;
@@ -189,9 +196,11 @@ function runAudit(targetPath, jsonOutput = false) {
189
196
  const args = process.argv.slice(2);
190
197
  if (args[0] === "audit") {
191
198
  const jsonOutput = args.includes("--json");
199
+ const reportOutput = args.includes("--report");
192
200
  const target = args.find((arg) => arg !== "audit" &&
193
- arg !== "--json");
194
- runAudit(target, jsonOutput);
201
+ arg !== "--json" &&
202
+ arg !== "--report");
203
+ runAudit(target, jsonOutput, reportOutput);
195
204
  }
196
205
  else {
197
206
  console.log(`\n${C.bold}FortressJS CLI${C.reset}`);
@@ -199,5 +208,7 @@ else {
199
208
  console.log(` fortress audit`);
200
209
  console.log(` fortress audit .`);
201
210
  console.log(` fortress audit ./src`);
202
- 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`);
203
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.3",
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
+ }