@solongate/proxy 0.52.0 → 0.54.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/global-install.js +4 -0
- package/dist/index.js +14 -1
- package/dist/login.js +4 -0
- package/dist/shield.js +10 -1
- package/hooks/audit.mjs +12 -1
- package/hooks/guard.bundled.mjs +14 -2
- package/hooks/guard.mjs +13 -2
- package/hooks/shield.mjs +11 -1
- package/package.json +1 -1
package/dist/global-install.js
CHANGED
|
@@ -138,6 +138,10 @@ function resolveRealClaude() {
|
|
|
138
138
|
try {
|
|
139
139
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
140
140
|
const out = execFileSync(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
141
|
+
if (process.platform === "win32") {
|
|
142
|
+
const low = (s) => s.toLowerCase();
|
|
143
|
+
return out.find((l) => low(l).endsWith(".cmd")) || out.find((l) => low(l).endsWith(".exe")) || out.find((l) => low(l).endsWith(".bat")) || out[0] || null;
|
|
144
|
+
}
|
|
141
145
|
return out[0] || null;
|
|
142
146
|
} catch {
|
|
143
147
|
return null;
|
package/dist/index.js
CHANGED
|
@@ -6715,6 +6715,10 @@ function resolveRealClaude() {
|
|
|
6715
6715
|
try {
|
|
6716
6716
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
6717
6717
|
const out = execFileSync2(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
6718
|
+
if (process.platform === "win32") {
|
|
6719
|
+
const low = (s) => s.toLowerCase();
|
|
6720
|
+
return out.find((l) => low(l).endsWith(".cmd")) || out.find((l) => low(l).endsWith(".exe")) || out.find((l) => low(l).endsWith(".bat")) || out[0] || null;
|
|
6721
|
+
}
|
|
6718
6722
|
return out[0] || null;
|
|
6719
6723
|
} catch {
|
|
6720
6724
|
return null;
|
|
@@ -7029,6 +7033,15 @@ function loadCfg() {
|
|
|
7029
7033
|
}
|
|
7030
7034
|
return { patterns: DLP_PATTERNS.map((p) => p.name), custom: [] };
|
|
7031
7035
|
}
|
|
7036
|
+
function dlpGlobToRe(glob, flags) {
|
|
7037
|
+
let re = "";
|
|
7038
|
+
for (const ch of String(glob || "")) {
|
|
7039
|
+
if (ch === "*") re += "[^\\s]*";
|
|
7040
|
+
else if (".+?^${}()|[]\\".indexOf(ch) !== -1) re += "\\" + ch;
|
|
7041
|
+
else re += ch;
|
|
7042
|
+
}
|
|
7043
|
+
return new RegExp(re, flags);
|
|
7044
|
+
}
|
|
7032
7045
|
function redactString(s, cfg) {
|
|
7033
7046
|
if (!cfg || typeof s !== "string" || !s) return s;
|
|
7034
7047
|
const allow = new Set(cfg.patterns);
|
|
@@ -7036,7 +7049,7 @@ function redactString(s, cfg) {
|
|
|
7036
7049
|
for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, `[REDACTED: ${p.name}]`);
|
|
7037
7050
|
for (const c3 of cfg.custom) {
|
|
7038
7051
|
try {
|
|
7039
|
-
out = out.replace(
|
|
7052
|
+
out = out.replace(dlpGlobToRe(c3.re, "g"), `[REDACTED: ${c3.name || "custom"}]`);
|
|
7040
7053
|
} catch {
|
|
7041
7054
|
}
|
|
7042
7055
|
}
|
package/dist/login.js
CHANGED
|
@@ -145,6 +145,10 @@ function resolveRealClaude() {
|
|
|
145
145
|
try {
|
|
146
146
|
const finder = process.platform === "win32" ? "where" : "which";
|
|
147
147
|
const out = execFileSync(finder, ["claude"], { encoding: "utf-8" }).split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
148
|
+
if (process.platform === "win32") {
|
|
149
|
+
const low = (s) => s.toLowerCase();
|
|
150
|
+
return out.find((l) => low(l).endsWith(".cmd")) || out.find((l) => low(l).endsWith(".exe")) || out.find((l) => low(l).endsWith(".bat")) || out[0] || null;
|
|
151
|
+
}
|
|
148
152
|
return out[0] || null;
|
|
149
153
|
} catch {
|
|
150
154
|
return null;
|
package/dist/shield.js
CHANGED
|
@@ -39,6 +39,15 @@ function loadCfg() {
|
|
|
39
39
|
}
|
|
40
40
|
return { patterns: DLP_PATTERNS.map((p) => p.name), custom: [] };
|
|
41
41
|
}
|
|
42
|
+
function dlpGlobToRe(glob, flags) {
|
|
43
|
+
let re = "";
|
|
44
|
+
for (const ch of String(glob || "")) {
|
|
45
|
+
if (ch === "*") re += "[^\\s]*";
|
|
46
|
+
else if (".+?^${}()|[]\\".indexOf(ch) !== -1) re += "\\" + ch;
|
|
47
|
+
else re += ch;
|
|
48
|
+
}
|
|
49
|
+
return new RegExp(re, flags);
|
|
50
|
+
}
|
|
42
51
|
function redactString(s, cfg) {
|
|
43
52
|
if (!cfg || typeof s !== "string" || !s) return s;
|
|
44
53
|
const allow = new Set(cfg.patterns);
|
|
@@ -46,7 +55,7 @@ function redactString(s, cfg) {
|
|
|
46
55
|
for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, `[REDACTED: ${p.name}]`);
|
|
47
56
|
for (const c of cfg.custom) {
|
|
48
57
|
try {
|
|
49
|
-
out = out.replace(
|
|
58
|
+
out = out.replace(dlpGlobToRe(c.re, "g"), `[REDACTED: ${c.name || "custom"}]`);
|
|
50
59
|
} catch {
|
|
51
60
|
}
|
|
52
61
|
}
|
package/hooks/audit.mjs
CHANGED
|
@@ -206,6 +206,17 @@ function loadDlpRedact() {
|
|
|
206
206
|
|
|
207
207
|
// Replace every secret match with a labelled placeholder. cfg = { patterns:
|
|
208
208
|
// string[] (enabled built-in names), custom: {name,re}[] }.
|
|
209
|
+
// Custom patterns are GLOBs: `*` = any run of non-whitespace (so a fragment
|
|
210
|
+
// matches a whole token), same wildcard mechanic as policy/ghost.
|
|
211
|
+
function dlpGlobToRe(glob, flags) {
|
|
212
|
+
let re = '';
|
|
213
|
+
for (const ch of String(glob || '')) {
|
|
214
|
+
if (ch === '*') re += '[^\\s]*';
|
|
215
|
+
else if ('.+?^${}()|[]\\'.indexOf(ch) !== -1) re += '\\' + ch;
|
|
216
|
+
else re += ch;
|
|
217
|
+
}
|
|
218
|
+
return new RegExp(re, flags);
|
|
219
|
+
}
|
|
209
220
|
function dlpRedactText(text, cfg) {
|
|
210
221
|
if (!cfg || typeof text !== 'string' || !text) return text;
|
|
211
222
|
const allow = new Set(Array.isArray(cfg.patterns) ? cfg.patterns : []);
|
|
@@ -214,7 +225,7 @@ function dlpRedactText(text, cfg) {
|
|
|
214
225
|
if (allow.has(p.name)) out = out.replace(p.re, '[REDACTED:' + p.name + ']');
|
|
215
226
|
}
|
|
216
227
|
for (const c of Array.isArray(cfg.custom) ? cfg.custom : []) {
|
|
217
|
-
try { out = out.replace(
|
|
228
|
+
try { out = out.replace(dlpGlobToRe(c.re, 'g'), '[REDACTED:' + (c.name || 'custom') + ']'); } catch { /* skip invalid */ }
|
|
218
229
|
}
|
|
219
230
|
return out;
|
|
220
231
|
}
|
package/hooks/guard.bundled.mjs
CHANGED
|
@@ -6535,7 +6535,7 @@ import { resolve, join } from "node:path";
|
|
|
6535
6535
|
import { homedir } from "node:os";
|
|
6536
6536
|
import { gunzipSync } from "node:zlib";
|
|
6537
6537
|
import { createHash } from "node:crypto";
|
|
6538
|
-
var HOOK_VERSION =
|
|
6538
|
+
var HOOK_VERSION = 19;
|
|
6539
6539
|
var MAX_FILE_READ = 1024 * 1024;
|
|
6540
6540
|
function safeReadFileSync(filePath, encoding = "utf-8") {
|
|
6541
6541
|
try {
|
|
@@ -7010,6 +7010,18 @@ var DLP_PATTERNS = [
|
|
|
7010
7010
|
{ name: "Bearer token", re: /bearer\s+[A-Za-z0-9._-]{20,}/i },
|
|
7011
7011
|
{ name: "secret assignment", re: /(api[_-]?key|secret|token|password|passwd|access[_-]?key)["']?\s*[:=]\s*["']?[A-Za-z0-9/+_.-]{12,}/i }
|
|
7012
7012
|
];
|
|
7013
|
+
function dlpGlobToRe(glob) {
|
|
7014
|
+
let re = "";
|
|
7015
|
+
for (const ch of String(glob || "")) {
|
|
7016
|
+
if (ch === "*")
|
|
7017
|
+
re += "[^\\s]*";
|
|
7018
|
+
else if (".+?^${}()|[]\\".indexOf(ch) !== -1)
|
|
7019
|
+
re += "\\" + ch;
|
|
7020
|
+
else
|
|
7021
|
+
re += ch;
|
|
7022
|
+
}
|
|
7023
|
+
return new RegExp(re);
|
|
7024
|
+
}
|
|
7013
7025
|
function dlpScan(args, cfg) {
|
|
7014
7026
|
if (!cfg)
|
|
7015
7027
|
return null;
|
|
@@ -7026,7 +7038,7 @@ function dlpScan(args, cfg) {
|
|
|
7026
7038
|
}
|
|
7027
7039
|
for (const c of Array.isArray(cfg.custom) ? cfg.custom : []) {
|
|
7028
7040
|
try {
|
|
7029
|
-
if (
|
|
7041
|
+
if (dlpGlobToRe(c.re).test(text))
|
|
7030
7042
|
return c.name || "custom pattern";
|
|
7031
7043
|
} catch {
|
|
7032
7044
|
}
|
package/hooks/guard.mjs
CHANGED
|
@@ -31,7 +31,7 @@ import { createHash } from 'node:crypto';
|
|
|
31
31
|
// the installed hook self-updates when the cloud version is higher (see
|
|
32
32
|
// maybeSelfUpdate). This is what makes guard fixes propagate without a manual
|
|
33
33
|
// reinstall — the same trust model as the OPA WASM this hook already runs.
|
|
34
|
-
const HOOK_VERSION =
|
|
34
|
+
const HOOK_VERSION = 19;
|
|
35
35
|
|
|
36
36
|
// Safe file read with size limit (1MB max) to prevent DoS via large files
|
|
37
37
|
const MAX_FILE_READ = 1024 * 1024; // 1MB
|
|
@@ -665,6 +665,17 @@ const DLP_PATTERNS = [
|
|
|
665
665
|
{ name: 'secret assignment', re: /(api[_-]?key|secret|token|password|passwd|access[_-]?key)["']?\s*[:=]\s*["']?[A-Za-z0-9/+_.-]{12,}/i },
|
|
666
666
|
];
|
|
667
667
|
|
|
668
|
+
// Custom patterns are GLOBs: `*` = any run of non-whitespace, same wildcard
|
|
669
|
+
// mechanic as policy/ghost.
|
|
670
|
+
function dlpGlobToRe(glob) {
|
|
671
|
+
let re = '';
|
|
672
|
+
for (const ch of String(glob || '')) {
|
|
673
|
+
if (ch === '*') re += '[^\\s]*';
|
|
674
|
+
else if ('.+?^${}()|[]\\'.indexOf(ch) !== -1) re += '\\' + ch;
|
|
675
|
+
else re += ch;
|
|
676
|
+
}
|
|
677
|
+
return new RegExp(re);
|
|
678
|
+
}
|
|
668
679
|
// Scan args against the enabled built-in patterns + any user custom patterns.
|
|
669
680
|
// `cfg` = { patterns: string[], custom: {name,re}[] }.
|
|
670
681
|
function dlpScan(args, cfg) {
|
|
@@ -676,7 +687,7 @@ function dlpScan(args, cfg) {
|
|
|
676
687
|
if (allow.has(p.name) && p.re.test(text)) return p.name;
|
|
677
688
|
}
|
|
678
689
|
for (const c of Array.isArray(cfg.custom) ? cfg.custom : []) {
|
|
679
|
-
try { if (
|
|
690
|
+
try { if (dlpGlobToRe(c.re).test(text)) return c.name || 'custom pattern'; } catch { /* skip invalid */ }
|
|
680
691
|
}
|
|
681
692
|
return null;
|
|
682
693
|
}
|
package/hooks/shield.mjs
CHANGED
|
@@ -55,13 +55,23 @@ function loadCfg() {
|
|
|
55
55
|
return { patterns: DLP_PATTERNS.map((p) => p.name), custom: [] };
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// Custom patterns are GLOBs: `*` = any run of non-whitespace, same as policy/ghost.
|
|
59
|
+
function dlpGlobToRe(glob, flags) {
|
|
60
|
+
let re = '';
|
|
61
|
+
for (const ch of String(glob || '')) {
|
|
62
|
+
if (ch === '*') re += '[^\\s]*';
|
|
63
|
+
else if ('.+?^${}()|[]\\'.indexOf(ch) !== -1) re += '\\' + ch;
|
|
64
|
+
else re += ch;
|
|
65
|
+
}
|
|
66
|
+
return new RegExp(re, flags);
|
|
67
|
+
}
|
|
58
68
|
function redactString(s, cfg) {
|
|
59
69
|
if (!cfg || typeof s !== 'string' || !s) return s;
|
|
60
70
|
const allow = new Set(cfg.patterns);
|
|
61
71
|
let out = s;
|
|
62
72
|
for (const p of DLP_PATTERNS) if (allow.has(p.name)) out = out.replace(p.re, `[REDACTED: ${p.name}]`);
|
|
63
73
|
for (const c of cfg.custom) {
|
|
64
|
-
try { out = out.replace(
|
|
74
|
+
try { out = out.replace(dlpGlobToRe(c.re, 'g'), `[REDACTED: ${c.name || 'custom'}]`); } catch { /* skip */ }
|
|
65
75
|
}
|
|
66
76
|
return out;
|
|
67
77
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.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": {
|