opencode-nim-rotator 0.0.1 → 0.0.3

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/README.md CHANGED
@@ -23,7 +23,7 @@ The postinstall script automatically adds the plugin to your `~/.config/opencode
23
23
  Run the TUI manager:
24
24
 
25
25
  ```bash
26
- bun opencode-nim-rotator
26
+ opencode-nim-rotator
27
27
  ```
28
28
 
29
29
  Or manually — add at least one key via OpenCode's auth system:
@@ -37,7 +37,7 @@ Select "Enter NVIDIA NIM API Key" and paste your key.
37
37
  ### 2. Add more keys via the TUI
38
38
 
39
39
  ```bash
40
- bun opencode-nim-rotator
40
+ opencode-nim-rotator
41
41
  ```
42
42
 
43
43
  The TUI lets you:
@@ -112,7 +112,8 @@ Keys are stored in `~/.config/opencode/nim-rotator-keys.json` with file mode `06
112
112
  ],
113
113
  "currentIndex": 0,
114
114
  "rotationStrategy": "round-robin",
115
- "updatedAt": 1700000000000
115
+ "updatedAt": 1700000000000,
116
+ "lastUsedKeyId": "uuid"
116
117
  }
117
118
  ```
118
119
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
3
  import { createCliRenderer } from "@opentui/core";
4
- import { state } from "../src/tui/state.js";
5
- import { initApp } from "../src/tui/app.js";
4
+ import { state } from "../dist/tui/state.js";
5
+ import { initApp } from "../dist/tui/app.js";
6
6
 
7
7
  const renderer = await createCliRenderer({ exitOnCtrlC: false });
8
8
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAC;AAkCtE,eAAO,MAAM,mBAAmB,EAAE,MAyFjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAsB,MAAM,qBAAqB,CAAC;AA2CtE,eAAO,MAAM,mBAAmB,EAAE,MA8FjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -3,17 +3,27 @@ const PROVIDER_ID = "nvidia";
3
3
  const NIM_BASE_URL = "https://integrate.api.nvidia.com";
4
4
  const VALID_STRATEGIES = ["round-robin", "least-failures"];
5
5
  function isValidStrategy(val) {
6
- return typeof val === "string" && VALID_STRATEGIES.includes(val);
6
+ return val === "round-robin" || val === "least-failures";
7
7
  }
8
- function isAuthError(obj) {
8
+ function isRecoverableError(obj) {
9
9
  if (typeof obj === "object" && obj !== null) {
10
- const code = obj.code;
11
- const status = obj.status;
12
- if (code === 401 || code === 403 || status === 401 || status === 403)
10
+ const rec = obj;
11
+ const name = rec.name;
12
+ if (name === "ProviderAuthError")
13
13
  return true;
14
+ if (name === "APIError") {
15
+ const data = rec.data;
16
+ const statusCode = data?.statusCode;
17
+ if (statusCode === 401 || statusCode === 403 || statusCode === 429)
18
+ return true;
19
+ }
14
20
  }
15
21
  const msg = String(obj).toLowerCase();
16
- return (msg.includes("401") || msg.includes("403") || msg.includes("unauthorized"));
22
+ return (/\b401\b/.test(msg) ||
23
+ /\b403\b/.test(msg) ||
24
+ /\b429\b/.test(msg) ||
25
+ msg.includes("unauthorized") ||
26
+ msg.includes("rate limit"));
17
27
  }
18
28
  export const NvidiaNimKeyRotator = async (input, options) => {
19
29
  const config = {
@@ -89,10 +99,15 @@ export const NvidiaNimKeyRotator = async (input, options) => {
89
99
  }
90
100
  },
91
101
  event: async ({ event }) => {
92
- if (event.type === "session.error" && isAuthError(event.error)) {
93
- if (store.lastUsedKeyId) {
94
- recordFailure(store, store.lastUsedKeyId);
95
- saveStore(store, config);
102
+ if (event.type === "session.error") {
103
+ const evt = event;
104
+ const props = evt.properties;
105
+ const error = evt.error ?? props?.error;
106
+ if (isRecoverableError(error)) {
107
+ if (store.lastUsedKeyId) {
108
+ recordFailure(store, store.lastUsedKeyId);
109
+ saveStore(store, config);
110
+ }
96
111
  }
97
112
  }
98
113
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,SAAS,EACT,MAAM,EACN,UAAU,EACV,aAAa,EACb,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC7B,MAAM,YAAY,GAAG,kCAAkC,CAAC;AACxD,MAAM,gBAAgB,GAAG,CAAC,aAAa,EAAE,gBAAgB,CAAU,CAAC;AAEpE,SAAS,eAAe,CACtB,GAAY;IAEZ,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,gBAAgB,CAAC,QAAQ,CAAC,GAAU,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAI,GAAW,CAAC,IAAI,CAAC;QAC/B,MAAM,MAAM,GAAI,GAAW,CAAC,MAAM,CAAC;QACnC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;YAClE,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACtC,OAAO,CACL,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,CAC3E,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAW,KAAK,EAC9C,KAAkB,EAClB,OAAiC,EACjC,EAAE;IACF,MAAM,MAAM,GAAmB;QAC7B,SAAS,EAAE,OAAO,EAAE,SAA+B;QACnD,gBAAgB,EAAE,eAAe,CAAC,OAAO,EAAE,gBAAgB,CAAC;YAC1D,CAAC,CAAC,OAAQ,CAAC,gBAAgB;YAC3B,CAAC,CAAC,aAAa;KAClB,CAAC;IAEF,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAEhD,wCAAwC;IACxC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC1C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;YAClE,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;gBACrC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAU;QACnB,IAAI,EAAE;YACJ,QAAQ,EAAE,WAAW;YACrB,sDAAsD;YACtD,uDAAuD;YACvD,0DAA0D;YAC1D,mCAAmC;YACnC,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,KAAK;oBACX,KAAK,EAAE,0BAA0B;oBACjC,KAAK,CAAC,SAAS,CAAC,MAAM;wBACpB,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC;wBAC/B,IAAI,CAAC,GAAG;4BAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;wBAEpC,IAAI,CAAC;4BACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,YAAY,EAAE;gCACnD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,GAAG,EAAE,EAAE;6BAC5C,CAAC,CAAC;4BACH,IAAI,CAAC,GAAG,CAAC,EAAE;gCAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;wBACzC,CAAC;wBAAC,MAAM,CAAC;4BACP,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;wBAC5B,CAAC;wBAED,OAAO;4BACL,IAAI,EAAE,SAAS;4BACf,GAAG;4BACH,QAAQ,EAAE,WAAW;yBACtB,CAAC;oBACJ,CAAC;iBACF;aACF;SACF;QACD,+DAA+D;QAC/D,6DAA6D;QAC7D,iEAAiE;QACjE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvC,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;gBAC5D,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YACpC,IAAI,MAAM,CAAC,GAAG,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;gBAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBACvC,IAAI,IAAI,EAAE,CAAC;oBACT,MAAM,CAAC,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;oBACzC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;QACD,KAAK,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YACzB,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,WAAW,CAAE,KAAa,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxE,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;oBACxB,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;oBAC1C,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/storage.d.ts CHANGED
@@ -1,6 +1,8 @@
1
- import type { ApiKeyEntry, KeyStore, KeyStoreConfig } from "./types.js";
1
+ import type { ApiKeyEntry, ExportedKey, ExportPayload, KeyStore, KeyStoreConfig } from "./types.js";
2
2
  export declare const DEFAULT_MAX_FAILURES = 5;
3
3
  export declare function resolveStorePath(config?: KeyStoreConfig): string;
4
+ export declare function checkFilePermissions(filePath: string): string | null;
5
+ export declare function validateExportPath(filePath: string): string | null;
4
6
  export declare function loadStore(config?: KeyStoreConfig): KeyStore;
5
7
  export declare function saveStore(store: KeyStore, config?: KeyStoreConfig): void;
6
8
  export declare function addKey(store: KeyStore, name: string, key: string): void;
@@ -15,4 +17,22 @@ export declare function getNextKey(store: KeyStore, config?: KeyStoreConfig): {
15
17
  } | null;
16
18
  export declare function recordFailure(store: KeyStore, keyId: string): void;
17
19
  export declare function resetFailures(store: KeyStore, keyId?: string): void;
20
+ export declare function exportKeys(store: KeyStore): ExportPayload;
21
+ export declare function writeExportFile(payload: ExportPayload, filePath: string): void;
22
+ export declare function readAndValidateImportFile(filePath: string): {
23
+ raw: string;
24
+ } | {
25
+ error: string;
26
+ };
27
+ export interface ImportResult {
28
+ added: number;
29
+ skipped: number;
30
+ errors: string[];
31
+ pendingKeys: ExportedKey[];
32
+ }
33
+ export declare function validateImportPayload(raw: string): ImportResult;
34
+ export declare function applyImport(store: KeyStore, pendingKeys: ExportedKey[]): {
35
+ added: number;
36
+ skipped: number;
37
+ };
18
38
  //# sourceMappingURL=storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQxE,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAWtC,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAMhE;AAED,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,QAAQ,CAwB3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAUxE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAUvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAO3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAG5E;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,QAAQ,EACf,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI,CAGN;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAK9D;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,cAAc,GACtB,WAAW,EAAE,CAGf;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,cAAc,GACtB;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAyB5C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAOnE"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,QAAQ,EACR,cAAc,EACf,MAAM,YAAY,CAAC;AAQpB,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAkBtC,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAMhE;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyBpE;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAelE;AA2BD,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,QAAQ,CAmD3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAmBxE;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAUvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAO3D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAG5E;AAED,wBAAgB,SAAS,CACvB,KAAK,EAAE,QAAQ,EACf,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,OAAO,GAChB,IAAI,CAGN;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,CAK9D;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,cAAc,GACtB,WAAW,EAAE,CAGf;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,QAAQ,EACf,MAAM,CAAC,EAAE,cAAc,GACtB;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkC5C;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAGlE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAOnE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,QAAQ,GAAG,aAAa,CAMzD;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,GACf,IAAI,CAmBN;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,GACf;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAcrC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,EAAE,WAAW,EAAE,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAuF/D;AAED,wBAAgB,WAAW,CACzB,KAAK,EAAE,QAAQ,EACf,WAAW,EAAE,WAAW,EAAE,GACzB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAsBpC"}
package/dist/storage.js CHANGED
@@ -1,14 +1,20 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
- import { join, dirname } from "path";
1
+ import { closeSync, existsSync, fstatSync, lstatSync, mkdirSync, openSync, readSync, readFileSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync, } from "fs";
2
+ import { join, dirname, basename, resolve } from "path";
3
3
  import { homedir } from "os";
4
4
  const DEFAULT_STORE_PATH = join(homedir(), ".config", "opencode", "nim-rotator-keys.json");
5
5
  export const DEFAULT_MAX_FAILURES = 5;
6
+ const MAX_IMPORT_SIZE = 1024 * 1024;
7
+ const MAX_IMPORT_KEYS = 100;
8
+ const MAX_KEY_LENGTH = 256;
9
+ const MAX_NAME_LENGTH = 128;
10
+ const SYSTEM_PATH_PREFIXES = ["/etc/", "/proc/", "/sys/", "/dev/"];
6
11
  function getDefaultStore() {
7
12
  return {
8
13
  keys: [],
9
14
  currentIndex: 0,
10
15
  rotationStrategy: "round-robin",
11
16
  updatedAt: Date.now(),
17
+ lastUsedKeyId: undefined,
12
18
  };
13
19
  }
14
20
  export function resolveStorePath(config) {
@@ -16,24 +22,118 @@ export function resolveStorePath(config) {
16
22
  process.env.NIM_ROTATOR_STORE_PATH ??
17
23
  DEFAULT_STORE_PATH);
18
24
  }
25
+ export function checkFilePermissions(filePath) {
26
+ try {
27
+ if (!existsSync(filePath))
28
+ return "File does not exist";
29
+ const resolvedPath = realpathSync(filePath);
30
+ const lstat = lstatSync(filePath);
31
+ if (lstat.isSymbolicLink()) {
32
+ return "File is a symbolic link. Refusing to follow symlinks.";
33
+ }
34
+ const stat = statSync(resolvedPath);
35
+ const mode = stat.mode;
36
+ const othersPerm = mode & 0o007;
37
+ if (othersPerm !== 0) {
38
+ return "File is world-accessible. Refusing to read from insecure file.";
39
+ }
40
+ const groupPerm = mode & 0o070;
41
+ if ((groupPerm & 0o040) !== 0) {
42
+ return "File is group-readable. Refusing to read from insecure file.";
43
+ }
44
+ if ((groupPerm & 0o020) !== 0) {
45
+ return "File is group-writable. Refusing to read from insecure file.";
46
+ }
47
+ return null;
48
+ }
49
+ catch {
50
+ return "Cannot verify file permissions";
51
+ }
52
+ }
53
+ export function validateExportPath(filePath) {
54
+ let resolved;
55
+ const dir = dirname(filePath);
56
+ try {
57
+ const dirRes = realpathSync(dir);
58
+ resolved = join(dirRes, basename(filePath));
59
+ }
60
+ catch {
61
+ resolved = resolve(filePath);
62
+ }
63
+ for (const prefix of SYSTEM_PATH_PREFIXES) {
64
+ if (resolved.startsWith(prefix)) {
65
+ return "Cannot write to system directories";
66
+ }
67
+ }
68
+ return null;
69
+ }
70
+ function readSecureFile(filePath) {
71
+ let fd;
72
+ try {
73
+ fd = openSync(filePath, "r");
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ try {
79
+ const stat = fstatSync(fd);
80
+ const mode = stat.mode;
81
+ const othersPerm = mode & 0o007;
82
+ if (othersPerm !== 0)
83
+ return null;
84
+ const groupPerm = mode & 0o070;
85
+ if ((groupPerm & 0o040) !== 0)
86
+ return null;
87
+ if ((groupPerm & 0o020) !== 0)
88
+ return null;
89
+ const buf = Buffer.alloc(stat.size);
90
+ const bytesRead = readSync(fd, buf, 0, stat.size, 0);
91
+ return buf.toString("utf-8", 0, bytesRead);
92
+ }
93
+ catch {
94
+ return null;
95
+ }
96
+ finally {
97
+ closeSync(fd);
98
+ }
99
+ }
19
100
  export function loadStore(config) {
20
101
  const storePath = resolveStorePath(config);
21
102
  try {
22
103
  if (existsSync(storePath)) {
23
- const raw = readFileSync(storePath, "utf-8");
104
+ const resolvedPath = realpathSync(storePath);
105
+ const lstat = lstatSync(storePath);
106
+ if (lstat.isSymbolicLink()) {
107
+ console.error("[nim-rotator] SECURITY: Key store is a symlink. Refusing to load.");
108
+ return getDefaultStore();
109
+ }
110
+ const permError = checkFilePermissions(storePath);
111
+ if (permError) {
112
+ console.error(`[nim-rotator] SECURITY: ${permError}`);
113
+ console.error(`[nim-rotator] Fix permissions: chmod 600 "${storePath}"`);
114
+ return getDefaultStore();
115
+ }
116
+ const raw = readFileSync(resolvedPath, "utf-8");
24
117
  const data = JSON.parse(raw);
25
- if (!data.keys || !Array.isArray(data.keys)) {
26
- console.warn(`[nim-rotator] Store at "${storePath}" has invalid keys format, using defaults`);
118
+ if (!data || typeof data !== "object" || !Array.isArray(data.keys)) {
119
+ console.warn("[nim-rotator] Store has invalid format, using defaults");
27
120
  return getDefaultStore();
28
121
  }
29
122
  return {
30
- ...getDefaultStore(),
31
- ...data,
123
+ keys: Array.isArray(data.keys) ? data.keys : [],
124
+ currentIndex: typeof data.currentIndex === "number" ? data.currentIndex : 0,
125
+ rotationStrategy: data.rotationStrategy === "least-failures"
126
+ ? "least-failures"
127
+ : "round-robin",
128
+ updatedAt: typeof data.updatedAt === "number" ? data.updatedAt : Date.now(),
129
+ lastUsedKeyId: typeof data.lastUsedKeyId === "string"
130
+ ? data.lastUsedKeyId
131
+ : undefined,
32
132
  };
33
133
  }
34
134
  }
35
- catch (err) {
36
- console.error(`[nim-rotator] Failed to load store at "${storePath}":`, err);
135
+ catch {
136
+ console.error("[nim-rotator] Failed to load key store. Check file permissions and format.");
37
137
  console.warn("[nim-rotator] Starting with a fresh store. Your existing keys are preserved on disk.");
38
138
  }
39
139
  return getDefaultStore();
@@ -42,12 +142,23 @@ export function saveStore(store, config) {
42
142
  const storePath = resolveStorePath(config);
43
143
  const dir = dirname(storePath);
44
144
  if (!existsSync(dir)) {
45
- mkdirSync(dir, { recursive: true });
145
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
46
146
  }
47
147
  store.updatedAt = Date.now();
48
- writeFileSync(storePath, JSON.stringify(store, null, 2) + "\n", {
49
- mode: 0o600,
50
- });
148
+ const tmpPath = storePath + ".tmp." + process.pid;
149
+ try {
150
+ writeFileSync(tmpPath, JSON.stringify(store, null, 2) + "\n", {
151
+ mode: 0o600,
152
+ });
153
+ renameSync(tmpPath, storePath);
154
+ }
155
+ catch (err) {
156
+ try {
157
+ unlinkSync(tmpPath);
158
+ }
159
+ catch { }
160
+ throw err;
161
+ }
51
162
  }
52
163
  export function addKey(store, name, key) {
53
164
  const entry = {
@@ -93,7 +204,12 @@ export function getNextKey(store, config) {
93
204
  return null;
94
205
  const strategy = config?.rotationStrategy ?? store.rotationStrategy ?? "round-robin";
95
206
  if (strategy === "least-failures") {
96
- const sorted = [...active].sort((a, b) => a.failureCount - b.failureCount);
207
+ const sorted = [...active].sort((a, b) => {
208
+ if (a.failureCount !== b.failureCount) {
209
+ return a.failureCount - b.failureCount;
210
+ }
211
+ return (a.lastUsedAt ?? 0) - (b.lastUsedAt ?? 0);
212
+ });
97
213
  const best = sorted[0];
98
214
  const idx = store.keys.indexOf(best);
99
215
  store.currentIndex = idx;
@@ -102,10 +218,15 @@ export function getNextKey(store, config) {
102
218
  return { key: best, index: idx };
103
219
  }
104
220
  // round-robin
105
- let idx = store.currentIndex % active.length;
221
+ const idx = store.currentIndex % active.length;
106
222
  const selected = active[idx];
107
223
  const realIdx = store.keys.indexOf(selected);
108
- store.currentIndex = (idx + 1) % active.length;
224
+ if (store.currentIndex >= active.length) {
225
+ store.currentIndex = 0;
226
+ }
227
+ else {
228
+ store.currentIndex = (idx + 1) % active.length;
229
+ }
109
230
  store.lastUsedKeyId = selected.id;
110
231
  selected.lastUsedAt = Date.now();
111
232
  return { key: selected, index: realIdx };
@@ -126,4 +247,138 @@ export function resetFailures(store, keyId) {
126
247
  k.failureCount = 0;
127
248
  }
128
249
  }
250
+ export function exportKeys(store) {
251
+ return {
252
+ version: 1,
253
+ exportedAt: Date.now(),
254
+ keys: store.keys.map((k) => ({ name: k.name, key: k.key })),
255
+ };
256
+ }
257
+ export function writeExportFile(payload, filePath) {
258
+ const pathError = validateExportPath(filePath);
259
+ if (pathError)
260
+ throw new Error(pathError);
261
+ const dir = dirname(filePath);
262
+ if (!existsSync(dir)) {
263
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
264
+ }
265
+ const tmpPath = filePath + ".tmp." + process.pid;
266
+ try {
267
+ writeFileSync(tmpPath, JSON.stringify(payload, null, 2) + "\n", {
268
+ mode: 0o600,
269
+ });
270
+ renameSync(tmpPath, filePath);
271
+ }
272
+ catch (err) {
273
+ try {
274
+ unlinkSync(tmpPath);
275
+ }
276
+ catch { }
277
+ throw err;
278
+ }
279
+ }
280
+ export function readAndValidateImportFile(filePath) {
281
+ const resolved = resolve(filePath);
282
+ for (const prefix of SYSTEM_PATH_PREFIXES) {
283
+ if (resolved.startsWith(prefix)) {
284
+ return { error: "Cannot read from system directories" };
285
+ }
286
+ }
287
+ const permError = checkFilePermissions(filePath);
288
+ if (permError)
289
+ return { error: permError };
290
+ const raw = readSecureFile(filePath);
291
+ if (raw === null)
292
+ return { error: "Cannot read file or file has insecure permissions" };
293
+ return { raw };
294
+ }
295
+ export function validateImportPayload(raw) {
296
+ const result = {
297
+ added: 0,
298
+ skipped: 0,
299
+ errors: [],
300
+ pendingKeys: [],
301
+ };
302
+ if (raw.length > MAX_IMPORT_SIZE) {
303
+ result.errors.push(`Import file too large (max ${MAX_IMPORT_SIZE / 1024}KB)`);
304
+ return result;
305
+ }
306
+ let data;
307
+ try {
308
+ data = JSON.parse(raw);
309
+ }
310
+ catch {
311
+ result.errors.push("Invalid JSON format");
312
+ return result;
313
+ }
314
+ if (typeof data !== "object" || data === null) {
315
+ result.errors.push("Expected a JSON object");
316
+ return result;
317
+ }
318
+ const rec = data;
319
+ if (rec.version !== 1) {
320
+ result.errors.push("Unsupported export version");
321
+ return result;
322
+ }
323
+ if (!Array.isArray(rec.keys)) {
324
+ result.errors.push("Missing or invalid 'keys' array");
325
+ return result;
326
+ }
327
+ for (const entry of rec.keys) {
328
+ if (result.pendingKeys.length >= MAX_IMPORT_KEYS) {
329
+ result.errors.push(`Too many keys in import file (max ${MAX_IMPORT_KEYS})`);
330
+ break;
331
+ }
332
+ if (typeof entry !== "object" ||
333
+ entry === null ||
334
+ typeof entry.name !== "string" ||
335
+ typeof entry.key !== "string") {
336
+ result.errors.push("Invalid key entry: must have 'name' and 'key' strings");
337
+ continue;
338
+ }
339
+ const name = entry.name.trim();
340
+ const key = entry.key.trim();
341
+ if (!name) {
342
+ result.errors.push("Key entry has empty name");
343
+ continue;
344
+ }
345
+ if (name.length > MAX_NAME_LENGTH) {
346
+ result.errors.push("Key name exceeds maximum length");
347
+ continue;
348
+ }
349
+ if (!key) {
350
+ result.errors.push(`Key "${name}" has empty key value`);
351
+ continue;
352
+ }
353
+ if (key.length > MAX_KEY_LENGTH) {
354
+ result.errors.push(`Key "${name}" exceeds maximum length`);
355
+ continue;
356
+ }
357
+ if (!key.startsWith("nvapi-")) {
358
+ result.errors.push(`Key "${name}" does not start with 'nvapi-'`);
359
+ continue;
360
+ }
361
+ result.pendingKeys.push({ name, key });
362
+ }
363
+ return result;
364
+ }
365
+ export function applyImport(store, pendingKeys) {
366
+ let added = 0;
367
+ let skipped = 0;
368
+ for (const { name, key } of pendingKeys) {
369
+ const existingByName = store.keys.find((k) => k.name === name);
370
+ if (existingByName) {
371
+ skipped++;
372
+ continue;
373
+ }
374
+ const existingByKey = store.keys.find((k) => k.key === key);
375
+ if (existingByKey) {
376
+ skipped++;
377
+ continue;
378
+ }
379
+ addKey(store, name, key);
380
+ added++;
381
+ }
382
+ return { added, skipped };
383
+ }
129
384
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../src/themes.ts"],"names":[],"mappings":"AA6EA,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAWnE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,CAOjE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAWzE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IACN,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;CAClC,EACD,MAAM,EAAE,iBAAiB,GACxB,IAAI,CASN;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AA+PD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAEjD;AAED,wBAAgB,UAAU,IAAI,YAAY,EAAE,CAE3C;AAED,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CAG5D;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAM/C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAShD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAmBvD;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE5D;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,cAAc,IAAI,YAAY,CAS7C"}
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../src/themes.ts"],"names":[],"mappings":"AA6EA,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAWnE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,gBAAgB,CAOjE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,iBAAiB,CAWzE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE;IACN,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,uBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,wBAAwB,EAAE,MAAM,CAAC;CAClC,EACD,MAAM,EAAE,iBAAiB,GACxB,IAAI,CASN;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AA+PD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,CAEjD;AAED,wBAAgB,UAAU,IAAI,YAAY,EAAE,CAE3C;AAED,wBAAgB,4BAA4B,IAAI,MAAM,GAAG,IAAI,CAG5D;AAED,wBAAgB,gBAAgB,IAAI,YAAY,CAM/C;AAID,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAQhD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAavD;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE5D;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,cAAc,IAAI,YAAY,CAS7C"}
package/dist/themes.js CHANGED
@@ -369,12 +369,12 @@ export function getResolvedTheme() {
369
369
  }
370
370
  return themes["opencode"];
371
371
  }
372
+ const THEME_OVERRIDE_PATH = join(CONFIG_DIR, "nim-rotator-theme.json");
372
373
  export function getThemeOverride() {
373
374
  try {
374
- const storePath = join(CONFIG_DIR, "nim-rotator-keys.json");
375
- if (!existsSync(storePath))
375
+ if (!existsSync(THEME_OVERRIDE_PATH))
376
376
  return null;
377
- const raw = readFileSync(storePath, "utf-8");
377
+ const raw = readFileSync(THEME_OVERRIDE_PATH, "utf-8");
378
378
  const data = JSON.parse(raw);
379
379
  return data.theme ?? null;
380
380
  }
@@ -383,23 +383,17 @@ export function getThemeOverride() {
383
383
  }
384
384
  export function saveThemeOverride(themeId) {
385
385
  try {
386
- const storePath = join(CONFIG_DIR, "nim-rotator-keys.json");
387
- let data = {};
388
- if (existsSync(storePath)) {
389
- const raw = readFileSync(storePath, "utf-8");
390
- data = JSON.parse(raw);
391
- }
392
- data.theme = themeId;
393
- const dir = dirname(storePath);
386
+ const data = { theme: themeId };
387
+ const dir = dirname(THEME_OVERRIDE_PATH);
394
388
  if (!existsSync(dir)) {
395
- mkdirSync(dir, { recursive: true });
389
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
396
390
  }
397
- writeFileSync(storePath, JSON.stringify(data, null, 2) + "\n", {
391
+ writeFileSync(THEME_OVERRIDE_PATH, JSON.stringify(data, null, 2) + "\n", {
398
392
  mode: 0o600,
399
393
  });
400
394
  }
401
395
  catch (err) {
402
- console.warn("[nim-rotator] Could not save theme preference:", err);
396
+ console.warn("[nim-rotator] Could not save theme preference");
403
397
  }
404
398
  }
405
399
  let previewThemeOverride = null;