@solongate/proxy 0.55.0 → 0.56.0

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
@@ -7017,14 +7017,36 @@ import { createServer, request as httpRequest } from "http";
7017
7017
  import { request as httpsRequest } from "https";
7018
7018
  import { spawn as spawn2 } from "child_process";
7019
7019
  import { URL as URL2 } from "url";
7020
- import { readFileSync as readFileSync6, existsSync as existsSync5 } from "fs";
7020
+ import { readFileSync as readFileSync6, existsSync as existsSync5, readdirSync, statSync } from "fs";
7021
7021
  import { resolve as resolve4 } from "path";
7022
7022
  import { homedir as homedir3 } from "os";
7023
+ function findCacheFile() {
7024
+ const dir = resolve4(homedir3(), ".solongate");
7025
+ const envSel = process.env.SOLONGATE_AGENT_ID;
7026
+ if (envSel) {
7027
+ const f = resolve4(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
7028
+ if (existsSync5(f)) return f;
7029
+ }
7030
+ let best = null, bestTs = -1;
7031
+ try {
7032
+ for (const name of readdirSync(dir)) {
7033
+ if (name.startsWith(".policy-cache-") && name.endsWith(".json")) {
7034
+ const full = resolve4(dir, name);
7035
+ const ts = statSync(full).mtimeMs;
7036
+ if (ts > bestTs) {
7037
+ bestTs = ts;
7038
+ best = full;
7039
+ }
7040
+ }
7041
+ }
7042
+ } catch {
7043
+ }
7044
+ return best;
7045
+ }
7023
7046
  function loadCfg() {
7024
7047
  try {
7025
- const sel = (process.env.SOLONGATE_AGENT_ID || "default").replace(/[^a-zA-Z0-9_-]/g, "_");
7026
- const f = resolve4(homedir3(), ".solongate", ".policy-cache-" + sel + ".json");
7027
- if (existsSync5(f)) {
7048
+ const f = findCacheFile();
7049
+ if (f && existsSync5(f)) {
7028
7050
  const c3 = JSON.parse(readFileSync6(f, "utf-8"));
7029
7051
  const d = c3?.security?.dlpRedact;
7030
7052
  if (d && Array.isArray(d.patterns)) return { patterns: d.patterns, custom: Array.isArray(d.custom) ? d.custom : [] };
package/dist/shield.js CHANGED
@@ -3,7 +3,7 @@ import { createServer, request as httpRequest } from "http";
3
3
  import { request as httpsRequest } from "https";
4
4
  import { spawn } from "child_process";
5
5
  import { URL } from "url";
6
- import { readFileSync, existsSync } from "fs";
6
+ import { readFileSync, existsSync, readdirSync, statSync } from "fs";
7
7
  import { resolve } from "path";
8
8
  import { homedir } from "os";
9
9
  var log = (...a) => process.stderr.write(`[SolonGate shield] ${a.map(String).join(" ")}
@@ -26,11 +26,33 @@ var DLP_PATTERNS = [
26
26
  { name: "Bearer token", re: /bearer\s+[A-Za-z0-9._-]{20,}/gi },
27
27
  { name: "secret assignment", re: /(api[_-]?key|secret|token|password|passwd|access[_-]?key)["']?\s*[:=]\s*["']?[A-Za-z0-9/+_.-]{12,}/gi }
28
28
  ];
29
+ function findCacheFile() {
30
+ const dir = resolve(homedir(), ".solongate");
31
+ const envSel = process.env.SOLONGATE_AGENT_ID;
32
+ if (envSel) {
33
+ const f = resolve(dir, ".policy-cache-" + envSel.replace(/[^a-zA-Z0-9_-]/g, "_") + ".json");
34
+ if (existsSync(f)) return f;
35
+ }
36
+ let best = null, bestTs = -1;
37
+ try {
38
+ for (const name of readdirSync(dir)) {
39
+ if (name.startsWith(".policy-cache-") && name.endsWith(".json")) {
40
+ const full = resolve(dir, name);
41
+ const ts = statSync(full).mtimeMs;
42
+ if (ts > bestTs) {
43
+ bestTs = ts;
44
+ best = full;
45
+ }
46
+ }
47
+ }
48
+ } catch {
49
+ }
50
+ return best;
51
+ }
29
52
  function loadCfg() {
30
53
  try {
31
- const sel = (process.env.SOLONGATE_AGENT_ID || "default").replace(/[^a-zA-Z0-9_-]/g, "_");
32
- const f = resolve(homedir(), ".solongate", ".policy-cache-" + sel + ".json");
33
- if (existsSync(f)) {
54
+ const f = findCacheFile();
55
+ if (f && existsSync(f)) {
34
56
  const c = JSON.parse(readFileSync(f, "utf-8"));
35
57
  const d = c?.security?.dlpRedact;
36
58
  if (d && Array.isArray(d.patterns)) return { patterns: d.patterns, custom: Array.isArray(d.custom) ? d.custom : [] };
package/hooks/shield.mjs CHANGED
@@ -17,7 +17,7 @@
17
17
  import { createServer, request as httpRequest } from 'node:http';
18
18
  import { request as httpsRequest } from 'node:https';
19
19
  import { spawn } from 'node:child_process';
20
- import { readFileSync, existsSync } from 'node:fs';
20
+ import { readFileSync, existsSync, readdirSync, statSync } from 'node:fs';
21
21
  import { resolve } from 'node:path';
22
22
  import { homedir } from 'node:os';
23
23
 
@@ -42,11 +42,35 @@ const DLP_PATTERNS = [
42
42
  { name: 'secret assignment', re: /(api[_-]?key|secret|token|password|passwd|access[_-]?key)["']?\s*[:=]\s*["']?[A-Za-z0-9/+_.-]{12,}/gi },
43
43
  ];
44
44
 
45
+ // Find the policy cache to read. The guard writes one per agent
46
+ // (.policy-cache-<agent>.json) - the shield wraps `claude` and doesn't know the
47
+ // agent id, so unless SOLONGATE_AGENT_ID is set it picks the MOST RECENTLY
48
+ // written cache (the active session's). A fixed 'default' missed the guard's
49
+ // real cache, so custom patterns never reached the shield.
50
+ function findCacheFile() {
51
+ const dir = resolve(homedir(), '.solongate');
52
+ const envSel = process.env.SOLONGATE_AGENT_ID;
53
+ if (envSel) {
54
+ const f = resolve(dir, '.policy-cache-' + envSel.replace(/[^a-zA-Z0-9_-]/g, '_') + '.json');
55
+ if (existsSync(f)) return f;
56
+ }
57
+ let best = null, bestTs = -1;
58
+ try {
59
+ for (const name of readdirSync(dir)) {
60
+ if (name.startsWith('.policy-cache-') && name.endsWith('.json')) {
61
+ const full = resolve(dir, name);
62
+ const ts = statSync(full).mtimeMs;
63
+ if (ts > bestTs) { bestTs = ts; best = full; }
64
+ }
65
+ }
66
+ } catch { /* dir missing */ }
67
+ return best;
68
+ }
69
+
45
70
  function loadCfg() {
46
71
  try {
47
- const sel = (process.env.SOLONGATE_AGENT_ID || 'default').replace(/[^a-zA-Z0-9_-]/g, '_');
48
- const f = resolve(homedir(), '.solongate', '.policy-cache-' + sel + '.json');
49
- if (existsSync(f)) {
72
+ const f = findCacheFile();
73
+ if (f && existsSync(f)) {
50
74
  const c = JSON.parse(readFileSync(f, 'utf-8'));
51
75
  const d = c && c.security && c.security.dlpRedact;
52
76
  if (d && Array.isArray(d.patterns)) return { patterns: d.patterns, custom: Array.isArray(d.custom) ? d.custom : [] };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.55.0",
3
+ "version": "0.56.0",
4
4
  "description": "AI tool security proxy — protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
5
5
  "type": "module",
6
6
  "bin": {