@solongate/proxy 0.6.2 → 0.6.3
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 +12 -14
- package/dist/init.js +12 -14
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -985,17 +985,13 @@ function matchGlob(str, pattern) {
|
|
|
985
985
|
|
|
986
986
|
// \u2500\u2500 Path Glob (supports **) \u2500\u2500
|
|
987
987
|
function matchPathGlob(path, pattern) {
|
|
988
|
-
const p = path.replace(
|
|
989
|
-
const g = pattern.replace(
|
|
988
|
+
const p = path.replace(/\\\\/g, '/').toLowerCase();
|
|
989
|
+
const g = pattern.replace(/\\\\/g, '/').toLowerCase();
|
|
990
990
|
if (p === g) return true;
|
|
991
991
|
if (g.includes('**')) {
|
|
992
|
-
const parts = g.split('**');
|
|
993
|
-
if (parts.length ===
|
|
994
|
-
|
|
995
|
-
const matchPre = !pre || p.startsWith(pre) || p.includes(pre);
|
|
996
|
-
const matchSuf = !suf || p.endsWith(suf) || p.includes(suf.slice(1));
|
|
997
|
-
return matchPre && matchSuf;
|
|
998
|
-
}
|
|
992
|
+
const parts = g.split('**').filter(s => s.length > 0);
|
|
993
|
+
if (parts.length === 0) return true; // just ** or ****
|
|
994
|
+
return parts.every(segment => p.includes(segment));
|
|
999
995
|
}
|
|
1000
996
|
return matchGlob(p, g);
|
|
1001
997
|
}
|
|
@@ -1024,14 +1020,14 @@ function extractFilenames(args) {
|
|
|
1024
1020
|
for (const s of scanStrings(args)) {
|
|
1025
1021
|
if (/^https?:\\/\\//i.test(s)) continue;
|
|
1026
1022
|
if (s.includes('/') || s.includes('\\\\')) {
|
|
1027
|
-
const base = s.replace(
|
|
1023
|
+
const base = s.replace(/\\\\/g, '/').split('/').pop();
|
|
1028
1024
|
if (base) names.add(base);
|
|
1029
1025
|
continue;
|
|
1030
1026
|
}
|
|
1031
1027
|
if (s.includes(' ')) {
|
|
1032
1028
|
for (const tok of s.split(/\\s+/)) {
|
|
1033
1029
|
if (tok.includes('/') || tok.includes('\\\\')) {
|
|
1034
|
-
const b = tok.replace(
|
|
1030
|
+
const b = tok.replace(/\\\\/g, '/').split('/').pop();
|
|
1035
1031
|
if (b && looksLikeFilename(b)) names.add(b);
|
|
1036
1032
|
} else if (looksLikeFilename(tok)) names.add(tok);
|
|
1037
1033
|
}
|
|
@@ -1132,7 +1128,7 @@ process.stdin.on('end', async () => {
|
|
|
1132
1128
|
const args = data.tool_input || {};
|
|
1133
1129
|
|
|
1134
1130
|
// \u2500\u2500 Self-protection: block access to hook files and settings \u2500\u2500
|
|
1135
|
-
const allStrings = scanStrings(args).map(s => s.replace(
|
|
1131
|
+
const allStrings = scanStrings(args).map(s => s.replace(/\\\\/g, '/').toLowerCase());
|
|
1136
1132
|
const protectedPaths = ['.solongate', '.claude/settings.json', '.cursor/settings.json', 'policy.json'];
|
|
1137
1133
|
for (const s of allStrings) {
|
|
1138
1134
|
for (const p of protectedPaths) {
|
|
@@ -1144,10 +1140,12 @@ process.stdin.on('end', async () => {
|
|
|
1144
1140
|
}
|
|
1145
1141
|
}
|
|
1146
1142
|
|
|
1147
|
-
// Load policy
|
|
1143
|
+
// Load policy (use cwd from hook data if available)
|
|
1144
|
+
const hookCwd = data.cwd || process.cwd();
|
|
1148
1145
|
let policy;
|
|
1149
1146
|
try {
|
|
1150
|
-
|
|
1147
|
+
const policyPath = resolve(hookCwd, 'policy.json');
|
|
1148
|
+
policy = JSON.parse(readFileSync(policyPath, 'utf-8'));
|
|
1151
1149
|
} catch {
|
|
1152
1150
|
process.exit(0); // No policy = allow all
|
|
1153
1151
|
}
|
package/dist/init.js
CHANGED
|
@@ -174,17 +174,13 @@ function matchGlob(str, pattern) {
|
|
|
174
174
|
|
|
175
175
|
// \u2500\u2500 Path Glob (supports **) \u2500\u2500
|
|
176
176
|
function matchPathGlob(path, pattern) {
|
|
177
|
-
const p = path.replace(
|
|
178
|
-
const g = pattern.replace(
|
|
177
|
+
const p = path.replace(/\\\\/g, '/').toLowerCase();
|
|
178
|
+
const g = pattern.replace(/\\\\/g, '/').toLowerCase();
|
|
179
179
|
if (p === g) return true;
|
|
180
180
|
if (g.includes('**')) {
|
|
181
|
-
const parts = g.split('**');
|
|
182
|
-
if (parts.length ===
|
|
183
|
-
|
|
184
|
-
const matchPre = !pre || p.startsWith(pre) || p.includes(pre);
|
|
185
|
-
const matchSuf = !suf || p.endsWith(suf) || p.includes(suf.slice(1));
|
|
186
|
-
return matchPre && matchSuf;
|
|
187
|
-
}
|
|
181
|
+
const parts = g.split('**').filter(s => s.length > 0);
|
|
182
|
+
if (parts.length === 0) return true; // just ** or ****
|
|
183
|
+
return parts.every(segment => p.includes(segment));
|
|
188
184
|
}
|
|
189
185
|
return matchGlob(p, g);
|
|
190
186
|
}
|
|
@@ -213,14 +209,14 @@ function extractFilenames(args) {
|
|
|
213
209
|
for (const s of scanStrings(args)) {
|
|
214
210
|
if (/^https?:\\/\\//i.test(s)) continue;
|
|
215
211
|
if (s.includes('/') || s.includes('\\\\')) {
|
|
216
|
-
const base = s.replace(
|
|
212
|
+
const base = s.replace(/\\\\/g, '/').split('/').pop();
|
|
217
213
|
if (base) names.add(base);
|
|
218
214
|
continue;
|
|
219
215
|
}
|
|
220
216
|
if (s.includes(' ')) {
|
|
221
217
|
for (const tok of s.split(/\\s+/)) {
|
|
222
218
|
if (tok.includes('/') || tok.includes('\\\\')) {
|
|
223
|
-
const b = tok.replace(
|
|
219
|
+
const b = tok.replace(/\\\\/g, '/').split('/').pop();
|
|
224
220
|
if (b && looksLikeFilename(b)) names.add(b);
|
|
225
221
|
} else if (looksLikeFilename(tok)) names.add(tok);
|
|
226
222
|
}
|
|
@@ -321,7 +317,7 @@ process.stdin.on('end', async () => {
|
|
|
321
317
|
const args = data.tool_input || {};
|
|
322
318
|
|
|
323
319
|
// \u2500\u2500 Self-protection: block access to hook files and settings \u2500\u2500
|
|
324
|
-
const allStrings = scanStrings(args).map(s => s.replace(
|
|
320
|
+
const allStrings = scanStrings(args).map(s => s.replace(/\\\\/g, '/').toLowerCase());
|
|
325
321
|
const protectedPaths = ['.solongate', '.claude/settings.json', '.cursor/settings.json', 'policy.json'];
|
|
326
322
|
for (const s of allStrings) {
|
|
327
323
|
for (const p of protectedPaths) {
|
|
@@ -333,10 +329,12 @@ process.stdin.on('end', async () => {
|
|
|
333
329
|
}
|
|
334
330
|
}
|
|
335
331
|
|
|
336
|
-
// Load policy
|
|
332
|
+
// Load policy (use cwd from hook data if available)
|
|
333
|
+
const hookCwd = data.cwd || process.cwd();
|
|
337
334
|
let policy;
|
|
338
335
|
try {
|
|
339
|
-
|
|
336
|
+
const policyPath = resolve(hookCwd, 'policy.json');
|
|
337
|
+
policy = JSON.parse(readFileSync(policyPath, 'utf-8'));
|
|
340
338
|
} catch {
|
|
341
339
|
process.exit(0); // No policy = allow all
|
|
342
340
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "MCP security proxy — protect any MCP server with customizable policies, path/command constraints, rate limiting, and audit logging. Zero code changes required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|