@solongate/proxy 0.81.89 → 0.81.91
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/commands/index.js +1 -0
- package/dist/index.js +35 -7
- package/dist/tui/index.js +35 -7
- package/package.json +1 -1
package/dist/commands/index.js
CHANGED
|
@@ -134,6 +134,7 @@ async function request(method, path, opts = {}) {
|
|
|
134
134
|
}
|
|
135
135
|
if (res.status === 401) throw new ApiError(401, "AUTHENTICATION_ERROR", "Invalid API key. Run `solongate` and log in from the Accounts panel.");
|
|
136
136
|
if (res.status === 429) throw new ApiError(429, "RATE_LIMITED", "Rate limited by the API. Slow down and retry.");
|
|
137
|
+
if (res.status >= 500) throw new ApiError(res.status, "SERVER_ERROR", text || "SolonGate API had a problem (server error). Please try again in a moment.");
|
|
137
138
|
throw new ApiError(res.status, "ERROR", text || res.statusText || `HTTP ${res.status}`);
|
|
138
139
|
}
|
|
139
140
|
return json;
|
package/dist/index.js
CHANGED
|
@@ -7274,6 +7274,7 @@ async function request(method, path, opts = {}) {
|
|
|
7274
7274
|
}
|
|
7275
7275
|
if (res.status === 401) throw new ApiError(401, "AUTHENTICATION_ERROR", "Invalid API key. Run `solongate` and log in from the Accounts panel.");
|
|
7276
7276
|
if (res.status === 429) throw new ApiError(429, "RATE_LIMITED", "Rate limited by the API. Slow down and retry.");
|
|
7277
|
+
if (res.status >= 500) throw new ApiError(res.status, "SERVER_ERROR", text || "SolonGate API had a problem (server error). Please try again in a moment.");
|
|
7277
7278
|
throw new ApiError(res.status, "ERROR", text || res.statusText || `HTTP ${res.status}`);
|
|
7278
7279
|
}
|
|
7279
7280
|
return json;
|
|
@@ -8840,6 +8841,10 @@ function PoliciesPanel({ focused }) {
|
|
|
8840
8841
|
setRi(0);
|
|
8841
8842
|
}
|
|
8842
8843
|
}, [detail.data]);
|
|
8844
|
+
usePoll(() => {
|
|
8845
|
+
list6.reloadQuiet();
|
|
8846
|
+
activeQ.reloadQuiet();
|
|
8847
|
+
}, 6e3);
|
|
8843
8848
|
const mutate = (nextRules, nextMode = mode) => {
|
|
8844
8849
|
setRules(nextRules);
|
|
8845
8850
|
setMode(nextMode);
|
|
@@ -8876,6 +8881,13 @@ function PoliciesPanel({ focused }) {
|
|
|
8876
8881
|
};
|
|
8877
8882
|
useInput2(
|
|
8878
8883
|
(input, key) => {
|
|
8884
|
+
if (input === "r" && !editing) {
|
|
8885
|
+
list6.reload();
|
|
8886
|
+
activeQ.reload();
|
|
8887
|
+
detail.reload();
|
|
8888
|
+
setStatus("refreshed");
|
|
8889
|
+
return;
|
|
8890
|
+
}
|
|
8879
8891
|
if (view === "list") {
|
|
8880
8892
|
if (key.upArrow) setPi((n) => Math.max(0, n - 1));
|
|
8881
8893
|
else if (key.downArrow) setPi((n) => Math.min(policies.length - 1, n + 1));
|
|
@@ -8966,7 +8978,7 @@ function PoliciesPanel({ focused }) {
|
|
|
8966
8978
|
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: activeBy ? ` (${activeBy})` : "" })
|
|
8967
8979
|
] }) : /* @__PURE__ */ jsx3(Text3, { color: theme.bad, bold: true, children: "\u25CB NONE \u2014 nothing enforced, grants refused" })
|
|
8968
8980
|
] }),
|
|
8969
|
-
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate
|
|
8981
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate \xB7 r refresh" : "press \u2192 to browse" }),
|
|
8970
8982
|
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, flexDirection: "column", children: policies.map((p, i) => /* @__PURE__ */ jsxs3(Text3, { color: i === pi ? theme.accentBright : void 0, bold: i === pi, children: [
|
|
8971
8983
|
(i === pi ? "\u25B8 " : " ") + truncate2(p.name, 26).padEnd(27),
|
|
8972
8984
|
/* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
|
|
@@ -9097,8 +9109,13 @@ function RateLimitPanel({ focused }) {
|
|
|
9097
9109
|
const [fi, setFi] = useState4(0);
|
|
9098
9110
|
const [status, setStatus] = useState4(null);
|
|
9099
9111
|
useEffect4(() => {
|
|
9100
|
-
if (layersQ.data && !
|
|
9101
|
-
}, [layersQ.data
|
|
9112
|
+
if (layersQ.data && !dirty) setDraft({ ...layersQ.data.layers.rateLimit });
|
|
9113
|
+
}, [layersQ.data]);
|
|
9114
|
+
usePoll(() => {
|
|
9115
|
+
if (!dirty) layersQ.reloadQuiet();
|
|
9116
|
+
historyQ.reloadQuiet();
|
|
9117
|
+
insightsQ.reloadQuiet();
|
|
9118
|
+
}, 6e3);
|
|
9102
9119
|
const adjust = (dir, step) => {
|
|
9103
9120
|
if (!draft) return;
|
|
9104
9121
|
const field = FIELDS2[fi];
|
|
@@ -9115,6 +9132,7 @@ function RateLimitPanel({ focused }) {
|
|
|
9115
9132
|
setDraft({ ...res.layers.rateLimit });
|
|
9116
9133
|
setDirty(false);
|
|
9117
9134
|
setStatus("\u2713 Saved");
|
|
9135
|
+
layersQ.reload();
|
|
9118
9136
|
historyQ.reload();
|
|
9119
9137
|
insightsQ.reload();
|
|
9120
9138
|
} catch (e) {
|
|
@@ -9129,13 +9147,19 @@ function RateLimitPanel({ focused }) {
|
|
|
9129
9147
|
else if (key.leftArrow) adjust(-1, step);
|
|
9130
9148
|
else if (key.rightArrow) adjust(1, step);
|
|
9131
9149
|
else if (input === "s") void save();
|
|
9150
|
+
else if (input === "r") {
|
|
9151
|
+
layersQ.reload();
|
|
9152
|
+
historyQ.reload();
|
|
9153
|
+
insightsQ.reload();
|
|
9154
|
+
setStatus("refreshed");
|
|
9155
|
+
}
|
|
9132
9156
|
},
|
|
9133
9157
|
{ isActive: focused }
|
|
9134
9158
|
);
|
|
9135
9159
|
const history = (historyQ.data?.history ?? []).slice().sort((a, b) => b.ts - a.ts);
|
|
9136
9160
|
const lastChange = history[0];
|
|
9137
9161
|
const peaks = insightsQ.data?.["peaks"] ?? { minute: 0, hour: 0, day: 0 };
|
|
9138
|
-
const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => new Date(b.minute).getTime() - new Date(a.minute).getTime());
|
|
9162
|
+
const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
|
|
9139
9163
|
return /* @__PURE__ */ jsx4(DataView, { loading: layersQ.loading && !draft, error: layersQ.error, children: draft ? (() => {
|
|
9140
9164
|
const lim = draft.perMinute;
|
|
9141
9165
|
const now = insightsQ.data ? insightsQ.data["activity"]?.minute?.slice(-1)[0]?.count ?? 0 : 0;
|
|
@@ -9147,7 +9171,7 @@ function RateLimitPanel({ focused }) {
|
|
|
9147
9171
|
const shown = anomalies2.slice(0, burstBudget);
|
|
9148
9172
|
const bw = Math.max(10, cols - 30);
|
|
9149
9173
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", height: rows, overflow: "hidden", children: [
|
|
9150
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save" : "press \u2192 to edit" }),
|
|
9174
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save \xB7 r refresh" : "press \u2192 to edit" }),
|
|
9151
9175
|
/* @__PURE__ */ jsxs4(FieldRow, { label: "Mode", active: focused && fi === 0, children: [
|
|
9152
9176
|
/* @__PURE__ */ jsx4(Text4, { color: modeColor(draft.mode), bold: true, children: draft.mode }),
|
|
9153
9177
|
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: draft.mode === "off" ? " no limit" : draft.mode === "detect" ? " flag bursts, never block" : " DENY calls over the limit" })
|
|
@@ -9251,13 +9275,16 @@ function DlpPanel({ focused }) {
|
|
|
9251
9275
|
const [newName, setNewName] = useState5("");
|
|
9252
9276
|
const [input, setInput] = useState5("");
|
|
9253
9277
|
useEffect5(() => {
|
|
9254
|
-
if (q.data && !
|
|
9278
|
+
if (q.data && !dirty) {
|
|
9255
9279
|
setDlp({ ...q.data.layers.dlp, patterns: [...q.data.layers.dlp.patterns], custom: [...q.data.layers.dlp.custom] });
|
|
9256
9280
|
setAvailable(q.data.availablePatterns);
|
|
9257
9281
|
setGhostOn(q.data.layers.ghost.mode === "on");
|
|
9258
9282
|
setGhostPats([...q.data.layers.ghost.patterns]);
|
|
9259
9283
|
}
|
|
9260
|
-
}, [q.data
|
|
9284
|
+
}, [q.data]);
|
|
9285
|
+
usePoll(() => {
|
|
9286
|
+
if (!dirty && !adding) q.reloadQuiet();
|
|
9287
|
+
}, 6e3);
|
|
9261
9288
|
const mutate = (next) => {
|
|
9262
9289
|
setDlp(next);
|
|
9263
9290
|
setDirty(true);
|
|
@@ -9274,6 +9301,7 @@ function DlpPanel({ focused }) {
|
|
|
9274
9301
|
setGhostPats([...res.layers.ghost.patterns]);
|
|
9275
9302
|
setDirty(false);
|
|
9276
9303
|
setStatus("\u2713 Saved");
|
|
9304
|
+
q.reload();
|
|
9277
9305
|
} catch (e) {
|
|
9278
9306
|
setStatus("\u2717 " + (e instanceof Error ? e.message : String(e)));
|
|
9279
9307
|
}
|
package/dist/tui/index.js
CHANGED
|
@@ -504,6 +504,7 @@ async function request(method, path, opts = {}) {
|
|
|
504
504
|
}
|
|
505
505
|
if (res.status === 401) throw new ApiError(401, "AUTHENTICATION_ERROR", "Invalid API key. Run `solongate` and log in from the Accounts panel.");
|
|
506
506
|
if (res.status === 429) throw new ApiError(429, "RATE_LIMITED", "Rate limited by the API. Slow down and retry.");
|
|
507
|
+
if (res.status >= 500) throw new ApiError(res.status, "SERVER_ERROR", text || "SolonGate API had a problem (server error). Please try again in a moment.");
|
|
507
508
|
throw new ApiError(res.status, "ERROR", text || res.statusText || `HTTP ${res.status}`);
|
|
508
509
|
}
|
|
509
510
|
return json;
|
|
@@ -1958,6 +1959,10 @@ function PoliciesPanel({ focused }) {
|
|
|
1958
1959
|
setRi(0);
|
|
1959
1960
|
}
|
|
1960
1961
|
}, [detail.data]);
|
|
1962
|
+
usePoll(() => {
|
|
1963
|
+
list5.reloadQuiet();
|
|
1964
|
+
activeQ.reloadQuiet();
|
|
1965
|
+
}, 6e3);
|
|
1961
1966
|
const mutate = (nextRules, nextMode = mode) => {
|
|
1962
1967
|
setRules(nextRules);
|
|
1963
1968
|
setMode(nextMode);
|
|
@@ -1994,6 +1999,13 @@ function PoliciesPanel({ focused }) {
|
|
|
1994
1999
|
};
|
|
1995
2000
|
useInput2(
|
|
1996
2001
|
(input, key) => {
|
|
2002
|
+
if (input === "r" && !editing) {
|
|
2003
|
+
list5.reload();
|
|
2004
|
+
activeQ.reload();
|
|
2005
|
+
detail.reload();
|
|
2006
|
+
setStatus("refreshed");
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
1997
2009
|
if (view === "list") {
|
|
1998
2010
|
if (key.upArrow) setPi((n) => Math.max(0, n - 1));
|
|
1999
2011
|
else if (key.downArrow) setPi((n) => Math.min(policies.length - 1, n + 1));
|
|
@@ -2084,7 +2096,7 @@ function PoliciesPanel({ focused }) {
|
|
|
2084
2096
|
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: activeBy ? ` (${activeBy})` : "" })
|
|
2085
2097
|
] }) : /* @__PURE__ */ jsx3(Text3, { color: theme.bad, bold: true, children: "\u25CB NONE \u2014 nothing enforced, grants refused" })
|
|
2086
2098
|
] }),
|
|
2087
|
-
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate
|
|
2099
|
+
/* @__PURE__ */ jsx3(Text3, { color: theme.dim, children: focused ? "\u2191\u2193 select \xB7 enter open \xB7 a activate \xB7 x deactivate \xB7 r refresh" : "press \u2192 to browse" }),
|
|
2088
2100
|
/* @__PURE__ */ jsx3(Box3, { marginTop: 1, flexDirection: "column", children: policies.map((p, i) => /* @__PURE__ */ jsxs3(Text3, { color: i === pi ? theme.accentBright : void 0, bold: i === pi, children: [
|
|
2089
2101
|
(i === pi ? "\u25B8 " : " ") + truncate(p.name, 26).padEnd(27),
|
|
2090
2102
|
/* @__PURE__ */ jsxs3(Text3, { color: theme.dim, children: [
|
|
@@ -2190,8 +2202,13 @@ function RateLimitPanel({ focused }) {
|
|
|
2190
2202
|
const [fi, setFi] = useState4(0);
|
|
2191
2203
|
const [status, setStatus] = useState4(null);
|
|
2192
2204
|
useEffect4(() => {
|
|
2193
|
-
if (layersQ.data && !
|
|
2194
|
-
}, [layersQ.data
|
|
2205
|
+
if (layersQ.data && !dirty) setDraft({ ...layersQ.data.layers.rateLimit });
|
|
2206
|
+
}, [layersQ.data]);
|
|
2207
|
+
usePoll(() => {
|
|
2208
|
+
if (!dirty) layersQ.reloadQuiet();
|
|
2209
|
+
historyQ.reloadQuiet();
|
|
2210
|
+
insightsQ.reloadQuiet();
|
|
2211
|
+
}, 6e3);
|
|
2195
2212
|
const adjust = (dir, step) => {
|
|
2196
2213
|
if (!draft) return;
|
|
2197
2214
|
const field = FIELDS2[fi];
|
|
@@ -2208,6 +2225,7 @@ function RateLimitPanel({ focused }) {
|
|
|
2208
2225
|
setDraft({ ...res.layers.rateLimit });
|
|
2209
2226
|
setDirty(false);
|
|
2210
2227
|
setStatus("\u2713 Saved");
|
|
2228
|
+
layersQ.reload();
|
|
2211
2229
|
historyQ.reload();
|
|
2212
2230
|
insightsQ.reload();
|
|
2213
2231
|
} catch (e) {
|
|
@@ -2222,13 +2240,19 @@ function RateLimitPanel({ focused }) {
|
|
|
2222
2240
|
else if (key.leftArrow) adjust(-1, step);
|
|
2223
2241
|
else if (key.rightArrow) adjust(1, step);
|
|
2224
2242
|
else if (input === "s") void save();
|
|
2243
|
+
else if (input === "r") {
|
|
2244
|
+
layersQ.reload();
|
|
2245
|
+
historyQ.reload();
|
|
2246
|
+
insightsQ.reload();
|
|
2247
|
+
setStatus("refreshed");
|
|
2248
|
+
}
|
|
2225
2249
|
},
|
|
2226
2250
|
{ isActive: focused }
|
|
2227
2251
|
);
|
|
2228
2252
|
const history = (historyQ.data?.history ?? []).slice().sort((a, b) => b.ts - a.ts);
|
|
2229
2253
|
const lastChange = history[0];
|
|
2230
2254
|
const peaks = insightsQ.data?.["peaks"] ?? { minute: 0, hour: 0, day: 0 };
|
|
2231
|
-
const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => new Date(b.minute).getTime() - new Date(a.minute).getTime());
|
|
2255
|
+
const anomalies2 = (insightsQ.data?.["anomalies"] ?? []).slice().sort((a, b) => b.count - a.count || new Date(b.minute).getTime() - new Date(a.minute).getTime());
|
|
2232
2256
|
return /* @__PURE__ */ jsx4(DataView, { loading: layersQ.loading && !draft, error: layersQ.error, children: draft ? (() => {
|
|
2233
2257
|
const lim = draft.perMinute;
|
|
2234
2258
|
const now = insightsQ.data ? insightsQ.data["activity"]?.minute?.slice(-1)[0]?.count ?? 0 : 0;
|
|
@@ -2240,7 +2264,7 @@ function RateLimitPanel({ focused }) {
|
|
|
2240
2264
|
const shown = anomalies2.slice(0, burstBudget);
|
|
2241
2265
|
const bw = Math.max(10, cols - 30);
|
|
2242
2266
|
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", height: rows, overflow: "hidden", children: [
|
|
2243
|
-
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save" : "press \u2192 to edit" }),
|
|
2267
|
+
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, wrap: "truncate", children: focused ? "\u2191\u2193 field \xB7 \u2190\u2192 \xB11 \xB7 shift+\u2190\u2192 \xB110 \xB7 s save \xB7 r refresh" : "press \u2192 to edit" }),
|
|
2244
2268
|
/* @__PURE__ */ jsxs4(FieldRow, { label: "Mode", active: focused && fi === 0, children: [
|
|
2245
2269
|
/* @__PURE__ */ jsx4(Text4, { color: modeColor(draft.mode), bold: true, children: draft.mode }),
|
|
2246
2270
|
/* @__PURE__ */ jsx4(Text4, { color: theme.dim, children: draft.mode === "off" ? " no limit" : draft.mode === "detect" ? " flag bursts, never block" : " DENY calls over the limit" })
|
|
@@ -2329,13 +2353,16 @@ function DlpPanel({ focused }) {
|
|
|
2329
2353
|
const [newName, setNewName] = useState5("");
|
|
2330
2354
|
const [input, setInput] = useState5("");
|
|
2331
2355
|
useEffect5(() => {
|
|
2332
|
-
if (q.data && !
|
|
2356
|
+
if (q.data && !dirty) {
|
|
2333
2357
|
setDlp({ ...q.data.layers.dlp, patterns: [...q.data.layers.dlp.patterns], custom: [...q.data.layers.dlp.custom] });
|
|
2334
2358
|
setAvailable(q.data.availablePatterns);
|
|
2335
2359
|
setGhostOn(q.data.layers.ghost.mode === "on");
|
|
2336
2360
|
setGhostPats([...q.data.layers.ghost.patterns]);
|
|
2337
2361
|
}
|
|
2338
|
-
}, [q.data
|
|
2362
|
+
}, [q.data]);
|
|
2363
|
+
usePoll(() => {
|
|
2364
|
+
if (!dirty && !adding) q.reloadQuiet();
|
|
2365
|
+
}, 6e3);
|
|
2339
2366
|
const mutate = (next) => {
|
|
2340
2367
|
setDlp(next);
|
|
2341
2368
|
setDirty(true);
|
|
@@ -2352,6 +2379,7 @@ function DlpPanel({ focused }) {
|
|
|
2352
2379
|
setGhostPats([...res.layers.ghost.patterns]);
|
|
2353
2380
|
setDirty(false);
|
|
2354
2381
|
setStatus("\u2713 Saved");
|
|
2382
|
+
q.reload();
|
|
2355
2383
|
} catch (e) {
|
|
2356
2384
|
setStatus("\u2717 " + (e instanceof Error ? e.message : String(e)));
|
|
2357
2385
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.81.
|
|
3
|
+
"version": "0.81.91",
|
|
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": {
|