@solongate/proxy 0.82.86 → 0.82.88
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 +10 -0
- package/dist/index.js +46 -6
- package/dist/tui/index.js +9 -4
- package/package.json +1 -1
|
@@ -18,6 +18,16 @@ export declare function saveAccount(acc: SavedAccount): void;
|
|
|
18
18
|
/** Remove a saved account from this device (does NOT revoke the cloud key). */
|
|
19
19
|
export declare function removeAccount(apiKey: string): void;
|
|
20
20
|
export declare function setViewCredentials(creds: Credentials | null): void;
|
|
21
|
+
/** The unroutable address a guest ("Skip for now") account is stored under. */
|
|
22
|
+
export declare const GUEST_EMAIL_SUFFIX = "@anonymous.solongate.invalid";
|
|
23
|
+
/**
|
|
24
|
+
* True when the account this device is enforcing with is a guest one.
|
|
25
|
+
*
|
|
26
|
+
* A guest has no dashboard rights beyond reading, and the CLI is the same
|
|
27
|
+
* account reached a different way, so the management commands answer the same
|
|
28
|
+
* way the dashboard does rather than half-working here.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isGuestAccount(): boolean;
|
|
21
31
|
/** True when the given key is the ACTIVE one the guard hooks use. */
|
|
22
32
|
export declare function isActiveAccount(apiKey: string): boolean;
|
|
23
33
|
/**
|
package/dist/index.js
CHANGED
|
@@ -7518,6 +7518,24 @@ var init_local_log = __esm({
|
|
|
7518
7518
|
});
|
|
7519
7519
|
|
|
7520
7520
|
// src/api-client/client.ts
|
|
7521
|
+
var client_exports = {};
|
|
7522
|
+
__export(client_exports, {
|
|
7523
|
+
ApiError: () => ApiError,
|
|
7524
|
+
DEFAULT_API_URL: () => DEFAULT_API_URL2,
|
|
7525
|
+
GUEST_EMAIL_SUFFIX: () => GUEST_EMAIL_SUFFIX,
|
|
7526
|
+
NotAuthenticatedError: () => NotAuthenticatedError,
|
|
7527
|
+
clearActiveCredential: () => clearActiveCredential,
|
|
7528
|
+
isActiveAccount: () => isActiveAccount,
|
|
7529
|
+
isAuthenticated: () => isAuthenticated,
|
|
7530
|
+
isGuestAccount: () => isGuestAccount,
|
|
7531
|
+
listAccounts: () => listAccounts,
|
|
7532
|
+
removeAccount: () => removeAccount,
|
|
7533
|
+
request: () => request,
|
|
7534
|
+
resolveCredentials: () => resolveCredentials,
|
|
7535
|
+
saveAccount: () => saveAccount,
|
|
7536
|
+
setActiveAccount: () => setActiveAccount,
|
|
7537
|
+
setViewCredentials: () => setViewCredentials
|
|
7538
|
+
});
|
|
7521
7539
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync6, existsSync as existsSync5 } from "fs";
|
|
7522
7540
|
import { resolve as resolve4, join as join9 } from "path";
|
|
7523
7541
|
import { homedir as homedir7 } from "os";
|
|
@@ -7569,6 +7587,15 @@ function setViewCredentials(creds) {
|
|
|
7569
7587
|
viewOverride = creds;
|
|
7570
7588
|
cached2 = null;
|
|
7571
7589
|
}
|
|
7590
|
+
function isGuestAccount() {
|
|
7591
|
+
try {
|
|
7592
|
+
const active2 = loginCredentialFile().apiKey;
|
|
7593
|
+
if (!active2) return false;
|
|
7594
|
+
return listAccounts().some((a) => a.apiKey === active2 && (a.email ?? "").endsWith(GUEST_EMAIL_SUFFIX));
|
|
7595
|
+
} catch {
|
|
7596
|
+
return false;
|
|
7597
|
+
}
|
|
7598
|
+
}
|
|
7572
7599
|
function isActiveAccount(apiKey) {
|
|
7573
7600
|
return loginCredentialFile().apiKey === apiKey;
|
|
7574
7601
|
}
|
|
@@ -7723,7 +7750,7 @@ async function request(method, path, opts = {}) {
|
|
|
7723
7750
|
}
|
|
7724
7751
|
return json;
|
|
7725
7752
|
}
|
|
7726
|
-
var DEFAULT_API_URL2, accountsFile, viewOverride, ApiError, NotAuthenticatedError, cached2;
|
|
7753
|
+
var DEFAULT_API_URL2, accountsFile, viewOverride, GUEST_EMAIL_SUFFIX, ApiError, NotAuthenticatedError, cached2;
|
|
7727
7754
|
var init_client = __esm({
|
|
7728
7755
|
"src/api-client/client.ts"() {
|
|
7729
7756
|
"use strict";
|
|
@@ -7731,6 +7758,7 @@ var init_client = __esm({
|
|
|
7731
7758
|
DEFAULT_API_URL2 = "https://api.solongate.com";
|
|
7732
7759
|
accountsFile = () => join9(homedir7(), ".solongate", "accounts.json");
|
|
7733
7760
|
viewOverride = null;
|
|
7761
|
+
GUEST_EMAIL_SUFFIX = "@anonymous.solongate.invalid";
|
|
7734
7762
|
ApiError = class extends Error {
|
|
7735
7763
|
status;
|
|
7736
7764
|
code;
|
|
@@ -11857,7 +11885,8 @@ function SettingsPanel({
|
|
|
11857
11885
|
}
|
|
11858
11886
|
const loading = !locked && (localQ.loading && !localQ.data || whQ.loading && !whQ.data || alertQ.loading && !alertQ.data || guardQ.loading && !guardQ.data || selfQ.loading && !selfQ.data);
|
|
11859
11887
|
const rawError = locked ? null : localQ.error ?? whQ.error ?? alertQ.error ?? guardQ.error ?? selfQ.error;
|
|
11860
|
-
const authError = rawError && /invalid api key|authentication|401|unauthor/i.test(rawError) ? rawError : null;
|
|
11888
|
+
const authError = rawError && /invalid api key|authentication|401|unauthor|not logged in/i.test(rawError) ? rawError : null;
|
|
11889
|
+
const noKey = !!authError && /not logged in/i.test(authError);
|
|
11861
11890
|
const error = authError ? null : rawError;
|
|
11862
11891
|
const onOff = (on) => on ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, children: "on " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "off" });
|
|
11863
11892
|
const chanOf = (rule) => [...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
|
|
@@ -12053,7 +12082,10 @@ function SettingsPanel({
|
|
|
12053
12082
|
const moreBelow = Math.max(0, lineEls.length - (startL + budget));
|
|
12054
12083
|
return /* @__PURE__ */ jsx8(DataView, { loading, error, children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
12055
12084
|
/* @__PURE__ */ jsx8(Text8, { 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" }),
|
|
12056
|
-
authError ? /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", color: theme.bad, children: truncate2(
|
|
12085
|
+
authError ? /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", color: theme.bad, children: truncate2(
|
|
12086
|
+
noKey ? "\u2717 this device is not paired yet \u2014 press + add account below to sign in and pair it" : "\u2717 this device's key is invalid or was revoked \u2014 press x on the account below to remove it, then + add account to pair again",
|
|
12087
|
+
cols
|
|
12088
|
+
) }) : null,
|
|
12057
12089
|
editing ? /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
12058
12090
|
/* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: editing === "path" ? "local log path: " : "webhook url: " }),
|
|
12059
12091
|
/* @__PURE__ */ jsx8(TextInput6, { value: input, onChange: setInput, onSubmit: submitInput })
|
|
@@ -12157,8 +12189,9 @@ function App() {
|
|
|
12157
12189
|
const acctIdx = Math.max(0, accounts.findIndex((a) => a.apiKey === viewKey));
|
|
12158
12190
|
const cur = accounts[acctIdx];
|
|
12159
12191
|
const rawEmail = cur?.email ?? "";
|
|
12160
|
-
const
|
|
12161
|
-
const
|
|
12192
|
+
const isGuestAccount2 = rawEmail.endsWith("@anonymous.solongate.invalid");
|
|
12193
|
+
const hasKey = isAuthenticated();
|
|
12194
|
+
const acctLabel2 = !cur ? "not logged in" : !hasKey ? "signed out" : isGuestAccount2 ? "Anonymous" : rawEmail || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}`;
|
|
12162
12195
|
useEffect8(() => {
|
|
12163
12196
|
if (!cur || cur.email) return;
|
|
12164
12197
|
let alive = true;
|
|
@@ -12193,7 +12226,7 @@ function App() {
|
|
|
12193
12226
|
setViewKey(next?.apiKey);
|
|
12194
12227
|
setViewNonce((n) => n + 1);
|
|
12195
12228
|
};
|
|
12196
|
-
const locked = accounts.length === 0 || !
|
|
12229
|
+
const locked = accounts.length === 0 || !hasKey;
|
|
12197
12230
|
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
12198
12231
|
useInput8((input, key) => {
|
|
12199
12232
|
if (help) {
|
|
@@ -16998,6 +17031,13 @@ async function main() {
|
|
|
16998
17031
|
}
|
|
16999
17032
|
const MGMT_COMMANDS = /* @__PURE__ */ new Set(["policy", "ratelimit", "dlp", "stats", "audit", "sessions", "session", "doctor", "watch", "alerts", "webhooks"]);
|
|
17000
17033
|
if (MGMT_COMMANDS.has(subcommand ?? "")) {
|
|
17034
|
+
const { isGuestAccount: isGuestAccount2 } = await Promise.resolve().then(() => (init_client(), client_exports));
|
|
17035
|
+
if (subcommand !== "doctor" && isGuestAccount2()) {
|
|
17036
|
+
process.stderr.write(
|
|
17037
|
+
"\n This is a guest account, which can look but not change.\n Create an account to use the management commands:\n https://auth.solongate.com\n\n Your project, its policy and everything already recorded carry over,\n and this device keeps working without being paired again.\n\n"
|
|
17038
|
+
);
|
|
17039
|
+
process.exit(1);
|
|
17040
|
+
}
|
|
17001
17041
|
const { runCommand: runCommand2 } = await Promise.resolve().then(() => (init_commands(), commands_exports));
|
|
17002
17042
|
const code = await runCommand2(subcommand, process.argv.slice(3));
|
|
17003
17043
|
process.exit(code);
|
package/dist/tui/index.js
CHANGED
|
@@ -5073,7 +5073,8 @@ function SettingsPanel({
|
|
|
5073
5073
|
}
|
|
5074
5074
|
const loading = !locked && (localQ.loading && !localQ.data || whQ.loading && !whQ.data || alertQ.loading && !alertQ.data || guardQ.loading && !guardQ.data || selfQ.loading && !selfQ.data);
|
|
5075
5075
|
const rawError = locked ? null : localQ.error ?? whQ.error ?? alertQ.error ?? guardQ.error ?? selfQ.error;
|
|
5076
|
-
const authError = rawError && /invalid api key|authentication|401|unauthor/i.test(rawError) ? rawError : null;
|
|
5076
|
+
const authError = rawError && /invalid api key|authentication|401|unauthor|not logged in/i.test(rawError) ? rawError : null;
|
|
5077
|
+
const noKey = !!authError && /not logged in/i.test(authError);
|
|
5077
5078
|
const error = authError ? null : rawError;
|
|
5078
5079
|
const onOff = (on) => on ? /* @__PURE__ */ jsx8(Text8, { color: theme.ok, children: "on " }) : /* @__PURE__ */ jsx8(Text8, { color: theme.dim, children: "off" });
|
|
5079
5080
|
const chanOf = (rule) => [...rule.emails ?? [], ...(rule.telegram ?? []).map((t) => "tg " + t)].join(", ") || "\u2014";
|
|
@@ -5269,7 +5270,10 @@ function SettingsPanel({
|
|
|
5269
5270
|
const moreBelow = Math.max(0, lineEls.length - (startL + budget));
|
|
5270
5271
|
return /* @__PURE__ */ jsx8(DataView, { loading, error, children: /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
5271
5272
|
/* @__PURE__ */ jsx8(Text8, { 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" }),
|
|
5272
|
-
authError ? /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", color: theme.bad, children: truncate(
|
|
5273
|
+
authError ? /* @__PURE__ */ jsx8(Text8, { wrap: "truncate", color: theme.bad, children: truncate(
|
|
5274
|
+
noKey ? "\u2717 this device is not paired yet \u2014 press + add account below to sign in and pair it" : "\u2717 this device's key is invalid or was revoked \u2014 press x on the account below to remove it, then + add account to pair again",
|
|
5275
|
+
cols
|
|
5276
|
+
) }) : null,
|
|
5273
5277
|
editing ? /* @__PURE__ */ jsxs8(Box8, { children: [
|
|
5274
5278
|
/* @__PURE__ */ jsx8(Text8, { color: theme.warn, children: editing === "path" ? "local log path: " : "webhook url: " }),
|
|
5275
5279
|
/* @__PURE__ */ jsx8(TextInput6, { value: input, onChange: setInput, onSubmit: submitInput })
|
|
@@ -5351,7 +5355,8 @@ function App() {
|
|
|
5351
5355
|
const cur = accounts[acctIdx];
|
|
5352
5356
|
const rawEmail = cur?.email ?? "";
|
|
5353
5357
|
const isGuestAccount = rawEmail.endsWith("@anonymous.solongate.invalid");
|
|
5354
|
-
const
|
|
5358
|
+
const hasKey = isAuthenticated();
|
|
5359
|
+
const acctLabel2 = !cur ? "not logged in" : !hasKey ? "signed out" : isGuestAccount ? "Anonymous" : rawEmail || cur.user || cur.project || `account \u2026${cur.apiKey.slice(-4)}`;
|
|
5355
5360
|
useEffect8(() => {
|
|
5356
5361
|
if (!cur || cur.email) return;
|
|
5357
5362
|
let alive = true;
|
|
@@ -5386,7 +5391,7 @@ function App() {
|
|
|
5386
5391
|
setViewKey(next?.apiKey);
|
|
5387
5392
|
setViewNonce((n) => n + 1);
|
|
5388
5393
|
};
|
|
5389
|
-
const locked = accounts.length === 0 || !
|
|
5394
|
+
const locked = accounts.length === 0 || !hasKey;
|
|
5390
5395
|
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
5391
5396
|
useInput8((input, key) => {
|
|
5392
5397
|
if (help) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.88",
|
|
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": {
|