@solongate/proxy 0.81.85 → 0.81.87
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 +9 -15
- package/dist/self-update.d.ts +0 -3
- package/dist/tui/index.js +9 -11
- package/hooks/guard.bundled.mjs +28 -3
- package/hooks/guard.mjs +30 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6663,17 +6663,15 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
6663
6663
|
const state = readState();
|
|
6664
6664
|
if (latest) writeState({ ...state, lastCheckAt: Date.now(), latestSeen: latest });
|
|
6665
6665
|
if (!latest || !newerThan(latest, current)) return;
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
}
|
|
6666
|
+
if (readState().installed === latest) {
|
|
6667
|
+
onStatus({ kind: "updated", version: latest });
|
|
6668
|
+
return;
|
|
6669
|
+
}
|
|
6670
|
+
onStatus({ kind: "updating", version: latest });
|
|
6671
|
+
if (await runGlobalInstall(latest)) {
|
|
6672
|
+
writeState({ ...readState(), installed: latest });
|
|
6673
|
+
onStatus({ kind: "updated", version: latest });
|
|
6675
6674
|
}
|
|
6676
|
-
onStatus({ kind: "manual", version: latest });
|
|
6677
6675
|
} catch {
|
|
6678
6676
|
}
|
|
6679
6677
|
}
|
|
@@ -6695,12 +6693,8 @@ function maybeSelfUpdate(notify = (l) => process.stderr.write(l + "\n")) {
|
|
|
6695
6693
|
writeState({ ...readState(), attempts: { [latest]: now } });
|
|
6696
6694
|
if (spawnGlobalInstall(latest)) {
|
|
6697
6695
|
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 updating in the background, next run uses it${c.reset}`);
|
|
6698
|
-
return;
|
|
6699
6696
|
}
|
|
6700
|
-
} else {
|
|
6701
|
-
return;
|
|
6702
6697
|
}
|
|
6703
|
-
notify(`${c.dim}\u2191 solongate v${latest} available (running v${current}) \u2014 update: ${c.reset}${c.cyan}npm i -g ${PKG}@latest${c.reset}`);
|
|
6704
6698
|
} catch {
|
|
6705
6699
|
}
|
|
6706
6700
|
})();
|
|
@@ -11072,7 +11066,7 @@ function App() {
|
|
|
11072
11066
|
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "account: " }),
|
|
11073
11067
|
/* @__PURE__ */ jsx8(Text8, { color: locked ? theme.warn : theme.accentBright, bold: true, children: acctLabel2 }),
|
|
11074
11068
|
locked ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 log in from Settings to unlock the dataroom" }) : accounts.length > 1 ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: ` (${acctIdx + 1}/${accounts.length} \xB7 a switch \xB7 Settings to manage)` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 Settings to add another" }),
|
|
11075
|
-
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) :
|
|
11069
|
+
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) : null
|
|
11076
11070
|
] }),
|
|
11077
11071
|
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexGrow: 1, children: [
|
|
11078
11072
|
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", flexShrink: 0, width: 16, borderStyle: "round", borderColor: focus === "nav" ? theme.accent : "gray", paddingX: 1, children: SECTIONS.map((s, i) => {
|
package/dist/self-update.d.ts
CHANGED
package/dist/tui/index.js
CHANGED
|
@@ -4138,17 +4138,15 @@ async function tuiUpdateFlow(onStatus) {
|
|
|
4138
4138
|
const state = readState2();
|
|
4139
4139
|
if (latest) writeState2({ ...state, lastCheckAt: Date.now(), latestSeen: latest });
|
|
4140
4140
|
if (!latest || !newerThan(latest, current)) return;
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
}
|
|
4141
|
+
if (readState2().installed === latest) {
|
|
4142
|
+
onStatus({ kind: "updated", version: latest });
|
|
4143
|
+
return;
|
|
4144
|
+
}
|
|
4145
|
+
onStatus({ kind: "updating", version: latest });
|
|
4146
|
+
if (await runGlobalInstall(latest)) {
|
|
4147
|
+
writeState2({ ...readState2(), installed: latest });
|
|
4148
|
+
onStatus({ kind: "updated", version: latest });
|
|
4150
4149
|
}
|
|
4151
|
-
onStatus({ kind: "manual", version: latest });
|
|
4152
4150
|
} catch {
|
|
4153
4151
|
}
|
|
4154
4152
|
}
|
|
@@ -4292,7 +4290,7 @@ function App() {
|
|
|
4292
4290
|
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "account: " }),
|
|
4293
4291
|
/* @__PURE__ */ jsx8(Text8, { color: locked ? theme.warn : theme.accentBright, bold: true, children: acctLabel2 }),
|
|
4294
4292
|
locked ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 log in from Settings to unlock the dataroom" }) : accounts.length > 1 ? /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: ` (${acctIdx + 1}/${accounts.length} \xB7 a switch \xB7 Settings to manage)` }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: " \xB7 Settings to add another" }),
|
|
4295
|
-
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) :
|
|
4293
|
+
update2.kind === "updating" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 updating to v${update2.version}\u2026` }) : update2.kind === "updated" ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, bold: true, children: ` \u2191 v${update2.version} installed \u2014 restart (q, then solongate) to apply` }) : null
|
|
4296
4294
|
] }),
|
|
4297
4295
|
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexGrow: 1, children: [
|
|
4298
4296
|
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", flexShrink: 0, width: 16, borderStyle: "round", borderColor: focus === "nav" ? theme.accent : "gray", paddingX: 1, children: SECTIONS.map((s, i) => {
|
package/hooks/guard.bundled.mjs
CHANGED
|
@@ -6536,7 +6536,7 @@ import { resolve, join, dirname, isAbsolute } from "node:path";
|
|
|
6536
6536
|
import { homedir } from "node:os";
|
|
6537
6537
|
import { gunzipSync } from "node:zlib";
|
|
6538
6538
|
import { createHash } from "node:crypto";
|
|
6539
|
-
var HOOK_VERSION =
|
|
6539
|
+
var HOOK_VERSION = 43;
|
|
6540
6540
|
function localLogsOnly(security) {
|
|
6541
6541
|
if (security && typeof security === "object") {
|
|
6542
6542
|
const l = security.localLogs;
|
|
@@ -7180,6 +7180,29 @@ function dlpGlobToRe(glob) {
|
|
|
7180
7180
|
}
|
|
7181
7181
|
return new RegExp(re, "i");
|
|
7182
7182
|
}
|
|
7183
|
+
function dlpViews(text) {
|
|
7184
|
+
const views = [text];
|
|
7185
|
+
try {
|
|
7186
|
+
const dequoted = text.replace(/[`'"\\]/g, "");
|
|
7187
|
+
if (dequoted !== text)
|
|
7188
|
+
views.push(dequoted);
|
|
7189
|
+
const src = dequoted !== text ? text + "\n" + dequoted : text;
|
|
7190
|
+
const toks = src.match(/[A-Za-z0-9+/]{16,}={0,2}/g) || [];
|
|
7191
|
+
let decoded = "";
|
|
7192
|
+
for (const t of toks.slice(0, 60)) {
|
|
7193
|
+
try {
|
|
7194
|
+
const d = Buffer.from(t, "base64").toString("latin1");
|
|
7195
|
+
if (/[ -~]{8,}/.test(d))
|
|
7196
|
+
decoded += d + "\n";
|
|
7197
|
+
} catch {
|
|
7198
|
+
}
|
|
7199
|
+
}
|
|
7200
|
+
if (decoded)
|
|
7201
|
+
views.push(decoded);
|
|
7202
|
+
} catch {
|
|
7203
|
+
}
|
|
7204
|
+
return views;
|
|
7205
|
+
}
|
|
7183
7206
|
function dlpScan(args, cfg) {
|
|
7184
7207
|
if (!cfg)
|
|
7185
7208
|
return null;
|
|
@@ -7189,14 +7212,16 @@ function dlpScan(args, cfg) {
|
|
|
7189
7212
|
} catch {
|
|
7190
7213
|
return null;
|
|
7191
7214
|
}
|
|
7215
|
+
const views = dlpViews(text);
|
|
7192
7216
|
const allow = new Set(Array.isArray(cfg.patterns) ? cfg.patterns : []);
|
|
7193
7217
|
for (const p of DLP_PATTERNS) {
|
|
7194
|
-
if (allow.has(p.name) && p.re.test(
|
|
7218
|
+
if (allow.has(p.name) && views.some((v) => p.re.test(v)))
|
|
7195
7219
|
return p.name;
|
|
7196
7220
|
}
|
|
7197
7221
|
for (const c of Array.isArray(cfg.custom) ? cfg.custom : []) {
|
|
7198
7222
|
try {
|
|
7199
|
-
|
|
7223
|
+
const re = dlpGlobToRe(c.re);
|
|
7224
|
+
if (views.some((v) => re.test(v)))
|
|
7200
7225
|
return c.name || "custom pattern";
|
|
7201
7226
|
} catch {
|
|
7202
7227
|
}
|
package/hooks/guard.mjs
CHANGED
|
@@ -32,7 +32,7 @@ import { createHash } from 'node:crypto';
|
|
|
32
32
|
// the installed hook self-updates when the cloud version is higher (see
|
|
33
33
|
// maybeSelfUpdate). This is what makes guard fixes propagate without a manual
|
|
34
34
|
// reinstall — the same trust model as the OPA WASM this hook already runs.
|
|
35
|
-
const HOOK_VERSION =
|
|
35
|
+
const HOOK_VERSION = 43;
|
|
36
36
|
|
|
37
37
|
// True when local log storage is ON. In that mode logs are kept LOCAL ONLY and
|
|
38
38
|
// nothing is sent to the cloud audit log.
|
|
@@ -900,18 +900,45 @@ function dlpGlobToRe(glob) {
|
|
|
900
900
|
}
|
|
901
901
|
return new RegExp(re, 'i');
|
|
902
902
|
}
|
|
903
|
+
// De-obfuscated VIEWS of the scanned text, so an agent can't smuggle a secret
|
|
904
|
+
// past the literal patterns by SPLITTING it (printf "AKIA""3XZ9…") or ENCODING it
|
|
905
|
+
// (echo <base64> | base64 -d). We scan every view. Not exhaustive — pattern DLP
|
|
906
|
+
// can never be — but it closes the two obvious bypasses.
|
|
907
|
+
function dlpViews(text) {
|
|
908
|
+
const views = [text];
|
|
909
|
+
try {
|
|
910
|
+
// 1) Drop shell quotes + backslashes so a split secret collapses back to a
|
|
911
|
+
// contiguous run: "AKIA""3XZ9…" / 'AKIA'\''…' / AKIA\3XZ9 → AKIA3XZ9…
|
|
912
|
+
const dequoted = text.replace(/[`'"\\]/g, '');
|
|
913
|
+
if (dequoted !== text) views.push(dequoted);
|
|
914
|
+
// 2) Decode base64-looking tokens (from both the raw and the dequoted view —
|
|
915
|
+
// the payload itself may be split too) and scan the decoded bytes.
|
|
916
|
+
const src = dequoted !== text ? text + '\n' + dequoted : text;
|
|
917
|
+
const toks = src.match(/[A-Za-z0-9+/]{16,}={0,2}/g) || [];
|
|
918
|
+
let decoded = '';
|
|
919
|
+
for (const t of toks.slice(0, 60)) {
|
|
920
|
+
try {
|
|
921
|
+
const d = Buffer.from(t, 'base64').toString('latin1');
|
|
922
|
+
if (/[ -~]{8,}/.test(d)) decoded += d + '\n'; // keep printable decodes only
|
|
923
|
+
} catch { /* not base64 */ }
|
|
924
|
+
}
|
|
925
|
+
if (decoded) views.push(decoded);
|
|
926
|
+
} catch { /* fall back to the raw view */ }
|
|
927
|
+
return views;
|
|
928
|
+
}
|
|
903
929
|
// Scan args against the enabled built-in patterns + any user custom patterns.
|
|
904
930
|
// `cfg` = { patterns: string[], custom: {name,re}[] }.
|
|
905
931
|
function dlpScan(args, cfg) {
|
|
906
932
|
if (!cfg) return null;
|
|
907
933
|
let text = '';
|
|
908
934
|
try { text = JSON.stringify(args || {}); } catch { return null; }
|
|
935
|
+
const views = dlpViews(text);
|
|
909
936
|
const allow = new Set(Array.isArray(cfg.patterns) ? cfg.patterns : []);
|
|
910
937
|
for (const p of DLP_PATTERNS) {
|
|
911
|
-
if (allow.has(p.name) && p.re.test(
|
|
938
|
+
if (allow.has(p.name) && views.some((v) => p.re.test(v))) return p.name;
|
|
912
939
|
}
|
|
913
940
|
for (const c of Array.isArray(cfg.custom) ? cfg.custom : []) {
|
|
914
|
-
try {
|
|
941
|
+
try { const re = dlpGlobToRe(c.re); if (views.some((v) => re.test(v))) return c.name || 'custom pattern'; } catch { /* skip invalid */ }
|
|
915
942
|
}
|
|
916
943
|
return null;
|
|
917
944
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.87",
|
|
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": {
|