@solongate/proxy 0.81.11 → 0.81.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -10923,15 +10923,18 @@ function dlpGlobToRe(glob, flags) {
10923
10923
  function redactString(s, cfg) {
10924
10924
  if (!cfg || typeof s !== "string" || !s) return s;
10925
10925
  const allow = new Set(cfg.patterns);
10926
+ const NUL = String.fromCharCode(0);
10927
+ const labels = [];
10928
+ const stash = (label) => NUL + (labels.push(label) - 1) + NUL;
10926
10929
  let out2 = s;
10927
- for (const p of DLP_PATTERNS) if (allow.has(p.name)) out2 = out2.replace(p.re, `[REDACTED: ${p.name}]`);
10930
+ for (const p of DLP_PATTERNS) if (allow.has(p.name)) out2 = out2.replace(p.re, () => stash(`[REDACTED: ${p.name}]`));
10928
10931
  for (const c2 of cfg.custom) {
10929
10932
  try {
10930
- out2 = out2.replace(dlpGlobToRe(c2.re, "g"), `[REDACTED: ${c2.name || "custom"}]`);
10933
+ out2 = out2.replace(dlpGlobToRe(c2.re, "gi"), () => stash(`[REDACTED: ${c2.name || "custom"}]`));
10931
10934
  } catch {
10932
10935
  }
10933
10936
  }
10934
- return out2;
10937
+ return out2.replace(new RegExp(NUL + "(\\d+)" + NUL, "g"), (_, i) => labels[+i] || "");
10935
10938
  }
10936
10939
  function redactDeep(value, cfg) {
10937
10940
  const ghost = cfg && Array.isArray(cfg.ghost) ? cfg.ghost : null;
@@ -10960,9 +10963,9 @@ function pickUpstream() {
10960
10963
  }
10961
10964
  }
10962
10965
  function startProxy(upstream) {
10963
- const cfg = loadCfg();
10964
10966
  const forward = upstream.protocol === "https:" ? httpsRequest : httpRequest;
10965
10967
  const server = createServer((req, res) => {
10968
+ const cfg = loadCfg();
10966
10969
  const chunks = [];
10967
10970
  req.on("data", (c2) => chunks.push(c2));
10968
10971
  req.on("end", () => {
package/dist/shield.js CHANGED
@@ -164,15 +164,18 @@ function dlpGlobToRe(glob, flags) {
164
164
  function redactString(s, cfg) {
165
165
  if (!cfg || typeof s !== "string" || !s) return s;
166
166
  const allow = new Set(cfg.patterns);
167
+ const NUL = String.fromCharCode(0);
168
+ const labels = [];
169
+ const stash = (label) => NUL + (labels.push(label) - 1) + NUL;
167
170
  let out = s;
168
- for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, `[REDACTED: ${p.name}]`);
171
+ for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, () => stash(`[REDACTED: ${p.name}]`));
169
172
  for (const c of cfg.custom) {
170
173
  try {
171
- out = out.replace(dlpGlobToRe(c.re, "g"), `[REDACTED: ${c.name || "custom"}]`);
174
+ out = out.replace(dlpGlobToRe(c.re, "gi"), () => stash(`[REDACTED: ${c.name || "custom"}]`));
172
175
  } catch {
173
176
  }
174
177
  }
175
- return out;
178
+ return out.replace(new RegExp(NUL + "(\\d+)" + NUL, "g"), (_, i) => labels[+i] || "");
176
179
  }
177
180
  function redactDeep(value, cfg) {
178
181
  const ghost = cfg && Array.isArray(cfg.ghost) ? cfg.ghost : null;
@@ -201,9 +204,9 @@ function pickUpstream() {
201
204
  }
202
205
  }
203
206
  function startProxy(upstream) {
204
- const cfg = loadCfg();
205
207
  const forward = upstream.protocol === "https:" ? httpsRequest : httpRequest;
206
208
  const server = createServer((req, res) => {
209
+ const cfg = loadCfg();
207
210
  const chunks = [];
208
211
  req.on("data", (c) => chunks.push(c));
209
212
  req.on("end", () => {
package/hooks/audit.mjs CHANGED
@@ -330,16 +330,19 @@ function dlpGlobToRe(glob, flags) {
330
330
  return new RegExp(re, flags);
331
331
  }
332
332
  function dlpRedactText(text, cfg) {
333
- if (!cfg || typeof text !== 'string' || !text) return text;
333
+ if (!cfg || typeof text !== "string" || !text) return text;
334
334
  const allow = new Set(Array.isArray(cfg.patterns) ? cfg.patterns : []);
335
+ const NUL = String.fromCharCode(0);
336
+ const labels = [];
337
+ const stash = (label) => NUL + (labels.push(label) - 1) + NUL;
335
338
  let out = text;
336
339
  for (const p of DLP_PATTERNS) {
337
- if (allow.has(p.name)) out = out.replace(p.re, '[REDACTED:' + p.name + ']');
340
+ if (allow.has(p.name)) out = out.replace(p.re, () => stash("[REDACTED:" + p.name + "]"));
338
341
  }
339
342
  for (const c of Array.isArray(cfg.custom) ? cfg.custom : []) {
340
- try { out = out.replace(dlpGlobToRe(c.re, 'g'), '[REDACTED:' + (c.name || 'custom') + ']'); } catch { /* skip invalid */ }
343
+ try { out = out.replace(dlpGlobToRe(c.re, "gi"), () => stash("[REDACTED:" + (c.name || "custom") + "]")); } catch {}
341
344
  }
342
- return out;
345
+ return out.replace(new RegExp(NUL + "(\\d+)" + NUL, "g"), (_, i) => labels[+i] || "");
343
346
  }
344
347
 
345
348
  // Best-effort extraction of the model-visible text from a tool_response. Shapes
@@ -7159,7 +7159,7 @@ function dlpGlobToRe(glob) {
7159
7159
  else
7160
7160
  re += ch;
7161
7161
  }
7162
- return new RegExp(re);
7162
+ return new RegExp(re, "i");
7163
7163
  }
7164
7164
  function dlpScan(args, cfg) {
7165
7165
  if (!cfg)
package/hooks/guard.mjs CHANGED
@@ -834,7 +834,7 @@ function dlpGlobToRe(glob) {
834
834
  else if ('.+?^${}()|[]\\'.indexOf(ch) !== -1) re += '\\' + ch;
835
835
  else re += ch;
836
836
  }
837
- return new RegExp(re);
837
+ return new RegExp(re, 'i');
838
838
  }
839
839
  // Scan args against the enabled built-in patterns + any user custom patterns.
840
840
  // `cfg` = { patterns: string[], custom: {name,re}[] }.
package/hooks/shield.mjs CHANGED
@@ -171,14 +171,17 @@ function dlpGlobToRe(glob, flags) {
171
171
  return new RegExp(re, flags);
172
172
  }
173
173
  function redactString(s, cfg) {
174
- if (!cfg || typeof s !== 'string' || !s) return s;
174
+ if (!cfg || typeof s !== "string" || !s) return s;
175
175
  const allow = new Set(cfg.patterns);
176
+ const NUL = String.fromCharCode(0);
177
+ const labels = [];
178
+ const stash = (label) => NUL + (labels.push(label) - 1) + NUL;
176
179
  let out = s;
177
- for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, `[REDACTED: ${p.name}]`);
180
+ for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, () => stash(`[REDACTED: ${p.name}]`));
178
181
  for (const c of cfg.custom) {
179
- try { out = out.replace(dlpGlobToRe(c.re, 'g'), `[REDACTED: ${c.name || 'custom'}]`); } catch { /* skip */ }
182
+ try { out = out.replace(dlpGlobToRe(c.re, "gi"), () => stash(`[REDACTED: ${c.name || "custom"}]`)); } catch {}
180
183
  }
181
- return out;
184
+ return out.replace(new RegExp(NUL + "(\\d+)" + NUL, "g"), (_, i) => labels[+i] || "");
182
185
  }
183
186
 
184
187
  function redactDeep(value, cfg) {
@@ -210,9 +213,13 @@ function pickUpstream() {
210
213
  }
211
214
 
212
215
  function startProxy(upstream) {
213
- const cfg = loadCfg();
214
216
  const forward = upstream.protocol === 'https:' ? httpsRequest : httpRequest;
215
217
  const server = createServer((req, res) => {
218
+ // Re-read the DLP config on every request (cheap: a small JSON) so changing
219
+ // DLP mode / patterns in the dashboard takes effect WITHOUT restarting claude —
220
+ // the guard rewrites this cache within ~one call, matching how the audit hook
221
+ // already re-reads per call. Loading once at startup left the shield stale.
222
+ const cfg = loadCfg();
216
223
  const chunks = [];
217
224
  req.on('data', (c) => chunks.push(c));
218
225
  req.on('end', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.81.11",
3
+ "version": "0.81.13",
4
4
  "description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
5
5
  "type": "module",
6
6
  "bin": {