@integsec/agentic-pentest-proxy 0.2.5 → 0.2.6

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.
Files changed (146) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +250 -54
  3. package/dist/bin/integsec-agentic-pentest-manifest.d.ts +3 -0
  4. package/dist/bin/integsec-agentic-pentest-manifest.d.ts.map +1 -0
  5. package/dist/bin/integsec-agentic-pentest-manifest.js +180 -0
  6. package/dist/bin/integsec-agentic-pentest-manifest.js.map +1 -0
  7. package/dist/bin/integsec-agentic-pentest-proxy.d.ts +1 -1
  8. package/dist/bin/integsec-agentic-pentest-proxy.d.ts.map +1 -1
  9. package/dist/bin/integsec-agentic-pentest-proxy.js +8 -4
  10. package/dist/bin/integsec-agentic-pentest-proxy.js.map +1 -1
  11. package/dist/src/audit/azure-monitor.d.ts +2 -2
  12. package/dist/src/audit/azure-monitor.d.ts.map +1 -1
  13. package/dist/src/audit/azure-monitor.js +8 -5
  14. package/dist/src/audit/azure-monitor.js.map +1 -1
  15. package/dist/src/audit/cloudwatch.d.ts.map +1 -1
  16. package/dist/src/audit/cloudwatch.js.map +1 -1
  17. package/dist/src/audit/gcp-logging.d.ts.map +1 -1
  18. package/dist/src/audit/gcp-logging.js +4 -6
  19. package/dist/src/audit/gcp-logging.js.map +1 -1
  20. package/dist/src/audit/index.d.ts +7 -0
  21. package/dist/src/audit/index.d.ts.map +1 -1
  22. package/dist/src/audit/index.js +11 -1
  23. package/dist/src/audit/index.js.map +1 -1
  24. package/dist/src/audit/local.d.ts.map +1 -1
  25. package/dist/src/audit/local.js +2 -1
  26. package/dist/src/audit/local.js.map +1 -1
  27. package/dist/src/builder/dry-run.d.ts +12 -0
  28. package/dist/src/builder/dry-run.d.ts.map +1 -0
  29. package/dist/src/builder/dry-run.js +103 -0
  30. package/dist/src/builder/dry-run.js.map +1 -0
  31. package/dist/src/builder/manifest-writer.d.ts +7 -0
  32. package/dist/src/builder/manifest-writer.d.ts.map +1 -0
  33. package/dist/src/builder/manifest-writer.js +17 -0
  34. package/dist/src/builder/manifest-writer.js.map +1 -0
  35. package/dist/src/builder/review-display.d.ts +10 -0
  36. package/dist/src/builder/review-display.d.ts.map +1 -0
  37. package/dist/src/builder/review-display.js +55 -0
  38. package/dist/src/builder/review-display.js.map +1 -0
  39. package/dist/src/builder/smart-validator.d.ts +39 -0
  40. package/dist/src/builder/smart-validator.d.ts.map +1 -0
  41. package/dist/src/builder/smart-validator.js +157 -0
  42. package/dist/src/builder/smart-validator.js.map +1 -0
  43. package/dist/src/builder/steps/domains.d.ts +10 -0
  44. package/dist/src/builder/steps/domains.d.ts.map +1 -0
  45. package/dist/src/builder/steps/domains.js +71 -0
  46. package/dist/src/builder/steps/domains.js.map +1 -0
  47. package/dist/src/builder/steps/engagement-info.d.ts +17 -0
  48. package/dist/src/builder/steps/engagement-info.d.ts.map +1 -0
  49. package/dist/src/builder/steps/engagement-info.js +49 -0
  50. package/dist/src/builder/steps/engagement-info.js.map +1 -0
  51. package/dist/src/builder/steps/engagement-window.d.ts +15 -0
  52. package/dist/src/builder/steps/engagement-window.d.ts.map +1 -0
  53. package/dist/src/builder/steps/engagement-window.js +57 -0
  54. package/dist/src/builder/steps/engagement-window.js.map +1 -0
  55. package/dist/src/builder/steps/exclusions.d.ts +13 -0
  56. package/dist/src/builder/steps/exclusions.d.ts.map +1 -0
  57. package/dist/src/builder/steps/exclusions.js +57 -0
  58. package/dist/src/builder/steps/exclusions.js.map +1 -0
  59. package/dist/src/builder/steps/ip-ranges.d.ts +10 -0
  60. package/dist/src/builder/steps/ip-ranges.d.ts.map +1 -0
  61. package/dist/src/builder/steps/ip-ranges.js +64 -0
  62. package/dist/src/builder/steps/ip-ranges.js.map +1 -0
  63. package/dist/src/builder/steps/review.d.ts +10 -0
  64. package/dist/src/builder/steps/review.d.ts.map +1 -0
  65. package/dist/src/builder/steps/review.js +29 -0
  66. package/dist/src/builder/steps/review.js.map +1 -0
  67. package/dist/src/builder/steps/techniques.d.ts +13 -0
  68. package/dist/src/builder/steps/techniques.d.ts.map +1 -0
  69. package/dist/src/builder/steps/techniques.js +68 -0
  70. package/dist/src/builder/steps/techniques.js.map +1 -0
  71. package/dist/src/builder/steps/urls-and-cloud.d.ts +15 -0
  72. package/dist/src/builder/steps/urls-and-cloud.d.ts.map +1 -0
  73. package/dist/src/builder/steps/urls-and-cloud.js +53 -0
  74. package/dist/src/builder/steps/urls-and-cloud.js.map +1 -0
  75. package/dist/src/builder/web/api.d.ts +9 -0
  76. package/dist/src/builder/web/api.d.ts.map +1 -0
  77. package/dist/src/builder/web/api.js +40 -0
  78. package/dist/src/builder/web/api.js.map +1 -0
  79. package/dist/src/builder/web/client-form.html +222 -0
  80. package/dist/src/builder/web/server.d.ts +14 -0
  81. package/dist/src/builder/web/server.d.ts.map +1 -0
  82. package/dist/src/builder/web/server.js +85 -0
  83. package/dist/src/builder/web/server.js.map +1 -0
  84. package/dist/src/builder/wizard.d.ts +9 -0
  85. package/dist/src/builder/wizard.d.ts.map +1 -0
  86. package/dist/src/builder/wizard.js +49 -0
  87. package/dist/src/builder/wizard.js.map +1 -0
  88. package/dist/src/config.d.ts +11 -1
  89. package/dist/src/config.d.ts.map +1 -1
  90. package/dist/src/config.js +15 -2
  91. package/dist/src/config.js.map +1 -1
  92. package/dist/src/dns-resolver.d.ts +10 -1
  93. package/dist/src/dns-resolver.d.ts.map +1 -1
  94. package/dist/src/dns-resolver.js +41 -3
  95. package/dist/src/dns-resolver.js.map +1 -1
  96. package/dist/src/extractor.d.ts +12 -0
  97. package/dist/src/extractor.d.ts.map +1 -1
  98. package/dist/src/extractor.js +386 -0
  99. package/dist/src/extractor.js.map +1 -1
  100. package/dist/src/index.d.ts +1 -1
  101. package/dist/src/index.js +1 -1
  102. package/dist/src/ip-matcher.d.ts +23 -0
  103. package/dist/src/ip-matcher.d.ts.map +1 -1
  104. package/dist/src/ip-matcher.js +96 -23
  105. package/dist/src/ip-matcher.js.map +1 -1
  106. package/dist/src/manifest-schema.d.ts +12 -62
  107. package/dist/src/manifest-schema.d.ts.map +1 -1
  108. package/dist/src/manifest.d.ts +6 -0
  109. package/dist/src/manifest.d.ts.map +1 -1
  110. package/dist/src/manifest.js +21 -6
  111. package/dist/src/manifest.js.map +1 -1
  112. package/dist/src/proxy.d.ts +19 -4
  113. package/dist/src/proxy.d.ts.map +1 -1
  114. package/dist/src/proxy.js +111 -33
  115. package/dist/src/proxy.js.map +1 -1
  116. package/dist/src/safe-filename.d.ts +3 -0
  117. package/dist/src/safe-filename.d.ts.map +1 -0
  118. package/dist/src/safe-filename.js +8 -0
  119. package/dist/src/safe-filename.js.map +1 -0
  120. package/dist/src/sanitizer.d.ts.map +1 -1
  121. package/dist/src/sanitizer.js +36 -10
  122. package/dist/src/sanitizer.js.map +1 -1
  123. package/dist/src/technique-checker.d.ts +14 -0
  124. package/dist/src/technique-checker.d.ts.map +1 -1
  125. package/dist/src/technique-checker.js +123 -2
  126. package/dist/src/technique-checker.js.map +1 -1
  127. package/dist/src/transports/http.d.ts +6 -2
  128. package/dist/src/transports/http.d.ts.map +1 -1
  129. package/dist/src/transports/http.js +101 -13
  130. package/dist/src/transports/http.js.map +1 -1
  131. package/dist/src/transports/sse.d.ts +1 -1
  132. package/dist/src/transports/sse.d.ts.map +1 -1
  133. package/dist/src/transports/sse.js +28 -18
  134. package/dist/src/transports/sse.js.map +1 -1
  135. package/dist/src/transports/stdio.d.ts +2 -2
  136. package/dist/src/transports/stdio.d.ts.map +1 -1
  137. package/dist/src/transports/stdio.js +77 -48
  138. package/dist/src/transports/stdio.js.map +1 -1
  139. package/dist/src/types.d.ts +1 -1
  140. package/dist/src/types.d.ts.map +1 -1
  141. package/dist/src/validator.d.ts +19 -28
  142. package/dist/src/validator.d.ts.map +1 -1
  143. package/dist/src/validator.js +315 -113
  144. package/dist/src/validator.js.map +1 -1
  145. package/examples/claude-desktop-burp-config.json +6 -6
  146. package/package.json +21 -11
