@ecmaos/kernel 0.6.4 → 0.6.5
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/.vite/manifest.json +12 -12
- package/dist/{install-DIY-HQ9n.js → install-CNseKaMB.js} +2 -2
- package/dist/{install-DIY-HQ9n.js.map → install-CNseKaMB.js.map} +1 -1
- package/dist/{kernel-DtEbpoeV.js → kernel-C_Xvcpox.js} +463 -95
- package/dist/kernel-C_Xvcpox.js.map +1 -0
- package/dist/kernel.js +1 -1
- package/dist/{topbar.min-BK1fdCNA.js → topbar.min-D7kPyIYf.js} +2 -2
- package/dist/{topbar.min-BK1fdCNA.js.map → topbar.min-D7kPyIYf.js.map} +1 -1
- package/dist/ui.js +2 -4
- package/dist/ui.js.map +1 -1
- package/dist/{uninstall-BOyXf2bF.js → uninstall-CamF7_kP.js} +2 -2
- package/dist/{uninstall-BOyXf2bF.js.map → uninstall-CamF7_kP.js.map} +1 -1
- package/package.json +7 -6
- package/dist/kernel-DtEbpoeV.js.map +0 -1
|
@@ -25369,39 +25369,101 @@ const _Auth = class _Auth {
|
|
|
25369
25369
|
// Create a new credential
|
|
25370
25370
|
create: /* @__PURE__ */ __name(async (options) => {
|
|
25371
25371
|
try {
|
|
25372
|
-
|
|
25372
|
+
if (!this.passkey.isSupported()) {
|
|
25373
|
+
throw new Error("WebAuthn is not supported in this browser");
|
|
25374
|
+
}
|
|
25375
|
+
if (!window.isSecureContext) {
|
|
25376
|
+
throw new Error("WebAuthn requires a secure context (HTTPS or localhost)");
|
|
25377
|
+
}
|
|
25378
|
+
const credential = await navigator.credentials.create({ publicKey: options });
|
|
25379
|
+
if (!credential || !(credential instanceof PublicKeyCredential)) {
|
|
25380
|
+
throw new Error("Failed to create credential");
|
|
25381
|
+
}
|
|
25382
|
+
return credential;
|
|
25373
25383
|
} catch (error) {
|
|
25374
|
-
|
|
25375
|
-
|
|
25384
|
+
if (error instanceof Error) {
|
|
25385
|
+
if (error.name === "NotAllowedError") {
|
|
25386
|
+
throw new Error("User cancelled or denied the operation");
|
|
25387
|
+
} else if (error.name === "InvalidStateError") {
|
|
25388
|
+
throw new Error("Credential already exists or operation is invalid");
|
|
25389
|
+
} else if (error.name === "NotSupportedError") {
|
|
25390
|
+
throw new Error("The operation is not supported");
|
|
25391
|
+
} else if (error.name === "SecurityError") {
|
|
25392
|
+
throw new Error("Security error: operation not allowed");
|
|
25393
|
+
}
|
|
25394
|
+
throw error;
|
|
25395
|
+
}
|
|
25396
|
+
throw new Error(`Error creating credential: ${String(error)}`);
|
|
25376
25397
|
}
|
|
25377
25398
|
}, "create"),
|
|
25378
25399
|
// Get an existing credential
|
|
25379
25400
|
get: /* @__PURE__ */ __name(async (options) => {
|
|
25380
25401
|
try {
|
|
25381
|
-
|
|
25402
|
+
if (!this.passkey.isSupported()) {
|
|
25403
|
+
throw new Error("WebAuthn is not supported in this browser");
|
|
25404
|
+
}
|
|
25405
|
+
if (!window.isSecureContext) {
|
|
25406
|
+
throw new Error("WebAuthn requires a secure context (HTTPS or localhost)");
|
|
25407
|
+
}
|
|
25408
|
+
const credential = await navigator.credentials.get({ publicKey: options });
|
|
25409
|
+
if (!credential || !(credential instanceof PublicKeyCredential)) {
|
|
25410
|
+
return null;
|
|
25411
|
+
}
|
|
25412
|
+
return credential;
|
|
25382
25413
|
} catch (error) {
|
|
25383
|
-
|
|
25384
|
-
|
|
25414
|
+
if (error instanceof Error) {
|
|
25415
|
+
if (error.name === "NotAllowedError") {
|
|
25416
|
+
throw new Error("User cancelled or denied the operation");
|
|
25417
|
+
} else if (error.name === "InvalidStateError") {
|
|
25418
|
+
throw new Error("No matching credential found");
|
|
25419
|
+
} else if (error.name === "NotSupportedError") {
|
|
25420
|
+
throw new Error("The operation is not supported");
|
|
25421
|
+
} else if (error.name === "SecurityError") {
|
|
25422
|
+
throw new Error("Security error: operation not allowed");
|
|
25423
|
+
}
|
|
25424
|
+
throw error;
|
|
25425
|
+
}
|
|
25426
|
+
throw new Error(`Error getting credential: ${String(error)}`);
|
|
25385
25427
|
}
|
|
25386
25428
|
}, "get"),
|
|
25387
25429
|
// Check if WebAuthn is supported in the current browser
|
|
25388
25430
|
isSupported: /* @__PURE__ */ __name(() => {
|
|
25389
|
-
return !!window.PublicKeyCredential;
|
|
25431
|
+
return !!window.PublicKeyCredential && !!navigator.credentials;
|
|
25390
25432
|
}, "isSupported"),
|
|
25391
|
-
//
|
|
25392
|
-
|
|
25393
|
-
|
|
25394
|
-
|
|
25395
|
-
|
|
25396
|
-
|
|
25397
|
-
|
|
25398
|
-
|
|
25399
|
-
|
|
25400
|
-
|
|
25401
|
-
|
|
25402
|
-
|
|
25403
|
-
|
|
25404
|
-
|
|
25433
|
+
// Verify a passkey signature
|
|
25434
|
+
verify: /* @__PURE__ */ __name(async (credential, challenge, publicKey) => {
|
|
25435
|
+
try {
|
|
25436
|
+
const response = credential.response;
|
|
25437
|
+
const signature = response.signature;
|
|
25438
|
+
const clientDataJSON = response.clientDataJSON;
|
|
25439
|
+
const authenticatorData = response.authenticatorData;
|
|
25440
|
+
const clientData = JSON.parse(new TextDecoder().decode(clientDataJSON));
|
|
25441
|
+
const receivedChallenge = Uint8Array.from(atob(clientData.challenge), (c) => c.charCodeAt(0));
|
|
25442
|
+
const expectedChallenge = challenge;
|
|
25443
|
+
if (receivedChallenge.length !== expectedChallenge.length) {
|
|
25444
|
+
return false;
|
|
25445
|
+
}
|
|
25446
|
+
for (let i = 0; i < expectedChallenge.length; i++) {
|
|
25447
|
+
if (receivedChallenge[i] !== expectedChallenge[i]) {
|
|
25448
|
+
return false;
|
|
25449
|
+
}
|
|
25450
|
+
}
|
|
25451
|
+
const clientDataHash = await crypto.subtle.digest("SHA-256", clientDataJSON);
|
|
25452
|
+
const signedData = new Uint8Array(authenticatorData.byteLength + clientDataHash.byteLength);
|
|
25453
|
+
signedData.set(new Uint8Array(authenticatorData), 0);
|
|
25454
|
+
signedData.set(new Uint8Array(clientDataHash), authenticatorData.byteLength);
|
|
25455
|
+
const isValid2 = await crypto.subtle.verify(
|
|
25456
|
+
{ name: "ECDSA", hash: "SHA-256" },
|
|
25457
|
+
publicKey,
|
|
25458
|
+
signature,
|
|
25459
|
+
signedData
|
|
25460
|
+
);
|
|
25461
|
+
return isValid2;
|
|
25462
|
+
} catch (error) {
|
|
25463
|
+
console.error("Error verifying passkey:", error);
|
|
25464
|
+
return false;
|
|
25465
|
+
}
|
|
25466
|
+
}, "verify")
|
|
25405
25467
|
});
|
|
25406
25468
|
__publicField(this, "password", {
|
|
25407
25469
|
create: /* @__PURE__ */ __name(async (options) => {
|
|
@@ -28559,7 +28621,7 @@ const _Dom = class _Dom {
|
|
|
28559
28621
|
}
|
|
28560
28622
|
async topbar(show) {
|
|
28561
28623
|
if (!this._topbar) return;
|
|
28562
|
-
const { default: topbar } = await import("./topbar.min-
|
|
28624
|
+
const { default: topbar } = await import("./topbar.min-D7kPyIYf.js").then((n) => n.t);
|
|
28563
28625
|
this._topbarShow = show ?? !this._topbarShow;
|
|
28564
28626
|
if (this._topbarShow) topbar.show();
|
|
28565
28627
|
else topbar.hide();
|
|
@@ -59629,7 +59691,7 @@ const _TerminalCommand = class _TerminalCommand {
|
|
|
59629
59691
|
};
|
|
59630
59692
|
__name(_TerminalCommand, "TerminalCommand");
|
|
59631
59693
|
let TerminalCommand = _TerminalCommand;
|
|
59632
|
-
function createCommand$
|
|
59694
|
+
function createCommand$i(kernel, shell, terminal) {
|
|
59633
59695
|
return new TerminalCommand({
|
|
59634
59696
|
command: "cat",
|
|
59635
59697
|
description: "Concatenate files and print on the standard output",
|
|
@@ -59713,8 +59775,8 @@ function createCommand$h(kernel, shell, terminal) {
|
|
|
59713
59775
|
}, "run")
|
|
59714
59776
|
});
|
|
59715
59777
|
}
|
|
59716
|
-
__name(createCommand$
|
|
59717
|
-
function createCommand$
|
|
59778
|
+
__name(createCommand$i, "createCommand$i");
|
|
59779
|
+
function createCommand$h(kernel, shell, terminal) {
|
|
59718
59780
|
return new TerminalCommand({
|
|
59719
59781
|
command: "cd",
|
|
59720
59782
|
description: "Change the shell working directory",
|
|
@@ -59735,8 +59797,8 @@ function createCommand$g(kernel, shell, terminal) {
|
|
|
59735
59797
|
}, "run")
|
|
59736
59798
|
});
|
|
59737
59799
|
}
|
|
59738
|
-
__name(createCommand$
|
|
59739
|
-
function createCommand$
|
|
59800
|
+
__name(createCommand$h, "createCommand$h");
|
|
59801
|
+
function createCommand$g(kernel, shell, terminal) {
|
|
59740
59802
|
return new TerminalCommand({
|
|
59741
59803
|
command: "chmod",
|
|
59742
59804
|
description: "Change file mode bits",
|
|
@@ -59762,8 +59824,8 @@ function createCommand$f(kernel, shell, terminal) {
|
|
|
59762
59824
|
}, "run")
|
|
59763
59825
|
});
|
|
59764
59826
|
}
|
|
59765
|
-
__name(createCommand$
|
|
59766
|
-
function createCommand$
|
|
59827
|
+
__name(createCommand$g, "createCommand$g");
|
|
59828
|
+
function createCommand$f(kernel, shell, terminal) {
|
|
59767
59829
|
return new TerminalCommand({
|
|
59768
59830
|
command: "cp",
|
|
59769
59831
|
description: "Copy files",
|
|
@@ -59785,8 +59847,8 @@ function createCommand$e(kernel, shell, terminal) {
|
|
|
59785
59847
|
}, "run")
|
|
59786
59848
|
});
|
|
59787
59849
|
}
|
|
59788
|
-
__name(createCommand$
|
|
59789
|
-
function createCommand$
|
|
59850
|
+
__name(createCommand$f, "createCommand$f");
|
|
59851
|
+
function createCommand$e(kernel, shell, terminal) {
|
|
59790
59852
|
return new TerminalCommand({
|
|
59791
59853
|
command: "echo",
|
|
59792
59854
|
description: "Print arguments to the standard output",
|
|
@@ -59814,8 +59876,8 @@ function createCommand$d(kernel, shell, terminal) {
|
|
|
59814
59876
|
}, "run")
|
|
59815
59877
|
});
|
|
59816
59878
|
}
|
|
59817
|
-
__name(createCommand$
|
|
59818
|
-
function createCommand$
|
|
59879
|
+
__name(createCommand$e, "createCommand$e");
|
|
59880
|
+
function createCommand$d(kernel, shell, terminal) {
|
|
59819
59881
|
return new TerminalCommand({
|
|
59820
59882
|
command: "ln",
|
|
59821
59883
|
description: "Create links between files",
|
|
@@ -59907,7 +59969,7 @@ function createCommand$c(kernel, shell, terminal) {
|
|
|
59907
59969
|
}, "run")
|
|
59908
59970
|
});
|
|
59909
59971
|
}
|
|
59910
|
-
__name(createCommand$
|
|
59972
|
+
__name(createCommand$d, "createCommand$d");
|
|
59911
59973
|
var humanFormat$2 = { exports: {} };
|
|
59912
59974
|
var humanFormat$1 = humanFormat$2.exports;
|
|
59913
59975
|
var hasRequiredHumanFormat;
|
|
@@ -60188,7 +60250,7 @@ function requireHumanFormat() {
|
|
|
60188
60250
|
__name(requireHumanFormat, "requireHumanFormat");
|
|
60189
60251
|
var humanFormatExports = requireHumanFormat();
|
|
60190
60252
|
const humanFormat = /* @__PURE__ */ getDefaultExportFromCjs(humanFormatExports);
|
|
60191
|
-
function createCommand$
|
|
60253
|
+
function createCommand$c(kernel, shell, terminal) {
|
|
60192
60254
|
return new TerminalCommand({
|
|
60193
60255
|
command: "ls",
|
|
60194
60256
|
description: "List directory contents",
|
|
@@ -60353,8 +60415,8 @@ function createCommand$b(kernel, shell, terminal) {
|
|
|
60353
60415
|
}, "run")
|
|
60354
60416
|
});
|
|
60355
60417
|
}
|
|
60356
|
-
__name(createCommand$
|
|
60357
|
-
function createCommand$
|
|
60418
|
+
__name(createCommand$c, "createCommand$c");
|
|
60419
|
+
function createCommand$b(kernel, shell, terminal) {
|
|
60358
60420
|
return new TerminalCommand({
|
|
60359
60421
|
command: "mkdir",
|
|
60360
60422
|
description: "Create a directory",
|
|
@@ -60373,8 +60435,8 @@ function createCommand$a(kernel, shell, terminal) {
|
|
|
60373
60435
|
}, "run")
|
|
60374
60436
|
});
|
|
60375
60437
|
}
|
|
60376
|
-
__name(createCommand$
|
|
60377
|
-
function createCommand$
|
|
60438
|
+
__name(createCommand$b, "createCommand$b");
|
|
60439
|
+
function createCommand$a(kernel, shell, terminal) {
|
|
60378
60440
|
return new TerminalCommand({
|
|
60379
60441
|
command: "mv",
|
|
60380
60442
|
description: "Move or rename files",
|
|
@@ -60413,8 +60475,8 @@ function createCommand$9(kernel, shell, terminal) {
|
|
|
60413
60475
|
}, "run")
|
|
60414
60476
|
});
|
|
60415
60477
|
}
|
|
60416
|
-
__name(createCommand$
|
|
60417
|
-
function createCommand$
|
|
60478
|
+
__name(createCommand$a, "createCommand$a");
|
|
60479
|
+
function createCommand$9(kernel, shell, terminal) {
|
|
60418
60480
|
return new TerminalCommand({
|
|
60419
60481
|
command: "pwd",
|
|
60420
60482
|
description: "Print the shell working directory",
|
|
@@ -60430,8 +60492,8 @@ function createCommand$8(kernel, shell, terminal) {
|
|
|
60430
60492
|
}, "run")
|
|
60431
60493
|
});
|
|
60432
60494
|
}
|
|
60433
|
-
__name(createCommand$
|
|
60434
|
-
function createCommand$
|
|
60495
|
+
__name(createCommand$9, "createCommand$9");
|
|
60496
|
+
function createCommand$8(kernel, shell, terminal) {
|
|
60435
60497
|
return new TerminalCommand({
|
|
60436
60498
|
command: "rm",
|
|
60437
60499
|
description: "Remove files or directories",
|
|
@@ -60451,8 +60513,8 @@ function createCommand$7(kernel, shell, terminal) {
|
|
|
60451
60513
|
}, "run")
|
|
60452
60514
|
});
|
|
60453
60515
|
}
|
|
60454
|
-
__name(createCommand$
|
|
60455
|
-
function createCommand$
|
|
60516
|
+
__name(createCommand$8, "createCommand$8");
|
|
60517
|
+
function createCommand$7(kernel, shell, terminal) {
|
|
60456
60518
|
return new TerminalCommand({
|
|
60457
60519
|
command: "rmdir",
|
|
60458
60520
|
description: "Remove a directory",
|
|
@@ -60471,7 +60533,7 @@ function createCommand$6(kernel, shell, terminal) {
|
|
|
60471
60533
|
}, "run")
|
|
60472
60534
|
});
|
|
60473
60535
|
}
|
|
60474
|
-
__name(createCommand$
|
|
60536
|
+
__name(createCommand$7, "createCommand$7");
|
|
60475
60537
|
const MAX_32_BITS = 4294967295;
|
|
60476
60538
|
const MAX_16_BITS = 65535;
|
|
60477
60539
|
const MAX_8_BITS = 255;
|
|
@@ -65266,7 +65328,7 @@ const table = {
|
|
|
65266
65328
|
return mimeTypes;
|
|
65267
65329
|
})();
|
|
65268
65330
|
t(configure);
|
|
65269
|
-
function createCommand$
|
|
65331
|
+
function createCommand$6(kernel, shell, terminal) {
|
|
65270
65332
|
return new TerminalCommand({
|
|
65271
65333
|
command: "stat",
|
|
65272
65334
|
description: "Display information about a file or directory",
|
|
@@ -65296,8 +65358,8 @@ function createCommand$5(kernel, shell, terminal) {
|
|
|
65296
65358
|
}, "run")
|
|
65297
65359
|
});
|
|
65298
65360
|
}
|
|
65299
|
-
__name(createCommand$
|
|
65300
|
-
function createCommand$
|
|
65361
|
+
__name(createCommand$6, "createCommand$6");
|
|
65362
|
+
function createCommand$5(kernel, shell, terminal) {
|
|
65301
65363
|
return new TerminalCommand({
|
|
65302
65364
|
command: "touch",
|
|
65303
65365
|
description: "Create an empty file",
|
|
@@ -65316,8 +65378,8 @@ function createCommand$4(kernel, shell, terminal) {
|
|
|
65316
65378
|
}, "run")
|
|
65317
65379
|
});
|
|
65318
65380
|
}
|
|
65319
|
-
__name(createCommand$
|
|
65320
|
-
function createCommand$
|
|
65381
|
+
__name(createCommand$5, "createCommand$5");
|
|
65382
|
+
function createCommand$4(kernel, shell, terminal) {
|
|
65321
65383
|
return new TerminalCommand({
|
|
65322
65384
|
command: "hex",
|
|
65323
65385
|
description: "Display file contents in hexadecimal format",
|
|
@@ -65389,7 +65451,7 @@ function createCommand$3(kernel, shell, terminal) {
|
|
|
65389
65451
|
}, "run")
|
|
65390
65452
|
});
|
|
65391
65453
|
}
|
|
65392
|
-
__name(createCommand$
|
|
65454
|
+
__name(createCommand$4, "createCommand$4");
|
|
65393
65455
|
const csi = "\x1B[";
|
|
65394
65456
|
const ansi = {};
|
|
65395
65457
|
ansi.style = {
|
|
@@ -65567,7 +65629,7 @@ ansi.erase = {
|
|
|
65567
65629
|
return csi + (n || 0) + "K";
|
|
65568
65630
|
}, "inLine")
|
|
65569
65631
|
};
|
|
65570
|
-
function createCommand$
|
|
65632
|
+
function createCommand$3(kernel, shell, terminal) {
|
|
65571
65633
|
return new TerminalCommand({
|
|
65572
65634
|
command: "less",
|
|
65573
65635
|
description: "View file contents interactively",
|
|
@@ -65730,6 +65792,181 @@ function createCommand$2(kernel, shell, terminal) {
|
|
|
65730
65792
|
}, "run")
|
|
65731
65793
|
});
|
|
65732
65794
|
}
|
|
65795
|
+
__name(createCommand$3, "createCommand$3");
|
|
65796
|
+
function createCommand$2(kernel, shell, terminal) {
|
|
65797
|
+
return new TerminalCommand({
|
|
65798
|
+
command: "passkey",
|
|
65799
|
+
description: "Manage passkey credentials for WebAuthn authentication",
|
|
65800
|
+
kernel,
|
|
65801
|
+
shell,
|
|
65802
|
+
terminal,
|
|
65803
|
+
options: [
|
|
65804
|
+
{ name: "help", type: Boolean, description: kernel.i18n.t("Display help") },
|
|
65805
|
+
{ name: "subcommand", type: String, defaultOption: true, description: "Subcommand: register, list, remove, remove-all" },
|
|
65806
|
+
{ name: "name", type: String, description: "Name/description for the passkey (used with register)" },
|
|
65807
|
+
{ name: "id", type: String, description: "Passkey ID to remove (used with remove)" }
|
|
65808
|
+
],
|
|
65809
|
+
run: /* @__PURE__ */ __name(async (argv, process2) => {
|
|
65810
|
+
if (!process2) return 1;
|
|
65811
|
+
const currentUid = shell.credentials.uid;
|
|
65812
|
+
const user2 = kernel.users.get(currentUid);
|
|
65813
|
+
if (!user2) {
|
|
65814
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: Current user not found"));
|
|
65815
|
+
return 1;
|
|
65816
|
+
}
|
|
65817
|
+
const subcommand = argv.subcommand?.toLowerCase();
|
|
65818
|
+
if (!subcommand || subcommand === "help" || argv.help) {
|
|
65819
|
+
await writelnStdout(process2, terminal, "Usage: passkey <subcommand> [options]");
|
|
65820
|
+
await writelnStdout(process2, terminal, "");
|
|
65821
|
+
await writelnStdout(process2, terminal, "Subcommands:");
|
|
65822
|
+
await writelnStdout(process2, terminal, " register [--name <name>] Register a new passkey");
|
|
65823
|
+
await writelnStdout(process2, terminal, " list List all registered passkeys");
|
|
65824
|
+
await writelnStdout(process2, terminal, " remove --id <id> Remove a specific passkey");
|
|
65825
|
+
await writelnStdout(process2, terminal, " remove-all Remove all passkeys");
|
|
65826
|
+
return 0;
|
|
65827
|
+
}
|
|
65828
|
+
try {
|
|
65829
|
+
switch (subcommand) {
|
|
65830
|
+
case "register": {
|
|
65831
|
+
if (!kernel.auth.passkey.isSupported()) {
|
|
65832
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: WebAuthn is not supported in this browser"));
|
|
65833
|
+
return 1;
|
|
65834
|
+
}
|
|
65835
|
+
const name = argv.name || void 0;
|
|
65836
|
+
const username = user2.username;
|
|
65837
|
+
const userId = new TextEncoder().encode(username);
|
|
65838
|
+
const challenge = crypto.getRandomValues(new Uint8Array(32));
|
|
65839
|
+
const rpId = globalThis.location.hostname || "localhost";
|
|
65840
|
+
const createOptions = {
|
|
65841
|
+
challenge,
|
|
65842
|
+
rp: {
|
|
65843
|
+
name: kernel.name || "ecmaOS",
|
|
65844
|
+
id: rpId
|
|
65845
|
+
},
|
|
65846
|
+
user: {
|
|
65847
|
+
id: userId,
|
|
65848
|
+
name: username,
|
|
65849
|
+
displayName: username
|
|
65850
|
+
},
|
|
65851
|
+
pubKeyCredParams: [
|
|
65852
|
+
{ type: "public-key", alg: -7 },
|
|
65853
|
+
{ type: "public-key", alg: -257 }
|
|
65854
|
+
],
|
|
65855
|
+
authenticatorSelection: {
|
|
65856
|
+
userVerification: "preferred"
|
|
65857
|
+
},
|
|
65858
|
+
timeout: 6e4
|
|
65859
|
+
};
|
|
65860
|
+
await writelnStdout(process2, terminal, chalk$1.yellow("Please interact with your authenticator to register a passkey..."));
|
|
65861
|
+
const credential = await kernel.auth.passkey.create(createOptions);
|
|
65862
|
+
if (!credential || !(credential instanceof PublicKeyCredential)) {
|
|
65863
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: Failed to create passkey. Registration cancelled or failed."));
|
|
65864
|
+
return 1;
|
|
65865
|
+
}
|
|
65866
|
+
const publicKeyCredential = credential;
|
|
65867
|
+
const response = publicKeyCredential.response;
|
|
65868
|
+
const credentialId = btoa(String.fromCharCode(...new Uint8Array(publicKeyCredential.rawId)));
|
|
65869
|
+
let publicKeyArray;
|
|
65870
|
+
try {
|
|
65871
|
+
if (typeof response.getPublicKey === "function") {
|
|
65872
|
+
try {
|
|
65873
|
+
const publicKeyCrypto = response.getPublicKey();
|
|
65874
|
+
if (publicKeyCrypto && publicKeyCrypto instanceof CryptoKey) {
|
|
65875
|
+
const publicKeyJwk = await crypto.subtle.exportKey("jwk", publicKeyCrypto);
|
|
65876
|
+
publicKeyArray = new TextEncoder().encode(JSON.stringify(publicKeyJwk));
|
|
65877
|
+
} else {
|
|
65878
|
+
throw new Error("getPublicKey() did not return a valid CryptoKey");
|
|
65879
|
+
}
|
|
65880
|
+
} catch (exportError) {
|
|
65881
|
+
await writelnStderr(process2, terminal, chalk$1.yellow(`Warning: Could not extract public key via getPublicKey(): ${exportError instanceof Error ? exportError.message : String(exportError)}. Using attestationObject instead.`));
|
|
65882
|
+
const attestationObject = response.attestationObject;
|
|
65883
|
+
publicKeyArray = new Uint8Array(attestationObject);
|
|
65884
|
+
}
|
|
65885
|
+
} else {
|
|
65886
|
+
const attestationObject = response.attestationObject;
|
|
65887
|
+
publicKeyArray = new Uint8Array(attestationObject);
|
|
65888
|
+
}
|
|
65889
|
+
} catch (error) {
|
|
65890
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error processing credential data: ${error instanceof Error ? error.message : String(error)}`));
|
|
65891
|
+
return 1;
|
|
65892
|
+
}
|
|
65893
|
+
const passkey = {
|
|
65894
|
+
id: crypto.randomUUID(),
|
|
65895
|
+
credentialId,
|
|
65896
|
+
publicKey: publicKeyArray,
|
|
65897
|
+
createdAt: Date.now(),
|
|
65898
|
+
name
|
|
65899
|
+
};
|
|
65900
|
+
await kernel.users.addPasskey(currentUid, passkey);
|
|
65901
|
+
await writelnStdout(process2, terminal, chalk$1.green(`Passkey registered successfully${name ? `: ${name}` : ""}`));
|
|
65902
|
+
await writelnStdout(process2, terminal, `Passkey ID: ${passkey.id}`);
|
|
65903
|
+
return 0;
|
|
65904
|
+
}
|
|
65905
|
+
case "list": {
|
|
65906
|
+
const passkeys = await kernel.users.getPasskeys(currentUid);
|
|
65907
|
+
if (passkeys.length === 0) {
|
|
65908
|
+
await writelnStdout(process2, terminal, "No passkeys registered for this user.");
|
|
65909
|
+
return 0;
|
|
65910
|
+
}
|
|
65911
|
+
await writelnStdout(process2, terminal, `Registered passkeys (${passkeys.length}):`);
|
|
65912
|
+
await writelnStdout(process2, terminal, "");
|
|
65913
|
+
for (const pk of passkeys) {
|
|
65914
|
+
const createdDate = new Date(pk.createdAt).toLocaleString();
|
|
65915
|
+
const lastUsedDate = pk.lastUsed ? new Date(pk.lastUsed).toLocaleString() : "Never";
|
|
65916
|
+
await writelnStdout(process2, terminal, ` ID: ${pk.id}`);
|
|
65917
|
+
if (pk.name) {
|
|
65918
|
+
await writelnStdout(process2, terminal, ` Name: ${pk.name}`);
|
|
65919
|
+
}
|
|
65920
|
+
await writelnStdout(process2, terminal, ` Created: ${createdDate}`);
|
|
65921
|
+
await writelnStdout(process2, terminal, ` Last used: ${lastUsedDate}`);
|
|
65922
|
+
await writelnStdout(process2, terminal, "");
|
|
65923
|
+
}
|
|
65924
|
+
return 0;
|
|
65925
|
+
}
|
|
65926
|
+
case "remove": {
|
|
65927
|
+
const id = argv.id;
|
|
65928
|
+
if (!id) {
|
|
65929
|
+
await writelnStderr(process2, terminal, chalk$1.red("Error: --id is required for remove command"));
|
|
65930
|
+
await writelnStdout(process2, terminal, "Usage: passkey remove --id <id>");
|
|
65931
|
+
return 1;
|
|
65932
|
+
}
|
|
65933
|
+
const passkeys = await kernel.users.getPasskeys(currentUid);
|
|
65934
|
+
const passkey = passkeys.find((pk) => pk.id === id);
|
|
65935
|
+
if (!passkey) {
|
|
65936
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error: Passkey with ID ${id} not found`));
|
|
65937
|
+
return 1;
|
|
65938
|
+
}
|
|
65939
|
+
await kernel.users.removePasskey(currentUid, id);
|
|
65940
|
+
await writelnStdout(process2, terminal, chalk$1.green(`Passkey removed successfully${passkey.name ? `: ${passkey.name}` : ""}`));
|
|
65941
|
+
return 0;
|
|
65942
|
+
}
|
|
65943
|
+
case "remove-all": {
|
|
65944
|
+
const passkeys = await kernel.users.getPasskeys(currentUid);
|
|
65945
|
+
if (passkeys.length === 0) {
|
|
65946
|
+
await writelnStdout(process2, terminal, "No passkeys to remove.");
|
|
65947
|
+
return 0;
|
|
65948
|
+
}
|
|
65949
|
+
await kernel.users.savePasskeys(currentUid, []);
|
|
65950
|
+
const passkeysPath = `${user2.home}/.passkeys`;
|
|
65951
|
+
try {
|
|
65952
|
+
await kernel.filesystem.fs.unlink(passkeysPath);
|
|
65953
|
+
} catch {
|
|
65954
|
+
}
|
|
65955
|
+
await writelnStdout(process2, terminal, chalk$1.green(`Removed ${passkeys.length} passkey(s)`));
|
|
65956
|
+
return 0;
|
|
65957
|
+
}
|
|
65958
|
+
default:
|
|
65959
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error: Unknown subcommand: ${subcommand}`));
|
|
65960
|
+
await writelnStdout(process2, terminal, 'Run "passkey help" for usage information');
|
|
65961
|
+
return 1;
|
|
65962
|
+
}
|
|
65963
|
+
} catch (error) {
|
|
65964
|
+
await writelnStderr(process2, terminal, chalk$1.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
|
|
65965
|
+
return 1;
|
|
65966
|
+
}
|
|
65967
|
+
}, "run")
|
|
65968
|
+
});
|
|
65969
|
+
}
|
|
65733
65970
|
__name(createCommand$2, "createCommand$2");
|
|
65734
65971
|
function parseSedExpression(expr) {
|
|
65735
65972
|
expr = expr.trim();
|
|
@@ -66168,22 +66405,23 @@ function createCommand(kernel, shell, terminal) {
|
|
|
66168
66405
|
__name(createCommand, "createCommand");
|
|
66169
66406
|
function createAllCommands(kernel, shell, terminal) {
|
|
66170
66407
|
return {
|
|
66171
|
-
cat: createCommand$
|
|
66172
|
-
cd: createCommand$
|
|
66173
|
-
chmod: createCommand$
|
|
66174
|
-
cp: createCommand$
|
|
66175
|
-
echo: createCommand$
|
|
66176
|
-
ln: createCommand$
|
|
66177
|
-
ls: createCommand$
|
|
66178
|
-
mkdir: createCommand$
|
|
66179
|
-
mv: createCommand$
|
|
66180
|
-
pwd: createCommand$
|
|
66181
|
-
rm: createCommand$
|
|
66182
|
-
rmdir: createCommand$
|
|
66183
|
-
stat: createCommand$
|
|
66184
|
-
touch: createCommand$
|
|
66185
|
-
hex: createCommand$
|
|
66186
|
-
less: createCommand$
|
|
66408
|
+
cat: createCommand$i(kernel, shell, terminal),
|
|
66409
|
+
cd: createCommand$h(kernel, shell, terminal),
|
|
66410
|
+
chmod: createCommand$g(kernel, shell, terminal),
|
|
66411
|
+
cp: createCommand$f(kernel, shell, terminal),
|
|
66412
|
+
echo: createCommand$e(kernel, shell, terminal),
|
|
66413
|
+
ln: createCommand$d(kernel, shell, terminal),
|
|
66414
|
+
ls: createCommand$c(kernel, shell, terminal),
|
|
66415
|
+
mkdir: createCommand$b(kernel, shell, terminal),
|
|
66416
|
+
mv: createCommand$a(kernel, shell, terminal),
|
|
66417
|
+
pwd: createCommand$9(kernel, shell, terminal),
|
|
66418
|
+
rm: createCommand$8(kernel, shell, terminal),
|
|
66419
|
+
rmdir: createCommand$7(kernel, shell, terminal),
|
|
66420
|
+
stat: createCommand$6(kernel, shell, terminal),
|
|
66421
|
+
touch: createCommand$5(kernel, shell, terminal),
|
|
66422
|
+
hex: createCommand$4(kernel, shell, terminal),
|
|
66423
|
+
less: createCommand$3(kernel, shell, terminal),
|
|
66424
|
+
passkey: createCommand$2(kernel, shell, terminal),
|
|
66187
66425
|
sed: createCommand$1(kernel, shell, terminal),
|
|
66188
66426
|
tee: createCommand(kernel, shell, terminal)
|
|
66189
66427
|
};
|
|
@@ -66289,7 +66527,7 @@ const TerminalCommands = /* @__PURE__ */ __name((kernel, shell, terminal) => {
|
|
|
66289
66527
|
{ name: "reinstall", type: Boolean, description: "Reinstall the package if it is already installed" }
|
|
66290
66528
|
],
|
|
66291
66529
|
run: /* @__PURE__ */ __name(async (argv) => {
|
|
66292
|
-
const { default: install } = await import("./install-
|
|
66530
|
+
const { default: install } = await import("./install-CNseKaMB.js");
|
|
66293
66531
|
return await install({ kernel, shell, terminal, args: [argv.package, argv.registry, argv.reinstall] });
|
|
66294
66532
|
}, "run")
|
|
66295
66533
|
}),
|
|
@@ -66304,7 +66542,7 @@ const TerminalCommands = /* @__PURE__ */ __name((kernel, shell, terminal) => {
|
|
|
66304
66542
|
{ name: "package", type: String, typeLabel: "{underline package}", defaultOption: true, description: "The package name and optional version (e.g. package@1.0.0). If no version is specified, all versions will be uninstalled." }
|
|
66305
66543
|
],
|
|
66306
66544
|
run: /* @__PURE__ */ __name(async (argv) => {
|
|
66307
|
-
const { default: uninstall } = await import("./uninstall-
|
|
66545
|
+
const { default: uninstall } = await import("./uninstall-CamF7_kP.js");
|
|
66308
66546
|
return await uninstall({ kernel, shell, terminal, args: [argv.package] });
|
|
66309
66547
|
}, "run")
|
|
66310
66548
|
}),
|
|
@@ -72157,10 +72395,27 @@ const _Users = class _Users {
|
|
|
72157
72395
|
/**
|
|
72158
72396
|
* Login a user
|
|
72159
72397
|
*/
|
|
72160
|
-
async login(username, password) {
|
|
72398
|
+
async login(username, password, passkeyCredential) {
|
|
72161
72399
|
const user2 = Array.from(this._users.values()).find((u) => u.username === username);
|
|
72162
|
-
|
|
72163
|
-
if (
|
|
72400
|
+
if (!user2) throw new Error("Invalid username or password");
|
|
72401
|
+
if (passkeyCredential) {
|
|
72402
|
+
const passkeys = await this.getPasskeys(user2.uid);
|
|
72403
|
+
const credential = passkeyCredential;
|
|
72404
|
+
const credentialId = btoa(String.fromCharCode(...new Uint8Array(credential.rawId)));
|
|
72405
|
+
const matchingPasskey = passkeys.find((pk) => pk.credentialId === credentialId);
|
|
72406
|
+
if (!matchingPasskey) {
|
|
72407
|
+
throw new Error("Passkey not found for this user");
|
|
72408
|
+
}
|
|
72409
|
+
matchingPasskey.lastUsed = Date.now();
|
|
72410
|
+
await this.savePasskeys(user2.uid, passkeys);
|
|
72411
|
+
} else if (password) {
|
|
72412
|
+
const hashedPassword = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(password.trim()));
|
|
72413
|
+
if (user2.password !== Array.from(new Uint8Array(hashedPassword)).map((b) => b.toString(16).padStart(2, "0")).join("")) {
|
|
72414
|
+
throw new Error("Invalid username or password");
|
|
72415
|
+
}
|
|
72416
|
+
} else {
|
|
72417
|
+
throw new Error("Password or passkey required");
|
|
72418
|
+
}
|
|
72164
72419
|
const cred = createCredentials({
|
|
72165
72420
|
uid: user2.uid,
|
|
72166
72421
|
gid: user2.gid,
|
|
@@ -72204,6 +72459,77 @@ const _Users = class _Users {
|
|
|
72204
72459
|
throw new Error(`User with UID ${uid} not found`);
|
|
72205
72460
|
}
|
|
72206
72461
|
}
|
|
72462
|
+
/**
|
|
72463
|
+
* Get all passkeys for a user
|
|
72464
|
+
*/
|
|
72465
|
+
async getPasskeys(uid) {
|
|
72466
|
+
const user2 = this._users.get(uid);
|
|
72467
|
+
if (!user2) return [];
|
|
72468
|
+
const passkeysPath = `${user2.home}/.passkeys`;
|
|
72469
|
+
try {
|
|
72470
|
+
const exists2 = await this._options.kernel.filesystem.fs.exists(passkeysPath);
|
|
72471
|
+
if (!exists2) return [];
|
|
72472
|
+
const content = await this._options.kernel.filesystem.fs.readFile(passkeysPath, "utf-8");
|
|
72473
|
+
const parsed = JSON.parse(content);
|
|
72474
|
+
return parsed.map((pk) => {
|
|
72475
|
+
const publicKeyArray = JSON.parse(pk.publicKey);
|
|
72476
|
+
return {
|
|
72477
|
+
...pk,
|
|
72478
|
+
publicKey: new Uint8Array(publicKeyArray)
|
|
72479
|
+
};
|
|
72480
|
+
});
|
|
72481
|
+
} catch (error) {
|
|
72482
|
+
this._options.kernel.log.warn(`Failed to read passkeys for user ${uid}: ${error}`);
|
|
72483
|
+
return [];
|
|
72484
|
+
}
|
|
72485
|
+
}
|
|
72486
|
+
/**
|
|
72487
|
+
* Save passkeys for a user
|
|
72488
|
+
*/
|
|
72489
|
+
async savePasskeys(uid, passkeys) {
|
|
72490
|
+
const user2 = this._users.get(uid);
|
|
72491
|
+
if (!user2) throw new Error(`User with UID ${uid} not found`);
|
|
72492
|
+
const passkeysPath = `${user2.home}/.passkeys`;
|
|
72493
|
+
const serialized = passkeys.map((pk) => {
|
|
72494
|
+
const publicKeyArray = pk.publicKey instanceof ArrayBuffer ? Array.from(new Uint8Array(pk.publicKey)) : Array.from(pk.publicKey);
|
|
72495
|
+
return {
|
|
72496
|
+
...pk,
|
|
72497
|
+
publicKey: JSON.stringify(publicKeyArray)
|
|
72498
|
+
};
|
|
72499
|
+
});
|
|
72500
|
+
await this._options.kernel.filesystem.fs.writeFile(
|
|
72501
|
+
passkeysPath,
|
|
72502
|
+
JSON.stringify(serialized, null, 2),
|
|
72503
|
+
{ encoding: "utf-8", mode: 384 }
|
|
72504
|
+
);
|
|
72505
|
+
try {
|
|
72506
|
+
await this._options.kernel.filesystem.fs.chown(passkeysPath, uid, user2.gid);
|
|
72507
|
+
} catch {
|
|
72508
|
+
}
|
|
72509
|
+
}
|
|
72510
|
+
/**
|
|
72511
|
+
* Add a passkey to a user's collection
|
|
72512
|
+
*/
|
|
72513
|
+
async addPasskey(uid, passkey) {
|
|
72514
|
+
const existing = await this.getPasskeys(uid);
|
|
72515
|
+
existing.push(passkey);
|
|
72516
|
+
await this.savePasskeys(uid, existing);
|
|
72517
|
+
}
|
|
72518
|
+
/**
|
|
72519
|
+
* Remove a passkey by ID
|
|
72520
|
+
*/
|
|
72521
|
+
async removePasskey(uid, passkeyId) {
|
|
72522
|
+
const existing = await this.getPasskeys(uid);
|
|
72523
|
+
const filtered = existing.filter((pk) => pk.id !== passkeyId);
|
|
72524
|
+
await this.savePasskeys(uid, filtered);
|
|
72525
|
+
}
|
|
72526
|
+
/**
|
|
72527
|
+
* Check if a user has any registered passkeys
|
|
72528
|
+
*/
|
|
72529
|
+
async hasPasskeys(uid) {
|
|
72530
|
+
const passkeys = await this.getPasskeys(uid);
|
|
72531
|
+
return passkeys.length > 0;
|
|
72532
|
+
}
|
|
72207
72533
|
};
|
|
72208
72534
|
__name(_Users, "Users");
|
|
72209
72535
|
let Users = _Users;
|
|
@@ -73568,10 +73894,10 @@ const _Workers = class _Workers {
|
|
|
73568
73894
|
};
|
|
73569
73895
|
__name(_Workers, "Workers");
|
|
73570
73896
|
let Workers = _Workers;
|
|
73571
|
-
const __vite_import_meta_env__ = { "AUTHOR": { "name": "Jay Mathis", "email": "code@mathis.network", "url": "https://github.com/mathiscode" }, "BASE_URL": "/", "DESCRIPTION": "ecmaOS: Micro-kernel and framework for web technologies", "DEV": false, "HOMEPAGE": "https://ecmaos.sh", "KNOWN_ISSUES": ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"], "MODE": "production", "NAME": "@ecmaos/kernel", "PROD": true, "REPOSITORY": "https://github.com/ecmaos/ecmaos", "SSR": false, "TIPS": ["If it ever fails to boot, check your logs
|
|
73897
|
+
const __vite_import_meta_env__ = { "AUTHOR": { "name": "Jay Mathis", "email": "code@mathis.network", "url": "https://github.com/mathiscode" }, "BASE_URL": "/", "DESCRIPTION": "ecmaOS: Micro-kernel and framework for web technologies", "DEV": false, "HOMEPAGE": "https://ecmaos.sh", "KNOWN_ISSUES": ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"], "MODE": "production", "NAME": "@ecmaos/kernel", "PROD": true, "REPOSITORY": "https://github.com/ecmaos/ecmaos", "SSR": false, "TIPS": ["If it ever fails to boot, check your logs, try clearing all data, try incognito mode, or try another browser", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "You can register and login with a passkey: 'passkey register' and 'passkey list'", "Try 'fetch /xkcd-os.sixel'"], "VERSION": "0.6.5", "VITE_APP_SHOW_DEFAULT_LOGIN": "true", "VITE_BOOT_DISABLE_ISSUES": "true", "VITE_BOOT_DISABLE_LOGO_CONSOLE": "false", "VITE_BOOT_DISABLE_LOGO_FIGLET": "false", "VITE_BOOT_DISABLE_TIPS": "false", "VITE_INITFS": "/initfs.tar.gz", "VITE_KERNEL_INTERVALS_PROC": "1000", "VITE_KERNEL_MODULES": "@ecmaos-modules/boilerplate@0.1.0", "VITE_METAL_SOCKET": "ws://localhost:30445/socket", "VITE_PORT": "30443", "VITE_RECOMMENDED_APPS": "@ecmaos-apps/code,@ecmaos-apps/edit,@ecmaos-apps/ai,@ecmaos-apps/webamp,@ecmaos-apps/news", "XTERM_VERSION": "5.5.0", "ZENFS_VERSION": "2.4.2" };
|
|
73572
73898
|
var define_import_meta_env_AUTHOR_default = { name: "Jay Mathis", email: "code@mathis.network", url: "https://github.com/mathiscode" };
|
|
73573
73899
|
var define_import_meta_env_KNOWN_ISSUES_default = ["It's best to stick to Chromium-based browsers for the most features", "Keyboard is broken on mobile; ecmaOS is not mobile-friendly at this time", "Don't expect any sort of POSIX compliance at this stage", "Most commands/devices are very basic implementations, not complete reproductions", "stdin/stdout/stderr streams and redirection can be wonky and don't work everywhere, but are coming along", "CTRL-C will return you to a prompt, but doesn't currently interrupt a process", "Lots of unfinished work; watch your step"];
|
|
73574
|
-
var define_import_meta_env_TIPS_default = ["If it ever fails to boot, check your logs
|
|
73900
|
+
var define_import_meta_env_TIPS_default = ["If it ever fails to boot, check your logs, try clearing all data, try incognito mode, or try another browser", "You can run some devices that offer a CLI - e.g. '/dev/battery --help'", "Use the 'install' command to install packages - e.g. 'install @ecmaos-apps/news'", "You can install any NPM package - e.g. 'install jquery'", "Use the 'news' command to see the latest news about ecmaOS", "Type 'ls /bin' to see all built-in commands", "Type 'ls /usr/bin' to see all installed commands", "You can set your environment variables in ~/.env (try setting PROMPT to a PS1-like format)", "You can register and login with a passkey: 'passkey register' and 'passkey list'", "Try 'fetch /xkcd-os.sixel'"];
|
|
73575
73901
|
const DefaultKernelOptions = {
|
|
73576
73902
|
devices: DefaultDevices,
|
|
73577
73903
|
dom: DefaultDomOptions,
|
|
@@ -73613,7 +73939,7 @@ const _Kernel = class _Kernel {
|
|
|
73613
73939
|
/** Name of the kernel */
|
|
73614
73940
|
__publicField(this, "name", "@ecmaos/kernel");
|
|
73615
73941
|
/** Version string of the kernel */
|
|
73616
|
-
__publicField(this, "version", "0.6.
|
|
73942
|
+
__publicField(this, "version", "0.6.5");
|
|
73617
73943
|
/** Authentication and authorization service */
|
|
73618
73944
|
__publicField(this, "auth");
|
|
73619
73945
|
/** BIOS module providing low-level functionality */
|
|
@@ -73771,7 +74097,7 @@ const _Kernel = class _Kernel {
|
|
|
73771
74097
|
];
|
|
73772
74098
|
this.terminal.writeln(chalk$2.red.bold(`🐉 ${t2("kernel.experimental", "EXPERIMENTAL")} 🐉`));
|
|
73773
74099
|
this.terminal.writeln(
|
|
73774
|
-
`${this.terminal.createSpecialLink("https://ecmaos.sh", "@ecmaos/kernel")}@${"0.6.
|
|
74100
|
+
`${this.terminal.createSpecialLink("https://ecmaos.sh", "@ecmaos/kernel")}@${"0.6.5"}` + chalk$2.cyan(` [${dependencyLinks.map((link2) => link2.link).join(", ")}]`)
|
|
73775
74101
|
);
|
|
73776
74102
|
this.terminal.writeln(`${t2("kernel.madeBy", "Made with ❤️ by Jay Mathis")} ${this.terminal.createSpecialLink(
|
|
73777
74103
|
define_import_meta_env_AUTHOR_default?.url || "https://github.com/mathiscode",
|
|
@@ -73788,14 +74114,14 @@ const _Kernel = class _Kernel {
|
|
|
73788
74114
|
if (logoFiglet && true) {
|
|
73789
74115
|
console.log(`%c${logoFiglet}`, "color: green");
|
|
73790
74116
|
console.log(`%c${"https://github.com/ecmaos/ecmaos"}`, "color: blue; text-decoration: underline; font-size: 16px");
|
|
73791
|
-
this.log.info(`${"@ecmaos/kernel"} v${"0.6.
|
|
74117
|
+
this.log.info(`${"@ecmaos/kernel"} v${"0.6.5"}`);
|
|
73792
74118
|
}
|
|
73793
74119
|
if (Notification?.permission === "default") Notification.requestPermission();
|
|
73794
74120
|
if (Notification?.permission === "denied") this.log.warn(t2("kernel.permissionNotificationDenied", "Notification permission denied"));
|
|
73795
74121
|
this.intervals.set("title-blink", () => {
|
|
73796
74122
|
globalThis.document.title = globalThis.document.title.includes("_") ? "ecmaos# " : "ecmaos# _";
|
|
73797
74123
|
}, 600);
|
|
73798
|
-
this.toast.success(`${"@ecmaos/kernel"} v${"0.6.
|
|
74124
|
+
this.toast.success(`${"@ecmaos/kernel"} v${"0.6.5"}`);
|
|
73799
74125
|
}
|
|
73800
74126
|
await this.configure({ devices: this.options.devices || DefaultDevices, filesystem: Filesystem.options() });
|
|
73801
74127
|
const requiredPaths = [
|
|
@@ -73956,20 +74282,62 @@ const _Kernel = class _Kernel {
|
|
|
73956
74282
|
const icon = isSecure ? "🔒" : "🔓";
|
|
73957
74283
|
this.terminal.writeln(`${icon} ${protocolStr}//${hostname}${port}`);
|
|
73958
74284
|
const username = await this.terminal.readline(`👤 ${this.i18n.t("Username")}: `);
|
|
73959
|
-
const
|
|
73960
|
-
|
|
73961
|
-
|
|
73962
|
-
|
|
74285
|
+
const user22 = Array.from(this.users.all.values()).find((u) => u.username === username);
|
|
74286
|
+
let loginSuccess = false;
|
|
74287
|
+
let userCred = null;
|
|
74288
|
+
if (user22) {
|
|
74289
|
+
const passkeys = await this.users.getPasskeys(user22.uid);
|
|
74290
|
+
if (passkeys.length > 0 && this.auth.passkey.isSupported()) {
|
|
74291
|
+
try {
|
|
74292
|
+
const challenge = crypto.getRandomValues(new Uint8Array(32));
|
|
74293
|
+
const rpId = globalThis.location.hostname || "localhost";
|
|
74294
|
+
const allowCredentials = passkeys.map((pk) => {
|
|
74295
|
+
const credentialIdBytes = Uint8Array.from(atob(pk.credentialId), (c) => c.charCodeAt(0));
|
|
74296
|
+
return {
|
|
74297
|
+
id: credentialIdBytes.buffer,
|
|
74298
|
+
type: "public-key",
|
|
74299
|
+
transports: ["usb", "nfc", "ble", "internal"]
|
|
74300
|
+
};
|
|
74301
|
+
});
|
|
74302
|
+
const requestOptions = {
|
|
74303
|
+
challenge,
|
|
74304
|
+
allowCredentials,
|
|
74305
|
+
rpId,
|
|
74306
|
+
userVerification: "preferred",
|
|
74307
|
+
timeout: 6e4
|
|
74308
|
+
};
|
|
74309
|
+
this.terminal.writeln(chalk$2.yellow("🔐 Please use your passkey to authenticate..."));
|
|
74310
|
+
const credential = await this.auth.passkey.get(requestOptions);
|
|
74311
|
+
if (credential && credential instanceof PublicKeyCredential) {
|
|
74312
|
+
userCred = await this.users.login(username, void 0, credential);
|
|
74313
|
+
loginSuccess = true;
|
|
74314
|
+
} else {
|
|
74315
|
+
this.terminal.writeln(chalk$2.yellow("Passkey authentication cancelled or failed. Falling back to password..."));
|
|
74316
|
+
}
|
|
74317
|
+
} catch (err2) {
|
|
74318
|
+
this.terminal.writeln(chalk$2.yellow(`Passkey authentication error: ${err2.message}. Falling back to password...`));
|
|
74319
|
+
}
|
|
74320
|
+
}
|
|
74321
|
+
}
|
|
74322
|
+
if (!loginSuccess) {
|
|
74323
|
+
const password = await this.terminal.readline(`🔑 ${this.i18n.t("Password")}: `, true);
|
|
74324
|
+
userCred = await this.users.login(username, password);
|
|
74325
|
+
}
|
|
74326
|
+
if (!userCred) {
|
|
74327
|
+
throw new Error("Login failed");
|
|
74328
|
+
}
|
|
74329
|
+
this.shell.credentials = userCred.cred;
|
|
74330
|
+
this.shell.context = bindContext({ root: "/", pwd: "/", credentials: userCred.cred });
|
|
73963
74331
|
await this.shell.loadEnvFile();
|
|
73964
|
-
this.shell.env.set("UID",
|
|
73965
|
-
this.shell.env.set("GID",
|
|
73966
|
-
this.shell.env.set("SUID", cred.suid.toString());
|
|
73967
|
-
this.shell.env.set("SGID", cred.sgid.toString());
|
|
73968
|
-
this.shell.env.set("EUID", cred.euid.toString());
|
|
73969
|
-
this.shell.env.set("EGID", cred.egid.toString());
|
|
73970
|
-
this.shell.env.set("SHELL",
|
|
73971
|
-
this.shell.env.set("HOME",
|
|
73972
|
-
this.shell.env.set("USER",
|
|
74332
|
+
this.shell.env.set("UID", userCred.user.uid.toString());
|
|
74333
|
+
this.shell.env.set("GID", userCred.user.gid.toString());
|
|
74334
|
+
this.shell.env.set("SUID", userCred.cred.suid.toString());
|
|
74335
|
+
this.shell.env.set("SGID", userCred.cred.sgid.toString());
|
|
74336
|
+
this.shell.env.set("EUID", userCred.cred.euid.toString());
|
|
74337
|
+
this.shell.env.set("EGID", userCred.cred.egid.toString());
|
|
74338
|
+
this.shell.env.set("SHELL", userCred.user.shell || "ecmaos");
|
|
74339
|
+
this.shell.env.set("HOME", userCred.user.home || "/root");
|
|
74340
|
+
this.shell.env.set("USER", userCred.user.username);
|
|
73973
74341
|
process$1.env = Object.fromEntries(this.shell.env);
|
|
73974
74342
|
break;
|
|
73975
74343
|
} catch (err2) {
|
|
@@ -74499,7 +74867,7 @@ const _Kernel = class _Kernel {
|
|
|
74499
74867
|
memory: "?",
|
|
74500
74868
|
platform: navigator.userAgentData?.platform || navigator?.platform || navigator.userAgent,
|
|
74501
74869
|
querystring: location.search,
|
|
74502
|
-
version: `${"@ecmaos/kernel"} ${"0.6.
|
|
74870
|
+
version: `${"@ecmaos/kernel"} ${"0.6.5"}`,
|
|
74503
74871
|
language: navigator.language,
|
|
74504
74872
|
host: location.host,
|
|
74505
74873
|
userAgent: navigator.userAgent,
|
|
@@ -74676,4 +75044,4 @@ export {
|
|
|
74676
75044
|
path$1 as p,
|
|
74677
75045
|
semver as s
|
|
74678
75046
|
};
|
|
74679
|
-
//# sourceMappingURL=kernel-
|
|
75047
|
+
//# sourceMappingURL=kernel-C_Xvcpox.js.map
|