varlock 1.0.0 → 1.1.0
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/auto-load.js +2 -2
- package/dist/{chunk-VODQDF4Q.js → chunk-6RF54KKR.js} +36 -7
- package/dist/chunk-6RF54KKR.js.map +1 -0
- package/dist/{chunk-UKFHSMKY.js → chunk-7GFD2ATN.js} +4 -4
- package/dist/{chunk-UKFHSMKY.js.map → chunk-7GFD2ATN.js.map} +1 -1
- package/dist/{chunk-QNTIIXD5.js → chunk-A6THM3IR.js} +5 -5
- package/dist/{chunk-QNTIIXD5.js.map → chunk-A6THM3IR.js.map} +1 -1
- package/dist/{chunk-FTVXXJMG.js → chunk-CDLU5P62.js} +3 -3
- package/dist/{chunk-FTVXXJMG.js.map → chunk-CDLU5P62.js.map} +1 -1
- package/dist/{chunk-V2MTE4J6.js → chunk-E3F6QKDZ.js} +5 -5
- package/dist/{chunk-V2MTE4J6.js.map → chunk-E3F6QKDZ.js.map} +1 -1
- package/dist/{chunk-YHOWSHVH.js → chunk-F5H5MJ6U.js} +32 -5
- package/dist/chunk-F5H5MJ6U.js.map +1 -0
- package/dist/{chunk-6DXWXIQV.js → chunk-GURKQO4J.js} +259 -149
- package/dist/chunk-GURKQO4J.js.map +1 -0
- package/dist/{chunk-2ABRAKHE.js → chunk-H6NILU2I.js} +4 -4
- package/dist/{chunk-2ABRAKHE.js.map → chunk-H6NILU2I.js.map} +1 -1
- package/dist/{chunk-2EEXFFKL.js → chunk-JIUWL2NT.js} +6 -6
- package/dist/{chunk-2EEXFFKL.js.map → chunk-JIUWL2NT.js.map} +1 -1
- package/dist/chunk-JUPAI2X4.js +30 -0
- package/dist/chunk-JUPAI2X4.js.map +1 -0
- package/dist/chunk-O3WTD6L4.js +37 -0
- package/dist/chunk-O3WTD6L4.js.map +1 -0
- package/dist/{chunk-GBCB7Y3B.js → chunk-QP7TS4SU.js} +6 -5
- package/dist/chunk-QP7TS4SU.js.map +1 -0
- package/dist/{chunk-AMNNQL7K.js → chunk-QSYH5IDD.js} +3 -3
- package/dist/{chunk-AMNNQL7K.js.map → chunk-QSYH5IDD.js.map} +1 -1
- package/dist/{chunk-JEZQ2DFL.js → chunk-RBFS2QGC.js} +9 -8
- package/dist/chunk-RBFS2QGC.js.map +1 -0
- package/dist/{chunk-XADO6HQG.js → chunk-S5O4AAVX.js} +6 -6
- package/dist/{chunk-XADO6HQG.js.map → chunk-S5O4AAVX.js.map} +1 -1
- package/dist/{chunk-CKWXLVMV.js → chunk-SDN53OAC.js} +4 -4
- package/dist/{chunk-CKWXLVMV.js.map → chunk-SDN53OAC.js.map} +1 -1
- package/dist/{chunk-QJ6NMN5H.js → chunk-TQXYC3G3.js} +5 -5
- package/dist/{chunk-QJ6NMN5H.js.map → chunk-TQXYC3G3.js.map} +1 -1
- package/dist/{chunk-6JKWTWLB.js → chunk-U2O3AUM2.js} +6 -6
- package/dist/{chunk-6JKWTWLB.js.map → chunk-U2O3AUM2.js.map} +1 -1
- package/dist/{chunk-LOIJO4MO.js → chunk-VN4LKYXR.js} +4 -4
- package/dist/{chunk-LOIJO4MO.js.map → chunk-VN4LKYXR.js.map} +1 -1
- package/dist/{chunk-U7RQPX5K.js → chunk-XWYFSG46.js} +27 -6
- package/dist/chunk-XWYFSG46.js.map +1 -0
- package/dist/{chunk-XTOUG72X.js → chunk-YO6WHPM4.js} +5 -5
- package/dist/{chunk-XTOUG72X.js.map → chunk-YO6WHPM4.js.map} +1 -1
- package/dist/{chunk-NJONB6CB.js → chunk-ZJNDICC4.js} +5 -5
- package/dist/{chunk-NJONB6CB.js.map → chunk-ZJNDICC4.js.map} +1 -1
- package/dist/cli/cli-executable.js +33 -33
- package/dist/cli/cli-executable.js.map +1 -1
- package/dist/config-item-6LTV4PNH.js +7 -0
- package/dist/{config-item-2FQ6I6PO.js.map → config-item-6LTV4PNH.js.map} +1 -1
- package/dist/dotenv-compat.js +2 -2
- package/dist/encrypt.command-F2OTB6HD.js +14 -0
- package/dist/{encrypt.command-K2SBJVQ5.js.map → encrypt.command-F2OTB6HD.js.map} +1 -1
- package/dist/{env-graph-CXTsI2Eg.d.ts → env-graph-iNQyTcya.d.ts} +4 -0
- package/dist/explain.command-TEIPRC7Q.js +15 -0
- package/dist/{explain.command-E6MR72IY.js.map → explain.command-TEIPRC7Q.js.map} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -7
- package/dist/init.command-5LP3UFKD.js +13 -0
- package/dist/{init.command-TGDNXHJ7.js.map → init.command-5LP3UFKD.js.map} +1 -1
- package/dist/install-plugin.command-X7RSLPUJ.js +13 -0
- package/dist/{install-plugin.command-Z2S5DIFS.js.map → install-plugin.command-X7RSLPUJ.js.map} +1 -1
- package/dist/lib/exec-sync-varlock.d.ts +34 -9
- package/dist/lib/exec-sync-varlock.js +1 -1
- package/dist/load.command-7SQRDQ3E.js +15 -0
- package/dist/{load.command-K2IH3646.js.map → load.command-7SQRDQ3E.js.map} +1 -1
- package/dist/lock.command-4LTGMJA3.js +7 -0
- package/dist/{lock.command-GL4CLXED.js.map → lock.command-4LTGMJA3.js.map} +1 -1
- package/dist/plugin-lib.d.ts +2 -2
- package/dist/printenv.command-ON7RMFEU.js +15 -0
- package/dist/{printenv.command-34LGQT6W.js.map → printenv.command-ON7RMFEU.js.map} +1 -1
- package/dist/reveal.command-BW6XYVXH.js +15 -0
- package/dist/{reveal.command-WOHYRSYO.js.map → reveal.command-BW6XYVXH.js.map} +1 -1
- package/dist/run.command-5QADABYL.js +16 -0
- package/dist/{run.command-PPC2X2N7.js.map → run.command-5QADABYL.js.map} +1 -1
- package/dist/runtime/env.d.ts +1 -1
- package/dist/{scan.command-4DJBQEML.js → scan.command-ZVW3XAUG.js} +9 -9
- package/dist/{scan.command-4DJBQEML.js.map → scan.command-ZVW3XAUG.js.map} +1 -1
- package/dist/telemetry.command-PY6E4QSH.js +13 -0
- package/dist/{telemetry.command-LIOCXWQK.js.map → telemetry.command-PY6E4QSH.js.map} +1 -1
- package/dist/typegen.command-KZ4O5IKQ.js +15 -0
- package/dist/{typegen.command-COL35ALE.js.map → typegen.command-KZ4O5IKQ.js.map} +1 -1
- package/native-bins/darwin/VarlockEnclave.app/Contents/CodeResources +0 -0
- package/native-bins/darwin/VarlockEnclave.app/Contents/MacOS/varlock-local-encrypt +0 -0
- package/native-bins/linux-arm64/varlock-local-encrypt +0 -0
- package/native-bins/linux-x64/varlock-local-encrypt +0 -0
- package/native-bins/win32-x64/varlock-local-encrypt.exe +0 -0
- package/package.json +1 -1
- package/dist/chunk-6DXWXIQV.js.map +0 -1
- package/dist/chunk-7WB7HK5Z.js +0 -21
- package/dist/chunk-7WB7HK5Z.js.map +0 -1
- package/dist/chunk-GBCB7Y3B.js.map +0 -1
- package/dist/chunk-JEZQ2DFL.js.map +0 -1
- package/dist/chunk-U7RQPX5K.js.map +0 -1
- package/dist/chunk-UUDTMOJS.js +0 -22
- package/dist/chunk-UUDTMOJS.js.map +0 -1
- package/dist/chunk-VODQDF4Q.js.map +0 -1
- package/dist/chunk-YHOWSHVH.js.map +0 -1
- package/dist/config-item-2FQ6I6PO.js +0 -7
- package/dist/encrypt.command-K2SBJVQ5.js +0 -14
- package/dist/explain.command-E6MR72IY.js +0 -15
- package/dist/init.command-TGDNXHJ7.js +0 -13
- package/dist/install-plugin.command-Z2S5DIFS.js +0 -13
- package/dist/load.command-K2IH3646.js +0 -15
- package/dist/lock.command-GL4CLXED.js +0 -7
- package/dist/printenv.command-34LGQT6W.js +0 -15
- package/dist/reveal.command-WOHYRSYO.js +0 -15
- package/dist/run.command-PPC2X2N7.js +0 -16
- package/dist/telemetry.command-LIOCXWQK.js +0 -13
- package/dist/typegen.command-COL35ALE.js +0 -15
|
@@ -1,30 +1,12 @@
|
|
|
1
|
-
import { getUserVarlockDir } from './chunk-
|
|
1
|
+
import { isWSL, getUserVarlockDir } from './chunk-O3WTD6L4.js';
|
|
2
2
|
import { __name } from './chunk-6PEHRAEP.js';
|
|
3
3
|
import { spawn, execFileSync, spawnSync } from 'child_process';
|
|
4
|
-
import
|
|
4
|
+
import fs from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
import net from 'net';
|
|
8
8
|
import crypto, { webcrypto } from 'crypto';
|
|
9
9
|
|
|
10
|
-
var _isWSL;
|
|
11
|
-
function isWSL() {
|
|
12
|
-
if (_isWSL !== void 0) return _isWSL;
|
|
13
|
-
if (process.env.WSL_DISTRO_NAME) {
|
|
14
|
-
_isWSL = true;
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
try {
|
|
18
|
-
const version = fs3.readFileSync("/proc/version", "utf-8");
|
|
19
|
-
_isWSL = /microsoft|wsl/i.test(version);
|
|
20
|
-
} catch {
|
|
21
|
-
_isWSL = false;
|
|
22
|
-
}
|
|
23
|
-
return _isWSL;
|
|
24
|
-
}
|
|
25
|
-
__name(isWSL, "isWSL");
|
|
26
|
-
|
|
27
|
-
// src/lib/local-encrypt/binary-resolver.ts
|
|
28
10
|
var __dirname$1 = path.dirname(fileURLToPath(import.meta.url));
|
|
29
11
|
function debug(msg) {
|
|
30
12
|
if (process.env.VARLOCK_DEBUG) {
|
|
@@ -39,9 +21,9 @@ function resolvePackageRoot() {
|
|
|
39
21
|
let dir = __dirname$1;
|
|
40
22
|
for (let i = 0; i < 10; i++) {
|
|
41
23
|
const pkgJsonPath = path.join(dir, "package.json");
|
|
42
|
-
if (
|
|
24
|
+
if (fs.existsSync(pkgJsonPath)) {
|
|
43
25
|
try {
|
|
44
|
-
const pkgJson = JSON.parse(
|
|
26
|
+
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
|
|
45
27
|
if (pkgJson.name === "varlock") return dir;
|
|
46
28
|
} catch {
|
|
47
29
|
}
|
|
@@ -67,15 +49,15 @@ function getNativeBinSubdir() {
|
|
|
67
49
|
__name(getNativeBinSubdir, "getNativeBinSubdir");
|
|
68
50
|
function resolveMacOSBinary(dir) {
|
|
69
51
|
const appBundlePath = path.join(dir, MACOS_APP_BUNDLE, "Contents", "MacOS", BINARY_NAME);
|
|
70
|
-
if (
|
|
52
|
+
if (fs.existsSync(appBundlePath)) return appBundlePath;
|
|
71
53
|
const barePath = path.join(dir, BINARY_NAME);
|
|
72
|
-
if (
|
|
54
|
+
if (fs.existsSync(barePath)) return barePath;
|
|
73
55
|
return void 0;
|
|
74
56
|
}
|
|
75
57
|
__name(resolveMacOSBinary, "resolveMacOSBinary");
|
|
76
58
|
function resolveStandardBinary(dir) {
|
|
77
59
|
const binaryPath = path.join(dir, getPlatformBinaryName());
|
|
78
|
-
if (
|
|
60
|
+
if (fs.existsSync(binaryPath)) return binaryPath;
|
|
79
61
|
return void 0;
|
|
80
62
|
}
|
|
81
63
|
__name(resolveStandardBinary, "resolveStandardBinary");
|
|
@@ -85,7 +67,7 @@ function resolveBinaryFromDir(dir) {
|
|
|
85
67
|
}
|
|
86
68
|
__name(resolveBinaryFromDir, "resolveBinaryFromDir");
|
|
87
69
|
function resolveSeaSibling() {
|
|
88
|
-
const execDir = path.dirname(
|
|
70
|
+
const execDir = path.dirname(fs.realpathSync(process.execPath));
|
|
89
71
|
const sibling = resolveBinaryFromDir(execDir);
|
|
90
72
|
if (sibling) return sibling;
|
|
91
73
|
const libexecDir = path.join(execDir, "..", "libexec");
|
|
@@ -95,9 +77,9 @@ __name(resolveSeaSibling, "resolveSeaSibling");
|
|
|
95
77
|
function resolveNpmBundled() {
|
|
96
78
|
const packageRoot = resolvePackageRoot();
|
|
97
79
|
const nativeBinsDir = path.join(packageRoot, "native-bins", getNativeBinSubdir());
|
|
98
|
-
if (
|
|
80
|
+
if (fs.existsSync(nativeBinsDir)) return resolveBinaryFromDir(nativeBinsDir);
|
|
99
81
|
const adjacentNativeBinsDir = path.join(path.dirname(packageRoot), "native-bins", getNativeBinSubdir());
|
|
100
|
-
if (
|
|
82
|
+
if (fs.existsSync(adjacentNativeBinsDir)) return resolveBinaryFromDir(adjacentNativeBinsDir);
|
|
101
83
|
return void 0;
|
|
102
84
|
}
|
|
103
85
|
__name(resolveNpmBundled, "resolveNpmBundled");
|
|
@@ -109,20 +91,20 @@ function resolveDevFallback() {
|
|
|
109
91
|
dir = parent;
|
|
110
92
|
if (process.platform === "darwin") {
|
|
111
93
|
const swiftBuild = path.join(dir, "packages", "encryption-binary-swift", "swift", ".build", "release", "VarlockEnclave");
|
|
112
|
-
if (
|
|
94
|
+
if (fs.existsSync(swiftBuild)) return swiftBuild;
|
|
113
95
|
}
|
|
114
96
|
const rustBuild = path.join(dir, "packages", "encryption-binary-rust", "target", "release", getPlatformBinaryName());
|
|
115
|
-
if (
|
|
97
|
+
if (fs.existsSync(rustBuild)) return rustBuild;
|
|
116
98
|
}
|
|
117
99
|
return void 0;
|
|
118
100
|
}
|
|
119
101
|
__name(resolveDevFallback, "resolveDevFallback");
|
|
120
102
|
function ensureExecutable(binaryPath) {
|
|
121
103
|
try {
|
|
122
|
-
|
|
104
|
+
fs.accessSync(binaryPath, fs.constants.X_OK);
|
|
123
105
|
} catch {
|
|
124
106
|
if (process.platform !== "win32") {
|
|
125
|
-
|
|
107
|
+
fs.chmodSync(binaryPath, 493);
|
|
126
108
|
}
|
|
127
109
|
}
|
|
128
110
|
return binaryPath;
|
|
@@ -163,6 +145,10 @@ function resolveNativeBinary() {
|
|
|
163
145
|
return void 0;
|
|
164
146
|
}
|
|
165
147
|
__name(resolveNativeBinary, "resolveNativeBinary");
|
|
148
|
+
var SEND_TIMEOUT_MS = 3e4;
|
|
149
|
+
var BIOMETRIC_TIMEOUT_MS = 9e4;
|
|
150
|
+
var INTERACTIVE_TIMEOUT_MS = 5 * 6e4;
|
|
151
|
+
var KILL_GRACE_MS = 2e3;
|
|
166
152
|
function debug2(msg) {
|
|
167
153
|
if (process.env.VARLOCK_DEBUG) {
|
|
168
154
|
process.stderr.write(`[varlock:daemon-client] ${msg}
|
|
@@ -170,6 +156,40 @@ function debug2(msg) {
|
|
|
170
156
|
}
|
|
171
157
|
}
|
|
172
158
|
__name(debug2, "debug");
|
|
159
|
+
function killDaemonProcess(pid) {
|
|
160
|
+
try {
|
|
161
|
+
process.kill(pid, "SIGTERM");
|
|
162
|
+
} catch {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
const start = Date.now();
|
|
166
|
+
while (Date.now() - start < KILL_GRACE_MS) {
|
|
167
|
+
try {
|
|
168
|
+
process.kill(pid, 0);
|
|
169
|
+
} catch {
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 100);
|
|
173
|
+
}
|
|
174
|
+
debug2(`daemon pid ${pid} didn't respond to SIGTERM, sending SIGKILL`);
|
|
175
|
+
try {
|
|
176
|
+
process.kill(pid, "SIGKILL");
|
|
177
|
+
} catch {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
const killStart = Date.now();
|
|
181
|
+
while (Date.now() - killStart < 500) {
|
|
182
|
+
try {
|
|
183
|
+
process.kill(pid, 0);
|
|
184
|
+
} catch {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50);
|
|
188
|
+
}
|
|
189
|
+
debug2(`daemon pid ${pid} is unkillable (likely in uninterruptible kernel wait) \u2014 proceeding anyway`);
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
__name(killDaemonProcess, "killDaemonProcess");
|
|
173
193
|
function getSocketDir() {
|
|
174
194
|
return path.join(getUserVarlockDir(), "local-encrypt");
|
|
175
195
|
}
|
|
@@ -181,6 +201,10 @@ function getSocketPath() {
|
|
|
181
201
|
return path.join(getSocketDir(), "daemon.sock");
|
|
182
202
|
}
|
|
183
203
|
__name(getSocketPath, "getSocketPath");
|
|
204
|
+
function getLockPath() {
|
|
205
|
+
return `${getSocketPath()}.lock`;
|
|
206
|
+
}
|
|
207
|
+
__name(getLockPath, "getLockPath");
|
|
184
208
|
function getPidPath() {
|
|
185
209
|
return path.join(getSocketDir(), "daemon.pid");
|
|
186
210
|
}
|
|
@@ -189,12 +213,29 @@ function getDaemonInfoPath() {
|
|
|
189
213
|
return path.join(getSocketDir(), "daemon.info");
|
|
190
214
|
}
|
|
191
215
|
__name(getDaemonInfoPath, "getDaemonInfoPath");
|
|
216
|
+
function getDaemonStateFiles() {
|
|
217
|
+
const files = [getPidPath(), getDaemonInfoPath()];
|
|
218
|
+
if (process.platform !== "win32") {
|
|
219
|
+
files.push(getSocketPath(), getLockPath());
|
|
220
|
+
}
|
|
221
|
+
return files;
|
|
222
|
+
}
|
|
223
|
+
__name(getDaemonStateFiles, "getDaemonStateFiles");
|
|
224
|
+
function cleanupDaemonFiles() {
|
|
225
|
+
for (const file of getDaemonStateFiles()) {
|
|
226
|
+
try {
|
|
227
|
+
fs.unlinkSync(file);
|
|
228
|
+
} catch {
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
__name(cleanupDaemonFiles, "cleanupDaemonFiles");
|
|
192
233
|
function checkDaemonBinaryStale() {
|
|
193
234
|
const infoPath = getDaemonInfoPath();
|
|
194
235
|
const pidPath = getPidPath();
|
|
195
236
|
let info;
|
|
196
237
|
try {
|
|
197
|
-
info = JSON.parse(
|
|
238
|
+
info = JSON.parse(fs.readFileSync(infoPath, "utf-8"));
|
|
198
239
|
} catch {
|
|
199
240
|
}
|
|
200
241
|
const currentBinaryPath = resolveNativeBinary();
|
|
@@ -204,7 +245,7 @@ function checkDaemonBinaryStale() {
|
|
|
204
245
|
debug2(`daemon binary path changed: ${info.binaryPath} \u2192 ${currentBinaryPath}`);
|
|
205
246
|
} else {
|
|
206
247
|
try {
|
|
207
|
-
const stat =
|
|
248
|
+
const stat = fs.statSync(currentBinaryPath);
|
|
208
249
|
if (stat.mtimeMs === info.binaryMtimeMs) {
|
|
209
250
|
debug2("daemon binary is current \u2014 no restart needed");
|
|
210
251
|
return void 0;
|
|
@@ -218,18 +259,20 @@ function checkDaemonBinaryStale() {
|
|
|
218
259
|
debug2("no daemon.info file \u2014 treating running daemon as stale");
|
|
219
260
|
}
|
|
220
261
|
try {
|
|
221
|
-
const pid = parseInt(
|
|
262
|
+
const pid = parseInt(fs.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
222
263
|
process.kill(pid, 0);
|
|
223
264
|
return pid;
|
|
224
265
|
} catch {
|
|
266
|
+
debug2("stale PID file points to dead process \u2014 cleaning up");
|
|
267
|
+
cleanupDaemonFiles();
|
|
225
268
|
return void 0;
|
|
226
269
|
}
|
|
227
270
|
}
|
|
228
271
|
__name(checkDaemonBinaryStale, "checkDaemonBinaryStale");
|
|
229
272
|
function writeDaemonInfo(binaryPath) {
|
|
230
273
|
try {
|
|
231
|
-
const stat =
|
|
232
|
-
|
|
274
|
+
const stat = fs.statSync(binaryPath);
|
|
275
|
+
fs.writeFileSync(getDaemonInfoPath(), JSON.stringify({
|
|
233
276
|
binaryPath,
|
|
234
277
|
binaryMtimeMs: stat.mtimeMs
|
|
235
278
|
}));
|
|
@@ -277,22 +320,8 @@ var DaemonClient = class {
|
|
|
277
320
|
const stalePid = this.spawnedInThisProcess ? void 0 : checkDaemonBinaryStale();
|
|
278
321
|
if (stalePid) {
|
|
279
322
|
debug2(`killing stale daemon (pid ${stalePid}) \u2014 binary has been updated`);
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
} catch {
|
|
283
|
-
}
|
|
284
|
-
for (const file of [getPidPath(), getDaemonInfoPath()]) {
|
|
285
|
-
try {
|
|
286
|
-
fs3.unlinkSync(file);
|
|
287
|
-
} catch {
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
if (process.platform !== "win32") {
|
|
291
|
-
try {
|
|
292
|
-
fs3.unlinkSync(socketPath);
|
|
293
|
-
} catch {
|
|
294
|
-
}
|
|
295
|
-
}
|
|
323
|
+
killDaemonProcess(stalePid);
|
|
324
|
+
cleanupDaemonFiles();
|
|
296
325
|
} else {
|
|
297
326
|
try {
|
|
298
327
|
await this.connectToSocket(socketPath);
|
|
@@ -302,7 +331,8 @@ var DaemonClient = class {
|
|
|
302
331
|
}
|
|
303
332
|
try {
|
|
304
333
|
await this.spawnDaemon();
|
|
305
|
-
} catch {
|
|
334
|
+
} catch (err) {
|
|
335
|
+
debug2(`spawnDaemon failed: ${err instanceof Error ? err.message : err}`);
|
|
306
336
|
await new Promise((r) => {
|
|
307
337
|
setTimeout(r, 1e3);
|
|
308
338
|
});
|
|
@@ -310,76 +340,88 @@ var DaemonClient = class {
|
|
|
310
340
|
await this.connectToSocket(socketPath);
|
|
311
341
|
}
|
|
312
342
|
async decrypt(ciphertext, keyId = "varlock-default") {
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
343
|
+
return this.withRetry(async () => {
|
|
344
|
+
await this.ensureConnected();
|
|
345
|
+
const result = await this.sendMessage({
|
|
346
|
+
action: "decrypt",
|
|
347
|
+
payload: { ciphertext, keyId }
|
|
348
|
+
}, BIOMETRIC_TIMEOUT_MS);
|
|
349
|
+
if (typeof result === "string") return result;
|
|
350
|
+
if (result && typeof result === "object" && "error" in result) {
|
|
351
|
+
throw new Error(String(result.error));
|
|
352
|
+
}
|
|
353
|
+
return String(result);
|
|
317
354
|
});
|
|
318
|
-
if (typeof result === "string") return result;
|
|
319
|
-
if (result && typeof result === "object" && "error" in result) {
|
|
320
|
-
throw new Error(String(result.error));
|
|
321
|
-
}
|
|
322
|
-
return String(result);
|
|
323
355
|
}
|
|
324
356
|
async promptSecret(opts) {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
357
|
+
return this.withRetry(async () => {
|
|
358
|
+
await this.ensureConnected();
|
|
359
|
+
try {
|
|
360
|
+
const result = await this.sendMessage({
|
|
361
|
+
action: "prompt-secret",
|
|
362
|
+
payload: {
|
|
363
|
+
itemKey: opts?.itemKey,
|
|
364
|
+
message: opts?.message,
|
|
365
|
+
keyId: opts?.keyId
|
|
366
|
+
}
|
|
367
|
+
}, INTERACTIVE_TIMEOUT_MS);
|
|
368
|
+
if (result && typeof result === "object" && "ciphertext" in result) {
|
|
369
|
+
return result.ciphertext;
|
|
333
370
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
return
|
|
371
|
+
return void 0;
|
|
372
|
+
} catch (err) {
|
|
373
|
+
if (err instanceof Error && err.message === "cancelled") return void 0;
|
|
374
|
+
throw err;
|
|
337
375
|
}
|
|
338
|
-
|
|
339
|
-
} catch (err) {
|
|
340
|
-
if (err instanceof Error && err.message === "cancelled") return void 0;
|
|
341
|
-
throw err;
|
|
342
|
-
}
|
|
376
|
+
});
|
|
343
377
|
}
|
|
344
378
|
async invalidateSession() {
|
|
345
|
-
|
|
346
|
-
|
|
379
|
+
return this.withRetry(async () => {
|
|
380
|
+
await this.ensureConnected();
|
|
381
|
+
await this.sendMessage({ action: "invalidate-session" });
|
|
382
|
+
});
|
|
347
383
|
}
|
|
348
384
|
async keychainGet(opts) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
385
|
+
return this.withRetry(async () => {
|
|
386
|
+
await this.ensureConnected();
|
|
387
|
+
const result = await this.sendMessage({
|
|
388
|
+
action: "keychain-get",
|
|
389
|
+
payload: opts
|
|
390
|
+
}, BIOMETRIC_TIMEOUT_MS);
|
|
391
|
+
if (typeof result === "string") return result;
|
|
392
|
+
if (result && typeof result === "object" && "error" in result) {
|
|
393
|
+
throw new Error(String(result.error));
|
|
394
|
+
}
|
|
395
|
+
return String(result);
|
|
353
396
|
});
|
|
354
|
-
if (typeof result === "string") return result;
|
|
355
|
-
if (result && typeof result === "object" && "error" in result) {
|
|
356
|
-
throw new Error(String(result.error));
|
|
357
|
-
}
|
|
358
|
-
return String(result);
|
|
359
397
|
}
|
|
360
398
|
async keychainSearch(opts) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
399
|
+
return this.withRetry(async () => {
|
|
400
|
+
await this.ensureConnected();
|
|
401
|
+
const result = await this.sendMessage({
|
|
402
|
+
action: "keychain-search",
|
|
403
|
+
payload: opts ?? {}
|
|
404
|
+
});
|
|
405
|
+
return result ?? [];
|
|
365
406
|
});
|
|
366
|
-
return result ?? [];
|
|
367
407
|
}
|
|
368
408
|
async keychainPick(opts) {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
409
|
+
return this.withRetry(async () => {
|
|
410
|
+
await this.ensureConnected();
|
|
411
|
+
try {
|
|
412
|
+
const result = await this.sendMessage({
|
|
413
|
+
action: "keychain-pick",
|
|
414
|
+
payload: { itemKey: opts?.itemKey }
|
|
415
|
+
}, INTERACTIVE_TIMEOUT_MS);
|
|
416
|
+
if (result && typeof result === "object" && "service" in result) {
|
|
417
|
+
return result;
|
|
418
|
+
}
|
|
419
|
+
return void 0;
|
|
420
|
+
} catch (err) {
|
|
421
|
+
if (err instanceof Error && err.message === "cancelled") return void 0;
|
|
422
|
+
throw err;
|
|
377
423
|
}
|
|
378
|
-
|
|
379
|
-
} catch (err) {
|
|
380
|
-
if (err instanceof Error && err.message === "cancelled") return void 0;
|
|
381
|
-
throw err;
|
|
382
|
-
}
|
|
424
|
+
});
|
|
383
425
|
}
|
|
384
426
|
cleanup() {
|
|
385
427
|
for (const { reject } of this.messageQueue.values()) {
|
|
@@ -392,6 +434,37 @@ var DaemonClient = class {
|
|
|
392
434
|
this.buffer = Buffer.alloc(0);
|
|
393
435
|
}
|
|
394
436
|
// -- Private --
|
|
437
|
+
/**
|
|
438
|
+
* Run an async operation, and on recoverable failure (timeout, connection
|
|
439
|
+
* closed) clean up, reconnect to the daemon, and retry once.
|
|
440
|
+
*/
|
|
441
|
+
async withRetry(fn) {
|
|
442
|
+
try {
|
|
443
|
+
return await fn();
|
|
444
|
+
} catch (err) {
|
|
445
|
+
const msg = err instanceof Error ? err.message : "";
|
|
446
|
+
const recoverable = msg.includes("timed out") || msg.includes("connection closed") || msg.includes("Not connected");
|
|
447
|
+
if (!recoverable) throw err;
|
|
448
|
+
debug2(`recoverable error, reconnecting: ${msg}`);
|
|
449
|
+
this.forceCleanup();
|
|
450
|
+
await this.ensureConnected();
|
|
451
|
+
return await fn();
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Aggressive cleanup: kill the daemon process if we know its PID,
|
|
456
|
+
* then reset client state so the next ensureConnected spawns fresh.
|
|
457
|
+
*/
|
|
458
|
+
forceCleanup() {
|
|
459
|
+
this.cleanup();
|
|
460
|
+
this.spawnedInThisProcess = false;
|
|
461
|
+
try {
|
|
462
|
+
const pid = parseInt(fs.readFileSync(getPidPath(), "utf-8").trim(), 10);
|
|
463
|
+
killDaemonProcess(pid);
|
|
464
|
+
} catch {
|
|
465
|
+
}
|
|
466
|
+
cleanupDaemonFiles();
|
|
467
|
+
}
|
|
395
468
|
connectToSocket(socketPath) {
|
|
396
469
|
return new Promise((resolve, reject) => {
|
|
397
470
|
const socket = new net.Socket();
|
|
@@ -417,6 +490,11 @@ var DaemonClient = class {
|
|
|
417
490
|
socket.on("close", () => {
|
|
418
491
|
this.isConnected = false;
|
|
419
492
|
this.socket = null;
|
|
493
|
+
for (const { reject: rej } of this.messageQueue.values()) {
|
|
494
|
+
rej(new Error("Daemon connection closed"));
|
|
495
|
+
}
|
|
496
|
+
this.messageQueue.clear();
|
|
497
|
+
this.buffer = Buffer.alloc(0);
|
|
420
498
|
});
|
|
421
499
|
socket.connect(socketPath);
|
|
422
500
|
});
|
|
@@ -443,7 +521,7 @@ var DaemonClient = class {
|
|
|
443
521
|
}
|
|
444
522
|
}
|
|
445
523
|
}
|
|
446
|
-
sendMessage(message) {
|
|
524
|
+
sendMessage(message, timeoutMs = SEND_TIMEOUT_MS) {
|
|
447
525
|
return new Promise((resolve, reject) => {
|
|
448
526
|
if (!this.isConnected || !this.socket) {
|
|
449
527
|
reject(new Error("Not connected to daemon"));
|
|
@@ -455,7 +533,20 @@ var DaemonClient = class {
|
|
|
455
533
|
const messageBytes = Buffer.from(jsonData, "utf-8");
|
|
456
534
|
const lengthBuf = Buffer.alloc(4);
|
|
457
535
|
lengthBuf.writeUInt32LE(messageBytes.length, 0);
|
|
458
|
-
|
|
536
|
+
const timeout = setTimeout(() => {
|
|
537
|
+
this.messageQueue.delete(messageId);
|
|
538
|
+
reject(new Error(`Daemon message timed out after ${timeoutMs}ms (action: ${message.action})`));
|
|
539
|
+
}, timeoutMs);
|
|
540
|
+
this.messageQueue.set(messageId, {
|
|
541
|
+
resolve: /* @__PURE__ */ __name((value) => {
|
|
542
|
+
clearTimeout(timeout);
|
|
543
|
+
resolve(value);
|
|
544
|
+
}, "resolve"),
|
|
545
|
+
reject: /* @__PURE__ */ __name((err) => {
|
|
546
|
+
clearTimeout(timeout);
|
|
547
|
+
reject(err);
|
|
548
|
+
}, "reject")
|
|
549
|
+
});
|
|
459
550
|
this.socket.write(Buffer.concat([lengthBuf, messageBytes]));
|
|
460
551
|
});
|
|
461
552
|
}
|
|
@@ -468,35 +559,26 @@ var DaemonClient = class {
|
|
|
468
559
|
const pidPath = getPidPath();
|
|
469
560
|
const isWindows = process.platform === "win32";
|
|
470
561
|
if (!isWindows) {
|
|
471
|
-
|
|
562
|
+
fs.mkdirSync(path.dirname(socketPath), { recursive: true });
|
|
472
563
|
}
|
|
473
|
-
|
|
474
|
-
if (
|
|
564
|
+
fs.mkdirSync(path.dirname(pidPath), { recursive: true });
|
|
565
|
+
if (fs.existsSync(pidPath)) {
|
|
475
566
|
try {
|
|
476
|
-
const pid = parseInt(
|
|
567
|
+
const pid = parseInt(fs.readFileSync(pidPath, "utf-8").trim(), 10);
|
|
477
568
|
process.kill(pid, 0);
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
569
|
+
try {
|
|
570
|
+
await this.connectToSocket(socketPath);
|
|
571
|
+
return;
|
|
572
|
+
} catch {
|
|
573
|
+
debug2(`daemon pid ${pid} alive but socket unresponsive \u2014 killing`);
|
|
574
|
+
killDaemonProcess(pid);
|
|
575
|
+
}
|
|
482
576
|
} catch {
|
|
483
577
|
}
|
|
484
578
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
fs3.unlinkSync(file);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
if (fs3.existsSync(socketPath)) {
|
|
492
|
-
throw new Error(`Failed to clean up stale socket file: ${socketPath}`);
|
|
493
|
-
}
|
|
494
|
-
} else {
|
|
495
|
-
for (const file of [pidPath, getDaemonInfoPath()]) {
|
|
496
|
-
if (fs3.existsSync(file)) {
|
|
497
|
-
fs3.unlinkSync(file);
|
|
498
|
-
}
|
|
499
|
-
}
|
|
579
|
+
cleanupDaemonFiles();
|
|
580
|
+
if (!isWindows && fs.existsSync(socketPath)) {
|
|
581
|
+
throw new Error(`Failed to clean up stale socket file: ${socketPath}`);
|
|
500
582
|
}
|
|
501
583
|
return new Promise((resolve, reject) => {
|
|
502
584
|
const child = spawn(binaryPath, [
|
|
@@ -708,7 +790,7 @@ function getKeyFilePath(keyId) {
|
|
|
708
790
|
}
|
|
709
791
|
__name(getKeyFilePath, "getKeyFilePath");
|
|
710
792
|
function keyExists(keyId = DEFAULT_KEY_ID) {
|
|
711
|
-
return
|
|
793
|
+
return fs.existsSync(getKeyFilePath(keyId));
|
|
712
794
|
}
|
|
713
795
|
__name(keyExists, "keyExists");
|
|
714
796
|
async function generateKey(keyId = DEFAULT_KEY_ID) {
|
|
@@ -720,18 +802,18 @@ async function generateKey(keyId = DEFAULT_KEY_ID) {
|
|
|
720
802
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
721
803
|
};
|
|
722
804
|
const keyStorePath = getKeyStorePath();
|
|
723
|
-
|
|
805
|
+
fs.mkdirSync(keyStorePath, { recursive: true });
|
|
724
806
|
const filePath = getKeyFilePath(keyId);
|
|
725
|
-
|
|
807
|
+
fs.writeFileSync(filePath, JSON.stringify(stored, null, 2), { mode: 384 });
|
|
726
808
|
return { keyId, publicKey: keyPair.publicKey };
|
|
727
809
|
}
|
|
728
810
|
__name(generateKey, "generateKey");
|
|
729
811
|
function loadKeyPair(keyId) {
|
|
730
812
|
const filePath = getKeyFilePath(keyId);
|
|
731
|
-
if (!
|
|
813
|
+
if (!fs.existsSync(filePath)) {
|
|
732
814
|
throw new Error(`Key not found: ${keyId}`);
|
|
733
815
|
}
|
|
734
|
-
const data =
|
|
816
|
+
const data = fs.readFileSync(filePath, "utf-8");
|
|
735
817
|
const parsed = JSON.parse(data);
|
|
736
818
|
const privateKey = parsed.privateKey ?? (parsed.protection === "none" ? parsed.protectedPrivateKey : void 0) ?? parsed.protectedPrivateKey;
|
|
737
819
|
if (!parsed.publicKey || !privateKey) {
|
|
@@ -771,21 +853,49 @@ function debug3(msg) {
|
|
|
771
853
|
}
|
|
772
854
|
}
|
|
773
855
|
__name(debug3, "debug");
|
|
774
|
-
var
|
|
775
|
-
function
|
|
776
|
-
if (
|
|
856
|
+
var _cachedSessionId;
|
|
857
|
+
function getSelfSessionId() {
|
|
858
|
+
if (_cachedSessionId) return _cachedSessionId;
|
|
777
859
|
try {
|
|
778
|
-
const ttyPath =
|
|
860
|
+
const ttyPath = fs.readlinkSync("/proc/self/fd/0");
|
|
779
861
|
if (ttyPath && ttyPath.startsWith("/dev/")) {
|
|
780
|
-
|
|
862
|
+
_cachedSessionId = ttyPath;
|
|
781
863
|
return ttyPath;
|
|
782
864
|
}
|
|
783
865
|
} catch {
|
|
784
866
|
}
|
|
785
|
-
|
|
786
|
-
|
|
867
|
+
try {
|
|
868
|
+
const chain = [process.pid];
|
|
869
|
+
let current = process.pid;
|
|
870
|
+
for (let i = 0; i < 64; i++) {
|
|
871
|
+
const stat = fs.readFileSync(`/proc/${current}/stat`, "utf-8");
|
|
872
|
+
const fields = stat.split(") ");
|
|
873
|
+
if (fields.length < 2) break;
|
|
874
|
+
const ppid = parseInt(fields[1].split(" ")[1], 10);
|
|
875
|
+
if (!ppid || ppid <= 1) break;
|
|
876
|
+
chain.push(ppid);
|
|
877
|
+
current = ppid;
|
|
878
|
+
}
|
|
879
|
+
if (chain.length >= 4) {
|
|
880
|
+
const scopePid = chain[chain.length - 3];
|
|
881
|
+
let startTime = 0;
|
|
882
|
+
try {
|
|
883
|
+
const scopeStat = fs.readFileSync(`/proc/${scopePid}/stat`, "utf-8");
|
|
884
|
+
const scopeFields = scopeStat.split(") ");
|
|
885
|
+
if (scopeFields.length >= 2) {
|
|
886
|
+
startTime = parseInt(scopeFields[1].split(" ")[19], 10) || 0;
|
|
887
|
+
}
|
|
888
|
+
} catch {
|
|
889
|
+
}
|
|
890
|
+
_cachedSessionId = `ptree:${scopePid}:${startTime}`;
|
|
891
|
+
return _cachedSessionId;
|
|
892
|
+
}
|
|
893
|
+
} catch {
|
|
894
|
+
}
|
|
895
|
+
_cachedSessionId = `pid:${process.pid}`;
|
|
896
|
+
return _cachedSessionId;
|
|
787
897
|
}
|
|
788
|
-
__name(
|
|
898
|
+
__name(getSelfSessionId, "getSelfSessionId");
|
|
789
899
|
var _wslDaemonPrestartAttempted = false;
|
|
790
900
|
function toWindowsPathFromWsl(pathInWsl) {
|
|
791
901
|
if (!isWSL()) return void 0;
|
|
@@ -1029,7 +1139,7 @@ async function decryptValue2(ciphertext, keyId = DEFAULT_KEY_ID2) {
|
|
|
1029
1139
|
}
|
|
1030
1140
|
const stdinPayload = JSON.stringify({
|
|
1031
1141
|
data: ciphertext,
|
|
1032
|
-
ttyId:
|
|
1142
|
+
ttyId: getSelfSessionId()
|
|
1033
1143
|
});
|
|
1034
1144
|
const runViaDaemon = /* @__PURE__ */ __name((timeout) => spawnSync(binaryPath, ["decrypt", "--key-id", keyId, "--data-stdin", "--via-daemon"], {
|
|
1035
1145
|
input: stdinPayload,
|
|
@@ -1088,5 +1198,5 @@ async function lockSession() {
|
|
|
1088
1198
|
__name(lockSession, "lockSession");
|
|
1089
1199
|
|
|
1090
1200
|
export { decryptValue2 as decryptValue, encryptValue2 as encryptValue, ensureKey, getBackendInfo, getDaemonClient, lockSession };
|
|
1091
|
-
//# sourceMappingURL=chunk-
|
|
1092
|
-
//# sourceMappingURL=chunk-
|
|
1201
|
+
//# sourceMappingURL=chunk-GURKQO4J.js.map
|
|
1202
|
+
//# sourceMappingURL=chunk-GURKQO4J.js.map
|