@vultisig/client-shared 0.2.16 → 0.2.17

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/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # @vultisig/client-shared
2
2
 
3
+ ## 0.2.17
4
+
5
+ ### Patch Changes
6
+
7
+ - [#878](https://github.com/vultisig/vultisig-sdk/pull/878) [`26dd218`](https://github.com/vultisig/vultisig-sdk/commit/26dd218282b198fdea9c1118e7fe5bc800c071fb) Thanks [@neavra](https://github.com/neavra)! - Harden the vault-registry config store (`config-store.ts`):
8
+
9
+ - `loadConfig` now warns to stderr (naming the path and parse error) when
10
+ `config.json` is corrupted instead of silently reverting to an empty
11
+ registry, and leaves the bad file intact at load time (the next saveConfig
12
+ still overwrites it once the user mutates state — this is not durable
13
+ recovery). A missing file is still treated as the normal first-run case (no
14
+ warning).
15
+ - `saveConfig` now writes `config.json` with `0o600` perms (and `chmod`s on
16
+ every write, since the mode is only honored on create) and creates the
17
+ config dir with `0o700`, mirroring credential-store's hardening.
18
+
19
+ - Updated dependencies [[`69bb830`](https://github.com/vultisig/vultisig-sdk/commit/69bb8307de72883f0c7693871a6ca040b7a0756c)]:
20
+ - @vultisig/sdk@2.8.4
21
+
3
22
  ## 0.2.16
4
23
 
5
24
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB,CAAA;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAOtD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAGlE;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
1
+ {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,EAAE,CAAA;CACrB,CAAA;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CA4BtD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlE;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -12,17 +12,49 @@ function getConfigFilePath() {
12
12
  return path.join(getConfigDir(), 'config.json');
13
13
  }
14
14
  export async function loadConfig() {
15
+ const filePath = getConfigFilePath();
16
+ let raw;
17
+ try {
18
+ raw = await fs.readFile(filePath, 'utf-8');
19
+ }
20
+ catch (err) {
21
+ // A missing file is the normal first-run case — stay silent. Any other
22
+ // read failure (e.g. EACCES) is worth surfacing before falling back.
23
+ if (err?.code !== 'ENOENT') {
24
+ console.warn(`[vultisig] Could not read config at ${filePath}: ${err?.message ?? String(err)}. Using an empty registry.`);
25
+ }
26
+ return { vaults: [] };
27
+ }
15
28
  try {
16
- const raw = await fs.readFile(getConfigFilePath(), 'utf-8');
17
29
  return JSON.parse(raw);
18
30
  }
19
- catch {
31
+ catch (err) {
32
+ // Corrupted config (e.g. partial write or single-byte corruption): warn
33
+ // loudly instead of silently factory-resetting, which would vanish the
34
+ // user's vault registry. The bad file is left intact AT LOAD TIME (the next
35
+ // saveConfig still overwrites it when the user mutates state) — this is not
36
+ // durable recovery, just a chance to inspect the file before the next write.
37
+ console.warn(`[vultisig] Config at ${filePath} is corrupted (${err?.message ?? String(err)}); using an empty registry. The file was left intact at load time.`);
20
38
  return { vaults: [] };
21
39
  }
22
40
  }
23
41
  export async function saveConfig(config) {
24
- await fs.mkdir(getConfigDir(), { recursive: true });
25
- await fs.writeFile(getConfigFilePath(), JSON.stringify(config, null, 2), 'utf-8');
42
+ const dir = getConfigDir();
43
+ const filePath = getConfigFilePath();
44
+ // 0o700 dir / 0o600 file: the registry maps vault IDs to on-disk vault file
45
+ // paths and lives alongside credentials. Mirror credential-store's hardening
46
+ // (commit 7bafd71a).
47
+ await fs.mkdir(dir, { recursive: true, mode: 0o700 });
48
+ await fs.writeFile(filePath, JSON.stringify(config, null, 2), { mode: 0o600 });
49
+ // writeFile's `mode` is honored only when the file is CREATED; an existing
50
+ // config.json keeps its old perms. chmod every write so a pre-existing (or
51
+ // out-of-band) file can't retain looser, world-readable perms.
52
+ try {
53
+ await fs.chmod(filePath, 0o600);
54
+ }
55
+ catch {
56
+ /* best-effort: non-POSIX FS (e.g. Windows) ignores perms */
57
+ }
26
58
  }
27
59
  export function getConfigPath() {
28
60
  return getConfigFilePath();
@@ -1 +1 @@
1
- {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,0EAA0E;AAE1E,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,4EAA4E;AAC5E,mFAAmF;AACnF,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAA;AAChF,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAA;AACjD,CAAC;AAYD,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,EAAE,EAAE,OAAO,CAAC,CAAA;QAC3D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAA;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACvB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkB;IACjD,MAAM,EAAE,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,EAAE,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;AACnF,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,EAAE,CAAA;AAC5B,CAAC"}
1
+ {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../src/config-store.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,0EAA0E;AAE1E,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACtC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,4EAA4E;AAC5E,mFAAmF;AACnF,SAAS,YAAY;IACnB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAA;AAChF,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAA;AACjD,CAAC;AAYD,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,IAAI,GAAW,CAAA;IACf,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,uEAAuE;QACvE,qEAAqE;QACrE,IAAK,GAA6B,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtD,OAAO,CAAC,IAAI,CACV,uCAAuC,QAAQ,KAAM,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,4BAA4B,CACvH,CAAA;QACH,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACvB,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAA;IACtC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,wEAAwE;QACxE,uEAAuE;QACvE,4EAA4E;QAC5E,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO,CAAC,IAAI,CACV,wBAAwB,QAAQ,kBAAmB,GAAa,EAAE,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,oEAAoE,CAC7J,CAAA;QACD,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACvB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAkB;IACjD,MAAM,GAAG,GAAG,YAAY,EAAE,CAAA;IAC1B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAA;IACpC,4EAA4E;IAC5E,6EAA6E;IAC7E,qBAAqB;IACrB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACrD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IAC9E,2EAA2E;IAC3E,2EAA2E;IAC3E,+DAA+D;IAC/D,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,4DAA4D;IAC9D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,EAAE,CAAA;AAC5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vultisig/client-shared",
3
- "version": "0.2.16",
3
+ "version": "0.2.17",
4
4
  "description": "Shared client infrastructure for Vultisig CLI and MCP — auth, config, tool descriptions",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@napi-rs/keyring": "^1.3.0",
34
- "@vultisig/sdk": "^2.7.0",
34
+ "@vultisig/sdk": "^2.8.4",
35
35
  "inquirer": "^14.0.2"
36
36
  },
37
37
  "devDependencies": {