@solongate/proxy 0.81.55 → 0.81.57
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/api-client/client.d.ts +2 -0
- package/dist/api-client/settings.d.ts +15 -0
- package/dist/commands/index.js +8 -0
- package/dist/index.js +362 -168
- package/dist/tui/index.js +361 -167
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7086,6 +7086,20 @@ function saveAccount(acc) {
|
|
|
7086
7086
|
} catch {
|
|
7087
7087
|
}
|
|
7088
7088
|
}
|
|
7089
|
+
function removeAccount(apiKey) {
|
|
7090
|
+
try {
|
|
7091
|
+
const list6 = (() => {
|
|
7092
|
+
try {
|
|
7093
|
+
const raw = JSON.parse(readFileSync8(accountsFile(), "utf-8"));
|
|
7094
|
+
return Array.isArray(raw) ? raw.filter((a) => a && a.apiKey) : [];
|
|
7095
|
+
} catch {
|
|
7096
|
+
return [];
|
|
7097
|
+
}
|
|
7098
|
+
})();
|
|
7099
|
+
writeFileSync6(accountsFile(), JSON.stringify(list6.filter((a) => a.apiKey !== apiKey), null, 2));
|
|
7100
|
+
} catch {
|
|
7101
|
+
}
|
|
7102
|
+
}
|
|
7089
7103
|
function setViewCredentials(creds) {
|
|
7090
7104
|
viewOverride = creds;
|
|
7091
7105
|
cached2 = null;
|
|
@@ -7394,11 +7408,13 @@ __export(settings_exports, {
|
|
|
7394
7408
|
getSecurityLayers: () => getSecurityLayers,
|
|
7395
7409
|
getSelfProtection: () => getSelfProtection,
|
|
7396
7410
|
getWebhooks: () => getWebhooks,
|
|
7411
|
+
sendTestAlert: () => sendTestAlert,
|
|
7397
7412
|
sendTestWebhook: () => sendTestWebhook,
|
|
7398
7413
|
setAlertEnabled: () => setAlertEnabled,
|
|
7399
7414
|
setLocalLogs: () => setLocalLogs,
|
|
7400
7415
|
setSecurityLayers: () => setSecurityLayers,
|
|
7401
7416
|
setSelfProtection: () => setSelfProtection,
|
|
7417
|
+
updateAlert: () => updateAlert,
|
|
7402
7418
|
updateWebhook: () => updateWebhook
|
|
7403
7419
|
});
|
|
7404
7420
|
function getSecurityLayers() {
|
|
@@ -7440,6 +7456,12 @@ function deleteAlert(id) {
|
|
|
7440
7456
|
function setAlertEnabled(id, enabled) {
|
|
7441
7457
|
return request("PATCH", "/settings/denial-alerts", { query: { id }, body: { enabled } });
|
|
7442
7458
|
}
|
|
7459
|
+
function updateAlert(id, patch) {
|
|
7460
|
+
return request("PATCH", "/settings/denial-alerts", { query: { id }, body: patch });
|
|
7461
|
+
}
|
|
7462
|
+
function sendTestAlert(id) {
|
|
7463
|
+
return request("POST", "/settings/denial-alerts/send-test", { body: { id } });
|
|
7464
|
+
}
|
|
7443
7465
|
function getWebhooks() {
|
|
7444
7466
|
return request("GET", "/settings/denial-webhook");
|
|
7445
7467
|
}
|
|
@@ -10076,6 +10098,7 @@ function SettingsPanel({
|
|
|
10076
10098
|
const [confirmDel, setConfirmDel] = useState7(null);
|
|
10077
10099
|
const [msg, setMsg] = useState7(null);
|
|
10078
10100
|
const [busy, setBusy] = useState7(false);
|
|
10101
|
+
const [editor, setEditor] = useState7(null);
|
|
10079
10102
|
const [accounts, setAccounts] = useState7(() => listAccounts());
|
|
10080
10103
|
const [login, setLogin] = useState7(null);
|
|
10081
10104
|
const [tick, setTick] = useState7(0);
|
|
@@ -10095,22 +10118,30 @@ function SettingsPanel({
|
|
|
10095
10118
|
const localQ = useLoader(() => listAccounts().length ? api.settings.getLocalLogs() : Promise.resolve(null));
|
|
10096
10119
|
const whQ = useLoader(() => listAccounts().length ? api.settings.getWebhooks() : Promise.resolve(null));
|
|
10097
10120
|
const alertQ = useLoader(() => listAccounts().length ? api.settings.getAlerts() : Promise.resolve(null));
|
|
10121
|
+
const guardQ = useLoader(() => listAccounts().length ? api.settings.getGuardStatus() : Promise.resolve(null));
|
|
10122
|
+
const selfQ = useLoader(() => listAccounts().length ? api.settings.getSelfProtection() : Promise.resolve(null));
|
|
10098
10123
|
const local = localQ.data;
|
|
10124
|
+
const guard = guardQ.data;
|
|
10125
|
+
const selfProt = selfQ.data;
|
|
10099
10126
|
const [hidden, setHidden] = useState7(/* @__PURE__ */ new Set());
|
|
10100
10127
|
const webhooks = (whQ.data?.webhooks ?? []).filter((w) => !hidden.has("wh:" + w.id));
|
|
10101
10128
|
const alerts = (alertQ.data?.rules ?? []).filter((r) => !hidden.has("alert:" + r.id));
|
|
10129
|
+
const hasEmailAlert = alerts.some((r) => alertChannel(r) === "email");
|
|
10130
|
+
const hasTgAlert = alerts.some((r) => alertChannel(r) === "telegram");
|
|
10102
10131
|
const rowsAll = [
|
|
10103
10132
|
...accounts.map((acc) => ({ kind: "acct", acc })),
|
|
10104
10133
|
{ kind: "acct-add" },
|
|
10105
10134
|
...locked ? [] : [
|
|
10135
|
+
{ kind: "guard" },
|
|
10136
|
+
{ kind: "self" },
|
|
10106
10137
|
{ kind: "ll-enabled" },
|
|
10107
10138
|
{ kind: "ll-path" },
|
|
10108
10139
|
{ kind: "ll-server" },
|
|
10109
10140
|
...webhooks.map((wh) => ({ kind: "wh", wh })),
|
|
10110
10141
|
{ kind: "wh-add" },
|
|
10111
10142
|
...alerts.map((rule) => ({ kind: "alert", rule })),
|
|
10112
|
-
{ kind: "alert-add-email" },
|
|
10113
|
-
{ kind: "alert-add-tg" }
|
|
10143
|
+
...hasEmailAlert ? [] : [{ kind: "alert-add-email" }],
|
|
10144
|
+
...hasTgAlert ? [] : [{ kind: "alert-add-tg" }]
|
|
10114
10145
|
]
|
|
10115
10146
|
];
|
|
10116
10147
|
const selClamped = Math.min(sel, rowsAll.length - 1);
|
|
@@ -10121,6 +10152,8 @@ function SettingsPanel({
|
|
|
10121
10152
|
localQ.reload();
|
|
10122
10153
|
whQ.reload();
|
|
10123
10154
|
alertQ.reload();
|
|
10155
|
+
guardQ.reload();
|
|
10156
|
+
selfQ.reload();
|
|
10124
10157
|
};
|
|
10125
10158
|
const run12 = (label, fn, reload) => {
|
|
10126
10159
|
if (busy) return;
|
|
@@ -10136,19 +10169,19 @@ function SettingsPanel({
|
|
|
10136
10169
|
abort.current = false;
|
|
10137
10170
|
setLogin({ phase: "starting" });
|
|
10138
10171
|
void (async () => {
|
|
10139
|
-
let
|
|
10172
|
+
let start;
|
|
10140
10173
|
try {
|
|
10141
|
-
|
|
10174
|
+
start = await startDeviceLogin(DEFAULT_API_URL2);
|
|
10142
10175
|
} catch (e) {
|
|
10143
10176
|
setLogin({ phase: "error", msg: "could not reach SolonGate: " + (e instanceof Error ? e.message : String(e)) });
|
|
10144
10177
|
return;
|
|
10145
10178
|
}
|
|
10146
|
-
setLogin({ phase: "waiting", url:
|
|
10147
|
-
openBrowser(
|
|
10148
|
-
while (Date.now() <
|
|
10149
|
-
await new Promise((r) => setTimeout(r,
|
|
10179
|
+
setLogin({ phase: "waiting", url: start.verifyUrl });
|
|
10180
|
+
openBrowser(start.verifyUrl);
|
|
10181
|
+
while (Date.now() < start.expiresAt && !abort.current) {
|
|
10182
|
+
await new Promise((r) => setTimeout(r, start.intervalMs));
|
|
10150
10183
|
if (abort.current) return;
|
|
10151
|
-
const res = await pollDeviceLogin(DEFAULT_API_URL2,
|
|
10184
|
+
const res = await pollDeviceLogin(DEFAULT_API_URL2, start.deviceCode);
|
|
10152
10185
|
if (res.status === "approved" && res.apiKey) {
|
|
10153
10186
|
saveAccount({ apiKey: res.apiKey, apiUrl: DEFAULT_API_URL2, project: res.project, user: res.user, email: res.email });
|
|
10154
10187
|
setLogin({ phase: "done", msg: `\u2713 added ${res.email || res.user || res.project || "account"}` });
|
|
@@ -10165,6 +10198,57 @@ function SettingsPanel({
|
|
|
10165
10198
|
if (!abort.current) setLogin({ phase: "error", msg: "timed out \u2014 press n to retry" });
|
|
10166
10199
|
})();
|
|
10167
10200
|
};
|
|
10201
|
+
const openAlertEditor = (channel, rule) => {
|
|
10202
|
+
setEditor({
|
|
10203
|
+
id: rule?.id,
|
|
10204
|
+
channel,
|
|
10205
|
+
target: (channel === "email" ? rule?.emails?.[0] : rule?.telegram?.[0]) ?? "",
|
|
10206
|
+
signal: rule?.signal ?? "any",
|
|
10207
|
+
threshold: rule?.threshold ?? THRESH_MIN,
|
|
10208
|
+
windowSeconds: rule?.windowSeconds ?? 300,
|
|
10209
|
+
field: rule ? 1 : 0
|
|
10210
|
+
// new rule starts on the target; existing on signal
|
|
10211
|
+
});
|
|
10212
|
+
if (!rule) {
|
|
10213
|
+
setInput("");
|
|
10214
|
+
setEditing("alert-target");
|
|
10215
|
+
}
|
|
10216
|
+
};
|
|
10217
|
+
const normTarget = (channel, raw) => {
|
|
10218
|
+
const v = raw.trim();
|
|
10219
|
+
if (channel === "email") {
|
|
10220
|
+
const email = v.replace(/^mailto:/i, "").replace(/^["'<]+|["'>]+$/g, "").replace(/[.,;:]+$/, "").replace(/\s+/g, "");
|
|
10221
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) return { value: email, error: "that does not look like an e-mail address" };
|
|
10222
|
+
return { value: email };
|
|
10223
|
+
}
|
|
10224
|
+
const tg = v.replace(/^@/, "").replace(/^(chat[\s_-]*)?id[:=\s]*/i, "").replace(/\s+/g, "");
|
|
10225
|
+
if (!/^-?\d{5,}$/.test(tg)) return { value: tg, error: "a telegram chat id is a number \u2014 get yours from @userinfobot" };
|
|
10226
|
+
return { value: tg };
|
|
10227
|
+
};
|
|
10228
|
+
const saveEditor = () => {
|
|
10229
|
+
if (!editor) return;
|
|
10230
|
+
const t = normTarget(editor.channel, editor.target);
|
|
10231
|
+
if (t.error) {
|
|
10232
|
+
setMsg({ text: "\u2717 " + t.error, level: "bad" });
|
|
10233
|
+
return;
|
|
10234
|
+
}
|
|
10235
|
+
const channels = editor.channel === "email" ? { emails: [t.value], telegram: [] } : { telegram: [t.value], emails: [] };
|
|
10236
|
+
const body = { signal: editor.signal, threshold: editor.threshold, windowSeconds: editor.windowSeconds, ...channels };
|
|
10237
|
+
const id = editor.id;
|
|
10238
|
+
setEditor(null);
|
|
10239
|
+
if (id) run12("alert updated", () => api.settings.updateAlert(id, body), alertQ.reload);
|
|
10240
|
+
else run12(`${editor.channel} alert added`, () => api.settings.createAlert({ name: "dataroom alert", ...body }), alertQ.reload);
|
|
10241
|
+
};
|
|
10242
|
+
const testAlert = (rule) => {
|
|
10243
|
+
run12(
|
|
10244
|
+
"alert test sent \u2014 check your " + (alertChannel(rule) ?? "channel"),
|
|
10245
|
+
() => api.settings.sendTestAlert(rule.id).then((r) => {
|
|
10246
|
+
if (!r.delivered.telegram && !r.delivered.email) throw new Error("no channel on this rule");
|
|
10247
|
+
}),
|
|
10248
|
+
() => {
|
|
10249
|
+
}
|
|
10250
|
+
);
|
|
10251
|
+
};
|
|
10168
10252
|
const activate = (r) => {
|
|
10169
10253
|
if (r.kind === "acct") {
|
|
10170
10254
|
setViewCredentials({ apiKey: r.acc.apiKey, apiUrl: r.acc.apiUrl });
|
|
@@ -10172,6 +10256,9 @@ function SettingsPanel({
|
|
|
10172
10256
|
setMsg({ text: `viewing ${acctLabel(r.acc)}`, level: "ok" });
|
|
10173
10257
|
} else if (r.kind === "acct-add") {
|
|
10174
10258
|
beginLogin();
|
|
10259
|
+
} else if (r.kind === "self") {
|
|
10260
|
+
if (!selfProt) return;
|
|
10261
|
+
run12(selfProt.enabled ? "self-protection disabled" : "self-protection enabled", () => api.settings.setSelfProtection(!selfProt.enabled), selfQ.reload);
|
|
10175
10262
|
} else if (r.kind === "ll-enabled") {
|
|
10176
10263
|
if (!local) return;
|
|
10177
10264
|
if (!local.enabled && !local.path.trim()) {
|
|
@@ -10194,13 +10281,12 @@ function SettingsPanel({
|
|
|
10194
10281
|
setInput("");
|
|
10195
10282
|
setEditing("wh-url");
|
|
10196
10283
|
} else if (r.kind === "alert") {
|
|
10197
|
-
|
|
10284
|
+
const ch = alertChannel(r.rule);
|
|
10285
|
+
if (ch) openAlertEditor(ch, r.rule);
|
|
10198
10286
|
} else if (r.kind === "alert-add-email") {
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
setInput("");
|
|
10203
|
-
setEditing("alert-tg");
|
|
10287
|
+
openAlertEditor("email");
|
|
10288
|
+
} else if (r.kind === "alert-add-tg") {
|
|
10289
|
+
openAlertEditor("telegram");
|
|
10204
10290
|
}
|
|
10205
10291
|
};
|
|
10206
10292
|
const submitInput = () => {
|
|
@@ -10218,22 +10304,8 @@ function SettingsPanel({
|
|
|
10218
10304
|
return;
|
|
10219
10305
|
}
|
|
10220
10306
|
run12("webhook added", () => api.settings.createWebhook({ url, events: "denials" }), whQ.reload);
|
|
10221
|
-
} else if (which === "alert-
|
|
10222
|
-
|
|
10223
|
-
const email = v.replace(/^mailto:/i, "").replace(/^["'<]+|["'>]+$/g, "").replace(/[.,;:]+$/, "").replace(/\s+/g, "").trim();
|
|
10224
|
-
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
10225
|
-
setMsg({ text: "\u2717 that does not look like an e-mail address", level: "bad" });
|
|
10226
|
-
return;
|
|
10227
|
-
}
|
|
10228
|
-
run12("email alert added", () => api.settings.createAlert({ ...ALERT_BASE, emails: [email] }), alertQ.reload);
|
|
10229
|
-
} else if (which === "alert-tg") {
|
|
10230
|
-
if (!v) return;
|
|
10231
|
-
const tg = v.replace(/^@/, "").replace(/^(chat[\s_-]*)?id[:=\s]*/i, "").replace(/\s+/g, "").trim();
|
|
10232
|
-
if (!/^-?\d{5,}$/.test(tg)) {
|
|
10233
|
-
setMsg({ text: "\u2717 a telegram chat id is a number \u2014 get yours from @userinfobot", level: "bad" });
|
|
10234
|
-
return;
|
|
10235
|
-
}
|
|
10236
|
-
run12("telegram alert added", () => api.settings.createAlert({ ...ALERT_BASE, telegram: [tg] }), alertQ.reload);
|
|
10307
|
+
} else if (which === "alert-target" && editor) {
|
|
10308
|
+
setEditor({ ...editor, target: v, field: 1 });
|
|
10237
10309
|
}
|
|
10238
10310
|
};
|
|
10239
10311
|
useInput6(
|
|
@@ -10245,6 +10317,35 @@ function SettingsPanel({
|
|
|
10245
10317
|
}
|
|
10246
10318
|
return;
|
|
10247
10319
|
}
|
|
10320
|
+
if (editor) {
|
|
10321
|
+
if (key.escape) {
|
|
10322
|
+
setEditor(null);
|
|
10323
|
+
return;
|
|
10324
|
+
}
|
|
10325
|
+
if (inp === "e" || key.return && editor.field === 0) {
|
|
10326
|
+
setInput(editor.target);
|
|
10327
|
+
setEditing("alert-target");
|
|
10328
|
+
return;
|
|
10329
|
+
}
|
|
10330
|
+
if (inp === "t" && editor.id) {
|
|
10331
|
+
const rule = alerts.find((a) => a.id === editor.id);
|
|
10332
|
+
if (rule) testAlert(rule);
|
|
10333
|
+
return;
|
|
10334
|
+
}
|
|
10335
|
+
if (key.return) {
|
|
10336
|
+
saveEditor();
|
|
10337
|
+
return;
|
|
10338
|
+
}
|
|
10339
|
+
if (key.upArrow) setEditor({ ...editor, field: (editor.field + EDITOR_FIELDS - 1) % EDITOR_FIELDS });
|
|
10340
|
+
else if (key.downArrow) setEditor({ ...editor, field: (editor.field + 1) % EDITOR_FIELDS });
|
|
10341
|
+
else if (key.leftArrow || key.rightArrow) {
|
|
10342
|
+
const d = key.rightArrow ? 1 : -1;
|
|
10343
|
+
if (editor.field === 1) setEditor({ ...editor, signal: SIGNALS2[(SIGNALS2.indexOf(editor.signal) + d + SIGNALS2.length) % SIGNALS2.length] });
|
|
10344
|
+
else if (editor.field === 2) setEditor({ ...editor, threshold: Math.max(THRESH_MIN, Math.min(THRESH_MAX, editor.threshold + d * 5)) });
|
|
10345
|
+
else if (editor.field === 3) setEditor({ ...editor, windowSeconds: WINDOWS[Math.max(0, Math.min(WINDOWS.length - 1, nearestWindowIdx(editor.windowSeconds) + d))] });
|
|
10346
|
+
}
|
|
10347
|
+
return;
|
|
10348
|
+
}
|
|
10248
10349
|
setMsg(null);
|
|
10249
10350
|
if (key.upArrow) {
|
|
10250
10351
|
setSel((n) => Math.max(0, n - 1));
|
|
@@ -10258,28 +10359,41 @@ function SettingsPanel({
|
|
|
10258
10359
|
const ok = setActiveAccount({ apiKey: cur.acc.apiKey, apiUrl: cur.acc.apiUrl });
|
|
10259
10360
|
setMsg(ok ? { text: `\u2713 ${acctLabel(cur.acc)} is now the ACTIVE key (guard + logging)`, level: "ok" } : { text: "\u2717 could not set active", level: "bad" });
|
|
10260
10361
|
refreshAccounts();
|
|
10261
|
-
} else if (cur.kind === "wh" || cur.kind === "alert" || cur.kind === "ll-enabled" || cur.kind === "ll-server")
|
|
10362
|
+
} else if (cur.kind === "wh" || cur.kind === "alert" || cur.kind === "self" || cur.kind === "ll-enabled" || cur.kind === "ll-server") {
|
|
10363
|
+
if (cur.kind === "alert") run12(cur.rule.enabled ? "alert disabled" : "alert enabled", () => api.settings.setAlertEnabled(cur.rule.id, !cur.rule.enabled), alertQ.reload);
|
|
10364
|
+
else activate(cur);
|
|
10365
|
+
}
|
|
10366
|
+
} else if (inp === "x" && cur.kind === "acct") {
|
|
10367
|
+
const k = "acct:" + cur.acc.apiKey;
|
|
10368
|
+
if (confirmDel !== k) {
|
|
10369
|
+
setConfirmDel(k);
|
|
10370
|
+
setMsg({ text: `press x again to remove ${acctLabel(cur.acc)} from this device (the cloud account is untouched)`, level: "bad" });
|
|
10371
|
+
return;
|
|
10372
|
+
}
|
|
10373
|
+
setConfirmDel(null);
|
|
10374
|
+
removeAccount(cur.acc.apiKey);
|
|
10375
|
+
setMsg({ text: `\u2713 removed ${acctLabel(cur.acc)} from this device`, level: "ok" });
|
|
10376
|
+
refreshAccounts();
|
|
10262
10377
|
} else if (inp === "t" && cur.kind === "wh") {
|
|
10263
|
-
run12(
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
|
|
10269
|
-
);
|
|
10270
|
-
} else if (inp === "n") beginLogin();
|
|
10378
|
+
run12("webhook test sent \u2014 check your endpoint", () => api.settings.sendTestWebhook(cur.wh.id).then((r) => {
|
|
10379
|
+
if (!r.delivered) throw new Error("endpoint rejected the test (non-2xx)");
|
|
10380
|
+
}), whQ.reload);
|
|
10381
|
+
} else if (inp === "t" && cur.kind === "alert") {
|
|
10382
|
+
testAlert(cur.rule);
|
|
10383
|
+
} else if (inp === "e" && cur.kind === "ll-path") activate(cur);
|
|
10271
10384
|
else if (inp === "e" && cur.kind === "wh") {
|
|
10272
10385
|
const next = EVENTS[(EVENTS.indexOf(cur.wh.events) + 1) % EVENTS.length];
|
|
10273
10386
|
run12(`webhook events \u2192 ${next}`, () => api.settings.updateWebhook(cur.wh.id, { events: next }), whQ.reload);
|
|
10274
|
-
} else if (inp === "e" && cur.kind === "
|
|
10387
|
+
} else if (inp === "e" && cur.kind === "alert") {
|
|
10388
|
+
const ch = alertChannel(cur.rule);
|
|
10389
|
+
if (ch) openAlertEditor(ch, cur.rule);
|
|
10390
|
+
} else if (inp === "n") beginLogin();
|
|
10275
10391
|
else if (inp === "a") {
|
|
10276
10392
|
if (cur.kind === "wh" || cur.kind === "wh-add") {
|
|
10277
10393
|
setInput("");
|
|
10278
10394
|
setEditing("wh-url");
|
|
10279
|
-
} else if (cur.kind === "alert
|
|
10280
|
-
|
|
10281
|
-
setEditing("alert-email");
|
|
10282
|
-
}
|
|
10395
|
+
} else if (cur.kind === "alert-add-email") openAlertEditor("email");
|
|
10396
|
+
else if (cur.kind === "alert-add-tg") openAlertEditor("telegram");
|
|
10283
10397
|
} else if (inp === "d" && (cur.kind === "wh" || cur.kind === "alert")) {
|
|
10284
10398
|
const k = keyOf(cur);
|
|
10285
10399
|
if (confirmDel !== k) {
|
|
@@ -10319,126 +10433,189 @@ function SettingsPanel({
|
|
|
10319
10433
|
] })
|
|
10320
10434
|
] });
|
|
10321
10435
|
}
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
10329
|
-
|
|
10330
|
-
const i = rowsAll.findIndex((x) => keyOf(x) === keyOf(r));
|
|
10331
|
-
return i >= start && i < start + listBudget;
|
|
10332
|
-
};
|
|
10333
|
-
return /* @__PURE__ */ jsx7(DataView, { loading, error, children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
10334
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: focused ? "\u2191\u2193 move \xB7 enter/m act \xB7 t test webhook \xB7 n add account \xB7 e events \xB7 d delete \xB7 r refresh" : "press \u2192 to configure" }),
|
|
10335
|
-
editing ? /* @__PURE__ */ jsxs7(Box7, { children: [
|
|
10336
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : editing === "wh-url" ? "webhook url: " : editing === "alert-email" ? "e-mail address: " : "telegram chat id (from @userinfobot): " }),
|
|
10337
|
-
/* @__PURE__ */ jsx7(TextInput5, { value: input, onChange: setInput, onSubmit: submitInput })
|
|
10338
|
-
] }) : msg ? /* @__PURE__ */ jsx7(Text7, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, cols) }) : login?.msg ? /* @__PURE__ */ jsx7(Text7, { color: login.phase === "error" ? theme.bad : theme.ok, children: login.msg }) : /* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
10339
|
-
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10436
|
+
if (editor) {
|
|
10437
|
+
const fieldRow = (idx, label, value, hint) => /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10438
|
+
/* @__PURE__ */ jsx7(Text7, { color: editor.field === idx ? theme.accentBright : theme.dim, children: editor.field === idx ? "\u25B8 " : " " }),
|
|
10439
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: label.padEnd(11) }),
|
|
10440
|
+
value,
|
|
10441
|
+
editor.field === idx && hint ? /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " " + hint }) : null
|
|
10442
|
+
] });
|
|
10443
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
10340
10444
|
/* @__PURE__ */ jsxs7(Text7, { bold: true, color: theme.accentBright, children: [
|
|
10341
|
-
"
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
") \xB7 \u25CF viewing = shown here \xB7 ACTIVE = key the guard uses"
|
|
10346
|
-
] })
|
|
10445
|
+
editor.id ? "Edit" : "New",
|
|
10446
|
+
" ",
|
|
10447
|
+
editor.channel,
|
|
10448
|
+
" alert"
|
|
10347
10449
|
] }),
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
10352
|
-
] })
|
|
10353
|
-
|
|
10450
|
+
/* @__PURE__ */ jsxs7(Text7, { color: theme.dim, children: [
|
|
10451
|
+
"\u2191\u2193 field \xB7 \u2190\u2192 change \xB7 e edit target \xB7 enter save",
|
|
10452
|
+
editor.id ? " \xB7 t test" : "",
|
|
10453
|
+
" \xB7 esc cancel"
|
|
10454
|
+
] }),
|
|
10455
|
+
editing === "alert-target" ? /* @__PURE__ */ jsxs7(Box7, { marginTop: 1, children: [
|
|
10456
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editor.channel === "email" ? "e-mail address: " : "telegram chat id (from @userinfobot): " }),
|
|
10457
|
+
/* @__PURE__ */ jsx7(TextInput5, { value: input, onChange: setInput, onSubmit: submitInput })
|
|
10458
|
+
] }) : msg ? /* @__PURE__ */ jsx7(Text7, { color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, cols) }) : /* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
10459
|
+
/* @__PURE__ */ jsxs7(Box7, { marginTop: 1, flexDirection: "column", children: [
|
|
10460
|
+
fieldRow(0, "target", editor.target ? /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(editor.target, cols - 16) }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "empty \u2014 press e" }), "press e to edit"),
|
|
10461
|
+
fieldRow(1, "signal", /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: SIGNAL_LABEL[editor.signal] }), "\u2190\u2192 change"),
|
|
10462
|
+
fieldRow(2, "threshold", /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: `\u2265 ${editor.threshold}` }), "\u2190\u2192 \xB15"),
|
|
10463
|
+
fieldRow(3, "window", /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: winLabel(editor.windowSeconds) }), "\u2190\u2192 change")
|
|
10464
|
+
] }),
|
|
10465
|
+
/* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsxs7(Text7, { color: theme.dim, children: [
|
|
10466
|
+
"fires when ",
|
|
10467
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: SIGNAL_LABEL[editor.signal] }),
|
|
10468
|
+
" reach ",
|
|
10469
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: editor.threshold }),
|
|
10470
|
+
" within",
|
|
10471
|
+
" ",
|
|
10472
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: winLabel(editor.windowSeconds) })
|
|
10473
|
+
] }) })
|
|
10474
|
+
] });
|
|
10475
|
+
}
|
|
10476
|
+
const loading = !locked && (localQ.loading && !localQ.data || whQ.loading && !whQ.data || alertQ.loading && !alertQ.data || guardQ.loading && !guardQ.data || selfQ.loading && !selfQ.data);
|
|
10477
|
+
const error = locked ? null : localQ.error ?? whQ.error ?? alertQ.error ?? guardQ.error ?? selfQ.error;
|
|
10478
|
+
const onOff = (on) => on ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: "on " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "off" });
|
|
10479
|
+
const chanOf = (rule) => [...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
|
|
10480
|
+
const isCur = (r) => keyOf(r) === keyOf(cur) && focused;
|
|
10481
|
+
const cursor = (r) => /* @__PURE__ */ jsx7(Text7, { color: isCur(r) ? theme.accentBright : theme.dim, children: isCur(r) ? "\u25B8 " : " " });
|
|
10482
|
+
const rowLine = (r) => {
|
|
10483
|
+
switch (r.kind) {
|
|
10484
|
+
case "acct": {
|
|
10485
|
+
const a = r.acc;
|
|
10354
10486
|
const isView = viewApiKey ? a.apiKey === viewApiKey : accounts[0]?.apiKey === a.apiKey;
|
|
10355
10487
|
const isActive = isActiveAccount(a.apiKey);
|
|
10356
10488
|
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10357
|
-
|
|
10489
|
+
cursor(r),
|
|
10358
10490
|
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(acctLabel(a), 30).padEnd(31) }),
|
|
10359
10491
|
isView ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: "\u25CF viewing " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " " }),
|
|
10360
10492
|
isActive ? /* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: "ACTIVE " }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " " }),
|
|
10361
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: a.project ? truncate2(a.project,
|
|
10362
|
-
] }
|
|
10363
|
-
}
|
|
10364
|
-
|
|
10365
|
-
/* @__PURE__ */
|
|
10366
|
-
|
|
10367
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
/* @__PURE__ */
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "
|
|
10493
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: a.project ? truncate2(a.project, 20) : "" })
|
|
10494
|
+
] });
|
|
10495
|
+
}
|
|
10496
|
+
case "acct-add":
|
|
10497
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10498
|
+
cursor(r),
|
|
10499
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add account (enter \u2014 device login in the browser)" })
|
|
10500
|
+
] });
|
|
10501
|
+
case "guard":
|
|
10502
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10503
|
+
cursor(r),
|
|
10504
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "guard".padEnd(11) }),
|
|
10505
|
+
guard ? /* @__PURE__ */ jsxs7(Fragment5, { children: [
|
|
10506
|
+
/* @__PURE__ */ jsx7(Text7, { color: guard.up_to_date ? theme.ok : theme.warn, children: `v${guard.installed ?? "?"}` }),
|
|
10507
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: guard.up_to_date ? " (latest)" : ` \u2192 v${guard.latest} available` }),
|
|
10508
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: ` \xB7 ${guard.device_count} device${guard.device_count === 1 ? "" : "s"}${guard.outdated_count ? ` \xB7 ${guard.outdated_count} outdated` : ""}` })
|
|
10509
|
+
] }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "loading\u2026" })
|
|
10510
|
+
] });
|
|
10511
|
+
case "self":
|
|
10512
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10513
|
+
cursor(r),
|
|
10514
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "self-prot".padEnd(11) }),
|
|
10515
|
+
selfProt ? onOff(selfProt.enabled) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "\u2026" }),
|
|
10516
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " blocks agents editing SolonGate\u2019s own hooks/config \xB7 enter toggles" })
|
|
10517
|
+
] });
|
|
10518
|
+
case "ll-enabled":
|
|
10519
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10520
|
+
cursor(r),
|
|
10521
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "enabled ".padEnd(11) }),
|
|
10378
10522
|
onOff(!!local?.enabled),
|
|
10379
10523
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " enter toggles" })
|
|
10380
|
-
] })
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10524
|
+
] });
|
|
10525
|
+
case "ll-path":
|
|
10526
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10527
|
+
cursor(r),
|
|
10528
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "path ".padEnd(11) }),
|
|
10384
10529
|
local?.path ? /* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(local.path, cols - 14) }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "not set \u2014 enter to edit" })
|
|
10385
|
-
] })
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10530
|
+
] });
|
|
10531
|
+
case "ll-server":
|
|
10532
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10533
|
+
cursor(r),
|
|
10534
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "dashboard".padEnd(11) }),
|
|
10389
10535
|
srv.running ? /* @__PURE__ */ jsx7(Text7, { color: theme.ok, children: `running 127.0.0.1:${srv.port}` }) : /* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "stopped" }),
|
|
10390
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: srv.running ? "
|
|
10391
|
-
] })
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
/* @__PURE__ */
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
webhooks.filter((wh) => inWindow({ kind: "wh", wh })).map((wh) => /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10403
|
-
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "wh:" + wh.id && focused ? theme.accentBright : theme.dim, children: mark({ kind: "wh", wh }) }),
|
|
10404
|
-
onOff(wh.enabled),
|
|
10405
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: (" " + wh.events).padEnd(9) }),
|
|
10406
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(wh.url, cols - 16) })
|
|
10407
|
-
] }, wh.id)),
|
|
10408
|
-
inWindow({ kind: "wh-add" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
10409
|
-
/* @__PURE__ */ jsx7(Text7, { color: cur.kind === "wh-add" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "wh-add" }) }),
|
|
10536
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: srv.running ? " survives closing the dataroom \xB7 enter stops" : " enter starts the dashboard local-logs link" })
|
|
10537
|
+
] });
|
|
10538
|
+
case "wh":
|
|
10539
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10540
|
+
cursor(r),
|
|
10541
|
+
onOff(r.wh.enabled),
|
|
10542
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: (" " + r.wh.events).padEnd(9) }),
|
|
10543
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(r.wh.url, cols - 16) })
|
|
10544
|
+
] });
|
|
10545
|
+
case "wh-add":
|
|
10546
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10547
|
+
cursor(r),
|
|
10410
10548
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add webhook (enter)" })
|
|
10411
|
-
] })
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
/* @__PURE__ */
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
/* @__PURE__ */ jsx7(Text7, { color: keyOf(cur) === "alert:" + rule.id && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert", rule }) }),
|
|
10424
|
-
onOff(rule.enabled),
|
|
10425
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: (" " + rule.signal).padEnd(11) }),
|
|
10426
|
-
/* @__PURE__ */ jsx7(Text7, { children: `\u2265${rule.threshold}/${rule.windowSeconds}s ` }),
|
|
10427
|
-
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(chanOf(rule), cols - 26) })
|
|
10428
|
-
] }, rule.id)),
|
|
10429
|
-
inWindow({ kind: "alert-add-email" }) ? /* @__PURE__ */ jsxs7(Text7, { children: [
|
|
10430
|
-
/* @__PURE__ */ jsx7(Text7, { color: cur.kind === "alert-add-email" && focused ? theme.accentBright : theme.dim, children: mark({ kind: "alert-add-email" }) }),
|
|
10549
|
+
] });
|
|
10550
|
+
case "alert":
|
|
10551
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10552
|
+
cursor(r),
|
|
10553
|
+
onOff(r.rule.enabled),
|
|
10554
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: (" " + SIGNAL_LABEL[r.rule.signal]).padEnd(13) }),
|
|
10555
|
+
/* @__PURE__ */ jsx7(Text7, { children: `\u2265${r.rule.threshold}/${winLabel(r.rule.windowSeconds)} `.padEnd(11) }),
|
|
10556
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.accent, children: truncate2(chanOf(r.rule), cols - 34) })
|
|
10557
|
+
] });
|
|
10558
|
+
case "alert-add-email":
|
|
10559
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10560
|
+
cursor(r),
|
|
10431
10561
|
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add email alert (enter)" })
|
|
10432
|
-
] })
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10562
|
+
] });
|
|
10563
|
+
case "alert-add-tg":
|
|
10564
|
+
return /* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10565
|
+
cursor(r),
|
|
10566
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: "+ add telegram alert (enter \u2014 numeric chat id from @userinfobot)" })
|
|
10567
|
+
] });
|
|
10568
|
+
}
|
|
10569
|
+
};
|
|
10570
|
+
const sectionOf = (r) => r.kind === "acct" || r.kind === "acct-add" ? "ACCOUNTS" : r.kind === "guard" || r.kind === "self" ? "PROTECTION" : r.kind === "ll-enabled" || r.kind === "ll-path" || r.kind === "ll-server" ? "LOCAL LOGS" : r.kind === "wh" || r.kind === "wh-add" ? "WEBHOOKS" : "ALERTS";
|
|
10571
|
+
const SECTION_DESC = {
|
|
10572
|
+
ACCOUNTS: `on this device (${accounts.length}) \xB7 \u25CF viewing \xB7 ACTIVE = guard key \xB7 x removes`,
|
|
10573
|
+
PROTECTION: "guard hook version + self-protection toggle",
|
|
10574
|
+
"LOCAL LOGS": "mirror every decision to a file + dashboard link",
|
|
10575
|
+
WEBHOOKS: `POST events to a URL (${webhooks.length}) \xB7 t tests`,
|
|
10576
|
+
ALERTS: `one email + one telegram (${alerts.length}) \xB7 enter edits \xB7 t tests`
|
|
10577
|
+
};
|
|
10578
|
+
const lineEls = [];
|
|
10579
|
+
const lineKey = [];
|
|
10580
|
+
let lastSec = "";
|
|
10581
|
+
rowsAll.forEach((r) => {
|
|
10582
|
+
const sec = sectionOf(r);
|
|
10583
|
+
if (sec !== lastSec) {
|
|
10584
|
+
lastSec = sec;
|
|
10585
|
+
lineEls.push(
|
|
10586
|
+
/* @__PURE__ */ jsxs7(Text7, { wrap: "truncate", children: [
|
|
10587
|
+
/* @__PURE__ */ jsx7(Text7, { bold: true, color: theme.accentBright, children: sec }),
|
|
10588
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " \u2014 " + SECTION_DESC[sec] })
|
|
10589
|
+
] }, "h:" + sec)
|
|
10590
|
+
);
|
|
10591
|
+
lineKey.push("");
|
|
10592
|
+
}
|
|
10593
|
+
lineEls.push(/* @__PURE__ */ jsx7(Box7, { children: rowLine(r) }, keyOf(r)));
|
|
10594
|
+
lineKey.push(keyOf(r));
|
|
10595
|
+
});
|
|
10596
|
+
if (hasEmailAlert && hasTgAlert) {
|
|
10597
|
+
lineEls.push(
|
|
10598
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.dim, children: " both channels in use \u2014 remove one (d) to change it" }, "both-note")
|
|
10599
|
+
);
|
|
10600
|
+
lineKey.push("");
|
|
10601
|
+
}
|
|
10602
|
+
const budget = Math.max(4, rows - 2);
|
|
10603
|
+
const selLine = Math.max(0, lineKey.indexOf(keyOf(cur)));
|
|
10604
|
+
const maxStart = Math.max(0, lineEls.length - budget);
|
|
10605
|
+
const startL = Math.min(Math.max(0, selLine - Math.floor(budget / 2)), maxStart);
|
|
10606
|
+
const win = lineEls.slice(startL, startL + budget);
|
|
10607
|
+
const moreAbove = startL;
|
|
10608
|
+
const moreBelow = Math.max(0, lineEls.length - (startL + budget));
|
|
10609
|
+
return /* @__PURE__ */ jsx7(DataView, { loading, error, children: /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
10610
|
+
/* @__PURE__ */ jsx7(Text7, { wrap: "truncate", color: theme.dim, children: focused ? `\u2191\u2193 move \xB7 enter act \xB7 m toggle \xB7 t test \xB7 e edit \xB7 x remove \xB7 d delete \xB7 n add${moreAbove ? ` \xB7 \u25B2${moreAbove}` : ""}${moreBelow ? ` \xB7 \u25BC${moreBelow}` : ""}` : "press \u2192 to configure" }),
|
|
10611
|
+
editing ? /* @__PURE__ */ jsxs7(Box7, { children: [
|
|
10612
|
+
/* @__PURE__ */ jsx7(Text7, { color: theme.warn, children: editing === "path" ? "local log path: " : "webhook url: " }),
|
|
10613
|
+
/* @__PURE__ */ jsx7(TextInput5, { value: input, onChange: setInput, onSubmit: submitInput })
|
|
10614
|
+
] }) : msg ? /* @__PURE__ */ jsx7(Text7, { wrap: "truncate", color: msg.level === "bad" ? theme.bad : theme.ok, children: truncate2(msg.text, cols) }) : login?.msg ? /* @__PURE__ */ jsx7(Text7, { wrap: "truncate", color: login.phase === "error" ? theme.bad : theme.ok, children: login.msg }) : /* @__PURE__ */ jsx7(Text7, { children: " " }),
|
|
10615
|
+
/* @__PURE__ */ jsx7(Box7, { flexDirection: "column", height: budget, overflow: "hidden", children: win })
|
|
10439
10616
|
] }) });
|
|
10440
10617
|
}
|
|
10441
|
-
var EVENTS, SPIN2,
|
|
10618
|
+
var EVENTS, SPIN2, SIGNALS2, SIGNAL_LABEL, WINDOWS, winLabel, THRESH_MIN, THRESH_MAX, nearestWindowIdx, EDITOR_FIELDS, acctLabel, alertChannel;
|
|
10442
10619
|
var init_Settings = __esm({
|
|
10443
10620
|
"src/tui/panels/Settings.tsx"() {
|
|
10444
10621
|
"use strict";
|
|
@@ -10451,8 +10628,20 @@ var init_Settings = __esm({
|
|
|
10451
10628
|
init_theme();
|
|
10452
10629
|
EVENTS = ["denials", "allowed", "all"];
|
|
10453
10630
|
SPIN2 = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
10454
|
-
|
|
10631
|
+
SIGNALS2 = ["any", "deny", "dlp", "ratelimit"];
|
|
10632
|
+
SIGNAL_LABEL = { any: "any signal", deny: "denials", dlp: "dlp secrets", ratelimit: "rate-limit" };
|
|
10633
|
+
WINDOWS = [30, 60, 300, 3600, 86400];
|
|
10634
|
+
winLabel = (s) => s < 60 ? `${s}s` : s < 3600 ? `${s / 60}m` : s < 86400 ? `${s / 3600}h` : `${s / 86400}d`;
|
|
10635
|
+
THRESH_MIN = 5;
|
|
10636
|
+
THRESH_MAX = 100;
|
|
10637
|
+
nearestWindowIdx = (s) => {
|
|
10638
|
+
let best = 0;
|
|
10639
|
+
for (let i = 1; i < WINDOWS.length; i++) if (Math.abs(WINDOWS[i] - s) < Math.abs(WINDOWS[best] - s)) best = i;
|
|
10640
|
+
return best;
|
|
10641
|
+
};
|
|
10642
|
+
EDITOR_FIELDS = 4;
|
|
10455
10643
|
acctLabel = (a) => a.email || a.user || "account \u2026" + a.apiKey.slice(-4);
|
|
10644
|
+
alertChannel = (r) => r.emails && r.emails.length ? "email" : r.telegram && r.telegram.length ? "telegram" : null;
|
|
10456
10645
|
}
|
|
10457
10646
|
});
|
|
10458
10647
|
|
|
@@ -10569,24 +10758,29 @@ function App() {
|
|
|
10569
10758
|
}
|
|
10570
10759
|
const Panel = current.Panel;
|
|
10571
10760
|
const panelBody = current.label === "Settings" ? /* @__PURE__ */ jsx8(SettingsPanel, { active: true, focused: focus === "panel", viewApiKey: viewKey, onView: viewAccount }) : /* @__PURE__ */ jsx8(Panel, { active: focus === "panel" || current.label !== "Live", focused: focus === "panel" });
|
|
10572
|
-
return
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10761
|
+
return (
|
|
10762
|
+
// height rows-1 (not rows): once total output reaches stdout.rows ink stops
|
|
10763
|
+
// diffing and clearTerminal-repaints every frame, which slides the banner.
|
|
10764
|
+
// overflow hidden makes it a hard guarantee even if a panel over-renders.
|
|
10765
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", width: cols, height: rows - 1, paddingX: 1, paddingTop: 1, overflow: "hidden", children: [
|
|
10766
|
+
/* @__PURE__ */ jsx8(Banner, { cols }),
|
|
10767
|
+
/* @__PURE__ */ jsxs8(Text8, { wrap: "truncate", children: [
|
|
10768
|
+
/* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "account: " }),
|
|
10769
|
+
/* @__PURE__ */ jsx8(Text8, { color: locked ? theme.warn : theme.accentBright, bold: true, children: acctLabel2 }),
|
|
10770
|
+
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" }),
|
|
10771
|
+
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` }) : update2.kind === "manual" ? /* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: ` \u2191 v${update2.version} available \u2014 npm i -g @solongate/proxy@latest` }) : null
|
|
10772
|
+
] }),
|
|
10773
|
+
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexGrow: 1, children: [
|
|
10774
|
+
/* @__PURE__ */ jsx8(Box8, { flexDirection: "column", width: 16, borderStyle: "round", borderColor: focus === "nav" ? theme.accent : "gray", paddingX: 1, children: SECTIONS.map((s, i) => {
|
|
10775
|
+
const isCur = i === effectiveSection;
|
|
10776
|
+
const disabled = locked && s.label !== "Settings";
|
|
10777
|
+
return /* @__PURE__ */ jsx8(Text8, { color: isCur ? theme.accentBright : disabled ? theme.dim : void 0, bold: isCur, dimColor: disabled, children: (isCur ? "\u25B8 " : disabled ? "\u2298 " : " ") + s.label }, s.label);
|
|
10778
|
+
}) }),
|
|
10779
|
+
/* @__PURE__ */ jsx8(Box8, { flexGrow: 1, borderStyle: "round", borderColor: focus === "panel" ? theme.accent : "gray", paddingX: 1, paddingY: 0, overflow: "hidden", children: panelBody })
|
|
10780
|
+
] }, viewNonce),
|
|
10781
|
+
/* @__PURE__ */ jsx8(Box8, { children: locked ? /* @__PURE__ */ jsx8(KeyHints, { hints: [["\u2192/enter", "open Settings"], ["n", "log in"], ["q", "quit"]] }) : focus === "nav" ? /* @__PURE__ */ jsx8(KeyHints, { hints: [["\u2191\u2193", "section"], ["\u2192/enter", "open"], ...accounts.length > 1 ? [["a", "account"]] : [], ["?", "help"], ["q", "quit"]] }) : /* @__PURE__ */ jsx8(KeyHints, { hints: [["\u2190/esc", "back"], ["\u2191\u2193", "in-panel"], ["space/s", "act"]] }) })
|
|
10782
|
+
] })
|
|
10783
|
+
);
|
|
10590
10784
|
}
|
|
10591
10785
|
function HelpOverlay({ cols, rows }) {
|
|
10592
10786
|
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", width: cols, height: rows, paddingX: 2, paddingTop: 1, children: [
|