@solongate/proxy 0.82.89 → 0.82.90
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/commands/index.js +1 -0
- package/dist/index.js +36 -0
- package/dist/tui/index.js +34 -0
- package/dist/tui/local-log.d.ts +12 -0
- package/package.json +1 -1
|
@@ -28,6 +28,8 @@ export declare const GUEST_EMAIL_SUFFIX = "@anonymous.solongate.invalid";
|
|
|
28
28
|
* way the dashboard does rather than half-working here.
|
|
29
29
|
*/
|
|
30
30
|
export declare function isGuestAccount(): boolean;
|
|
31
|
+
/** The key this device enforces with, or null when it is not paired. */
|
|
32
|
+
export declare function enforcingKey(): string | null;
|
|
31
33
|
/** True when the given key is the ACTIVE one the guard hooks use. */
|
|
32
34
|
export declare function isActiveAccount(apiKey: string): boolean;
|
|
33
35
|
/**
|
package/dist/commands/index.js
CHANGED
|
@@ -1182,6 +1182,7 @@ import { join as join4 } from "path";
|
|
|
1182
1182
|
// src/tui/local-log.ts
|
|
1183
1183
|
import { closeSync, existsSync as existsSync3, openSync, readdirSync, readFileSync as readFileSync4, readSync, statSync, writeFileSync as writeFileSync3 } from "fs";
|
|
1184
1184
|
import { homedir as homedir3 } from "os";
|
|
1185
|
+
import { createHash } from "crypto";
|
|
1185
1186
|
import { isAbsolute, join as join3 } from "path";
|
|
1186
1187
|
var DEFAULT_LOCAL_LOG = join3(homedir3(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
1187
1188
|
function localLogFile() {
|
package/dist/index.js
CHANGED
|
@@ -7404,6 +7404,7 @@ var init_components = __esm({
|
|
|
7404
7404
|
// src/tui/local-log.ts
|
|
7405
7405
|
import { closeSync, existsSync as existsSync4, openSync as openSync3, readdirSync, readFileSync as readFileSync8, readSync, statSync, writeFileSync as writeFileSync6 } from "fs";
|
|
7406
7406
|
import { homedir as homedir6 } from "os";
|
|
7407
|
+
import { createHash as createHash2 } from "crypto";
|
|
7407
7408
|
import { isAbsolute, join as join8 } from "path";
|
|
7408
7409
|
function localLogFile() {
|
|
7409
7410
|
try {
|
|
@@ -7435,6 +7436,30 @@ function localLogFile() {
|
|
|
7435
7436
|
}
|
|
7436
7437
|
return DEFAULT_LOCAL_LOG;
|
|
7437
7438
|
}
|
|
7439
|
+
function ensureLocalLogOwner(activeApiKey) {
|
|
7440
|
+
try {
|
|
7441
|
+
const marker = join8(homedir6(), ".solongate", "local-logs", ".owner");
|
|
7442
|
+
const want = activeApiKey ? createHash2("sha256").update(activeApiKey).digest("hex").slice(0, 16) : "";
|
|
7443
|
+
let have = "";
|
|
7444
|
+
try {
|
|
7445
|
+
have = readFileSync8(marker, "utf-8").trim();
|
|
7446
|
+
} catch {
|
|
7447
|
+
}
|
|
7448
|
+
if (have === want) return false;
|
|
7449
|
+
const cleared = have !== "" && localLogExists();
|
|
7450
|
+
if (cleared) clearLocalLog();
|
|
7451
|
+
try {
|
|
7452
|
+
writeFileSync6(marker, want);
|
|
7453
|
+
} catch {
|
|
7454
|
+
}
|
|
7455
|
+
return cleared;
|
|
7456
|
+
} catch {
|
|
7457
|
+
return false;
|
|
7458
|
+
}
|
|
7459
|
+
}
|
|
7460
|
+
function localLogExists() {
|
|
7461
|
+
return existsSync4(localLogFile());
|
|
7462
|
+
}
|
|
7438
7463
|
function tailLines(file, maxBytes = 131072) {
|
|
7439
7464
|
try {
|
|
7440
7465
|
const size = statSync(file).size;
|
|
@@ -7526,6 +7551,7 @@ __export(client_exports, {
|
|
|
7526
7551
|
GuestReadOnlyError: () => GuestReadOnlyError,
|
|
7527
7552
|
NotAuthenticatedError: () => NotAuthenticatedError,
|
|
7528
7553
|
clearActiveCredential: () => clearActiveCredential,
|
|
7554
|
+
enforcingKey: () => enforcingKey,
|
|
7529
7555
|
isActiveAccount: () => isActiveAccount,
|
|
7530
7556
|
isAuthenticated: () => isAuthenticated,
|
|
7531
7557
|
isGuestAccount: () => isGuestAccount,
|
|
@@ -7597,6 +7623,9 @@ function isGuestAccount() {
|
|
|
7597
7623
|
return false;
|
|
7598
7624
|
}
|
|
7599
7625
|
}
|
|
7626
|
+
function enforcingKey() {
|
|
7627
|
+
return loginCredentialFile().apiKey ?? null;
|
|
7628
|
+
}
|
|
7600
7629
|
function isActiveAccount(apiKey) {
|
|
7601
7630
|
return loginCredentialFile().apiKey === apiKey;
|
|
7602
7631
|
}
|
|
@@ -12238,6 +12267,12 @@ function App() {
|
|
|
12238
12267
|
setViewKey(next?.apiKey);
|
|
12239
12268
|
setViewNonce((n) => n + 1);
|
|
12240
12269
|
};
|
|
12270
|
+
useEffect8(() => {
|
|
12271
|
+
try {
|
|
12272
|
+
ensureLocalLogOwner(enforcingKey());
|
|
12273
|
+
} catch {
|
|
12274
|
+
}
|
|
12275
|
+
}, [accounts.length]);
|
|
12241
12276
|
const locked = accounts.length === 0;
|
|
12242
12277
|
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
12243
12278
|
useInput8((input, key) => {
|
|
@@ -12329,6 +12364,7 @@ var init_App = __esm({
|
|
|
12329
12364
|
init_nav();
|
|
12330
12365
|
init_client();
|
|
12331
12366
|
init_api_client();
|
|
12367
|
+
init_local_log();
|
|
12332
12368
|
init_self_update();
|
|
12333
12369
|
SECTIONS = [
|
|
12334
12370
|
{ label: "Live", Panel: LiveHint },
|
package/dist/tui/index.js
CHANGED
|
@@ -738,6 +738,7 @@ import { join as join5 } from "path";
|
|
|
738
738
|
// src/tui/local-log.ts
|
|
739
739
|
import { closeSync, existsSync, openSync, readdirSync, readFileSync as readFileSync2, readSync, statSync, writeFileSync } from "fs";
|
|
740
740
|
import { homedir as homedir2 } from "os";
|
|
741
|
+
import { createHash } from "crypto";
|
|
741
742
|
import { isAbsolute, join as join2 } from "path";
|
|
742
743
|
var DEFAULT_LOCAL_LOG = join2(homedir2(), ".solongate", "local-logs", "solongate-audit.jsonl");
|
|
743
744
|
function localLogFile() {
|
|
@@ -771,6 +772,30 @@ function localLogFile() {
|
|
|
771
772
|
return DEFAULT_LOCAL_LOG;
|
|
772
773
|
}
|
|
773
774
|
var LOCAL_LOG = localLogFile();
|
|
775
|
+
function ensureLocalLogOwner(activeApiKey) {
|
|
776
|
+
try {
|
|
777
|
+
const marker = join2(homedir2(), ".solongate", "local-logs", ".owner");
|
|
778
|
+
const want = activeApiKey ? createHash("sha256").update(activeApiKey).digest("hex").slice(0, 16) : "";
|
|
779
|
+
let have = "";
|
|
780
|
+
try {
|
|
781
|
+
have = readFileSync2(marker, "utf-8").trim();
|
|
782
|
+
} catch {
|
|
783
|
+
}
|
|
784
|
+
if (have === want) return false;
|
|
785
|
+
const cleared = have !== "" && localLogExists();
|
|
786
|
+
if (cleared) clearLocalLog();
|
|
787
|
+
try {
|
|
788
|
+
writeFileSync(marker, want);
|
|
789
|
+
} catch {
|
|
790
|
+
}
|
|
791
|
+
return cleared;
|
|
792
|
+
} catch {
|
|
793
|
+
return false;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
function localLogExists() {
|
|
797
|
+
return existsSync(localLogFile());
|
|
798
|
+
}
|
|
774
799
|
function tailLines(file, maxBytes = 131072) {
|
|
775
800
|
try {
|
|
776
801
|
const size = statSync(file).size;
|
|
@@ -914,6 +939,9 @@ function isGuestAccount() {
|
|
|
914
939
|
return false;
|
|
915
940
|
}
|
|
916
941
|
}
|
|
942
|
+
function enforcingKey() {
|
|
943
|
+
return loginCredentialFile().apiKey ?? null;
|
|
944
|
+
}
|
|
917
945
|
function isActiveAccount(apiKey) {
|
|
918
946
|
return loginCredentialFile().apiKey === apiKey;
|
|
919
947
|
}
|
|
@@ -5411,6 +5439,12 @@ function App() {
|
|
|
5411
5439
|
setViewKey(next?.apiKey);
|
|
5412
5440
|
setViewNonce((n) => n + 1);
|
|
5413
5441
|
};
|
|
5442
|
+
useEffect8(() => {
|
|
5443
|
+
try {
|
|
5444
|
+
ensureLocalLogOwner(enforcingKey());
|
|
5445
|
+
} catch {
|
|
5446
|
+
}
|
|
5447
|
+
}, [accounts.length]);
|
|
5414
5448
|
const locked = accounts.length === 0;
|
|
5415
5449
|
const effectiveSection = locked ? SETTINGS_SECTION : section;
|
|
5416
5450
|
useInput8((input, key) => {
|
package/dist/tui/local-log.d.ts
CHANGED
|
@@ -23,6 +23,18 @@ export declare function localLogFile(): string;
|
|
|
23
23
|
export declare const LOCAL_LOG: string;
|
|
24
24
|
/** True when the resolved file exists — viewers use it to say "no entries yet"
|
|
25
25
|
* instead of pointing at a path that was never written. */
|
|
26
|
+
/**
|
|
27
|
+
* Make sure the local log belongs to the account now in use.
|
|
28
|
+
*
|
|
29
|
+
* The file is one per machine and no entry records which account produced it,
|
|
30
|
+
* so after pairing a different account the previous one's calls were still
|
|
31
|
+
* sitting in Live. Clearing on an in-app account switch was not enough: the
|
|
32
|
+
* account can change by pairing a new device, by signing out, or from the
|
|
33
|
+
* dashboard. A marker beside the log records whose it is (a hash, never the
|
|
34
|
+
* key itself); when that stops matching, the file is not ours and is started
|
|
35
|
+
* over. Returns true when it cleared.
|
|
36
|
+
*/
|
|
37
|
+
export declare function ensureLocalLogOwner(activeApiKey: string | null | undefined): boolean;
|
|
26
38
|
export declare function localLogExists(): boolean;
|
|
27
39
|
/** Read the last `maxBytes` of a file as complete lines (first partial dropped). */
|
|
28
40
|
export declare function tailLines(file: string, maxBytes?: number): string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solongate/proxy",
|
|
3
|
-
"version": "0.82.
|
|
3
|
+
"version": "0.82.90",
|
|
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": {
|