@mnemonik/cli 7.109.3 → 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/auth/credentials.js
CHANGED
|
@@ -502,7 +502,9 @@ var require_ignore = __commonJS({
|
|
|
502
502
|
});
|
|
503
503
|
|
|
504
504
|
// packages/shared/dist/runtimeSigners.js
|
|
505
|
+
import { lstatSync, mkdirSync, readFileSync, writeFileSync, renameSync, unlinkSync } from "node:fs";
|
|
505
506
|
import { basename, dirname as dirname2, join as join2, resolve, sep, win32 } from "node:path";
|
|
507
|
+
import { createHash, createPublicKey, randomUUID, timingSafeEqual, verify as verifySignature } from "node:crypto";
|
|
506
508
|
import { execFile, execFileSync } from "node:child_process";
|
|
507
509
|
function windowsCommand(file) {
|
|
508
510
|
const root = process.env.SystemRoot;
|
|
@@ -510,14 +512,44 @@ function windowsCommand(file) {
|
|
|
510
512
|
throw new Error("acl_system_root_unavailable");
|
|
511
513
|
return win32.join(root, "System32", file);
|
|
512
514
|
}
|
|
513
|
-
function readIdentity(
|
|
514
|
-
const match = /^"([^"\r\n]+)","(S-1-(?:\d+-)+\d+)"$/.exec(
|
|
515
|
-
if (!match?.[1] || !match[2] ||
|
|
515
|
+
function readIdentity(stdout2) {
|
|
516
|
+
const match = /^"([^"\r\n]+)","(S-1-(?:\d+-)+\d+)"$/.exec(stdout2.trim());
|
|
517
|
+
if (!match?.[1] || !match[2] || stdout2.includes("\uFFFD"))
|
|
516
518
|
throw new Error("acl_identity_unavailable");
|
|
517
519
|
return { name: match[1], sid: match[2] };
|
|
518
520
|
}
|
|
521
|
+
function* readWindowsIdentity() {
|
|
522
|
+
const user = readIdentity(yield [windowsCommand("whoami.exe"), identityArgs]);
|
|
523
|
+
if (!ADMINISTRATOR_RID.test(user.sid))
|
|
524
|
+
return user;
|
|
525
|
+
const groups = yield [windowsCommand("whoami.exe"), groupArgs];
|
|
526
|
+
const local = /^"[^"\r\n]*","[^"\r\n]*","S-1-5-113",/m.test(groups);
|
|
527
|
+
return {
|
|
528
|
+
...user,
|
|
529
|
+
localAdministratorSid: local ? `${user.sid.slice(0, user.sid.lastIndexOf("-"))}-500` : null
|
|
530
|
+
};
|
|
531
|
+
}
|
|
519
532
|
function windowsCurrentAccountSync() {
|
|
520
|
-
|
|
533
|
+
if (currentIdentity)
|
|
534
|
+
return currentIdentity;
|
|
535
|
+
const commands = readWindowsIdentity();
|
|
536
|
+
let step = commands.next();
|
|
537
|
+
while (!step.done)
|
|
538
|
+
step = commands.next(hookExecuteSync(...step.value));
|
|
539
|
+
return currentIdentity = step.value;
|
|
540
|
+
}
|
|
541
|
+
async function windowsIdentity(run2) {
|
|
542
|
+
if (currentIdentity)
|
|
543
|
+
return currentIdentity;
|
|
544
|
+
identityPending ??= drive(readWindowsIdentity(), run2).then((identity) => currentIdentity = identity).finally(() => {
|
|
545
|
+
identityPending = void 0;
|
|
546
|
+
});
|
|
547
|
+
return identityPending;
|
|
548
|
+
}
|
|
549
|
+
async function verifyWindowsAcl(path, run2 = hookExecute, state) {
|
|
550
|
+
const user = await windowsIdentity(run2);
|
|
551
|
+
if (!privateEntries((await drive(saveAcl(path, false, [path], state), run2)).get(path), user, false))
|
|
552
|
+
throw new Error("acl_permissions");
|
|
521
553
|
}
|
|
522
554
|
function hookInvocation(file, args2) {
|
|
523
555
|
if (win32.basename(file) === "whoami.exe") {
|
|
@@ -537,12 +569,112 @@ function hookExecuteSync(file, args2, input) {
|
|
|
537
569
|
[file, args2] = hookInvocation(file, args2);
|
|
538
570
|
return execFileSync(file, args2, { ...hookOptions(file, args2), input });
|
|
539
571
|
}
|
|
540
|
-
|
|
572
|
+
function aclRecords(output, root, paths, onLookup) {
|
|
573
|
+
const records = /* @__PURE__ */ new Map();
|
|
574
|
+
const wanted = new Set(paths);
|
|
575
|
+
const lines = output.replace(/^\uFEFF/, "").trimEnd().split(/\r?\n/);
|
|
576
|
+
if (lines.length % 2)
|
|
577
|
+
throw new Error("acl_unavailable");
|
|
578
|
+
for (let index = 0; index < lines.length; index += 2) {
|
|
579
|
+
onLookup?.();
|
|
580
|
+
const relativePath = lines[index];
|
|
581
|
+
const descriptor = lines[index + 1];
|
|
582
|
+
if (relativePath === void 0 || descriptor === void 0)
|
|
583
|
+
throw new Error("acl_unavailable");
|
|
584
|
+
const path = resolve(dirname2(root), relativePath.replaceAll("\\", sep));
|
|
585
|
+
if (!wanted.has(path))
|
|
586
|
+
continue;
|
|
587
|
+
if (records.has(path))
|
|
588
|
+
throw new Error("acl_unavailable");
|
|
589
|
+
const dacl = /^D:(?:P|AI|AR)*((?:\([^()]*\))*)$/.exec(descriptor);
|
|
590
|
+
records.set(path, dacl?.[1]?.match(/\([^()]*\)/g) ?? []);
|
|
591
|
+
}
|
|
592
|
+
return records;
|
|
593
|
+
}
|
|
594
|
+
function privateEntries(entries, user, directory) {
|
|
595
|
+
if (!entries?.length)
|
|
596
|
+
throw new Error("acl_unavailable");
|
|
597
|
+
return entries.every((line) => {
|
|
598
|
+
const ace = /^\(([AD]);((?:OI|CI|NP|IO|ID|SA|FA)*);[A-Za-z0-9]+;;;((?:S-1-(?:\d+-)+\d+)|[A-Z]{2})\)$/.exec(line);
|
|
599
|
+
if (!ace)
|
|
600
|
+
throw new Error("acl_unavailable");
|
|
601
|
+
const sid = ace[3] === "LA" ? user.localAdministratorSid : ace[3];
|
|
602
|
+
return (!directory || !ace[2]?.includes("ID")) && (ace[1] === "D" || sid === user.sid);
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
function* prepareAclDirectory(state) {
|
|
606
|
+
const directory = join2(state, "audit-tmp");
|
|
607
|
+
if (auditDirectories.has(directory)) {
|
|
608
|
+
const stat2 = lstatSync(directory);
|
|
609
|
+
if (!stat2.isDirectory() || stat2.isSymbolicLink())
|
|
610
|
+
throw new Error("acl_permissions");
|
|
611
|
+
return directory;
|
|
612
|
+
}
|
|
613
|
+
let created = false;
|
|
614
|
+
try {
|
|
615
|
+
mkdirSync(directory, { mode: 448 });
|
|
616
|
+
created = true;
|
|
617
|
+
} catch (error) {
|
|
618
|
+
if (error.code !== "EEXIST")
|
|
619
|
+
throw error;
|
|
620
|
+
}
|
|
621
|
+
const stat = lstatSync(directory);
|
|
622
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
623
|
+
throw new Error("acl_permissions");
|
|
624
|
+
if (!auditDirectories.has(directory)) {
|
|
625
|
+
currentIdentity ??= yield* readWindowsIdentity();
|
|
626
|
+
yield [windowsCommand("icacls.exe"), aclArgs(directory, currentIdentity.sid, created)];
|
|
627
|
+
if (!created) {
|
|
628
|
+
const temp = join2(directory, `.acl-${randomUUID()}.tmp`);
|
|
629
|
+
writeFileSync(temp, "", { flag: "wx", mode: 384 });
|
|
630
|
+
try {
|
|
631
|
+
yield [windowsCommand("icacls.exe"), [directory, "/save", temp, "/l"]];
|
|
632
|
+
if (!privateEntries(aclRecords(readFileSync(temp, "utf16le"), directory, [directory]).get(directory), currentIdentity, true))
|
|
633
|
+
throw new Error("acl_permissions");
|
|
634
|
+
} finally {
|
|
635
|
+
unlinkSync(temp);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
auditDirectories.add(directory);
|
|
639
|
+
}
|
|
640
|
+
return directory;
|
|
641
|
+
}
|
|
642
|
+
function* saveAcl(path, recursive, paths = [path], state = lstatSync(path).isDirectory() ? path : dirname2(path)) {
|
|
643
|
+
const directory = yield* prepareAclDirectory(state);
|
|
644
|
+
const temp = join2(directory, `.acl-${randomUUID()}.tmp`);
|
|
645
|
+
writeFileSync(temp, "", { flag: "wx", mode: 384 });
|
|
646
|
+
try {
|
|
647
|
+
yield [windowsCommand("icacls.exe"), [path, "/save", temp, ...recursive ? ["/t"] : [], "/l"]];
|
|
648
|
+
return aclRecords(readFileSync(temp, "utf16le"), path, paths.filter((item) => item !== directory && !item.startsWith(directory + sep)));
|
|
649
|
+
} finally {
|
|
650
|
+
unlinkSync(temp);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
async function drive(commands, run2) {
|
|
654
|
+
try {
|
|
655
|
+
let step = commands.next();
|
|
656
|
+
while (!step.done)
|
|
657
|
+
step = commands.next(stdout(await run2(...step.value)));
|
|
658
|
+
return step.value;
|
|
659
|
+
} finally {
|
|
660
|
+
commands.return(void 0);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
var identityArgs, groupArgs, ADMINISTRATOR_RID, currentIdentity, ttl, identityPending, aclArgs, hookOptions, hookExecute, stdout, auditDirectories;
|
|
541
664
|
var init_runtimeSigners = __esm({
|
|
542
665
|
"packages/shared/dist/runtimeSigners.js"() {
|
|
543
666
|
"use strict";
|
|
544
667
|
identityArgs = ["/user", "/fo", "csv", "/nh"];
|
|
668
|
+
groupArgs = ["/groups", "/fo", "csv", "/nh"];
|
|
669
|
+
ADMINISTRATOR_RID = /^S-1-5-21-\d+-\d+-\d+-500$/;
|
|
545
670
|
ttl = 10 * 6e4;
|
|
671
|
+
aclArgs = (path, sid, created = false) => [
|
|
672
|
+
path,
|
|
673
|
+
"/inheritance:r",
|
|
674
|
+
"/grant:r",
|
|
675
|
+
`*${sid}:(OI)(CI)F`,
|
|
676
|
+
...created ? ["/remove:g", "*S-1-5-32-544", "*S-1-5-18"] : []
|
|
677
|
+
];
|
|
546
678
|
hookOptions = (file, args2) => ({
|
|
547
679
|
encoding: args2.includes("/u") ? "utf16le" : "utf8",
|
|
548
680
|
timeout: win32.basename(file) === "powershell.exe" ? 3e4 : 5e3,
|
|
@@ -550,6 +682,22 @@ var init_runtimeSigners = __esm({
|
|
|
550
682
|
maxBuffer: 16 * 1024 * 1024,
|
|
551
683
|
windowsVerbatimArguments: win32.basename(file) === "cmd.exe"
|
|
552
684
|
});
|
|
685
|
+
hookExecute = (file, args2, input) => {
|
|
686
|
+
const treeListing = win32.basename(file) === "icacls.exe" && args2.includes("/t") || win32.basename(file) === "cmd.exe" && args2.some((arg) => arg.startsWith("dir /q /a /s "));
|
|
687
|
+
[file, args2] = hookInvocation(file, args2);
|
|
688
|
+
const options = hookOptions(file, args2);
|
|
689
|
+
if (treeListing)
|
|
690
|
+
options.timeout = 3e4;
|
|
691
|
+
return new Promise((resolve3, reject) => {
|
|
692
|
+
const child = execFile(file, args2, options, (error, stdout2) => error ? reject(error) : resolve3({ stdout: stdout2 }));
|
|
693
|
+
if (input !== void 0) {
|
|
694
|
+
child.stdin?.on("error", reject);
|
|
695
|
+
child.stdin?.end(input);
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
};
|
|
699
|
+
stdout = (value) => value.stdout;
|
|
700
|
+
auditDirectories = /* @__PURE__ */ new Set();
|
|
553
701
|
}
|
|
554
702
|
});
|
|
555
703
|
|
|
@@ -2198,7 +2346,7 @@ var require_proper_lockfile = __commonJS({
|
|
|
2198
2346
|
|
|
2199
2347
|
// packages/credentials/dist/index.js
|
|
2200
2348
|
import { createHmac, randomBytes } from "node:crypto";
|
|
2201
|
-
import { join as
|
|
2349
|
+
import { join as join6 } from "node:path";
|
|
2202
2350
|
|
|
2203
2351
|
// packages/shared/dist/instructions.js
|
|
2204
2352
|
var INSTRUCTIONS_CONTENT = `Mnemonik provides persistent project memory: decisions, rationale, tasks, and policies across sessions. If no block begins "PROJECT_CONTEXT schemaVersion=", session_bootstrap({ cwd }) loads project context when cwd is the real absolute path of the project root; a placeholder or relative path fails. With that block, context is loaded and no session_bootstrap call is needed. Code and docs show current artifacts, git shows changes, and memory carries the why; memory_search recalls rationale or intent, then Grep or Read verifies current source.
|
|
@@ -6393,7 +6541,7 @@ init_repositoryRoot();
|
|
|
6393
6541
|
// packages/local-setup/dist/storage.js
|
|
6394
6542
|
init_hookRuntime();
|
|
6395
6543
|
init_hookRuntime();
|
|
6396
|
-
import { createHash, randomUUID } from "node:crypto";
|
|
6544
|
+
import { createHash as createHash2, randomUUID as randomUUID2 } from "node:crypto";
|
|
6397
6545
|
import { execFile as nodeExecFile } from "node:child_process";
|
|
6398
6546
|
import fs2 from "node:fs";
|
|
6399
6547
|
import { open, rename, readFile, mkdir, lstat, chmod, writeFile, unlink, rmdir } from "node:fs/promises";
|
|
@@ -6456,6 +6604,9 @@ async function windowsCurrentUserAcl(path, directory = false, options = {}, crea
|
|
|
6456
6604
|
});
|
|
6457
6605
|
});
|
|
6458
6606
|
}
|
|
6607
|
+
async function verifyWindowsCurrentUserOnly(path, state, run2) {
|
|
6608
|
+
await verifyWindowsAcl(path, run2, state);
|
|
6609
|
+
}
|
|
6459
6610
|
async function protectStateFile(path, platform = process.platform, aclOptions) {
|
|
6460
6611
|
if (platform === "win32")
|
|
6461
6612
|
await windowsCurrentUserAcl(path, false, aclOptions);
|
|
@@ -6465,7 +6616,7 @@ async function protectStateFile(path, platform = process.platform, aclOptions) {
|
|
|
6465
6616
|
}
|
|
6466
6617
|
async function atomicWrite(path, bytes, fault, assertOwned) {
|
|
6467
6618
|
await assertOwned?.();
|
|
6468
|
-
const temp = `${path}.${
|
|
6619
|
+
const temp = `${path}.${randomUUID2()}.tmp`;
|
|
6469
6620
|
const fd = await open(temp, "wx", 384);
|
|
6470
6621
|
let permissionStatus;
|
|
6471
6622
|
try {
|
|
@@ -6487,7 +6638,7 @@ async function atomicWrite(path, bytes, fault, assertOwned) {
|
|
|
6487
6638
|
async function withLock(path, waitMs, work) {
|
|
6488
6639
|
const lockfile = await sharedLockfile();
|
|
6489
6640
|
await mkdir(dirname3(path), { recursive: true, mode: 448 });
|
|
6490
|
-
const generation =
|
|
6641
|
+
const generation = randomUUID2();
|
|
6491
6642
|
const owner = join3(`${path}.lock`, "owner");
|
|
6492
6643
|
let compromised = false;
|
|
6493
6644
|
let acquired = false;
|
|
@@ -6552,6 +6703,100 @@ async function withLock(path, waitMs, work) {
|
|
|
6552
6703
|
}
|
|
6553
6704
|
}
|
|
6554
6705
|
|
|
6706
|
+
// packages/local-setup/dist/automaticUpdate.js
|
|
6707
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
6708
|
+
import { realpathSync } from "node:fs";
|
|
6709
|
+
import { stat as nodeStat, utimes } from "node:fs/promises";
|
|
6710
|
+
import { homedir as homedir2 } from "node:os";
|
|
6711
|
+
import { join as join4 } from "node:path";
|
|
6712
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
6713
|
+
var DAY_MS = 864e5;
|
|
6714
|
+
var statePath = (stateDir) => join4(stateDir, "automatic-update.json");
|
|
6715
|
+
function cliLauncherPath(options = {}) {
|
|
6716
|
+
const platform = options.platform ?? process.platform;
|
|
6717
|
+
const home = options.home ?? homedir2();
|
|
6718
|
+
return platform === "win32" ? join4(options.env?.LOCALAPPDATA || join4(home, "AppData", "Local"), "Mnemonik", "bin", "mnemonik.cmd") : join4(home, ".local", "bin", "mnemonik");
|
|
6719
|
+
}
|
|
6720
|
+
async function readState(path) {
|
|
6721
|
+
const bytes = await readBytes(path);
|
|
6722
|
+
if (!bytes)
|
|
6723
|
+
return {};
|
|
6724
|
+
const value = JSON.parse(bytes.toString());
|
|
6725
|
+
if (!value || typeof value !== "object" || value.lastAttempt !== void 0 && (!Number.isFinite(value.lastAttempt) || value.lastAttempt < 0))
|
|
6726
|
+
throw new Error("automatic_update_state_invalid");
|
|
6727
|
+
return value.lastAttempt === void 0 ? {} : { lastAttempt: value.lastAttempt };
|
|
6728
|
+
}
|
|
6729
|
+
async function maybeStartAutomaticUpdate(options = {}) {
|
|
6730
|
+
const stateDir = options.stateDir ?? stateDirectory(options.platform, options.env, options.home);
|
|
6731
|
+
const path = statePath(stateDir);
|
|
6732
|
+
try {
|
|
6733
|
+
const now = (options.now ?? Date.now)();
|
|
6734
|
+
const stat = options.stat ?? nodeStat;
|
|
6735
|
+
try {
|
|
6736
|
+
if (now - (await stat(path)).mtimeMs < DAY_MS)
|
|
6737
|
+
return false;
|
|
6738
|
+
} catch (error) {
|
|
6739
|
+
if (error.code !== "ENOENT")
|
|
6740
|
+
throw error;
|
|
6741
|
+
}
|
|
6742
|
+
if (!options.spawn && !(await stat(cliLauncherPath(options))).isFile())
|
|
6743
|
+
return false;
|
|
6744
|
+
return await withLock(path, 0, async (assertOwned) => {
|
|
6745
|
+
const state = await readState(path);
|
|
6746
|
+
if (state.lastAttempt !== void 0 && now - state.lastAttempt < DAY_MS)
|
|
6747
|
+
return false;
|
|
6748
|
+
await atomicWrite(path, Buffer.from(`${JSON.stringify({ lastAttempt: now })}
|
|
6749
|
+
`), void 0, assertOwned);
|
|
6750
|
+
await utimes(path, now / 1e3, now / 1e3);
|
|
6751
|
+
const platform = options.platform ?? process.platform;
|
|
6752
|
+
const launcher = cliLauncherPath(options);
|
|
6753
|
+
const command = platform === "win32" ? {
|
|
6754
|
+
file: options.env?.ComSpec || "cmd.exe",
|
|
6755
|
+
args: ["/d", "/s", "/c", `""${launcher}" update --automatic"`],
|
|
6756
|
+
windowsVerbatimArguments: true
|
|
6757
|
+
} : platform === "linux" && (options.env ?? process.env).INVOCATION_ID ? {
|
|
6758
|
+
// detached creates a process group, not a new systemd cgroup. An
|
|
6759
|
+
// updater spawned by the scanner must survive stopping that service.
|
|
6760
|
+
file: "systemd-run",
|
|
6761
|
+
args: [
|
|
6762
|
+
"--user",
|
|
6763
|
+
"--collect",
|
|
6764
|
+
"--quiet",
|
|
6765
|
+
`--setenv=MNEMONIK_STATE_DIR=${stateDir}`,
|
|
6766
|
+
"--",
|
|
6767
|
+
launcher,
|
|
6768
|
+
"update",
|
|
6769
|
+
"--automatic"
|
|
6770
|
+
]
|
|
6771
|
+
} : { file: launcher, args: ["update", "--automatic"] };
|
|
6772
|
+
const child = (options.spawn ?? nodeSpawn)(command.file, command.args, {
|
|
6773
|
+
detached: true,
|
|
6774
|
+
stdio: "ignore",
|
|
6775
|
+
windowsHide: true,
|
|
6776
|
+
..."windowsVerbatimArguments" in command ? { windowsVerbatimArguments: command.windowsVerbatimArguments } : {}
|
|
6777
|
+
});
|
|
6778
|
+
child.once("error", () => {
|
|
6779
|
+
});
|
|
6780
|
+
child.unref();
|
|
6781
|
+
return true;
|
|
6782
|
+
});
|
|
6783
|
+
} catch {
|
|
6784
|
+
return false;
|
|
6785
|
+
}
|
|
6786
|
+
}
|
|
6787
|
+
var HELPER_FLAG = "--mnemonik-automatic-update";
|
|
6788
|
+
function isHelperInvocation() {
|
|
6789
|
+
if (process.argv[2] !== HELPER_FLAG || !process.argv[3] || !process.argv[1])
|
|
6790
|
+
return false;
|
|
6791
|
+
try {
|
|
6792
|
+
return realpathSync(process.argv[1]) === realpathSync(fileURLToPath2(import.meta.url));
|
|
6793
|
+
} catch {
|
|
6794
|
+
return false;
|
|
6795
|
+
}
|
|
6796
|
+
}
|
|
6797
|
+
if (isHelperInvocation())
|
|
6798
|
+
void maybeStartAutomaticUpdate({ stateDir: process.argv[3] });
|
|
6799
|
+
|
|
6555
6800
|
// packages/local-setup/dist/index.js
|
|
6556
6801
|
var MAX_ORIGINAL_BYTES = 64 * 1024;
|
|
6557
6802
|
|
|
@@ -6570,10 +6815,10 @@ function isCredentialSessionUnavailableError(error) {
|
|
|
6570
6815
|
}
|
|
6571
6816
|
|
|
6572
6817
|
// packages/credentials/dist/storage.js
|
|
6573
|
-
import { createHash as
|
|
6818
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
6574
6819
|
import { lstat as nodeLstat, mkdir as mkdir2, open as open2, readdir, rmdir as rmdir2, unlink as unlink2 } from "node:fs/promises";
|
|
6575
6820
|
import { constants } from "node:fs";
|
|
6576
|
-
import { basename as basename2, dirname as dirname4, isAbsolute, join as
|
|
6821
|
+
import { basename as basename2, dirname as dirname4, isAbsolute, join as join5, parse, relative, resolve as resolve2, sep as sep2 } from "node:path";
|
|
6577
6822
|
var CredentialError = class extends Error {
|
|
6578
6823
|
reason;
|
|
6579
6824
|
constructor(reason) {
|
|
@@ -6582,22 +6827,22 @@ var CredentialError = class extends Error {
|
|
|
6582
6827
|
this.name = "CredentialError";
|
|
6583
6828
|
}
|
|
6584
6829
|
};
|
|
6585
|
-
var digest = (value) =>
|
|
6830
|
+
var digest = (value) => createHash3("sha256").update(value).digest("hex");
|
|
6586
6831
|
function credentialPaths(stateDir = stateDirectory(), familyId) {
|
|
6587
|
-
const root =
|
|
6832
|
+
const root = join5(stateDir, "credentials");
|
|
6588
6833
|
const familyName = familyId ? digest(familyId) : "";
|
|
6589
6834
|
return {
|
|
6590
6835
|
root,
|
|
6591
|
-
records:
|
|
6592
|
-
secrets:
|
|
6593
|
-
cliRecord:
|
|
6594
|
-
cliSecret:
|
|
6595
|
-
rootRecord:
|
|
6596
|
-
rootSecret:
|
|
6597
|
-
familyRecords:
|
|
6598
|
-
familySecrets:
|
|
6599
|
-
record:
|
|
6600
|
-
secret:
|
|
6836
|
+
records: join5(root, "records"),
|
|
6837
|
+
secrets: join5(root, "secrets"),
|
|
6838
|
+
cliRecord: join5(root, "records", "cli.json"),
|
|
6839
|
+
cliSecret: join5(root, "secrets", "cli.json"),
|
|
6840
|
+
rootRecord: join5(root, "records", "root-binding.json"),
|
|
6841
|
+
rootSecret: join5(root, "secrets", "root-binding.key"),
|
|
6842
|
+
familyRecords: join5(root, "records", "families"),
|
|
6843
|
+
familySecrets: join5(root, "secrets", "families"),
|
|
6844
|
+
record: join5(root, "records", "families", `${familyName}.json`),
|
|
6845
|
+
secret: join5(root, "secrets", "families", `${familyName}.json`)
|
|
6601
6846
|
};
|
|
6602
6847
|
}
|
|
6603
6848
|
var codeIs2 = (error, code) => error.code === code;
|
|
@@ -6609,6 +6854,7 @@ var SecureFiles = class {
|
|
|
6609
6854
|
fault;
|
|
6610
6855
|
execFile;
|
|
6611
6856
|
username;
|
|
6857
|
+
aclRun;
|
|
6612
6858
|
constructor(options = {}) {
|
|
6613
6859
|
this.stateDir = resolve2(options.stateDir ?? stateDirectory());
|
|
6614
6860
|
this.platform = options.platform ?? process.platform;
|
|
@@ -6617,6 +6863,7 @@ var SecureFiles = class {
|
|
|
6617
6863
|
this.fault = options.fault;
|
|
6618
6864
|
this.execFile = options.execFile;
|
|
6619
6865
|
this.username = options.username;
|
|
6866
|
+
this.aclRun = options.aclRun;
|
|
6620
6867
|
}
|
|
6621
6868
|
assertInsideState(path) {
|
|
6622
6869
|
const absolute = resolve2(path);
|
|
@@ -6632,7 +6879,7 @@ var SecureFiles = class {
|
|
|
6632
6879
|
const result = [];
|
|
6633
6880
|
let current2 = root;
|
|
6634
6881
|
for (const part of parts2) {
|
|
6635
|
-
current2 =
|
|
6882
|
+
current2 = join5(current2, part);
|
|
6636
6883
|
result.push(current2);
|
|
6637
6884
|
}
|
|
6638
6885
|
return result;
|
|
@@ -6651,20 +6898,34 @@ var SecureFiles = class {
|
|
|
6651
6898
|
if (value.isSymbolicLink())
|
|
6652
6899
|
throw new CredentialError("symlink_rejected");
|
|
6653
6900
|
const protectedComponent = component === this.stateDir || component.startsWith(`${this.stateDir}${sep2}`);
|
|
6654
|
-
if (!protectedComponent
|
|
6901
|
+
if (!protectedComponent)
|
|
6655
6902
|
continue;
|
|
6656
|
-
if (this.uid !== void 0 && value.uid !== this.uid)
|
|
6657
|
-
throw new CredentialError("wrong_owner");
|
|
6658
6903
|
const final = component === absolute;
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6904
|
+
if (this.platform === "win32") {
|
|
6905
|
+
if (final)
|
|
6906
|
+
await this.verifyWindowsPrivate(component);
|
|
6907
|
+
} else {
|
|
6908
|
+
if (this.uid !== void 0 && value.uid !== this.uid)
|
|
6909
|
+
throw new CredentialError("wrong_owner");
|
|
6910
|
+
const allowed = final && expectFile ? 384 : 448;
|
|
6911
|
+
if ((value.mode & 511 & ~allowed) !== 0)
|
|
6912
|
+
throw new CredentialError("weak_permissions");
|
|
6913
|
+
}
|
|
6662
6914
|
if (final && expectFile && !value.isFile())
|
|
6663
6915
|
throw new CredentialError("not_regular_file");
|
|
6664
6916
|
if (final && !expectFile && !value.isDirectory())
|
|
6665
6917
|
throw new CredentialError("not_regular_file");
|
|
6666
6918
|
}
|
|
6667
6919
|
}
|
|
6920
|
+
async verifyWindowsPrivate(path) {
|
|
6921
|
+
try {
|
|
6922
|
+
await verifyWindowsCurrentUserOnly(path, this.stateDir, this.aclRun);
|
|
6923
|
+
} catch (error) {
|
|
6924
|
+
if (error.message === "acl_permissions")
|
|
6925
|
+
throw new CredentialError("weak_permissions");
|
|
6926
|
+
throw error;
|
|
6927
|
+
}
|
|
6928
|
+
}
|
|
6668
6929
|
async makeDirectory(path) {
|
|
6669
6930
|
let created = false;
|
|
6670
6931
|
try {
|
|
@@ -6718,7 +6979,7 @@ var SecureFiles = class {
|
|
|
6718
6979
|
const prefix = `${basename2(absolute)}.`;
|
|
6719
6980
|
for (const name2 of await this.list(dirname4(absolute))) {
|
|
6720
6981
|
if (name2.startsWith(prefix) && name2.endsWith(".tmp"))
|
|
6721
|
-
await this.remove(
|
|
6982
|
+
await this.remove(join5(dirname4(absolute), name2));
|
|
6722
6983
|
}
|
|
6723
6984
|
throw error;
|
|
6724
6985
|
}
|
|
@@ -6765,7 +7026,7 @@ var SecureFiles = class {
|
|
|
6765
7026
|
|
|
6766
7027
|
// packages/credentials/dist/osSecretStore.js
|
|
6767
7028
|
import { execFile as nodeExecFile2 } from "node:child_process";
|
|
6768
|
-
import { randomUUID as
|
|
7029
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6769
7030
|
var service = "mnemonik.credentials.v1";
|
|
6770
7031
|
var unavailable = () => new Error("os_store_unavailable");
|
|
6771
7032
|
var cachedReads = /* @__PURE__ */ new Map();
|
|
@@ -6844,7 +7105,7 @@ function createStore(platform, execFile2) {
|
|
|
6844
7105
|
timeout: platform === "win32" ? 6e4 : 1e4,
|
|
6845
7106
|
maxBuffer: 64 * 1024,
|
|
6846
7107
|
windowsHide: true
|
|
6847
|
-
}, (error,
|
|
7108
|
+
}, (error, stdout2, stderr) => {
|
|
6848
7109
|
const code = error?.code;
|
|
6849
7110
|
const notFound = missing && (platform === "darwin" ? code === 44 && stderr.includes("The specified item could not be found in the keychain.") : platform === "win32" ? code === 3 : code === 1 && !stderr);
|
|
6850
7111
|
if (notFound)
|
|
@@ -6852,7 +7113,7 @@ function createStore(platform, execFile2) {
|
|
|
6852
7113
|
else if (error)
|
|
6853
7114
|
fail();
|
|
6854
7115
|
else
|
|
6855
|
-
resolve3(
|
|
7116
|
+
resolve3(stdout2);
|
|
6856
7117
|
});
|
|
6857
7118
|
child.stdin?.on("error", fail);
|
|
6858
7119
|
child.stdin?.end(input);
|
|
@@ -6911,7 +7172,7 @@ ${Buffer.from(secret, "utf8").toString("base64")}
|
|
|
6911
7172
|
if (failed)
|
|
6912
7173
|
return Promise.resolve(false);
|
|
6913
7174
|
return availability ??= (async () => {
|
|
6914
|
-
const probe = `${service}:probe:${
|
|
7175
|
+
const probe = `${service}:probe:${randomUUID3()}`;
|
|
6915
7176
|
if (platform === "darwin") {
|
|
6916
7177
|
await run2("security", ["-i"], "default-keychain -d user\n", false);
|
|
6917
7178
|
await operation("set", probe, "availability-probe");
|
|
@@ -7388,7 +7649,7 @@ function createCredentialAdapter(options = {}) {
|
|
|
7388
7649
|
const cli = await readRecord(paths.cliRecord, "cli-oauth");
|
|
7389
7650
|
const componentFamilyIds = [];
|
|
7390
7651
|
for (const name2 of await files.list(paths.familyRecords)) {
|
|
7391
|
-
const recordPath2 =
|
|
7652
|
+
const recordPath2 = join6(paths.familyRecords, name2);
|
|
7392
7653
|
const record = await readRecord(recordPath2, "component");
|
|
7393
7654
|
if (!record)
|
|
7394
7655
|
continue;
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export interface CliAuthOptions {
|
|
|
10
10
|
env?: NodeJS.ProcessEnv;
|
|
11
11
|
platform?: NodeJS.Platform;
|
|
12
12
|
deviceName?: string;
|
|
13
|
+
/** Reads the macOS Computer Name; replaced in tests. */
|
|
14
|
+
computerName?: () => Promise<string>;
|
|
13
15
|
print?: (line: string) => void;
|
|
14
16
|
fetch?: typeof fetch;
|
|
15
17
|
openBrowser?: (url: string) => Promise<void>;
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,uBAAuB,EAE5B,KAAK,kBAAkB,EAEvB,KAAK,wBAAwB,EAE9B,MAAM,uBAAuB,CAAC;AAK/B,eAAO,MAAM,UAAU,YACrB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,CACR,CAAC;AAIX,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,uBAAuB,CAAC,CAAC;IACzD,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CAC9C;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,OAAO,CAMT;AAkBD,wBAAgB,aAAa,CAAC,OAAO,GAAE,cAAmB;kBAmE/B,OAAO,CAAC,kBAAkB,CAAC;wBAsErB,OAAO,CAAC,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;2BAW/C,MAAM,KAAG,OAAO,CAAC,MAAM,CAAC;kBAgBnC,OAAO,CAAC,IAAI,CAAC;EAiBvC;AAED,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
|