402-mcp 4.1.1 → 4.1.2
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.
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
|
2
2
|
import { readFileSync, writeFileSync, openSync, closeSync, mkdirSync, chmodSync, statSync, constants as fsConstants } from 'node:fs';
|
|
3
|
+
import { execFileSync } from 'node:child_process';
|
|
3
4
|
import { dirname, join } from 'node:path';
|
|
4
|
-
import { homedir } from 'node:os';
|
|
5
|
+
import { homedir, platform } from 'node:os';
|
|
5
6
|
const SERVICE = '402-mcp';
|
|
6
7
|
const ACCOUNT = 'encryption-key';
|
|
7
8
|
const ALGORITHM = 'aes-256-gcm';
|
|
@@ -43,6 +44,16 @@ export function isEncrypted(data) {
|
|
|
43
44
|
return false;
|
|
44
45
|
return HEX_RE.test(obj.iv) && HEX_RE.test(obj.tag) && HEX_RE.test(obj.ciphertext);
|
|
45
46
|
}
|
|
47
|
+
/** The existing file key, or null. Never creates one — used only for migration. */
|
|
48
|
+
function readFallbackKeyIfPresent() {
|
|
49
|
+
try {
|
|
50
|
+
const hex = readFileSync(FALLBACK_KEY_PATH, 'utf8').trim();
|
|
51
|
+
return /^[0-9a-f]{64}$/.test(hex) ? Buffer.from(hex, 'hex') : null;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
46
57
|
function loadOrCreateFallbackKey() {
|
|
47
58
|
// Try to create atomically first (O_CREAT | O_EXCL fails if file exists)
|
|
48
59
|
mkdirSync(dirname(FALLBACK_KEY_PATH), { recursive: true, mode: 0o700 });
|
|
@@ -82,7 +93,72 @@ function loadOrCreateFallbackKey() {
|
|
|
82
93
|
const key = Buffer.from(hex, 'hex');
|
|
83
94
|
return key;
|
|
84
95
|
}
|
|
96
|
+
/**
|
|
97
|
+
* The macOS keychain via the `security` CLI. keytar is an optional dependency
|
|
98
|
+
* and a native module: it was archived upstream in 2023 and publishes no
|
|
99
|
+
* prebuilds for current Node, so on a modern runtime `import('keytar')` throws
|
|
100
|
+
* MODULE_NOT_FOUND for its .node binary and every key silently lands in the
|
|
101
|
+
* file fallback instead. The CLI ships with the OS, needs no build step, and
|
|
102
|
+
* cannot go stale against a Node release.
|
|
103
|
+
*/
|
|
104
|
+
const macKeychain = {
|
|
105
|
+
get() {
|
|
106
|
+
try {
|
|
107
|
+
// Exit code 44 (item not found) is the ordinary "no key yet" path.
|
|
108
|
+
return execFileSync('security', ['find-generic-password', '-s', SERVICE, '-a', ACCOUNT, '-w'], {
|
|
109
|
+
encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'],
|
|
110
|
+
}).trim() || null;
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
set(hex) {
|
|
117
|
+
try {
|
|
118
|
+
// The key goes in on stdin, never as an argument: argv is world-readable
|
|
119
|
+
// through ps, which would leak the very thing being protected. `-w` with
|
|
120
|
+
// no value prompts for the secret and then a confirmation, so it is
|
|
121
|
+
// written twice. -U updates an existing item rather than failing.
|
|
122
|
+
execFileSync('security', ['add-generic-password', '-s', SERVICE, '-a', ACCOUNT, '-U', '-w'], {
|
|
123
|
+
input: `${hex}\n${hex}\n`, stdio: ['pipe', 'ignore', 'ignore'],
|
|
124
|
+
});
|
|
125
|
+
return macKeychain.get() === hex;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
};
|
|
85
132
|
export async function getOrCreateKey() {
|
|
133
|
+
if (platform() === 'darwin') {
|
|
134
|
+
// A file key outranks anything in the keychain, and the ordering matters
|
|
135
|
+
// more than it looks. loadOrCreateFallbackKey only ever runs after the
|
|
136
|
+
// keychain path has failed, so once that file exists every subsequent
|
|
137
|
+
// write is encrypted under it — including on a machine where the keychain
|
|
138
|
+
// used to work and holds a now-stale item from an older key. Preferring
|
|
139
|
+
// the keychain there would hand back a key that decrypts nothing, and the
|
|
140
|
+
// stores read an undecryptable file as an empty one and overwrite it,
|
|
141
|
+
// destroying stored credentials and bearer notes without an error.
|
|
142
|
+
const fileKey = readFallbackKeyIfPresent();
|
|
143
|
+
if (fileKey) {
|
|
144
|
+
const hex = fileKey.toString('hex');
|
|
145
|
+
if (macKeychain.get() !== hex && macKeychain.set(hex)) {
|
|
146
|
+
console.error(`Note: encryption key copied into the macOS keychain. ${FALLBACK_KEY_PATH} still holds the same key and can be deleted once you have confirmed things still open.`);
|
|
147
|
+
}
|
|
148
|
+
return { key: fileKey, source: 'keychain' };
|
|
149
|
+
}
|
|
150
|
+
const existing = macKeychain.get();
|
|
151
|
+
if (existing && /^[0-9a-f]{64}$/.test(existing)) {
|
|
152
|
+
return { key: Buffer.from(existing, 'hex'), source: 'keychain' };
|
|
153
|
+
}
|
|
154
|
+
const newKey = randomBytes(32);
|
|
155
|
+
// Only claim the keychain once the value reads back intact; a half-written
|
|
156
|
+
// item that fell through to the file would strand anything encrypted under
|
|
157
|
+
// whichever key actually got used.
|
|
158
|
+
if (macKeychain.set(newKey.toString('hex'))) {
|
|
159
|
+
return { key: newKey, source: 'keychain' };
|
|
160
|
+
}
|
|
161
|
+
}
|
|
86
162
|
try {
|
|
87
163
|
const keytar = await import('keytar');
|
|
88
164
|
const existing = await keytar.default.getPassword(SERVICE, ACCOUNT);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/store/encryption.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,IAAI,WAAW,EAAE,MAAM,SAAS,CAAA;AACpI,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/store/encryption.ts"],"names":[],"mappings":"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"}
|