@mnemonik/cli 7.109.2 → 7.110.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/auth/credentials.js +297 -36
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +1914 -19
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/machineName.d.ts +8 -0
- package/dist/auth/machineName.d.ts.map +1 -0
- package/dist/auth/machineName.js +23 -0
- package/dist/auth/machineName.js.map +1 -0
- package/dist/consent.d.ts +29 -0
- package/dist/consent.d.ts.map +1 -0
- package/dist/consent.js +87 -0
- package/dist/consent.js.map +1 -0
- package/dist/diagnostics.js +301 -40
- package/dist/digests.json +102 -90
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +59 -44
- package/dist/help.js.map +1 -1
- package/dist/humanReason.d.ts +8 -0
- package/dist/humanReason.d.ts.map +1 -1
- package/dist/humanReason.js +44 -16
- package/dist/humanReason.js.map +1 -1
- package/dist/identity/migrate.js +1835 -44
- package/dist/install/hosts.d.ts +2 -0
- package/dist/install/hosts.d.ts.map +1 -1
- package/dist/install/hosts.js +23 -14
- package/dist/install/hosts.js.map +1 -1
- package/dist/install/journal.js +124 -11
- package/dist/install/journey.d.ts +20 -0
- package/dist/install/journey.d.ts.map +1 -1
- package/dist/install/journey.js +1913 -82
- package/dist/install/journey.js.map +1 -1
- package/dist/install/ownership.d.ts.map +1 -1
- package/dist/install/ownership.js +1818 -10
- package/dist/install/ownership.js.map +1 -1
- package/dist/install/transaction.js +1913 -19
- package/dist/install/ui.js +1910 -15
- package/dist/installation.js +133 -10
- package/dist/launcher.js +108 -4
- package/dist/output.d.ts +3 -0
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +11 -1
- package/dist/output.js.map +1 -1
- package/dist/preflight.d.ts +5 -0
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +14 -12
- package/dist/preflight.js.map +1 -1
- package/dist/project/eligibility.js +1917 -22
- package/dist/project/records.js +121 -8
- package/dist/project.d.ts +15 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +229 -15
- package/dist/project.js.map +1 -1
- package/dist/router.d.ts +2 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +2164 -122
- package/dist/router.js.map +1 -1
- package/dist/runtime/releaseSource.d.ts +6 -0
- package/dist/runtime/releaseSource.d.ts.map +1 -1
- package/dist/runtime/releaseSource.js +1933 -32
- package/dist/runtime/releaseSource.js.map +1 -1
- package/dist/runtime/selfUpdate.js +1809 -8
- package/dist/runtime/signers.js +28 -9
- package/dist/runtime/store.js +18 -6
- package/dist/runtime/updateCheck.d.ts +4 -0
- package/dist/runtime/updateCheck.d.ts.map +1 -0
- package/dist/runtime/updateCheck.js +6695 -0
- package/dist/runtime/updateCheck.js.map +1 -0
- package/dist/sbom.json +21 -21
- package/dist/scanner/control.d.ts +27 -1
- package/dist/scanner/control.d.ts.map +1 -1
- package/dist/scanner/control.js +207 -36
- package/dist/scanner/control.js.map +1 -1
- package/dist/scanner/discover.d.ts +5 -0
- package/dist/scanner/discover.d.ts.map +1 -1
- package/dist/scanner/discover.js +16 -6
- package/dist/scanner/discover.js.map +1 -1
- package/dist/scanner/enable.d.ts +2 -0
- package/dist/scanner/enable.d.ts.map +1 -1
- package/dist/scanner/enable.js +152 -14
- package/dist/scanner/enable.js.map +1 -1
- package/dist/scanner/picker.d.ts.map +1 -1
- package/dist/scanner/picker.js +5 -6
- package/dist/scanner/picker.js.map +1 -1
- package/dist/scanner/service.d.ts +2 -0
- package/dist/scanner/service.d.ts.map +1 -1
- package/dist/scanner/service.js +279 -54
- package/dist/scanner/service.js.map +1 -1
- package/dist/scanner/update.d.ts +8 -0
- package/dist/scanner/update.d.ts.map +1 -1
- package/dist/scanner/update.js +254 -20
- package/dist/scanner/update.js.map +1 -1
- package/dist/scanner-release.json +35 -30
- package/dist/screens/journey.d.ts +6 -1
- package/dist/screens/journey.d.ts.map +1 -1
- package/dist/screens/journey.js +29 -8
- package/dist/screens/journey.js.map +1 -1
- package/dist/status.d.ts +21 -0
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +1993 -39
- package/dist/status.js.map +1 -1
- package/dist/vendor/local-setup.js +256 -29
- package/dist/vendor/shared/runtimeSigners.js +38 -11
- package/package.json +31 -31
package/dist/scanner/service.js
CHANGED
|
@@ -502,11 +502,73 @@ var require_ignore = __commonJS({
|
|
|
502
502
|
});
|
|
503
503
|
|
|
504
504
|
// packages/shared/dist/runtimeSigners.js
|
|
505
|
-
|
|
505
|
+
import { basename, dirname as dirname2, join as join2, resolve, sep, win32 } from "node:path";
|
|
506
|
+
import { execFile, execFileSync } from "node:child_process";
|
|
507
|
+
function windowsCommand(file) {
|
|
508
|
+
const root = process.env.SystemRoot;
|
|
509
|
+
if (!root || !win32.isAbsolute(root))
|
|
510
|
+
throw new Error("acl_system_root_unavailable");
|
|
511
|
+
return win32.join(root, "System32", file);
|
|
512
|
+
}
|
|
513
|
+
function readIdentity(stdout) {
|
|
514
|
+
const match = /^"([^"\r\n]+)","(S-1-(?:\d+-)+\d+)"$/.exec(stdout.trim());
|
|
515
|
+
if (!match?.[1] || !match[2] || stdout.includes("\uFFFD"))
|
|
516
|
+
throw new Error("acl_identity_unavailable");
|
|
517
|
+
return { name: match[1], sid: match[2] };
|
|
518
|
+
}
|
|
519
|
+
function* readWindowsIdentity() {
|
|
520
|
+
const user = readIdentity(yield [windowsCommand("whoami.exe"), identityArgs]);
|
|
521
|
+
if (!ADMINISTRATOR_RID.test(user.sid))
|
|
522
|
+
return user;
|
|
523
|
+
const groups = yield [windowsCommand("whoami.exe"), groupArgs];
|
|
524
|
+
const local = /^"[^"\r\n]*","[^"\r\n]*","S-1-5-113",/m.test(groups);
|
|
525
|
+
return {
|
|
526
|
+
...user,
|
|
527
|
+
localAdministratorSid: local ? `${user.sid.slice(0, user.sid.lastIndexOf("-"))}-500` : null
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
function windowsCurrentAccountSync() {
|
|
531
|
+
if (currentIdentity)
|
|
532
|
+
return currentIdentity;
|
|
533
|
+
const commands = readWindowsIdentity();
|
|
534
|
+
let step = commands.next();
|
|
535
|
+
while (!step.done)
|
|
536
|
+
step = commands.next(hookExecuteSync(...step.value));
|
|
537
|
+
return currentIdentity = step.value;
|
|
538
|
+
}
|
|
539
|
+
function hookInvocation(file, args2) {
|
|
540
|
+
if (win32.basename(file) === "whoami.exe") {
|
|
541
|
+
if ([file, ...args2].some((arg) => /[%!"\r\n]/.test(arg)))
|
|
542
|
+
throw new Error("acl_path_unavailable");
|
|
543
|
+
const command = args2.map((arg) => /^(?:[a-z0-9]+|\/[a-z]+)$/i.test(arg) ? arg : `"${arg}"`).join(" ");
|
|
544
|
+
return [
|
|
545
|
+
windowsCommand("cmd.exe"),
|
|
546
|
+
["/d", "/v:off", "/s", "/c", `"chcp 65001>nul & "${file}" ${command}"`]
|
|
547
|
+
];
|
|
548
|
+
}
|
|
549
|
+
if (win32.basename(file) === "cmd.exe")
|
|
550
|
+
return [file, ["/u", ...args2]];
|
|
551
|
+
return [file, args2];
|
|
552
|
+
}
|
|
553
|
+
function hookExecuteSync(file, args2, input) {
|
|
554
|
+
[file, args2] = hookInvocation(file, args2);
|
|
555
|
+
return execFileSync(file, args2, { ...hookOptions(file, args2), input });
|
|
556
|
+
}
|
|
557
|
+
var identityArgs, groupArgs, ADMINISTRATOR_RID, currentIdentity, ttl, hookOptions;
|
|
506
558
|
var init_runtimeSigners = __esm({
|
|
507
559
|
"packages/shared/dist/runtimeSigners.js"() {
|
|
508
560
|
"use strict";
|
|
561
|
+
identityArgs = ["/user", "/fo", "csv", "/nh"];
|
|
562
|
+
groupArgs = ["/groups", "/fo", "csv", "/nh"];
|
|
563
|
+
ADMINISTRATOR_RID = /^S-1-5-21-\d+-\d+-\d+-500$/;
|
|
509
564
|
ttl = 10 * 6e4;
|
|
565
|
+
hookOptions = (file, args2) => ({
|
|
566
|
+
encoding: args2.includes("/u") ? "utf16le" : "utf8",
|
|
567
|
+
timeout: win32.basename(file) === "powershell.exe" ? 3e4 : 5e3,
|
|
568
|
+
windowsHide: true,
|
|
569
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
570
|
+
windowsVerbatimArguments: win32.basename(file) === "cmd.exe"
|
|
571
|
+
});
|
|
510
572
|
}
|
|
511
573
|
});
|
|
512
574
|
|
|
@@ -2075,12 +2137,12 @@ var require_adapter = __commonJS({
|
|
|
2075
2137
|
return newFs;
|
|
2076
2138
|
}
|
|
2077
2139
|
function toPromise(method) {
|
|
2078
|
-
return (...args2) => new Promise((
|
|
2140
|
+
return (...args2) => new Promise((resolve2, reject) => {
|
|
2079
2141
|
args2.push((err2, result) => {
|
|
2080
2142
|
if (err2) {
|
|
2081
2143
|
reject(err2);
|
|
2082
2144
|
} else {
|
|
2083
|
-
|
|
2145
|
+
resolve2(result);
|
|
2084
2146
|
}
|
|
2085
2147
|
});
|
|
2086
2148
|
method(...args2);
|
|
@@ -3763,13 +3825,13 @@ async function Module2(moduleArg = {}) {
|
|
|
3763
3825
|
}
|
|
3764
3826
|
readAsync = /* @__PURE__ */ __name(async (url) => {
|
|
3765
3827
|
if (isFileURI(url)) {
|
|
3766
|
-
return new Promise((
|
|
3828
|
+
return new Promise((resolve2, reject) => {
|
|
3767
3829
|
var xhr = new XMLHttpRequest();
|
|
3768
3830
|
xhr.open("GET", url, true);
|
|
3769
3831
|
xhr.responseType = "arraybuffer";
|
|
3770
3832
|
xhr.onload = () => {
|
|
3771
3833
|
if (xhr.status == 200 || xhr.status == 0 && xhr.response) {
|
|
3772
|
-
|
|
3834
|
+
resolve2(xhr.response);
|
|
3773
3835
|
return;
|
|
3774
3836
|
}
|
|
3775
3837
|
reject(xhr.status);
|
|
@@ -3965,9 +4027,9 @@ async function Module2(moduleArg = {}) {
|
|
|
3965
4027
|
__name(receiveInstantiationResult, "receiveInstantiationResult");
|
|
3966
4028
|
var info22 = getWasmImports();
|
|
3967
4029
|
if (Module["instantiateWasm"]) {
|
|
3968
|
-
return new Promise((
|
|
4030
|
+
return new Promise((resolve2, reject) => {
|
|
3969
4031
|
Module["instantiateWasm"](info22, (mod, inst) => {
|
|
3970
|
-
|
|
4032
|
+
resolve2(receiveInstance(mod, inst));
|
|
3971
4033
|
});
|
|
3972
4034
|
});
|
|
3973
4035
|
}
|
|
@@ -5298,8 +5360,8 @@ async function Module2(moduleArg = {}) {
|
|
|
5298
5360
|
if (runtimeInitialized) {
|
|
5299
5361
|
moduleRtn = Module;
|
|
5300
5362
|
} else {
|
|
5301
|
-
moduleRtn = new Promise((
|
|
5302
|
-
readyPromiseResolve =
|
|
5363
|
+
moduleRtn = new Promise((resolve2, reject) => {
|
|
5364
|
+
readyPromiseResolve = resolve2;
|
|
5303
5365
|
readyPromiseReject = reject;
|
|
5304
5366
|
});
|
|
5305
5367
|
}
|
|
@@ -6361,7 +6423,7 @@ function scannerAttemptHealthy(receipt, attempt, paused = false) {
|
|
|
6361
6423
|
// packages/shared/dist/launchdControl.js
|
|
6362
6424
|
import { setTimeout as delay } from "node:timers/promises";
|
|
6363
6425
|
import { mkdir, readFile, rm, writeFile, lstat } from "node:fs/promises";
|
|
6364
|
-
import { join as
|
|
6426
|
+
import { join as join3 } from "node:path";
|
|
6365
6427
|
async function printLaunchdRegistration(domain, label, run2) {
|
|
6366
6428
|
try {
|
|
6367
6429
|
return await run2("launchctl", ["print", `${domain}/${label}`]);
|
|
@@ -6410,7 +6472,7 @@ async function removeMacScanner(state, home, uid, run2, options = {}) {
|
|
|
6410
6472
|
return false;
|
|
6411
6473
|
throw error;
|
|
6412
6474
|
});
|
|
6413
|
-
const receipt = await readFile(
|
|
6475
|
+
const receipt = await readFile(join3(state, "scanner/status.json"), "utf8").catch((error) => {
|
|
6414
6476
|
if (error.code === "ENOENT")
|
|
6415
6477
|
return null;
|
|
6416
6478
|
throw error;
|
|
@@ -6430,20 +6492,20 @@ async function removeMacScanner(state, home, uid, run2, options = {}) {
|
|
|
6430
6492
|
const legacy = [`user/${uid}`, `gui/${uid}`];
|
|
6431
6493
|
await stopLaunchdRegistrations(legacy, "ai.mnemonik.scanner.replacement", run2, options);
|
|
6432
6494
|
await stopLaunchdRegistrations(legacy, "ai.mnemonik.scanner", run2, { ...options, recordedPid });
|
|
6433
|
-
await rm(
|
|
6495
|
+
await rm(join3(state, "scanner/service-replacement"), { recursive: true, force: true });
|
|
6434
6496
|
if (options.remove === false) {
|
|
6435
|
-
await mkdir(
|
|
6436
|
-
await writeFile(
|
|
6497
|
+
await mkdir(join3(state, "scanner/service-replacement"), { recursive: true });
|
|
6498
|
+
await writeFile(join3(state, "scanner/service-replacement/result.json"), JSON.stringify({ stopped: true }));
|
|
6437
6499
|
return;
|
|
6438
6500
|
}
|
|
6439
6501
|
if (present || launcherPresent)
|
|
6440
6502
|
await run2("sudo", ["-n", "/bin/rm", "-f", plist, launcher]);
|
|
6441
6503
|
for (const label of ["ai.mnemonik.scanner", "ai.mnemonik.scanner.replacement"])
|
|
6442
|
-
await rm(
|
|
6443
|
-
await rm(
|
|
6444
|
-
await rm(
|
|
6445
|
-
await rm(
|
|
6446
|
-
await rm(
|
|
6504
|
+
await rm(join3(home, "Library/LaunchAgents", `${label}.plist`), { force: true });
|
|
6505
|
+
await rm(join3(state, "scanner/assets"), { recursive: true, force: true });
|
|
6506
|
+
await rm(join3(state, "scanner/service-supervisor.json"), { force: true });
|
|
6507
|
+
await rm(join3(state, "scanner/service-migrated"), { force: true });
|
|
6508
|
+
await rm(join3(state, "scanner/system-service.plist"), { force: true });
|
|
6447
6509
|
}
|
|
6448
6510
|
async function stopLaunchdRegistrations(domains, label, run2, options = {}) {
|
|
6449
6511
|
const now = options.now ?? Date.now;
|
|
@@ -6487,11 +6549,11 @@ async function stopLaunchdRegistrations(domains, label, run2, options = {}) {
|
|
|
6487
6549
|
// packages/shared/dist/systemdControl.js
|
|
6488
6550
|
import { existsSync } from "node:fs";
|
|
6489
6551
|
import { rm as rm2 } from "node:fs/promises";
|
|
6490
|
-
import { basename, dirname as
|
|
6552
|
+
import { basename as basename2, dirname as dirname3, join as join4 } from "node:path";
|
|
6491
6553
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
6492
6554
|
async function uninstallSystemdUnit(unitPath, run2, options = {}) {
|
|
6493
6555
|
try {
|
|
6494
|
-
const unit =
|
|
6556
|
+
const unit = basename2(unitPath);
|
|
6495
6557
|
if (!/^mnemonik-scanner(?:-test-[0-9]+)?\.service$/.test(unit))
|
|
6496
6558
|
throw new Error("invalid_test_unit");
|
|
6497
6559
|
const command = (args2) => run2("systemctl", ["--user", ...args2]);
|
|
@@ -6523,7 +6585,7 @@ async function uninstallSystemdUnit(unitPath, run2, options = {}) {
|
|
|
6523
6585
|
} catch (error) {
|
|
6524
6586
|
if (existsSync(unitPath) || !new RegExp(`Unit file ${unit.replaceAll(".", "\\.")} does not exist\\.?\\s*$`).test(error.message))
|
|
6525
6587
|
throw error;
|
|
6526
|
-
await rm2(
|
|
6588
|
+
await rm2(join4(dirname3(unitPath), "default.target.wants", unit), { force: true });
|
|
6527
6589
|
await command(["daemon-reload"]);
|
|
6528
6590
|
}
|
|
6529
6591
|
if ((await inspect()).ActiveState === "failed")
|
|
@@ -6552,7 +6614,7 @@ async function uninstallSystemdUnit(unitPath, run2, options = {}) {
|
|
|
6552
6614
|
}
|
|
6553
6615
|
|
|
6554
6616
|
// packages/shared/dist/scannerPid.js
|
|
6555
|
-
import { execFileSync } from "node:child_process";
|
|
6617
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
6556
6618
|
import { readFileSync } from "node:fs";
|
|
6557
6619
|
var SCANNER_CMD_PATTERN = /(mnemonik-scanner|scanner[\\/]dist[\\/]index\.js)/;
|
|
6558
6620
|
var capture = {
|
|
@@ -6560,7 +6622,7 @@ var capture = {
|
|
|
6560
6622
|
stdio: ["ignore", "pipe", "ignore"],
|
|
6561
6623
|
timeout: 5e3
|
|
6562
6624
|
};
|
|
6563
|
-
function processCmdline(pid, platform, exec =
|
|
6625
|
+
function processCmdline(pid, platform, exec = execFileSync2) {
|
|
6564
6626
|
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
6565
6627
|
return null;
|
|
6566
6628
|
if (platform === "win32") {
|
|
@@ -6587,7 +6649,7 @@ function processCmdline(pid, platform, exec = execFileSync) {
|
|
|
6587
6649
|
return null;
|
|
6588
6650
|
}
|
|
6589
6651
|
}
|
|
6590
|
-
function pidIsScanner(pid, platform = process.platform, exec =
|
|
6652
|
+
function pidIsScanner(pid, platform = process.platform, exec = execFileSync2, identity) {
|
|
6591
6653
|
const cmdline = processCmdline(pid, platform, exec);
|
|
6592
6654
|
if (cmdline === null)
|
|
6593
6655
|
return false;
|
|
@@ -6604,11 +6666,13 @@ function pidIsScanner(pid, platform = process.platform, exec = execFileSync, ide
|
|
|
6604
6666
|
|
|
6605
6667
|
// packages/local-setup/dist/storage.js
|
|
6606
6668
|
init_hookRuntime();
|
|
6669
|
+
init_hookRuntime();
|
|
6607
6670
|
import { createHash, randomUUID } from "node:crypto";
|
|
6671
|
+
import { execFile as nodeExecFile } from "node:child_process";
|
|
6608
6672
|
import fs2 from "node:fs";
|
|
6609
6673
|
import { open, rename, readFile as readFile2, mkdir as mkdir2, lstat as lstat2, chmod, writeFile as writeFile2, unlink, rmdir } from "node:fs/promises";
|
|
6610
|
-
|
|
6611
|
-
import { dirname as
|
|
6674
|
+
import { homedir } from "node:os";
|
|
6675
|
+
import { dirname as dirname4, join as join5, win32 as win322, posix } from "node:path";
|
|
6612
6676
|
import { setTimeout as delay3 } from "node:timers/promises";
|
|
6613
6677
|
var lockfileKey = /* @__PURE__ */ Symbol.for("mnemonik.proper-lockfile");
|
|
6614
6678
|
function sharedLockfile() {
|
|
@@ -6616,6 +6680,15 @@ function sharedLockfile() {
|
|
|
6616
6680
|
return shared[lockfileKey] ??= Promise.resolve().then(() => __toESM(require_proper_lockfile(), 1)).then((module2) => module2.default);
|
|
6617
6681
|
}
|
|
6618
6682
|
var codeIs = (error, code) => error.code === code;
|
|
6683
|
+
function stateDirectory(platform = process.platform, env = process.env, home = homedir()) {
|
|
6684
|
+
if (env.MNEMONIK_STATE_DIR)
|
|
6685
|
+
return env.MNEMONIK_STATE_DIR;
|
|
6686
|
+
if (platform === "win32")
|
|
6687
|
+
return win322.join(env.LOCALAPPDATA || win322.join(home, "AppData", "Local"), "Mnemonik");
|
|
6688
|
+
if (platform === "darwin")
|
|
6689
|
+
return posix.join(home, "Library", "Application Support", "Mnemonik");
|
|
6690
|
+
return posix.join(env.XDG_STATE_HOME || posix.join(home, ".local", "state"), "mnemonik");
|
|
6691
|
+
}
|
|
6619
6692
|
async function readBytes(path) {
|
|
6620
6693
|
try {
|
|
6621
6694
|
if (!(await lstat2(path)).isFile())
|
|
@@ -6627,11 +6700,69 @@ async function readBytes(path) {
|
|
|
6627
6700
|
throw error;
|
|
6628
6701
|
}
|
|
6629
6702
|
}
|
|
6703
|
+
async function syncDirectory(path) {
|
|
6704
|
+
if (process.platform === "win32")
|
|
6705
|
+
return;
|
|
6706
|
+
const fd = await open(path, "r");
|
|
6707
|
+
try {
|
|
6708
|
+
await fd.sync();
|
|
6709
|
+
} finally {
|
|
6710
|
+
await fd.close();
|
|
6711
|
+
}
|
|
6712
|
+
}
|
|
6713
|
+
var windowsCurrentAccount = windowsCurrentAccountSync;
|
|
6714
|
+
async function windowsCurrentUserAcl(path, directory = false, options = {}, created = false) {
|
|
6715
|
+
const username = options.username ?? `*${windowsCurrentAccount().sid}`;
|
|
6716
|
+
const grant = `${username}:${directory ? "(OI)(CI)F" : "F"}`;
|
|
6717
|
+
const execFile3 = options.execFile ?? nodeExecFile;
|
|
6718
|
+
await new Promise((resolve2, reject) => {
|
|
6719
|
+
execFile3("icacls.exe", [
|
|
6720
|
+
path,
|
|
6721
|
+
"/inheritance:r",
|
|
6722
|
+
"/grant:r",
|
|
6723
|
+
grant,
|
|
6724
|
+
...created ? ["/remove:g", "*S-1-5-32-544", "*S-1-5-18"] : []
|
|
6725
|
+
], (error) => {
|
|
6726
|
+
if (error)
|
|
6727
|
+
reject(error);
|
|
6728
|
+
else
|
|
6729
|
+
resolve2();
|
|
6730
|
+
});
|
|
6731
|
+
});
|
|
6732
|
+
}
|
|
6733
|
+
async function protectStateFile(path, platform = process.platform, aclOptions) {
|
|
6734
|
+
if (platform === "win32")
|
|
6735
|
+
await windowsCurrentUserAcl(path, false, aclOptions);
|
|
6736
|
+
else
|
|
6737
|
+
await chmod(path, 384);
|
|
6738
|
+
return "private";
|
|
6739
|
+
}
|
|
6740
|
+
async function atomicWrite(path, bytes, fault, assertOwned) {
|
|
6741
|
+
await assertOwned?.();
|
|
6742
|
+
const temp = `${path}.${randomUUID()}.tmp`;
|
|
6743
|
+
const fd = await open(temp, "wx", 384);
|
|
6744
|
+
let permissionStatus;
|
|
6745
|
+
try {
|
|
6746
|
+
permissionStatus = await protectStateFile(temp);
|
|
6747
|
+
const split = Math.ceil(bytes.length / 2);
|
|
6748
|
+
await fd.writeFile(bytes.subarray(0, split));
|
|
6749
|
+
await fault?.("mid_write");
|
|
6750
|
+
await assertOwned?.();
|
|
6751
|
+
await fd.writeFile(bytes.subarray(split));
|
|
6752
|
+
await fd.sync();
|
|
6753
|
+
} finally {
|
|
6754
|
+
await fd.close();
|
|
6755
|
+
}
|
|
6756
|
+
await assertOwned?.();
|
|
6757
|
+
await rename(temp, path);
|
|
6758
|
+
await syncDirectory(dirname4(path));
|
|
6759
|
+
return permissionStatus;
|
|
6760
|
+
}
|
|
6630
6761
|
async function withLock(path, waitMs, work) {
|
|
6631
6762
|
const lockfile = await sharedLockfile();
|
|
6632
|
-
await mkdir2(
|
|
6763
|
+
await mkdir2(dirname4(path), { recursive: true, mode: 448 });
|
|
6633
6764
|
const generation = randomUUID();
|
|
6634
|
-
const owner =
|
|
6765
|
+
const owner = join5(`${path}.lock`, "owner");
|
|
6635
6766
|
let compromised = false;
|
|
6636
6767
|
let acquired = false;
|
|
6637
6768
|
const assertOwned = async () => {
|
|
@@ -6646,14 +6777,14 @@ async function withLock(path, waitMs, work) {
|
|
|
6646
6777
|
void mkdir2(dir).then(() => writeFile2(owner, generation, { mode: 384, flag: "wx" })).then(() => callback(), callback);
|
|
6647
6778
|
},
|
|
6648
6779
|
rmdir: (dir, callback) => {
|
|
6649
|
-
void unlink(
|
|
6780
|
+
void unlink(join5(dir, "owner")).catch((error) => {
|
|
6650
6781
|
if (!codeIs(error, "ENOENT"))
|
|
6651
6782
|
throw error;
|
|
6652
6783
|
}).then(() => rmdir(dir)).then(() => callback(), callback);
|
|
6653
6784
|
},
|
|
6654
6785
|
rmdirSync: (dir) => {
|
|
6655
6786
|
try {
|
|
6656
|
-
fs2.unlinkSync(
|
|
6787
|
+
fs2.unlinkSync(join5(dir, "owner"));
|
|
6657
6788
|
} catch (error) {
|
|
6658
6789
|
if (!codeIs(error, "ENOENT"))
|
|
6659
6790
|
throw error;
|
|
@@ -6695,14 +6826,108 @@ async function withLock(path, waitMs, work) {
|
|
|
6695
6826
|
}
|
|
6696
6827
|
}
|
|
6697
6828
|
|
|
6829
|
+
// packages/local-setup/dist/automaticUpdate.js
|
|
6830
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
6831
|
+
import { realpathSync } from "node:fs";
|
|
6832
|
+
import { stat as nodeStat, utimes } from "node:fs/promises";
|
|
6833
|
+
import { homedir as homedir2 } from "node:os";
|
|
6834
|
+
import { join as join6 } from "node:path";
|
|
6835
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6836
|
+
var DAY_MS = 864e5;
|
|
6837
|
+
var statePath = (stateDir) => join6(stateDir, "automatic-update.json");
|
|
6838
|
+
function cliLauncherPath(options = {}) {
|
|
6839
|
+
const platform = options.platform ?? process.platform;
|
|
6840
|
+
const home = options.home ?? homedir2();
|
|
6841
|
+
return platform === "win32" ? join6(options.env?.LOCALAPPDATA || join6(home, "AppData", "Local"), "Mnemonik", "bin", "mnemonik.cmd") : join6(home, ".local", "bin", "mnemonik");
|
|
6842
|
+
}
|
|
6843
|
+
async function readState(path) {
|
|
6844
|
+
const bytes = await readBytes(path);
|
|
6845
|
+
if (!bytes)
|
|
6846
|
+
return {};
|
|
6847
|
+
const value = JSON.parse(bytes.toString());
|
|
6848
|
+
if (!value || typeof value !== "object" || value.lastAttempt !== void 0 && (!Number.isFinite(value.lastAttempt) || value.lastAttempt < 0))
|
|
6849
|
+
throw new Error("automatic_update_state_invalid");
|
|
6850
|
+
return value.lastAttempt === void 0 ? {} : { lastAttempt: value.lastAttempt };
|
|
6851
|
+
}
|
|
6852
|
+
async function maybeStartAutomaticUpdate(options = {}) {
|
|
6853
|
+
const stateDir = options.stateDir ?? stateDirectory(options.platform, options.env, options.home);
|
|
6854
|
+
const path = statePath(stateDir);
|
|
6855
|
+
try {
|
|
6856
|
+
const now = (options.now ?? Date.now)();
|
|
6857
|
+
const stat = options.stat ?? nodeStat;
|
|
6858
|
+
try {
|
|
6859
|
+
if (now - (await stat(path)).mtimeMs < DAY_MS)
|
|
6860
|
+
return false;
|
|
6861
|
+
} catch (error) {
|
|
6862
|
+
if (error.code !== "ENOENT")
|
|
6863
|
+
throw error;
|
|
6864
|
+
}
|
|
6865
|
+
if (!options.spawn && !(await stat(cliLauncherPath(options))).isFile())
|
|
6866
|
+
return false;
|
|
6867
|
+
return await withLock(path, 0, async (assertOwned) => {
|
|
6868
|
+
const state = await readState(path);
|
|
6869
|
+
if (state.lastAttempt !== void 0 && now - state.lastAttempt < DAY_MS)
|
|
6870
|
+
return false;
|
|
6871
|
+
await atomicWrite(path, Buffer.from(`${JSON.stringify({ lastAttempt: now })}
|
|
6872
|
+
`), void 0, assertOwned);
|
|
6873
|
+
await utimes(path, now / 1e3, now / 1e3);
|
|
6874
|
+
const platform = options.platform ?? process.platform;
|
|
6875
|
+
const launcher = cliLauncherPath(options);
|
|
6876
|
+
const command = platform === "win32" ? {
|
|
6877
|
+
file: options.env?.ComSpec || "cmd.exe",
|
|
6878
|
+
args: ["/d", "/s", "/c", `""${launcher}" update --automatic"`],
|
|
6879
|
+
windowsVerbatimArguments: true
|
|
6880
|
+
} : platform === "linux" && (options.env ?? process.env).INVOCATION_ID ? {
|
|
6881
|
+
// detached creates a process group, not a new systemd cgroup. An
|
|
6882
|
+
// updater spawned by the scanner must survive stopping that service.
|
|
6883
|
+
file: "systemd-run",
|
|
6884
|
+
args: [
|
|
6885
|
+
"--user",
|
|
6886
|
+
"--collect",
|
|
6887
|
+
"--quiet",
|
|
6888
|
+
`--setenv=MNEMONIK_STATE_DIR=${stateDir}`,
|
|
6889
|
+
"--",
|
|
6890
|
+
launcher,
|
|
6891
|
+
"update",
|
|
6892
|
+
"--automatic"
|
|
6893
|
+
]
|
|
6894
|
+
} : { file: launcher, args: ["update", "--automatic"] };
|
|
6895
|
+
const child = (options.spawn ?? nodeSpawn)(command.file, command.args, {
|
|
6896
|
+
detached: true,
|
|
6897
|
+
stdio: "ignore",
|
|
6898
|
+
windowsHide: true,
|
|
6899
|
+
..."windowsVerbatimArguments" in command ? { windowsVerbatimArguments: command.windowsVerbatimArguments } : {}
|
|
6900
|
+
});
|
|
6901
|
+
child.once("error", () => {
|
|
6902
|
+
});
|
|
6903
|
+
child.unref();
|
|
6904
|
+
return true;
|
|
6905
|
+
});
|
|
6906
|
+
} catch {
|
|
6907
|
+
return false;
|
|
6908
|
+
}
|
|
6909
|
+
}
|
|
6910
|
+
var HELPER_FLAG = "--mnemonik-automatic-update";
|
|
6911
|
+
function isHelperInvocation() {
|
|
6912
|
+
if (process.argv[2] !== HELPER_FLAG || !process.argv[3] || !process.argv[1])
|
|
6913
|
+
return false;
|
|
6914
|
+
try {
|
|
6915
|
+
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath2(import.meta.url));
|
|
6916
|
+
} catch {
|
|
6917
|
+
return false;
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
if (isHelperInvocation())
|
|
6921
|
+
void maybeStartAutomaticUpdate({ stateDir: process.argv[3] });
|
|
6922
|
+
|
|
6698
6923
|
// packages/local-setup/dist/index.js
|
|
6699
6924
|
var MAX_ORIGINAL_BYTES = 64 * 1024;
|
|
6700
6925
|
|
|
6701
6926
|
// packages/cli/src/scanner/service.ts
|
|
6702
|
-
import { execFile } from "node:child_process";
|
|
6927
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
6703
6928
|
import { readFile as readFile3, rm as rm3, lstat as lstat3 } from "node:fs/promises";
|
|
6704
|
-
import { join as
|
|
6705
|
-
import { homedir } from "node:os";
|
|
6929
|
+
import { join as join7, dirname as dirname5 } from "node:path";
|
|
6930
|
+
import { homedir as homedir3 } from "node:os";
|
|
6706
6931
|
import { promisify } from "node:util";
|
|
6707
6932
|
import { setTimeout as delay4 } from "node:timers/promises";
|
|
6708
6933
|
import { RuntimeStore } from "../runtime/store.js";
|
|
@@ -6778,7 +7003,7 @@ function scannerService(options) {
|
|
|
6778
7003
|
const configureStore = async () => {
|
|
6779
7004
|
if (!options.store) {
|
|
6780
7005
|
const saved = JSON.parse(
|
|
6781
|
-
await new RuntimeStore(options.stateDir).bytes(
|
|
7006
|
+
await new RuntimeStore(options.stateDir).bytes(join7(options.stateDir, "scanner/state.json")).then((bytes) => bytes.toString()).catch((error) => {
|
|
6782
7007
|
if (error.code === "ENOENT") return "null";
|
|
6783
7008
|
throw error;
|
|
6784
7009
|
})
|
|
@@ -6805,8 +7030,8 @@ function scannerService(options) {
|
|
|
6805
7030
|
if (fixed && (!fixed.isFile() || fixed.uid !== 0 || fixed.mode & 18))
|
|
6806
7031
|
throw new Error("service_runtime_permission");
|
|
6807
7032
|
const entry = fixed ? macScannerLauncher : (retained ? await store.verifyRetainedRuntime("scanner", retained.reference) : await verify()).entry;
|
|
6808
|
-
return new Promise((
|
|
6809
|
-
const child =
|
|
7033
|
+
return new Promise((resolve2, reject) => {
|
|
7034
|
+
const child = execFile2(
|
|
6810
7035
|
entry,
|
|
6811
7036
|
["service", operation, "--json"],
|
|
6812
7037
|
{
|
|
@@ -6829,7 +7054,7 @@ function scannerService(options) {
|
|
|
6829
7054
|
return;
|
|
6830
7055
|
}
|
|
6831
7056
|
try {
|
|
6832
|
-
|
|
7057
|
+
resolve2(JSON.parse(stdout));
|
|
6833
7058
|
} catch (error2) {
|
|
6834
7059
|
reject(error2);
|
|
6835
7060
|
}
|
|
@@ -6883,7 +7108,7 @@ function scannerService(options) {
|
|
|
6883
7108
|
const describe = async () => {
|
|
6884
7109
|
const runtime = await verify();
|
|
6885
7110
|
return options.describe ? await options.describe() : JSON.parse(
|
|
6886
|
-
(await promisify(
|
|
7111
|
+
(await promisify(execFile2)(runtime.entry, ["service", "describe", "--json"], {
|
|
6887
7112
|
env: {
|
|
6888
7113
|
...process.env,
|
|
6889
7114
|
MNEMONIK_STATE_DIR: options.stateDir,
|
|
@@ -6898,13 +7123,13 @@ function scannerService(options) {
|
|
|
6898
7123
|
async recover() {
|
|
6899
7124
|
if ((options.platform ?? process.platform) !== "darwin") return false;
|
|
6900
7125
|
return withLock(
|
|
6901
|
-
|
|
7126
|
+
join7(options.stateDir, "scanner/launchd-replacement-control"),
|
|
6902
7127
|
5e3,
|
|
6903
7128
|
async () => {
|
|
6904
7129
|
const receipt = await scannerReceipt(options.stateDir);
|
|
6905
7130
|
const snapshot = receipt?.snapshot;
|
|
6906
7131
|
const attempt = await readFile3(
|
|
6907
|
-
|
|
7132
|
+
join7(options.stateDir, "scanner/service-replacement/result.json"),
|
|
6908
7133
|
"utf8"
|
|
6909
7134
|
).then((text) => JSON.parse(text)).catch(() => null);
|
|
6910
7135
|
const age = now() - Number(attempt?.startedAt);
|
|
@@ -6916,7 +7141,7 @@ function scannerService(options) {
|
|
|
6916
7141
|
if (receipt && snapshot?.lifecycle.pid === pid && (snapshot.lifecycle.state === "paused" || now() - receipt.recordedAt <= SCANNER_RECEIPT_STALE_MS))
|
|
6917
7142
|
return false;
|
|
6918
7143
|
const state = JSON.parse(
|
|
6919
|
-
await readFile3(
|
|
7144
|
+
await readFile3(join7(options.stateDir, "scanner/state.json"), "utf8")
|
|
6920
7145
|
);
|
|
6921
7146
|
if (state.paused) return false;
|
|
6922
7147
|
let runtime = await verify();
|
|
@@ -6985,7 +7210,7 @@ function scannerService(options) {
|
|
|
6985
7210
|
},
|
|
6986
7211
|
async exportPreview(out2) {
|
|
6987
7212
|
const runtime = await verify();
|
|
6988
|
-
return promisify(
|
|
7213
|
+
return promisify(execFile2)(runtime.entry, ["export-preview", "--out", out2], {
|
|
6989
7214
|
env: {
|
|
6990
7215
|
...process.env,
|
|
6991
7216
|
MNEMONIK_STATE_DIR: options.stateDir,
|
|
@@ -6998,7 +7223,7 @@ function scannerService(options) {
|
|
|
6998
7223
|
replacementRuntime = runtime;
|
|
6999
7224
|
verified = false;
|
|
7000
7225
|
const saved = JSON.parse(
|
|
7001
|
-
replacement.state?.after ?? await readFile3(
|
|
7226
|
+
replacement.state?.after ?? await readFile3(join7(options.stateDir, "scanner/state.json"), "utf8")
|
|
7002
7227
|
);
|
|
7003
7228
|
const startedAt = now();
|
|
7004
7229
|
await invoke("install", {
|
|
@@ -7009,13 +7234,13 @@ function scannerService(options) {
|
|
|
7009
7234
|
credentialFamilyId: saved.config?.credentialFamilyId,
|
|
7010
7235
|
runAtLogin: true,
|
|
7011
7236
|
restart: { policy: "on-failure", delayMs: 3e3 },
|
|
7012
|
-
logDestination:
|
|
7237
|
+
logDestination: join7(options.stateDir, "scanner/scanner.log"),
|
|
7013
7238
|
replacement
|
|
7014
7239
|
});
|
|
7015
7240
|
const deadline = now() + SCANNER_HANDOFF_BUDGET_MS;
|
|
7016
7241
|
while (now() < deadline) {
|
|
7017
7242
|
const attempt = await readFile3(
|
|
7018
|
-
|
|
7243
|
+
join7(options.stateDir, "scanner/service-replacement/result.json"),
|
|
7019
7244
|
"utf8"
|
|
7020
7245
|
).then(JSON.parse).catch(() => null);
|
|
7021
7246
|
if (attempt && attempt.startedAt >= startedAt) {
|
|
@@ -7051,34 +7276,34 @@ function scannerService(options) {
|
|
|
7051
7276
|
await invoke("stop");
|
|
7052
7277
|
},
|
|
7053
7278
|
async uninstall() {
|
|
7054
|
-
const native = (timeout) => options.supervisorRun ?? (async (file, args2) => (await promisify(
|
|
7279
|
+
const native = (timeout) => options.supervisorRun ?? (async (file, args2) => (await promisify(execFile2)(file, args2, { encoding: "utf8", timeout })).stdout);
|
|
7055
7280
|
try {
|
|
7056
7281
|
if ((options.platform ?? process.platform) === "darwin") {
|
|
7057
7282
|
return await withLock(
|
|
7058
|
-
|
|
7283
|
+
join7(options.stateDir, "scanner/launchd-replacement-control"),
|
|
7059
7284
|
SCANNER_REMOVAL_BUDGET_MS,
|
|
7060
7285
|
async () => {
|
|
7061
7286
|
await removeMacScanner(
|
|
7062
7287
|
options.stateDir,
|
|
7063
|
-
options.home ??
|
|
7288
|
+
options.home ?? homedir3(),
|
|
7064
7289
|
options.uid ?? process.getuid?.() ?? -1,
|
|
7065
7290
|
native(SCANNER_REMOVAL_BUDGET_MS),
|
|
7066
7291
|
{ now, sleep, plist: options.systemPlist }
|
|
7067
7292
|
);
|
|
7068
|
-
await rm3(
|
|
7293
|
+
await rm3(dirname5(store.pointerPath("scanner")), { recursive: true, force: true });
|
|
7069
7294
|
}
|
|
7070
7295
|
);
|
|
7071
7296
|
}
|
|
7072
7297
|
if ((options.platform ?? process.platform) === "linux") {
|
|
7073
|
-
const recordedPid = await readFile3(
|
|
7298
|
+
const recordedPid = await readFile3(join7(options.stateDir, "scanner/status.json"), "utf8").then(
|
|
7074
7299
|
(text) => JSON.parse(text).snapshot?.lifecycle?.pid
|
|
7075
7300
|
).catch((error) => {
|
|
7076
7301
|
if (error.code === "ENOENT") return void 0;
|
|
7077
7302
|
throw error;
|
|
7078
7303
|
});
|
|
7079
7304
|
await uninstallSystemdUnit(
|
|
7080
|
-
|
|
7081
|
-
process.env.XDG_CONFIG_HOME ??
|
|
7305
|
+
join7(
|
|
7306
|
+
process.env.XDG_CONFIG_HOME ?? join7(options.home ?? homedir3(), ".config"),
|
|
7082
7307
|
"systemd/user/mnemonik-scanner.service"
|
|
7083
7308
|
),
|
|
7084
7309
|
native(SCANNER_STOP_BUDGET_MS),
|
|
@@ -7088,7 +7313,7 @@ function scannerService(options) {
|
|
|
7088
7313
|
await invoke("stop");
|
|
7089
7314
|
await invoke("uninstall");
|
|
7090
7315
|
}
|
|
7091
|
-
await rm3(
|
|
7316
|
+
await rm3(dirname5(store.pointerPath("scanner")), { recursive: true, force: true });
|
|
7092
7317
|
} catch (error) {
|
|
7093
7318
|
const cause = error.cause;
|
|
7094
7319
|
throw new ScannerServiceLimited(
|