@@ -0,0 +1,17 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ export function serializeManifest(manifest) {
4
+ return JSON.stringify(manifest, null, 2) + "\n";
5
+ }
6
+ export function writeManifest(manifest, filePath, options = {}) {
7
+ const dir = path.dirname(filePath);
8
+ if (!fs.existsSync(dir)) {
9
+ fs.mkdirSync(dir, { recursive: true });
10
+ }
11
+ if (fs.existsSync(filePath) && !options.force) {
12
+ throw new Error(`File "${filePath}" already exists. Use --force to overwrite.`);
13
+ }
14
+ const json = serializeManifest(manifest);
15
+ fs.writeFileSync(filePath, json, "utf-8");
16
+ }
17
+ //# sourceMappingURL=manifest-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-writer.js","sourceRoot":"","sources":["../../../src/builder/manifest-writer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAOxB,MAAM,UAAU,iBAAiB,CAAC,QAAuB;IACvD,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,QAAuB,EACvB,QAAgB,EAChB,UAAwB,EAAE;IAE1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,SAAS,QAAQ,6CAA6C,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACzC,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import type { ScopeManifest } from "../types.js";
3
+ interface Props {
4
+ manifest: ScopeManifest;
5
+ sourcePath: string;
6
+ onDone: () => void;
7
+ }
8
+ export declare function ReviewDisplay({ manifest, sourcePath, onDone }: Props): React.ReactElement;
9
+ export {};
10
+ //# sourceMappingURL=review-display.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-display.d.ts","sourceRoot":"","sources":["../../../src/builder/review-display.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD,UAAU,KAAK;IACb,QAAQ,EAAE,aAAa,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAID,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAqEzF"}
@@ -0,0 +1,55 @@
1
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import Spinner from "ink-spinner";
5
+ import { validateCidr, validateDomain, validateWindowSanity, checkOrphanedExclusion, } from "./smart-validator.js";
6
+ import { runDryRun } from "./dry-run.js";
7
+ import { writeManifest } from "./manifest-writer.js";
8
+ export function ReviewDisplay({ manifest, sourcePath, onDone }) {
9
+ const [validationMsgs, setValidationMsgs] = useState([]);
10
+ const [dryRunResults, setDryRunResults] = useState(null);
11
+ const [action, setAction] = useState("pending");
12
+ useEffect(() => {
13
+ const msgs = [];
14
+ for (const cidr of manifest.authorized_targets.ip_ranges) {
15
+ msgs.push(...validateCidr(cidr));
16
+ }
17
+ for (const domain of manifest.authorized_targets.domains) {
18
+ msgs.push(...validateDomain(domain));
19
+ }
20
+ msgs.push(...validateWindowSanity(manifest.engagement_window.start, manifest.engagement_window.end));
21
+ for (const excluded of manifest.excluded_targets) {
22
+ msgs.push(...checkOrphanedExclusion(excluded, {
23
+ ip_ranges: manifest.authorized_targets.ip_ranges,
24
+ domains: manifest.authorized_targets.domains,
25
+ }));
26
+ }
27
+ setValidationMsgs(msgs);
28
+ runDryRun(manifest).then(setDryRunResults).catch(() => setDryRunResults([]));
29
+ }, []);
30
+ useInput((ch, key) => {
31
+ if (ch === "a" && action === "pending") {
32
+ const outputPath = sourcePath.replace(".pending.json", ".json");
33
+ try {
34
+ writeManifest(manifest, outputPath, { force: true });
35
+ setAction("approve");
36
+ setTimeout(onDone, 500);
37
+ }
38
+ catch { /* handled in display */ }
39
+ return;
40
+ }
41
+ if (ch === "r" && action === "pending") {
42
+ setAction("reject");
43
+ setTimeout(onDone, 500);
44
+ return;
45
+ }
46
+ if (key.escape) {
47
+ onDone();
48
+ return;
49
+ }
50
+ });
51
+ const errors = validationMsgs.filter((m) => m.level === "error");
52
+ const warnings = validationMsgs.filter((m) => m.level === "warning");
53
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsxs(Text, { bold: true, color: "cyan", children: ["Manifest Review: ", sourcePath] }), _jsx(Box, { marginTop: 1 }), _jsxs(Text, { bold: true, children: ["Engagement: ", manifest.engagement_id, " \u2014 ", manifest.client] }), _jsxs(Text, { children: ["Operator: ", manifest.operator] }), _jsxs(Text, { children: ["Window: ", manifest.engagement_window.start, " \u2192 ", manifest.engagement_window.end] }), _jsxs(Text, { children: ["Domains: ", manifest.authorized_targets.domains.join(", ") || "none"] }), _jsxs(Text, { children: ["IP Ranges: ", manifest.authorized_targets.ip_ranges.join(", ") || "none"] }), _jsxs(Text, { children: ["Exclusions: ", manifest.excluded_targets.join(", ") || "none"] }), _jsx(Box, { marginTop: 1 }), _jsx(Text, { bold: true, children: "Validation:" }), errors.length === 0 && warnings.length === 0 && (_jsx(Text, { color: "green", children: " \u2713 No issues found" })), errors.map((m, i) => _jsxs(Text, { color: "red", children: [" \u2717 ", m.message] }, `e${i}`)), warnings.map((m, i) => _jsxs(Text, { color: "yellow", children: [" \u26A0 ", m.message] }, `w${i}`)), _jsx(Box, { marginTop: 1 }), _jsx(Text, { bold: true, children: "Dry-Run:" }), dryRunResults === null ? (_jsxs(Text, { children: [" ", _jsx(Spinner, { type: "dots" }), " Running..."] })) : (dryRunResults.map((r, i) => (_jsxs(Text, { color: r.pass ? "green" : "red", children: [" ", r.pass ? "✓" : "✗", " ", r.tool, " \u2192 ", r.target, ": ", r.actual] }, i)))), _jsx(Box, { marginTop: 1 }), action === "pending" && (_jsx(Text, { dimColor: true, children: "[a] Approve [r] Reject [Esc] Cancel" })), action === "approve" && (_jsx(Text, { color: "green", bold: true, children: "\u2713 Approved and saved." })), action === "reject" && (_jsx(Text, { color: "red", bold: true, children: "\u2717 Rejected." }))] }));
54
+ }
55
+ //# sourceMappingURL=review-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-display.js","sourceRoot":"","sources":["../../../src/builder/review-display.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { DnsResolver } from "../dns-resolver.js";
2
+ export interface ValidationMessage {
3
+ level: "error" | "warning" | "info";
4
+ message: string;
5
+ }
6
+ export declare function validateEngagementId(id: string): ValidationMessage[];
7
+ export declare function validateCidr(cidr: string): ValidationMessage[];
8
+ export declare function validateDomain(domain: string): ValidationMessage[];
9
+ export declare function validateIsoDate(date: string): ValidationMessage[];
10
+ export declare function validateWindowSanity(start: string, end: string): ValidationMessage[];
11
+ export interface DomainPreviewResult {
12
+ ips: string[];
13
+ messages: ValidationMessage[];
14
+ }
15
+ /**
16
+ * Resolve a domain via the provided DnsResolver and return the IPs along with
17
+ * any validation messages (e.g. NXDOMAIN warning when no IPs are returned).
18
+ * A wildcard prefix (`*.`) is stripped before the DNS lookup.
19
+ */
20
+ export declare function resolveDomainPreview(domain: string, resolver: DnsResolver): Promise<DomainPreviewResult>;
21
+ /**
22
+ * Check whether any of the resolved IPs fall inside an authorized CIDR range.
23
+ * Returns an info message for the first match found.
24
+ */
25
+ export declare function checkOverlap(resolvedIps: string[], authorizedRanges: string[]): ValidationMessage[];
26
+ /**
27
+ * When a wildcard domain (e.g. `*.acme.com`) is present, suggest adding the
28
+ * apex (`acme.com`) separately if it is not already in the list.
29
+ */
30
+ export declare function checkWildcardApex(domain: string, currentDomains: string[]): ValidationMessage[];
31
+ /**
32
+ * Warn if an excluded target (IP or domain) is not covered by any authorized
33
+ * IP range or domain pattern, making the exclusion redundant.
34
+ */
35
+ export declare function checkOrphanedExclusion(excludedTarget: string, authorized: {
36
+ ip_ranges: string[];
37
+ domains: string[];
38
+ }): ValidationMessage[];
39
+ //# sourceMappingURL=smart-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-validator.d.ts","sourceRoot":"","sources":["../../../src/builder/smart-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAIjD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAQpE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAoB9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAYlE;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAQjE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAoBpF;AAMD,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,mBAAmB,CAAC,CAe9B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,EAAE,EACrB,gBAAgB,EAAE,MAAM,EAAE,GACzB,iBAAiB,EAAE,CAcrB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EAAE,GACvB,iBAAiB,EAAE,CAerB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE;IAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GACrD,iBAAiB,EAAE,CAiBrB"}
@@ -0,0 +1,157 @@
1
+ import { isCidr, isIpInCidr } from "../ip-matcher.js";
2
+ import { matchesDomain } from "../domain-matcher.js";
3
+ export function validateEngagementId(id) {
4
+ if (!id || id.trim() === "") {
5
+ return [{ level: "error", message: "Engagement ID must not be empty." }];
6
+ }
7
+ if (!/^ENG-\d{4}-\d{3,}$/.test(id)) {
8
+ return [{ level: "info", message: `Suggested format: ENG-YYYY-NNNN (e.g. ENG-${new Date().getFullYear()}-0001).` }];
9
+ }
10
+ return [];
11
+ }
12
+ export function validateCidr(cidr) {
13
+ if (!cidr || cidr.trim() === "") {
14
+ return [{ level: "error", message: "CIDR range must not be empty." }];
15
+ }
16
+ let normalized = cidr;
17
+ if (!cidr.includes("/")) {
18
+ normalized = cidr.includes(":") ? `${cidr}/128` : `${cidr}/32`;
19
+ }
20
+ if (!isCidr(normalized)) {
21
+ return [{ level: "error", message: `Invalid CIDR syntax: "${cidr}". Example: 10.10.10.0/24` }];
22
+ }
23
+ const slashIndex = normalized.indexOf("/");
24
+ if (slashIndex !== -1 && !normalized.includes(":")) {
25
+ const prefix = parseInt(normalized.slice(slashIndex + 1), 10);
26
+ if (prefix < 16) {
27
+ const count = Math.pow(2, 32 - prefix);
28
+ return [{ level: "warning", message: `This range covers ${count.toLocaleString()} addresses. Is /${prefix} intentional?` }];
29
+ }
30
+ }
31
+ return [];
32
+ }
33
+ export function validateDomain(domain) {
34
+ if (!domain || domain.trim() === "") {
35
+ return [{ level: "error", message: "Domain must not be empty." }];
36
+ }
37
+ if (/\s/.test(domain)) {
38
+ return [{ level: "error", message: `Domain "${domain}" contains whitespace.` }];
39
+ }
40
+ const pattern = /^(\*\.)?([a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?\.)*[a-zA-Z]{2,}\.?$/;
41
+ if (!pattern.test(domain)) {
42
+ return [{ level: "error", message: `"${domain}" does not look like a valid domain.` }];
43
+ }
44
+ return [];
45
+ }
46
+ export function validateIsoDate(date) {
47
+ if (!date || date.trim() === "") {
48
+ return [{ level: "error", message: "Date must not be empty." }];
49
+ }
50
+ if (isNaN(Date.parse(date))) {
51
+ return [{ level: "error", message: `"${date}" is not a valid ISO 8601 date. Example: 2026-03-29T08:00:00Z` }];
52
+ }
53
+ return [];
54
+ }
55
+ export function validateWindowSanity(start, end) {
56
+ const msgs = [];
57
+ const startMs = Date.parse(start);
58
+ const endMs = Date.parse(end);
59
+ if (isNaN(startMs) || isNaN(endMs))
60
+ return [];
61
+ if (endMs <= startMs) {
62
+ msgs.push({ level: "error", message: "End date is before or equal to start date." });
63
+ return msgs;
64
+ }
65
+ if (startMs < Date.now()) {
66
+ msgs.push({ level: "warning", message: "Start date is in the past." });
67
+ }
68
+ const durationMs = endMs - startMs;
69
+ if (durationMs > 30 * 24 * 3600_000) {
70
+ msgs.push({ level: "warning", message: `Engagement window exceeds 30 days (${Math.round(durationMs / 86400_000)} days).` });
71
+ }
72
+ if (durationMs < 3600_000) {
73
+ msgs.push({ level: "warning", message: "Engagement window is less than 1 hour." });
74
+ }
75
+ return msgs;
76
+ }
77
+ /**
78
+ * Resolve a domain via the provided DnsResolver and return the IPs along with
79
+ * any validation messages (e.g. NXDOMAIN warning when no IPs are returned).
80
+ * A wildcard prefix (`*.`) is stripped before the DNS lookup.
81
+ */
82
+ export async function resolveDomainPreview(domain, resolver) {
83
+ const lookupDomain = domain.startsWith("*.") ? domain.slice(2) : domain;
84
+ const ips = await resolver.resolve(lookupDomain);
85
+ if (ips.length === 0) {
86
+ return {
87
+ ips: [],
88
+ messages: [
89
+ {
90
+ level: "warning",
91
+ message: `"${lookupDomain}" did not resolve to any addresses (NXDOMAIN or DNS failure).`,
92
+ },
93
+ ],
94
+ };
95
+ }
96
+ return { ips, messages: [] };
97
+ }
98
+ /**
99
+ * Check whether any of the resolved IPs fall inside an authorized CIDR range.
100
+ * Returns an info message for the first match found.
101
+ */
102
+ export function checkOverlap(resolvedIps, authorizedRanges) {
103
+ for (const ip of resolvedIps) {
104
+ for (const range of authorizedRanges) {
105
+ if (isIpInCidr(ip, range)) {
106
+ return [
107
+ {
108
+ level: "info",
109
+ message: `Resolved IP ${ip} is already covered by authorized range ${range}.`,
110
+ },
111
+ ];
112
+ }
113
+ }
114
+ }
115
+ return [];
116
+ }
117
+ /**
118
+ * When a wildcard domain (e.g. `*.acme.com`) is present, suggest adding the
119
+ * apex (`acme.com`) separately if it is not already in the list.
120
+ */
121
+ export function checkWildcardApex(domain, currentDomains) {
122
+ if (!domain.startsWith("*.")) {
123
+ return [];
124
+ }
125
+ const apex = domain.slice(2);
126
+ const alreadyPresent = currentDomains.some((d) => d.toLowerCase() === apex.toLowerCase());
127
+ if (alreadyPresent) {
128
+ return [];
129
+ }
130
+ return [
131
+ {
132
+ level: "info",
133
+ message: `Wildcard "${domain}" does not cover the apex "${apex}". Add "${apex}" separately if needed.`,
134
+ },
135
+ ];
136
+ }
137
+ /**
138
+ * Warn if an excluded target (IP or domain) is not covered by any authorized
139
+ * IP range or domain pattern, making the exclusion redundant.
140
+ */
141
+ export function checkOrphanedExclusion(excludedTarget, authorized) {
142
+ const inRange = authorized.ip_ranges.some((range) => isIpInCidr(excludedTarget, range));
143
+ if (inRange) {
144
+ return [];
145
+ }
146
+ const matchesDomainPattern = authorized.domains.some((pattern) => matchesDomain(excludedTarget, pattern));
147
+ if (matchesDomainPattern) {
148
+ return [];
149
+ }
150
+ return [
151
+ {
152
+ level: "warning",
153
+ message: `Excluded target "${excludedTarget}" is redundant — it is not covered by any authorized range or domain.`,
154
+ },
155
+ ];
156
+ }
157
+ //# sourceMappingURL=smart-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smart-validator.js","sourceRoot":"","sources":["../../../src/builder/smart-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ interface Props {
3
+ initial?: string[];
4
+ authorizedIpRanges?: string[];
5
+ onComplete: (domains: string[]) => void;
6
+ onBack?: () => void;
7
+ }
8
+ export declare function DomainsStep({ initial, onComplete, onBack }: Props): React.ReactElement;
9
+ export {};
10
+ //# sourceMappingURL=domains.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.d.ts","sourceRoot":"","sources":["../../../../src/builder/steps/domains.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAKhD,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,WAAW,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAkEtF"}
@@ -0,0 +1,71 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useRef } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { validateDomain, checkWildcardApex, resolveDomainPreview } from "../smart-validator.js";
5
+ import { DnsResolver } from "../../dns-resolver.js";
6
+ export function DomainsStep({ initial, onComplete, onBack }) {
7
+ const [domains, setDomains] = useState(initial ?? []);
8
+ const [input, setInput] = useState("");
9
+ const [messages, setMessages] = useState([]);
10
+ const [resolvedInfo, setResolvedInfo] = useState("");
11
+ const resolverRef = useRef(new DnsResolver(0));
12
+ useInput((ch, key) => {
13
+ if (key.escape) {
14
+ if (input === "" && onBack) {
15
+ onBack();
16
+ }
17
+ else {
18
+ setInput("");
19
+ setMessages([]);
20
+ }
21
+ return;
22
+ }
23
+ if (ch === "d" && key.ctrl) {
24
+ onComplete(domains);
25
+ return;
26
+ }
27
+ if (key.return) {
28
+ if (input.trim() === "") {
29
+ onComplete(domains);
30
+ return;
31
+ }
32
+ const newDomains = input.split(",").map((d) => d.trim()).filter(Boolean);
33
+ const allMsgs = [];
34
+ const validDomains = [];
35
+ for (const domain of newDomains) {
36
+ const domainMsgs = validateDomain(domain);
37
+ if (domainMsgs.some((m) => m.level === "error")) {
38
+ allMsgs.push(...domainMsgs);
39
+ }
40
+ else {
41
+ validDomains.push(domain);
42
+ allMsgs.push(...checkWildcardApex(domain, [...domains, ...validDomains]));
43
+ }
44
+ }
45
+ if (allMsgs.some((m) => m.level === "error")) {
46
+ setMessages(allMsgs);
47
+ return;
48
+ }
49
+ setDomains((prev) => [...prev, ...validDomains]);
50
+ setMessages(allMsgs);
51
+ setInput("");
52
+ for (const domain of validDomains) {
53
+ resolveDomainPreview(domain, resolverRef.current).then((result) => {
54
+ if (result.ips.length > 0) {
55
+ setResolvedInfo((prev) => prev + `${domain} → ${result.ips.join(", ")}\n`);
56
+ }
57
+ });
58
+ }
59
+ return;
60
+ }
61
+ if (key.backspace || key.delete) {
62
+ setInput((prev) => prev.slice(0, -1));
63
+ return;
64
+ }
65
+ if (ch && !key.ctrl && !key.meta) {
66
+ setInput((prev) => prev + ch);
67
+ }
68
+ });
69
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Step 3: Authorized Domains" }), _jsx(Text, { dimColor: true, children: "Enter domains (comma-separated OK). Empty enter or Ctrl+D when done. Esc to go back." }), _jsx(Box, { marginTop: 1 }), domains.map((d, i) => (_jsxs(Text, { color: "green", children: [" \u2713 ", d] }, i))), _jsxs(Box, { children: [_jsx(Text, { children: "\u203A " }), _jsxs(Text, { children: [input, _jsx(Text, { dimColor: true, children: "\u2502" })] })] }), resolvedInfo && (_jsxs(Box, { marginTop: 1, flexDirection: "column", children: [_jsx(Text, { dimColor: true, children: "DNS Preview:" }), resolvedInfo.trim().split("\n").map((line, i) => (_jsxs(Text, { dimColor: true, children: [" ", line] }, i)))] })), messages.map((msg, i) => (_jsx(Box, { marginTop: i === 0 ? 1 : 0, children: _jsxs(Text, { color: msg.level === "error" ? "red" : msg.level === "warning" ? "yellow" : "blue", children: [msg.level === "error" ? "✗" : msg.level === "warning" ? "⚠" : "ℹ", " ", msg.message] }) }, i))), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: [domains.length, " domain(s) added"] }) })] }));
70
+ }
71
+ //# sourceMappingURL=domains.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domains.js","sourceRoot":"","sources":["../../../../src/builder/steps/domains.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ interface Props {
3
+ initial?: {
4
+ engagement_id?: string;
5
+ client?: string;
6
+ operator?: string;
7
+ };
8
+ onComplete: (data: {
9
+ engagement_id: string;
10
+ client: string;
11
+ operator: string;
12
+ }) => void;
13
+ onBack?: () => void;
14
+ }
15
+ export declare function EngagementInfoStep({ initial, onComplete, onBack }: Props): React.ReactElement;
16
+ export {};
17
+ //# sourceMappingURL=engagement-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engagement-info.d.ts","sourceRoot":"","sources":["../../../../src/builder/steps/engagement-info.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAGxC,UAAU,KAAK;IACb,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzE,UAAU,EAAE,CAAC,IAAI,EAAE;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACxF,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAUD,wBAAgB,kBAAkB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAoD7F"}
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ const FIELDS = [
5
+ { key: "engagement_id", label: "Engagement ID", placeholder: "ENG-2026-0001" },
6
+ { key: "client", label: "Client", placeholder: "Acme Corp" },
7
+ { key: "operator", label: "Operator", placeholder: "operator@integsec.com" },
8
+ ];
9
+ export function EngagementInfoStep({ initial, onComplete, onBack }) {
10
+ const [fieldIndex, setFieldIndex] = useState(0);
11
+ const [values, setValues] = useState({
12
+ engagement_id: initial?.engagement_id ?? "",
13
+ client: initial?.client ?? "",
14
+ operator: initial?.operator ?? "",
15
+ });
16
+ const [input, setInput] = useState(values[FIELDS[0].key]);
17
+ useInput((ch, key) => {
18
+ if (key.escape && onBack) {
19
+ onBack();
20
+ return;
21
+ }
22
+ if (key.return) {
23
+ const field = FIELDS[fieldIndex];
24
+ const newValues = { ...values, [field.key]: input };
25
+ setValues(newValues);
26
+ if (fieldIndex < FIELDS.length - 1) {
27
+ const nextIndex = fieldIndex + 1;
28
+ setFieldIndex(nextIndex);
29
+ setInput(newValues[FIELDS[nextIndex].key]);
30
+ }
31
+ else {
32
+ if (newValues.engagement_id && newValues.client && newValues.operator) {
33
+ onComplete(newValues);
34
+ }
35
+ }
36
+ return;
37
+ }
38
+ if (key.backspace || key.delete) {
39
+ setInput((prev) => prev.slice(0, -1));
40
+ return;
41
+ }
42
+ if (ch && !key.ctrl && !key.meta) {
43
+ setInput((prev) => prev + ch);
44
+ }
45
+ });
46
+ const field = FIELDS[fieldIndex];
47
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Step 1: Engagement Info" }), _jsx(Text, { dimColor: true, children: "Press Enter to confirm each field. Esc to go back." }), _jsx(Box, { marginTop: 1 }), FIELDS.map((f, i) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: i !== fieldIndex, children: [i < fieldIndex ? "✓" : i === fieldIndex ? "›" : " ", " ", f.label, ":", " "] }), i < fieldIndex ? (_jsx(Text, { color: "green", children: values[f.key] })) : i === fieldIndex ? (_jsxs(Text, { children: [input, _jsx(Text, { dimColor: true, children: "\u2502" })] })) : (_jsx(Text, { dimColor: true, children: f.placeholder }))] }, f.key)))] }));
48
+ }
49
+ //# sourceMappingURL=engagement-info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engagement-info.js","sourceRoot":"","sources":["../../../../src/builder/steps/engagement-info.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ interface Props {
3
+ initial?: {
4
+ start?: string;
5
+ end?: string;
6
+ };
7
+ onComplete: (data: {
8
+ start: string;
9
+ end: string;
10
+ }) => void;
11
+ onBack?: () => void;
12
+ }
13
+ export declare function EngagementWindowStep({ initial, onComplete, onBack }: Props): React.ReactElement;
14
+ export {};
15
+ //# sourceMappingURL=engagement-window.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engagement-window.d.ts","sourceRoot":"","sources":["../../../../src/builder/steps/engagement-window.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,KAAK;IACb,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,UAAU,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AASD,wBAAgB,oBAAoB,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CA4D/F"}
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { Box, Text, useInput } from "ink";
4
+ import { validateIsoDate, validateWindowSanity } from "../smart-validator.js";
5
+ const FIELDS = [
6
+ { key: "start", label: "Start (ISO 8601)", placeholder: "2026-04-01T08:00:00Z" },
7
+ { key: "end", label: "End (ISO 8601)", placeholder: "2026-04-15T17:00:00Z" },
8
+ ];
9
+ export function EngagementWindowStep({ initial, onComplete, onBack }) {
10
+ const [fieldIndex, setFieldIndex] = useState(0);
11
+ const [values, setValues] = useState({ start: initial?.start ?? "", end: initial?.end ?? "" });
12
+ const [input, setInput] = useState(values[FIELDS[0].key]);
13
+ const [messages, setMessages] = useState([]);
14
+ useInput((ch, key) => {
15
+ if (key.escape && onBack) {
16
+ onBack();
17
+ return;
18
+ }
19
+ if (key.return) {
20
+ const field = FIELDS[fieldIndex];
21
+ const fieldMsgs = validateIsoDate(input);
22
+ if (fieldMsgs.some((m) => m.level === "error")) {
23
+ setMessages(fieldMsgs);
24
+ return;
25
+ }
26
+ const newValues = { ...values, [field.key]: input };
27
+ setValues(newValues);
28
+ setMessages([]);
29
+ if (fieldIndex < FIELDS.length - 1) {
30
+ const nextIndex = fieldIndex + 1;
31
+ setFieldIndex(nextIndex);
32
+ setInput(newValues[FIELDS[nextIndex].key]);
33
+ }
34
+ else {
35
+ const windowMsgs = validateWindowSanity(newValues.start, newValues.end);
36
+ const errors = windowMsgs.filter((m) => m.level === "error");
37
+ if (errors.length > 0) {
38
+ setMessages(windowMsgs);
39
+ return;
40
+ }
41
+ if (windowMsgs.length > 0)
42
+ setMessages(windowMsgs);
43
+ onComplete(newValues);
44
+ }
45
+ return;
46
+ }
47
+ if (key.backspace || key.delete) {
48
+ setInput((prev) => prev.slice(0, -1));
49
+ return;
50
+ }
51
+ if (ch && !key.ctrl && !key.meta) {
52
+ setInput((prev) => prev + ch);
53
+ }
54
+ });
55
+ return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "Step 2: Engagement Window" }), _jsx(Text, { dimColor: true, children: "Enter start and end dates in ISO 8601 format. Esc to go back." }), _jsx(Box, { marginTop: 1 }), FIELDS.map((f, i) => (_jsxs(Box, { children: [_jsxs(Text, { dimColor: i !== fieldIndex, children: [i < fieldIndex ? "✓" : i === fieldIndex ? "›" : " ", " ", f.label, ":", " "] }), i < fieldIndex ? (_jsx(Text, { color: "green", children: values[f.key] })) : i === fieldIndex ? (_jsxs(Text, { children: [input, _jsx(Text, { dimColor: true, children: "\u2502" })] })) : (_jsx(Text, { dimColor: true, children: f.placeholder }))] }, f.key))), messages.map((msg, i) => (_jsx(Box, { marginTop: i === 0 ? 1 : 0, children: _jsxs(Text, { color: msg.level === "error" ? "red" : msg.level === "warning" ? "yellow" : "blue", children: [msg.level === "error" ? "✗" : msg.level === "warning" ? "⚠" : "ℹ", " ", msg.message] }) }, i)))] }));
56
+ }
57
+ //# sourceMappingURL=engagement-window.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engagement-window.js","sourceRoot":"","sources":["../../../../src/builder/steps/engagement-window.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ interface Props {
3
+ initial?: string[];
4
+ authorized: {
5
+ ip_ranges: string[];
6
+ domains: string[];
7
+ };
8
+ onComplete: (excluded: string[]) => void;
9
+ onBack?: () => void;
10
+ }
11
+ export declare function ExclusionsStep({ initial, authorized, onComplete, onBack }: Props): React.ReactElement;
12
+ export {};
13
+ //# sourceMappingURL=exclusions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclusions.d.ts","sourceRoot":"","sources":["../../../../src/builder/steps/exclusions.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAC;AAIxC,UAAU,KAAK;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE;QAAE,SAAS,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACvD,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACzC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAOD,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,YAAY,CAoDrG"}