@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
@@ -5,34 +5,42 @@
5
5
  * Used to determine whether a target IP is in-scope, private, or a cloud
6
6
  * metadata endpoint. This is security-critical code: every edge case matters.
7
7
  */
8
- import IPCIDR from "ip-cidr";
8
+ import { isIP } from "node:net";
9
+ import ipaddr from "ipaddr.js";
9
10
  // ─────────────────────────────────────────────────────────────────────────────
10
11
  // Helpers
11
12
  // ─────────────────────────────────────────────────────────────────────────────
12
13
  /**
13
14
  * Return true if `address` looks like an IPv6 string (contains a colon).
14
- * This is intentionally lightweight — full validation is delegated to ip-cidr.
15
+ * This is intentionally lightweight — full validation is delegated to ipaddr.js.
15
16
  */
16
17
  function looksLikeIPv6(address) {
17
18
  return address.includes(":");
18
19
  }
19
- /**
20
- * Normalise a range string so it always contains a `/`.
21
- *
22
- * Rules:
23
- * - If it already contains a `/` it is returned as-is.
24
- * - If it looks like an IPv6 bare address, append `/128`.
25
- * - Otherwise append `/32` (treat as an IPv4 exact-host CIDR).
26
- *
27
- * We intentionally do NOT strip whitespace here — a range with leading or
28
- * trailing whitespace is invalid and should propagate to ip-cidr which will
29
- * throw and be caught.
30
- */
31
- function normaliseCidr(range) {
32
- if (range.includes("/")) {
33
- return range;
20
+ /** Reject alternate numeric forms and zone IDs before delegating parsing. */
21
+ function parseRange(value) {
22
+ if (!value || value.includes("%"))
23
+ return null;
24
+ const parts = value.split("/");
25
+ if (parts.length > 2 || isIP(parts[0]) === 0)
26
+ return null;
27
+ const width = isIP(parts[0]) === 4 ? 32 : 128;
28
+ const prefix = parts.length === 1 ? width : Number(parts[1]);
29
+ if (parts.length === 2 && !/^\d{1,3}$/.test(parts[1]))
30
+ return null;
31
+ if (!Number.isInteger(prefix) || prefix < 0 || prefix > width)
32
+ return null;
33
+ try {
34
+ return [ipaddr.parse(parts[0]), prefix];
34
35
  }
35
- return looksLikeIPv6(range) ? `${range}/128` : `${range}/32`;
36
+ catch {
37
+ return null;
38
+ }
39
+ }
40
+ function comparableAddress(address) {
41
+ return address.kind() === "ipv6" && address.isIPv4MappedAddress()
42
+ ? address.toIPv4Address()
43
+ : address;
36
44
  }
37
45
  // ─────────────────────────────────────────────────────────────────────────────
38
46
  // Public API
@@ -49,12 +57,11 @@ export function isIpInCidr(ip, cidr) {
49
57
  return false;
50
58
  }
51
59
  try {
52
- const normalisedCidr = normaliseCidr(cidr);
53
- if (!IPCIDR.isValidCIDR(normalisedCidr)) {
60
+ const range = parseRange(cidr);
61
+ if (range === null || isIP(ip) === 0 || ip.includes("%"))
54
62
  return false;
55
- }
56
- const range = new IPCIDR(normalisedCidr);
57
- return range.contains(ip);
63
+ const address = comparableAddress(ipaddr.parse(ip));
64
+ return address.kind() === range[0].kind() && address.match(range);
58
65
  }
59
66
  catch {
60
67
  return false;
@@ -104,6 +111,72 @@ export function isRfc1918(ip) {
104
111
  }
105
112
  return isIpInAnyRange(ip, RFC1918_RANGES);
106
113
  }
114
+ /**
115
+ * Return true if `value` is a valid CIDR range (must contain a `/`).
116
+ */
117
+ export function isCidr(value) {
118
+ if (!value || !value.includes("/")) {
119
+ return false;
120
+ }
121
+ try {
122
+ return parseRange(value) !== null;
123
+ }
124
+ catch {
125
+ return false;
126
+ }
127
+ }
128
+ /**
129
+ * Return the [first, last] address of a CIDR or bare IP, or null if invalid.
130
+ */
131
+ /**
132
+ * Return true if every address in `inner` (CIDR or bare IP) lies within
133
+ * `outer` (CIDR or bare IP). Returns false for invalid or mixed-family input.
134
+ */
135
+ export function isRangeWithin(inner, outer) {
136
+ const inside = parseRange(inner);
137
+ const outside = parseRange(outer);
138
+ return inside !== null && outside !== null &&
139
+ inside[0].kind() === outside[0].kind() &&
140
+ inside[1] >= outside[1] && inside[0].match(outside);
141
+ }
142
+ /**
143
+ * Return true if the two ranges (CIDRs or bare IPs) share at least one
144
+ * address. CIDR blocks are either nested or disjoint, so checking whether
145
+ * either range's first address falls in the other is sufficient.
146
+ */
147
+ export function rangesOverlap(a, b) {
148
+ const first = parseRange(a);
149
+ const second = parseRange(b);
150
+ if (first === null || second === null || first[0].kind() !== second[0].kind())
151
+ return false;
152
+ return first[0].match(second) || second[0].match(first);
153
+ }
154
+ /**
155
+ * Addresses that an in-scope hostname must never silently resolve to:
156
+ * loopback, link-local (including cloud metadata) and unspecified addresses.
157
+ * Reaching these via an authorized *domain* is almost always DNS pointing
158
+ * somewhere unintended (e.g. metadata.acme.com → 169.254.169.254), so the
159
+ * validator requires them to be listed explicitly in ip_ranges.
160
+ */
161
+ const RESTRICTED_RANGES = [
162
+ "127.0.0.0/8",
163
+ "169.254.0.0/16",
164
+ "0.0.0.0/32",
165
+ "::1/128",
166
+ "::/128",
167
+ "fe80::/10",
168
+ "fd00:ec2::254/128",
169
+ ];
170
+ /**
171
+ * Return true if `ip` is loopback, link-local, unspecified or a cloud
172
+ * metadata endpoint.
173
+ */
174
+ export function isRestrictedIp(ip) {
175
+ if (!ip) {
176
+ return false;
177
+ }
178
+ return isIpInAnyRange(ip, RESTRICTED_RANGES);
179
+ }
107
180
  /**
108
181
  * Well-known cloud instance metadata endpoints.
109
182
  * 169.254.169.254 — AWS, Azure, GCP (IPv4)
@@ -1 +1 @@
1
- {"version":3,"file":"ip-matcher.js","sourceRoot":"","sources":["../../src/ip-matcher.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B,gFAAgF;AAChF,UAAU;AACV,gFAAgF;AAEhF;;;GAGG;AACH,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,CAAC;AAC/D,CAAC;AAED,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,IAAY;IACjD,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;QAE3C,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,cAAc,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,MAAgB;IACzD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,cAAc,GAAa;IAC/B,YAAY;IACZ,eAAe;IACf,gBAAgB;IAChB,gBAAgB;CACjB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,EAAU;IAClC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,iDAAiD;IACjD,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,cAAc,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,kBAAkB,GAAa;IACnC,iBAAiB;IACjB,eAAe;CAChB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,cAAc,CAAC,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"ip-matcher.js","sourceRoot":"","sources":["../../src/ip-matcher.ts"],"names":[],"mappings":"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"}
@@ -4,69 +4,19 @@ export declare const ScopeManifestSchema: z.ZodObject<{
4
4
  client: z.ZodString;
5
5
  operator: z.ZodString;
6
6
  authorized_targets: z.ZodObject<{
7
- ip_ranges: z.ZodArray<z.ZodString, "many">;
8
- domains: z.ZodArray<z.ZodString, "many">;
9
- urls: z.ZodArray<z.ZodString, "many">;
10
- cloud_accounts: z.ZodArray<z.ZodString, "many">;
11
- }, "strip", z.ZodTypeAny, {
12
- ip_ranges: string[];
13
- domains: string[];
14
- urls: string[];
15
- cloud_accounts: string[];
16
- }, {
17
- ip_ranges: string[];
18
- domains: string[];
19
- urls: string[];
20
- cloud_accounts: string[];
21
- }>;
22
- excluded_targets: z.ZodArray<z.ZodString, "many">;
23
- authorized_techniques: z.ZodArray<z.ZodString, "many">;
24
- excluded_techniques: z.ZodArray<z.ZodString, "many">;
7
+ ip_ranges: z.ZodArray<z.ZodString>;
8
+ domains: z.ZodArray<z.ZodString>;
9
+ urls: z.ZodArray<z.ZodString>;
10
+ cloud_accounts: z.ZodArray<z.ZodString>;
11
+ }, z.core.$strip>;
12
+ excluded_targets: z.ZodArray<z.ZodString>;
13
+ authorized_techniques: z.ZodArray<z.ZodString>;
14
+ excluded_techniques: z.ZodArray<z.ZodString>;
25
15
  engagement_window: z.ZodObject<{
26
- start: z.ZodEffects<z.ZodString, string, string>;
27
- end: z.ZodEffects<z.ZodString, string, string>;
28
- }, "strip", z.ZodTypeAny, {
29
- start: string;
30
- end: string;
31
- }, {
32
- start: string;
33
- end: string;
34
- }>;
35
- }, "strip", z.ZodTypeAny, {
36
- engagement_id: string;
37
- client: string;
38
- operator: string;
39
- authorized_targets: {
40
- ip_ranges: string[];
41
- domains: string[];
42
- urls: string[];
43
- cloud_accounts: string[];
44
- };
45
- excluded_targets: string[];
46
- authorized_techniques: string[];
47
- excluded_techniques: string[];
48
- engagement_window: {
49
- start: string;
50
- end: string;
51
- };
52
- }, {
53
- engagement_id: string;
54
- client: string;
55
- operator: string;
56
- authorized_targets: {
57
- ip_ranges: string[];
58
- domains: string[];
59
- urls: string[];
60
- cloud_accounts: string[];
61
- };
62
- excluded_targets: string[];
63
- authorized_techniques: string[];
64
- excluded_techniques: string[];
65
- engagement_window: {
66
- start: string;
67
- end: string;
68
- };
69
- }>;
16
+ start: z.ZodString;
17
+ end: z.ZodString;
18
+ }, z.core.$strip>;
19
+ }, z.core.$strip>;
70
20
  /**
71
21
  * Inferred TypeScript type from the Zod schema.
72
22
  * Use this instead of the hand-written `ScopeManifest` interface from
@@ -1 +1 @@
1
- {"version":3,"file":"manifest-schema.d.ts","sourceRoot":"","sources":["../../src/manifest-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiB9B,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"manifest-schema.d.ts","sourceRoot":"","sources":["../../src/manifest-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;iBAiB9B,CAAC;AAEH;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -1,3 +1,9 @@
1
1
  import type { ScopeManifest } from "./manifest-schema.js";
2
+ /** Accept a vault base URL or a complete /secrets/name/version reference. */
3
+ export declare function parseKeyVaultReference(reference: string, fallbackName?: string): {
4
+ vaultUrl: string;
5
+ secretName: string;
6
+ version?: string;
7
+ };
2
8
  export declare function loadManifest(): Promise<ScopeManifest>;
3
9
  //# sourceMappingURL=manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqB1D,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CA2G3D"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAqB1D,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,SAAmB,GACvF;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAe3D;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CA0G3D"}
@@ -17,6 +17,24 @@ function parseAndValidate(json, source) {
17
17
  }
18
18
  return result.data;
19
19
  }
20
+ /** Accept a vault base URL or a complete /secrets/name/version reference. */
21
+ export function parseKeyVaultReference(reference, fallbackName = "scope-manifest") {
22
+ const url = new URL(reference);
23
+ if (url.protocol !== "https:" || !url.hostname.endsWith(".vault.azure.net")) {
24
+ throw new Error("SCOPE_MANIFEST_KEYVAULT_URI must be an HTTPS Azure Key Vault URL");
25
+ }
26
+ const segments = url.pathname.split("/").filter(Boolean);
27
+ if (segments.length === 0)
28
+ return { vaultUrl: url.origin, secretName: fallbackName };
29
+ if (segments[0] !== "secrets" || segments.length < 2 || segments.length > 3) {
30
+ throw new Error("SCOPE_MANIFEST_KEYVAULT_URI must point to /secrets/name[/version]");
31
+ }
32
+ return {
33
+ vaultUrl: url.origin,
34
+ secretName: decodeURIComponent(segments[1]),
35
+ version: segments[2] ? decodeURIComponent(segments[2]) : undefined,
36
+ };
37
+ }
20
38
  export async function loadManifest() {
21
39
  // 1. Inline JSON env var — highest priority
22
40
  const inlineJson = process.env.SCOPE_MANIFEST_JSON;
@@ -67,12 +85,9 @@ export async function loadManifest() {
67
85
  const { SecretClient } = await import(/* @vite-ignore */ kvMod);
68
86
  const { DefaultAzureCredential } = await import(/* @vite-ignore */ idMod);
69
87
  const credential = new DefaultAzureCredential();
70
- const client = new SecretClient(keyvaultUri, credential);
71
- // The URI may be in the form https://vault.azure.net/secrets/secretName
72
- // or we use a convention: treat the env var as the vault base URI
73
- // and look for secret named "scope-manifest"
74
- const secretName = process.env.SCOPE_MANIFEST_KEYVAULT_SECRET_NAME || "scope-manifest";
75
- const secret = await client.getSecret(secretName);
88
+ const { vaultUrl, secretName, version } = parseKeyVaultReference(keyvaultUri, process.env.SCOPE_MANIFEST_KEYVAULT_SECRET_NAME || "scope-manifest");
89
+ const client = new SecretClient(vaultUrl, credential);
90
+ const secret = await client.getSecret(secretName, version ? { version } : undefined);
76
91
  if (!secret.value) {
77
92
  throw new Error(`Secret "${secretName}" in Key Vault has no value`);
78
93
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,12 @@
1
1
  import type { ScopeManifest } from "./types.js";
2
2
  import { AuditLogger } from "./audit/index.js";
3
3
  import type { ProxyConfig } from "./config.js";
4
+ export interface HandleResult {
5
+ /** True when the original message may be sent to the upstream unchanged. */
6
+ forward: boolean;
7
+ /** JSON-RPC response (object, or array for batches) to return to the agent instead. */
8
+ response?: unknown;
9
+ }
4
10
  export declare class ScopeEnforcementProxy {
5
11
  private validator;
6
12
  private auditLogger;
@@ -11,9 +17,18 @@ export declare class ScopeEnforcementProxy {
11
17
  getServerName(): string | undefined;
12
18
  constructor(manifest: ScopeManifest, config: ProxyConfig);
13
19
  getAuditLogger(): AuditLogger;
14
- handleMessage(message: unknown): Promise<{
15
- forward: boolean;
16
- response?: unknown;
17
- }>;
20
+ handleMessage(message: unknown): Promise<HandleResult>;
21
+ /**
22
+ * Build a JSON-RPC parse-error response for input the proxy could not parse.
23
+ * Unparseable input is never forwarded: a more lenient upstream parser could
24
+ * otherwise execute a tool call the proxy never saw.
25
+ */
26
+ static parseErrorResponse(): unknown;
27
+ private handleBatch;
28
+ /**
29
+ * Validate one tools/call request and write its audit entry. Never throws:
30
+ * any internal error becomes BLOCKED_INTERNAL_ERROR (fail closed).
31
+ */
32
+ private checkToolCall;
18
33
  }
19
34
  //# sourceMappingURL=proxy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAc,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,qBAAa,qBAAqB;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,UAAU,CAAqB;IAEvC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,aAAa,IAAI,MAAM,GAAG,SAAS;gBAEvB,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW;IASxD,cAAc,IAAI,WAAW;IAEvB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CAoDzF"}
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAgC,MAAM,YAAY,CAAC;AAE9E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAC;IACjB,uFAAuF;IACvF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,qBAAa,qBAAqB;IAChC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,UAAU,CAAqB;IAEvC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IACjC,aAAa,IAAI,MAAM,GAAG,SAAS;gBAEvB,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW;IAWxD,cAAc,IAAI,WAAW;IAEvB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC;IAoB5D;;;;OAIG;IACH,MAAM,CAAC,kBAAkB,IAAI,OAAO;YAYtB,WAAW;IA2BzB;;;OAGG;YACW,aAAa;CAuD5B"}
package/dist/src/proxy.js CHANGED
@@ -2,7 +2,8 @@ import { ScopeValidator } from "./validator.js";
2
2
  import { AuditLogger } from "./audit/index.js";
3
3
  import { sanitizeParams } from "./sanitizer.js";
4
4
  import { DnsResolver } from "./dns-resolver.js";
5
- import { TechniqueChecker } from "./technique-checker.js";
5
+ import { TechniqueChecker, loadTechniqueMappings } from "./technique-checker.js";
6
+ const SCOPE_VIOLATION_CODE = -32001;
6
7
  export class ScopeEnforcementProxy {
7
8
  validator;
8
9
  auditLogger;
@@ -15,28 +16,95 @@ export class ScopeEnforcementProxy {
15
16
  this.manifest = manifest;
16
17
  this.config = config;
17
18
  const dnsResolver = new DnsResolver(config.dnsCacheTtl);
18
- const techniqueChecker = new TechniqueChecker();
19
- this.validator = new ScopeValidator(manifest, dnsResolver, techniqueChecker);
19
+ const techniqueChecker = new TechniqueChecker(config.techniqueMapPath ? loadTechniqueMappings(config.techniqueMapPath) : undefined);
20
+ this.validator = new ScopeValidator(manifest, dnsResolver, techniqueChecker, config.allowUnstructuredCommands);
20
21
  this.auditLogger = new AuditLogger(config.auditLogPath);
21
22
  }
22
23
  getAuditLogger() { return this.auditLogger; }
23
24
  async handleMessage(message) {
24
- // Only intercept tools/call JSON-RPC requests
25
+ // JSON-RPC batch: every tools/call inside must pass. If any element is
26
+ // blocked the whole batch is rejected so that the agent gets exactly one
27
+ // response array and nothing out of scope reaches the upstream.
28
+ if (Array.isArray(message)) {
29
+ return this.handleBatch(message);
30
+ }
31
+ // Only intercept tools/call requests
25
32
  if (!isToolCallRequest(message)) {
26
33
  return { forward: true };
27
34
  }
28
- const { id, params } = message;
29
- const toolName = params?.name ?? "unknown";
30
- const toolParams = params?.arguments ?? {};
31
- const result = await this.validator.validate(toolName, toolParams);
32
- // Build audit entry
35
+ const { decision, error } = await this.checkToolCall(message);
36
+ if (decision.startsWith("BLOCKED")) {
37
+ return { forward: false, response: errorResponse(message.id, error) };
38
+ }
39
+ return { forward: true };
40
+ }
41
+ /**
42
+ * Build a JSON-RPC parse-error response for input the proxy could not parse.
43
+ * Unparseable input is never forwarded: a more lenient upstream parser could
44
+ * otherwise execute a tool call the proxy never saw.
45
+ */
46
+ static parseErrorResponse() {
47
+ return {
48
+ jsonrpc: "2.0",
49
+ id: null,
50
+ error: { code: -32700, message: "Parse error: the scope proxy only forwards valid JSON." },
51
+ };
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // Internals
55
+ // ---------------------------------------------------------------------------
56
+ async handleBatch(batch) {
57
+ const toolCalls = batch.filter(isToolCallRequest);
58
+ if (toolCalls.length === 0) {
59
+ return { forward: true };
60
+ }
61
+ const checks = await Promise.all(toolCalls.map(async (call) => ({ call, ...(await this.checkToolCall(call)) })));
62
+ const blocked = checks.filter((c) => c.decision.startsWith("BLOCKED"));
63
+ if (blocked.length === 0) {
64
+ return { forward: true };
65
+ }
66
+ const firstBlocked = blocked[0];
67
+ const responses = batch
68
+ .filter((m) => isRequest(m))
69
+ .map((m) => {
70
+ const own = checks.find((c) => c.call === m && c.decision.startsWith("BLOCKED"));
71
+ const msg = own
72
+ ? own.error
73
+ : `SCOPE_VIOLATION: Batch rejected because tool call id ${JSON.stringify(firstBlocked.call.id)} was blocked (${firstBlocked.decision}). Decision: BLOCKED_BATCH.`;
74
+ return errorResponse(m.id, msg);
75
+ });
76
+ return { forward: false, response: responses };
77
+ }
78
+ /**
79
+ * Validate one tools/call request and write its audit entry. Never throws:
80
+ * any internal error becomes BLOCKED_INTERNAL_ERROR (fail closed).
81
+ */
82
+ async checkToolCall(message) {
83
+ const params = isObject(message.params) ? message.params : {};
84
+ const toolName = params.name;
85
+ const rawArgs = params.arguments;
86
+ const toolParams = (rawArgs === undefined || rawArgs === null ? {} : rawArgs);
87
+ const startTime = Date.now();
88
+ let result;
89
+ try {
90
+ result = await this.validator.validate(toolName, toolParams);
91
+ }
92
+ catch (err) {
93
+ result = {
94
+ decision: "BLOCKED_INTERNAL_ERROR",
95
+ reason: "Validation failed with an internal error; failing closed.",
96
+ durationMs: Date.now() - startTime,
97
+ };
98
+ }
33
99
  const entry = {
34
100
  timestamp: new Date().toISOString(),
35
101
  engagement_id: this.manifest.engagement_id,
36
102
  client: this.manifest.client,
37
103
  operator: this.manifest.operator,
38
- tool_name: toolName,
39
- tool_parameters: sanitizeParams(toolParams),
104
+ tool_name: typeof toolName === "string" ? toolName : String(toolName),
105
+ tool_parameters: isObject(toolParams)
106
+ ? sanitizeParams(toolParams)
107
+ : { _invalid_arguments: "[REDACTED_INVALID_ARGUMENTS]" },
40
108
  extracted_target: result.extractedTarget ?? null,
41
109
  resolved_ips: result.resolvedIps ?? [],
42
110
  decision: result.decision,
@@ -46,31 +114,41 @@ export class ScopeEnforcementProxy {
46
114
  proxy_version: this.config.proxyVersion,
47
115
  server_name: this.serverName,
48
116
  };
49
- // Log asynchronously — never block on logging failure
50
- this.auditLogger.log(entry).catch((err) => {
51
- console.error(`[integsec-agentic-pentest-proxy] Failed to log audit entry: ${err.message}`);
52
- });
53
- // If blocked, return error response
54
- if (result.decision.startsWith("BLOCKED")) {
55
- return {
56
- forward: false,
57
- response: {
58
- jsonrpc: "2.0",
59
- id,
60
- error: {
61
- code: -32001,
62
- message: `SCOPE_VIOLATION: ${result.reason}. Decision: ${result.decision}.`,
63
- },
64
- },
65
- };
117
+ // Write the local audit entry before the call is forwarded so decisions
118
+ // survive an abrupt kill. Logging failures never block the decision.
119
+ try {
120
+ await this.auditLogger.log(entry);
121
+ await this.auditLogger.flushLocal();
66
122
  }
67
- return { forward: true };
123
+ catch (err) {
124
+ console.error(`[integsec-agentic-pentest-proxy] Failed to log audit entry: ${err instanceof Error ? err.message : String(err)}`);
125
+ }
126
+ return {
127
+ decision: result.decision,
128
+ error: `SCOPE_VIOLATION: ${result.reason} Decision: ${result.decision}.`,
129
+ };
68
130
  }
69
131
  }
132
+ function isObject(value) {
133
+ return typeof value === "object" && value !== null && !Array.isArray(value);
134
+ }
135
+ /**
136
+ * Any message with method "tools/call" is treated as a tool call, whether or
137
+ * not it carries a valid "jsonrpc" field — a lenient upstream might still
138
+ * execute it.
139
+ */
70
140
  function isToolCallRequest(msg) {
71
- if (typeof msg !== "object" || msg === null)
72
- return false;
73
- const obj = msg;
74
- return obj.method === "tools/call" && obj.jsonrpc === "2.0";
141
+ return isObject(msg) && msg.method === "tools/call";
142
+ }
143
+ /** Requests (not notifications) are the batch members that need a response. */
144
+ function isRequest(msg) {
145
+ return isObject(msg) && typeof msg.method === "string" && msg.id !== undefined && msg.id !== null;
146
+ }
147
+ function errorResponse(id, message) {
148
+ return {
149
+ jsonrpc: "2.0",
150
+ id: id ?? null,
151
+ error: { code: SCOPE_VIOLATION_CODE, message },
152
+ };
75
153
  }
76
154
  //# sourceMappingURL=proxy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAG1D,MAAM,OAAO,qBAAqB;IACxB,SAAS,CAAiB;IAC1B,WAAW,CAAc;IACzB,QAAQ,CAAgB;IACxB,MAAM,CAAc;IACpB,UAAU,CAAqB;IAEvC,aAAa,CAAC,IAAY,IAAU,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7D,aAAa,KAAyB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IAE/D,YAAY,QAAuB,EAAE,MAAmB;QACtD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACxD,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;QAChD,IAAI,CAAC,SAAS,GAAG,IAAI,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,gBAAgB,CAAC,CAAC;QAC7E,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC;IAED,cAAc,KAAkB,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1D,KAAK,CAAC,aAAa,CAAC,OAAgB;QAClC,8CAA8C;QAC9C,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,OAAc,CAAC;QACtC,MAAM,QAAQ,GAAW,MAAM,EAAE,IAAI,IAAI,SAAS,CAAC;QACnD,MAAM,UAAU,GAA4B,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC;QAEpE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEnE,oBAAoB;QACpB,MAAM,KAAK,GAAe;YACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa;YAC1C,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC5B,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ;YAChC,SAAS,EAAE,QAAQ;YACnB,eAAe,EAAE,cAAc,CAAC,UAAU,CAAC;YAC3C,gBAAgB,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI;YAChD,YAAY,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;YACtC,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,eAAe,EAAE,MAAM,CAAC,MAAM;YAC9B,kBAAkB,EAAE,MAAM,CAAC,gBAAgB,IAAI,IAAI;YACnD,WAAW,EAAE,MAAM,CAAC,UAAU;YAC9B,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY;YACvC,WAAW,EAAE,IAAI,CAAC,UAAU;SAC7B,CAAC;QAEF,sDAAsD;QACtD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACxC,OAAO,CAAC,KAAK,CAAC,+DAA+D,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9F,CAAC,CAAC,CAAC;QAEH,oCAAoC;QACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1C,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,QAAQ,EAAE;oBACR,OAAO,EAAE,KAAK;oBACd,EAAE;oBACF,KAAK,EAAE;wBACL,IAAI,EAAE,CAAC,KAAK;wBACZ,OAAO,EAAE,oBAAoB,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,QAAQ,GAAG;qBAC5E;iBACF;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC3B,CAAC;CACF;AAED,SAAS,iBAAiB,CAAC,GAAY;IACrC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,OAAO,GAAG,CAAC,MAAM,KAAK,YAAY,IAAI,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Keep ordinary engagement IDs readable while confining other values to one file. */
2
+ export declare function engagementFileStem(id: string): string;
3
+ //# sourceMappingURL=safe-filename.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-filename.d.ts","sourceRoot":"","sources":["../../src/safe-filename.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAGrD"}
@@ -0,0 +1,8 @@
1
+ import { createHash } from "node:crypto";
2
+ /** Keep ordinary engagement IDs readable while confining other values to one file. */
3
+ export function engagementFileStem(id) {
4
+ if (/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(id))
5
+ return id;
6
+ return `id-${createHash("sha256").update(id).digest("hex")}`;
7
+ }
8
+ //# sourceMappingURL=safe-filename.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safe-filename.js","sourceRoot":"","sources":["../../src/safe-filename.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAC3C,IAAI,oCAAoC,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,EAAE,CAAC;IAC7D,OAAO,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AAC/D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0DH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB"}
1
+ {"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgFH;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB"}