typescript-virtual-container 1.4.8 → 1.5.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/.vscode/settings.json +1 -1
- package/README.md +118 -80
- package/builds/self-standalone.mjs +1768 -0
- package/builds/standalone-wo-sftp.js +735 -268
- package/builds/standalone.cjs +734 -267
- package/builds/web-full-api.min.js +0 -1
- package/builds/web.min.js +0 -1
- package/bun.lock +3 -3
- package/dist/Honeypot/index.d.ts +6 -0
- package/dist/Honeypot/index.d.ts.map +1 -1
- package/dist/Honeypot/index.js +20 -0
- package/dist/Honeypot/index.js.map +1 -1
- package/dist/SSHMimic/exec.js +2 -2
- package/dist/SSHMimic/exec.js.map +1 -1
- package/dist/SSHMimic/index.d.ts +6 -5
- package/dist/SSHMimic/index.d.ts.map +1 -1
- package/dist/SSHMimic/index.js +8 -6
- package/dist/SSHMimic/index.js.map +1 -1
- package/dist/SSHMimic/sftp.d.ts +1 -0
- package/dist/SSHMimic/sftp.d.ts.map +1 -1
- package/dist/SSHMimic/sftp.js +4 -3
- package/dist/SSHMimic/sftp.js.map +1 -1
- package/dist/VirtualFileSystem/index.d.ts +14 -0
- package/dist/VirtualFileSystem/index.d.ts.map +1 -1
- package/dist/VirtualFileSystem/index.js +51 -3
- package/dist/VirtualFileSystem/index.js.map +1 -1
- package/dist/VirtualFileSystem/internalTypes.d.ts +4 -0
- package/dist/VirtualFileSystem/internalTypes.d.ts.map +1 -1
- package/dist/VirtualFileSystem/journal.d.ts +1 -0
- package/dist/VirtualFileSystem/journal.d.ts.map +1 -1
- package/dist/VirtualFileSystem/journal.js +11 -5
- package/dist/VirtualFileSystem/journal.js.map +1 -1
- package/dist/VirtualShell/idleManager.d.ts +6 -2
- package/dist/VirtualShell/idleManager.d.ts.map +1 -1
- package/dist/VirtualShell/idleManager.js +10 -6
- package/dist/VirtualShell/idleManager.js.map +1 -1
- package/dist/VirtualShell/index.d.ts +13 -1
- package/dist/VirtualShell/index.d.ts.map +1 -1
- package/dist/VirtualShell/index.js +10 -5
- package/dist/VirtualShell/index.js.map +1 -1
- package/dist/VirtualShell/shell.js +12 -12
- package/dist/VirtualShell/shell.js.map +1 -1
- package/dist/VirtualUserManager/index.d.ts +4 -2
- package/dist/VirtualUserManager/index.d.ts.map +1 -1
- package/dist/VirtualUserManager/index.js +8 -12
- package/dist/VirtualUserManager/index.js.map +1 -1
- package/dist/commands/apt.js +3 -3
- package/dist/commands/apt.js.map +1 -1
- package/dist/commands/cd.d.ts.map +1 -1
- package/dist/commands/cd.js +2 -1
- package/dist/commands/cd.js.map +1 -1
- package/dist/commands/command-helpers.d.ts +5 -2
- package/dist/commands/command-helpers.d.ts.map +1 -1
- package/dist/commands/command-helpers.js.map +1 -1
- package/dist/commands/helpers.d.ts +1 -1
- package/dist/commands/helpers.d.ts.map +1 -1
- package/dist/commands/helpers.js +3 -2
- package/dist/commands/helpers.js.map +1 -1
- package/dist/commands/index.d.ts +1 -1
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +1 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/lsb-release.js +1 -1
- package/dist/commands/lsb-release.js.map +1 -1
- package/dist/commands/runtime.d.ts +2 -0
- package/dist/commands/runtime.d.ts.map +1 -1
- package/dist/commands/runtime.js +5 -1
- package/dist/commands/runtime.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/linuxRootfs.d.ts +9 -5
- package/dist/modules/linuxRootfs.d.ts.map +1 -1
- package/dist/modules/linuxRootfs.js +1079 -148
- package/dist/modules/linuxRootfs.js.map +1 -1
- package/dist/self-standalone.js +22 -12
- package/dist/self-standalone.js.map +1 -1
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/HoneyPot.html +9 -9
- package/docs/classes/IdleManager.html +12 -9
- package/docs/classes/SshClient.html +18 -18
- package/docs/classes/VirtualFileSystem.html +34 -42
- package/docs/classes/VirtualPackageManager.html +13 -13
- package/docs/classes/VirtualSftpServer.html +3 -3
- package/docs/classes/VirtualShell.html +33 -29
- package/docs/classes/VirtualSshServer.html +12 -7
- package/docs/classes/VirtualUserManager.html +30 -30
- package/docs/functions/assertDiff.html +2 -2
- package/docs/functions/diffSnapshots.html +2 -2
- package/docs/functions/formatDiff.html +2 -2
- package/docs/functions/getArg.html +3 -3
- package/docs/functions/getFlag.html +2 -2
- package/docs/functions/ifFlag.html +2 -2
- package/docs/hierarchy.html +1 -1
- package/docs/index.html +11 -9
- package/docs/interfaces/AuditLogEntry.html +3 -3
- package/docs/interfaces/CommandContext.html +13 -13
- package/docs/interfaces/CommandResult.html +13 -13
- package/docs/interfaces/ExecStream.html +6 -6
- package/docs/interfaces/HoneyPotStats.html +5 -3
- package/docs/interfaces/IdleManagerOptions.html +3 -3
- package/docs/interfaces/InstalledPackage.html +11 -11
- package/docs/interfaces/NanoEditorSession.html +5 -5
- package/docs/interfaces/PackageDefinition.html +14 -14
- package/docs/interfaces/PackageFile.html +5 -5
- package/docs/interfaces/PasswordChallenge.html +16 -0
- package/docs/interfaces/RemoveOptions.html +3 -3
- package/docs/interfaces/ShellEnv.html +4 -4
- package/docs/interfaces/ShellModule.html +8 -8
- package/docs/interfaces/ShellProperties.html +5 -5
- package/docs/interfaces/ShellStream.html +7 -7
- package/docs/interfaces/SudoChallenge.html +9 -9
- package/docs/interfaces/VfsBaseNode.html +7 -7
- package/docs/interfaces/VfsDiff.html +6 -6
- package/docs/interfaces/VfsDiffEntry.html +4 -4
- package/docs/interfaces/VfsDiffModified.html +6 -6
- package/docs/interfaces/VfsDirectoryNode.html +8 -8
- package/docs/interfaces/VfsFileNode.html +9 -9
- package/docs/interfaces/VfsOptions.html +6 -6
- package/docs/interfaces/VfsSnapshot.html +3 -3
- package/docs/interfaces/VfsSnapshotBaseNode.html +4 -4
- package/docs/interfaces/VfsSnapshotDirectoryNode.html +5 -5
- package/docs/interfaces/VfsSnapshotFileNode.html +6 -6
- package/docs/interfaces/VirtualActiveSession.html +12 -0
- package/docs/interfaces/VirtualSftpServerOptions.html +7 -0
- package/docs/interfaces/VirtualShellVfsLike.html +15 -0
- package/docs/interfaces/VirtualShellVfsOptions.html +3 -0
- package/docs/interfaces/WriteFileOptions.html +4 -4
- package/docs/modules.html +1 -1
- package/docs/types/ArgParseOptions.html +4 -0
- package/docs/types/CommandMode.html +2 -2
- package/docs/types/CommandOutcome.html +2 -2
- package/docs/types/IdleState.html +1 -1
- package/docs/types/VfsNodeStats.html +2 -2
- package/docs/types/VfsNodeType.html +2 -2
- package/docs/types/VfsPersistenceMode.html +2 -2
- package/docs/types/VfsSnapshotNode.html +2 -2
- package/examples/web.min.js +0 -1
- package/package.json +11 -11
- package/scripts/generate-manuals-bundle.mjs +1 -1
- package/scripts/publish-package.sh +1 -1
- package/src/Honeypot/index.ts +24 -0
- package/src/SSHMimic/exec.ts +2 -2
- package/src/SSHMimic/index.ts +9 -6
- package/src/SSHMimic/sftp.ts +10 -3
- package/src/VirtualFileSystem/index.ts +46 -3
- package/src/VirtualFileSystem/internalTypes.ts +4 -0
- package/src/VirtualFileSystem/journal.ts +11 -5
- package/src/VirtualShell/idleManager.ts +10 -6
- package/src/VirtualShell/index.ts +18 -3
- package/src/VirtualShell/shell.ts +12 -12
- package/src/VirtualUserManager/index.ts +15 -13
- package/src/commands/apt.ts +3 -3
- package/src/commands/cd.ts +2 -1
- package/src/commands/command-helpers.ts +5 -1
- package/src/commands/helpers.ts +3 -2
- package/src/commands/index.ts +1 -1
- package/src/commands/lsb-release.ts +1 -1
- package/src/commands/runtime.ts +6 -1
- package/src/index.ts +5 -1
- package/src/modules/linuxRootfs.ts +1293 -207
- package/src/self-standalone.ts +26 -12
- package/tests/new-features.test.ts +2 -2
- package/tests/sftp.test.ts +13 -13
- package/typedoc.json +45 -0
- package/builds/self-standalone.js +0 -1300
- package/builds/self-standalone.js.map +0 -7
- package/builds/standalone-wo-sftp.js.map +0 -7
- package/builds/standalone.cjs.map +0 -7
- package/builds/web-full-api.min.js.map +0 -7
- package/builds/web.min.js.map +0 -7
|
@@ -42,6 +42,10 @@ export interface ShellProperties {
|
|
|
42
42
|
arch: string;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Minimal VFS interface accepted by {@link VirtualShell} as a drop-in replacement
|
|
47
|
+
* for the built-in {@link VirtualFileSystem}.
|
|
48
|
+
*/
|
|
45
49
|
export interface VirtualShellVfsLike {
|
|
46
50
|
restoreMirror(): Promise<void>;
|
|
47
51
|
flushMirror(): Promise<void>;
|
|
@@ -57,6 +61,9 @@ export interface VirtualShellVfsLike {
|
|
|
57
61
|
getUsageBytes?(targetPath?: string): number;
|
|
58
62
|
}
|
|
59
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Constructor options for {@link VirtualShell} when passing an existing VFS instance.
|
|
66
|
+
*/
|
|
60
67
|
export interface VirtualShellVfsOptions {
|
|
61
68
|
vfsInstance?: VirtualShellVfsLike;
|
|
62
69
|
}
|
|
@@ -153,7 +160,7 @@ class VirtualShell extends EventEmitter {
|
|
|
153
160
|
*
|
|
154
161
|
* @param hostname Virtual hostname used for prompts and idents.
|
|
155
162
|
* @param properties Customizable properties shown in `uname -a` and similar commands.
|
|
156
|
-
* @param
|
|
163
|
+
* @param vfsOptionsOrInstance Optional VFS persistence options (mode, snapshotPath) or an existing VFS instance.
|
|
157
164
|
*/
|
|
158
165
|
constructor(
|
|
159
166
|
hostname: string,
|
|
@@ -239,7 +246,7 @@ class VirtualShell extends EventEmitter {
|
|
|
239
246
|
*/
|
|
240
247
|
executeCommand(rawInput: string, authUser: string, cwd: string): void {
|
|
241
248
|
perf.mark("executeCommand");
|
|
242
|
-
|
|
249
|
+
this._idle?.ping();
|
|
243
250
|
runCommand(rawInput, authUser, this.hostname, "shell", cwd, this);
|
|
244
251
|
this.emit("command", { command: rawInput, user: authUser, cwd });
|
|
245
252
|
}
|
|
@@ -266,7 +273,7 @@ class VirtualShell extends EventEmitter {
|
|
|
266
273
|
terminalSize: { cols: number; rows: number },
|
|
267
274
|
): void {
|
|
268
275
|
perf.mark("startInteractiveSession");
|
|
269
|
-
|
|
276
|
+
this._idle?.ping();
|
|
270
277
|
// Interactive shell logic
|
|
271
278
|
this.emit("session:start", { user: authUser, sessionId, remoteAddress });
|
|
272
279
|
startShell(
|
|
@@ -452,6 +459,14 @@ class VirtualShell extends EventEmitter {
|
|
|
452
459
|
public get idleMs(): number {
|
|
453
460
|
return this._idle?.idleMs ?? 0;
|
|
454
461
|
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Ping the idle manager to signal external activity (e.g. SFTP, direct VFS writes).
|
|
465
|
+
* No-op when idle management is disabled.
|
|
466
|
+
*/
|
|
467
|
+
public pingIdle(): void {
|
|
468
|
+
this._idle?.ping();
|
|
469
|
+
}
|
|
455
470
|
}
|
|
456
471
|
|
|
457
472
|
export { VirtualShell };
|
|
@@ -2,7 +2,7 @@ import type { ChildProcessWithoutNullStreams } from "node:child_process";
|
|
|
2
2
|
import { readFile, unlink, writeFile } from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import type { ShellProperties, VirtualShell } from ".";
|
|
5
|
-
import { getCommandNames, makeDefaultEnv, runCommand } from "../commands";
|
|
5
|
+
import { getCommandNames, makeDefaultEnv, runCommand, userHome } from "../commands";
|
|
6
6
|
import {
|
|
7
7
|
spawnHtopProcess,
|
|
8
8
|
spawnNanoEditorProcess,
|
|
@@ -55,12 +55,12 @@ export function startShell(
|
|
|
55
55
|
let history = loadHistory(shell.vfs, authUser);
|
|
56
56
|
let historyIndex: number | null = null;
|
|
57
57
|
let historyDraft = "";
|
|
58
|
-
let cwd =
|
|
58
|
+
let cwd = userHome(authUser);
|
|
59
59
|
const shellEnv: ShellEnv = makeDefaultEnv(authUser, hostname);
|
|
60
60
|
let nanoSession: NanoSession | null = null;
|
|
61
61
|
let pendingSudo: PendingSudo | null = null;
|
|
62
62
|
const buildCurrentPrompt = (): string => {
|
|
63
|
-
const homePath =
|
|
63
|
+
const homePath = userHome(authUser);
|
|
64
64
|
const cwdLabel = cwd === homePath ? "~" : path.posix.basename(cwd) || "/";
|
|
65
65
|
return buildPrompt(authUser, hostname, cwdLabel);
|
|
66
66
|
};
|
|
@@ -71,7 +71,7 @@ export function startShell(
|
|
|
71
71
|
|
|
72
72
|
// Load .bashrc if it exists
|
|
73
73
|
void (async () => {
|
|
74
|
-
const bashrcPath =
|
|
74
|
+
const bashrcPath = `${userHome(authUser)}/.bashrc`;
|
|
75
75
|
if (shell.vfs.exists(bashrcPath)) {
|
|
76
76
|
try {
|
|
77
77
|
const bashrc = shell.vfs.readFile(bashrcPath);
|
|
@@ -146,7 +146,7 @@ export function startShell(
|
|
|
146
146
|
if (!challenge.commandLine) {
|
|
147
147
|
authUser = challenge.targetUser;
|
|
148
148
|
if (challenge.loginShell) {
|
|
149
|
-
cwd =
|
|
149
|
+
cwd = userHome(authUser);
|
|
150
150
|
}
|
|
151
151
|
shell.users.updateSession(sessionId, authUser, remoteAddress);
|
|
152
152
|
stream.write("\r\n");
|
|
@@ -154,7 +154,7 @@ export function startShell(
|
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
-
const runCwd = challenge.loginShell ?
|
|
157
|
+
const runCwd = challenge.loginShell ? userHome(challenge.targetUser) : cwd;
|
|
158
158
|
const result = await Promise.resolve(
|
|
159
159
|
runCommand(
|
|
160
160
|
challenge.commandLine,
|
|
@@ -196,7 +196,7 @@ export function startShell(
|
|
|
196
196
|
|
|
197
197
|
if (result.switchUser) {
|
|
198
198
|
authUser = result.switchUser;
|
|
199
|
-
cwd = result.nextCwd ??
|
|
199
|
+
cwd = result.nextCwd ?? userHome(authUser);
|
|
200
200
|
shell.users.updateSession(sessionId, authUser, remoteAddress);
|
|
201
201
|
} else if (result.nextCwd) {
|
|
202
202
|
cwd = result.nextCwd;
|
|
@@ -388,11 +388,11 @@ export function startShell(
|
|
|
388
388
|
}
|
|
389
389
|
|
|
390
390
|
const data = history.length > 0 ? `${history.join("\n")}\n` : "";
|
|
391
|
-
shell.vfs.writeFile(
|
|
391
|
+
shell.vfs.writeFile(`${userHome(authUser)}/.bash_history`, data);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
function readLastLogin(): { at: string; from: string } | null {
|
|
395
|
-
const lastlogPath =
|
|
395
|
+
const lastlogPath = `${userHome(authUser)}/.lastlog.json`;
|
|
396
396
|
if (!shell.vfs.exists(lastlogPath)) {
|
|
397
397
|
return null;
|
|
398
398
|
}
|
|
@@ -408,7 +408,7 @@ export function startShell(
|
|
|
408
408
|
}
|
|
409
409
|
|
|
410
410
|
function writeLastLogin(nowIso: string): void {
|
|
411
|
-
const lastlogPath =
|
|
411
|
+
const lastlogPath = `${userHome(authUser)}/.lastlog`;
|
|
412
412
|
shell.vfs.writeFile(
|
|
413
413
|
lastlogPath,
|
|
414
414
|
JSON.stringify({ at: nowIso, from: remoteAddress }),
|
|
@@ -651,7 +651,7 @@ export function startShell(
|
|
|
651
651
|
|
|
652
652
|
if (result.switchUser) {
|
|
653
653
|
authUser = result.switchUser;
|
|
654
|
-
cwd = result.nextCwd ??
|
|
654
|
+
cwd = result.nextCwd ?? userHome(authUser);
|
|
655
655
|
shell.users.updateSession(sessionId, authUser, remoteAddress);
|
|
656
656
|
lineBuffer = "";
|
|
657
657
|
cursorPos = 0;
|
|
@@ -686,7 +686,7 @@ export function startShell(
|
|
|
686
686
|
}
|
|
687
687
|
|
|
688
688
|
function loadHistory(vfs: VirtualFileSystem, authUser: string): string[] {
|
|
689
|
-
const historyPath =
|
|
689
|
+
const historyPath = `${userHome(authUser)}/.bash_history`;
|
|
690
690
|
if (!vfs.exists(historyPath)) {
|
|
691
691
|
vfs.writeFile(historyPath, "");
|
|
692
692
|
return [];
|
|
@@ -5,7 +5,10 @@ import type { PerfLogger } from "../utils/perfLogger";
|
|
|
5
5
|
import { createPerfLogger } from "../utils/perfLogger";
|
|
6
6
|
import type VirtualFileSystem from "../VirtualFileSystem";
|
|
7
7
|
|
|
8
|
-
/**
|
|
8
|
+
/**
|
|
9
|
+
* Persisted virtual user credential record.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
9
12
|
export interface VirtualUserRecord {
|
|
10
13
|
/** Unique login name. */
|
|
11
14
|
username: string;
|
|
@@ -61,7 +64,6 @@ export class VirtualUserManager extends EventEmitter {
|
|
|
61
64
|
* Creates a user manager instance backed by a virtual filesystem.
|
|
62
65
|
*
|
|
63
66
|
* @param vfs Backing virtual filesystem used for persistence.
|
|
64
|
-
* @param defaultRootPassword Initial root password used when root is created.
|
|
65
67
|
* @param autoSudoForNewUsers Whether newly created users are added to sudoers.
|
|
66
68
|
*/
|
|
67
69
|
constructor(
|
|
@@ -101,14 +103,14 @@ export class VirtualUserManager extends EventEmitter {
|
|
|
101
103
|
// changed = true;
|
|
102
104
|
// }
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
106
|
+
const homePath = "/root";
|
|
107
|
+
if (!this.vfs.exists(homePath)) {
|
|
108
|
+
this.vfs.mkdir(homePath, 0o755);
|
|
109
|
+
this.vfs.writeFile(
|
|
110
|
+
`${homePath}/README.txt`,
|
|
111
|
+
`Welcome to the virtual environment, root`,
|
|
112
|
+
);
|
|
113
|
+
}
|
|
112
114
|
|
|
113
115
|
if (changed) {
|
|
114
116
|
await this.persist();
|
|
@@ -171,7 +173,7 @@ export class VirtualUserManager extends EventEmitter {
|
|
|
171
173
|
*/
|
|
172
174
|
public getUsageBytes(username: string): number {
|
|
173
175
|
perf.mark("getUsageBytes");
|
|
174
|
-
const homePath = `/home/${username}`;
|
|
176
|
+
const homePath = username === "root" ? "/root" : `/home/${username}`;
|
|
175
177
|
if (!this.vfs.exists(homePath)) {
|
|
176
178
|
return 0;
|
|
177
179
|
}
|
|
@@ -200,7 +202,7 @@ export class VirtualUserManager extends EventEmitter {
|
|
|
200
202
|
}
|
|
201
203
|
|
|
202
204
|
const normalizedPath = normalizeVfsPath(targetPath);
|
|
203
|
-
const homePath = normalizeVfsPath(`/home/${username}`);
|
|
205
|
+
const homePath = normalizeVfsPath(username === "root" ? "/root" : `/home/${username}`);
|
|
204
206
|
const inUserHome =
|
|
205
207
|
normalizedPath === homePath || normalizedPath.startsWith(`${homePath}/`);
|
|
206
208
|
if (!inUserHome) {
|
|
@@ -277,7 +279,7 @@ export class VirtualUserManager extends EventEmitter {
|
|
|
277
279
|
if (this.autoSudoForNewUsers) {
|
|
278
280
|
this.sudoers.add(username);
|
|
279
281
|
}
|
|
280
|
-
const homePath = `/home/${username}`;
|
|
282
|
+
const homePath = username === "root" ? "/root" : `/home/${username}`;
|
|
281
283
|
if (!this.vfs.exists(homePath)) {
|
|
282
284
|
this.vfs.mkdir(homePath, 0o755);
|
|
283
285
|
this.vfs.writeFile(
|
package/src/commands/apt.ts
CHANGED
|
@@ -57,8 +57,8 @@ export const aptCommand: ShellModule = {
|
|
|
57
57
|
case "update": {
|
|
58
58
|
return {
|
|
59
59
|
stdout: [
|
|
60
|
-
"Hit:1 fortune://packages.fortune.local
|
|
61
|
-
"Hit:2 fortune://security.fortune.local
|
|
60
|
+
"Hit:1 fortune://packages.fortune.local nyx InRelease",
|
|
61
|
+
"Hit:2 fortune://security.fortune.local nyx-security InRelease",
|
|
62
62
|
"Reading package lists... Done",
|
|
63
63
|
"Building dependency tree... Done",
|
|
64
64
|
"Reading state information... Done",
|
|
@@ -218,7 +218,7 @@ export const aptCacheCommand: ShellModule = {
|
|
|
218
218
|
` Candidate: ${def.version}`,
|
|
219
219
|
` Version table:`,
|
|
220
220
|
` ${def.version} 500`,
|
|
221
|
-
` 500 fortune://packages.fortune.local
|
|
221
|
+
` 500 fortune://packages.fortune.local nyx/main amd64 Packages`,
|
|
222
222
|
].join("\n"),
|
|
223
223
|
exitCode: 0,
|
|
224
224
|
};
|
package/src/commands/cd.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ShellModule } from "../types/commands";
|
|
2
2
|
import { assertPathAccess, resolvePath } from "./helpers";
|
|
3
|
+
import { userHome } from "./runtime";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Change current working directory.
|
|
@@ -12,7 +13,7 @@ export const cdCommand: ShellModule = {
|
|
|
12
13
|
category: "navigation",
|
|
13
14
|
params: ["[path]"],
|
|
14
15
|
run: ({ authUser, shell, cwd, args }) => {
|
|
15
|
-
const target = resolvePath(cwd, args[0] ??
|
|
16
|
+
const target = resolvePath(cwd, args[0] ?? "~", userHome(authUser));
|
|
16
17
|
assertPathAccess(authUser, target, "cd");
|
|
17
18
|
const stats = shell.vfs.stat(target);
|
|
18
19
|
if (stats.type !== "directory") {
|
package/src/commands/helpers.ts
CHANGED
|
@@ -28,12 +28,13 @@ export function normalizeTerminalOutput(text: string): string {
|
|
|
28
28
|
.trimEnd();
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export function resolvePath(cwd: string, inputPath: string): string {
|
|
31
|
+
export function resolvePath(cwd: string, inputPath: string, homeDir?: string): string {
|
|
32
32
|
if (!inputPath || inputPath.trim() === "") {
|
|
33
33
|
return cwd;
|
|
34
34
|
}
|
|
35
35
|
if (inputPath.startsWith("~")) {
|
|
36
|
-
|
|
36
|
+
const home = homeDir ?? "/root";
|
|
37
|
+
return path.posix.normalize(`${home}${inputPath.slice(1)}`);
|
|
37
38
|
}
|
|
38
39
|
return inputPath.startsWith("/")
|
|
39
40
|
? path.posix.normalize(inputPath)
|
package/src/commands/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ export const lsbReleaseCommand: ShellModule = {
|
|
|
13
13
|
params: ["[-a] [-i] [-d] [-r] [-c]"],
|
|
14
14
|
run: ({ args, shell }) => {
|
|
15
15
|
let osName = shell.properties?.os ?? "Fortune GNU/Linux x64";
|
|
16
|
-
let codename = "
|
|
16
|
+
let codename = "nyx";
|
|
17
17
|
let version = "1.0";
|
|
18
18
|
|
|
19
19
|
try {
|
package/src/commands/runtime.ts
CHANGED
|
@@ -11,11 +11,16 @@ import { expandAsync, expandBraces } from "../utils/expand";
|
|
|
11
11
|
import { tokenizeCommand } from "../utils/tokenize";
|
|
12
12
|
import { resolveModule } from "./registry";
|
|
13
13
|
|
|
14
|
+
/** Returns the home directory path for a given user. Root lives at /root. */
|
|
15
|
+
export function userHome(authUser: string): string {
|
|
16
|
+
return authUser === "root" ? "/root" : `/home/${authUser}`;
|
|
17
|
+
}
|
|
18
|
+
|
|
14
19
|
export function makeDefaultEnv(authUser: string, hostname: string): ShellEnv {
|
|
15
20
|
return {
|
|
16
21
|
vars: {
|
|
17
22
|
PATH: "/usr/local/bin:/usr/bin:/bin",
|
|
18
|
-
HOME:
|
|
23
|
+
HOME: userHome(authUser),
|
|
19
24
|
USER: authUser,
|
|
20
25
|
LOGNAME: authUser,
|
|
21
26
|
SHELL: "/bin/sh",
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export { HoneyPot } from "./Honeypot/index";
|
|
2
2
|
export { SshClient } from "./SSHClient/index";
|
|
3
3
|
export { SftpMimic as VirtualSftpServer, SshMimic as VirtualSshServer } from "./SSHMimic/index";
|
|
4
|
+
export type { SftpMimicOptions as VirtualSftpServerOptions } from "./SSHMimic/sftp";
|
|
4
5
|
export { default as VirtualFileSystem } from "./VirtualFileSystem/index";
|
|
5
6
|
export { VirtualPackageManager } from "./VirtualPackageManager/index";
|
|
6
7
|
export { VirtualShell } from "./VirtualShell/index";
|
|
7
8
|
export { VirtualUserManager } from "./VirtualUserManager/index";
|
|
9
|
+
export type { VirtualActiveSession } from "./VirtualUserManager/index";
|
|
8
10
|
export { IdleManager } from "./VirtualShell/idleManager";
|
|
9
11
|
export type { IdleManagerOptions, IdleState } from "./VirtualShell/idleManager";
|
|
10
12
|
|
|
@@ -18,6 +20,7 @@ export type {
|
|
|
18
20
|
CommandOutcome,
|
|
19
21
|
CommandResult,
|
|
20
22
|
NanoEditorSession,
|
|
23
|
+
PasswordChallenge,
|
|
21
24
|
ShellEnv,
|
|
22
25
|
ShellModule,
|
|
23
26
|
SudoChallenge
|
|
@@ -38,7 +41,7 @@ export type {
|
|
|
38
41
|
WriteFileOptions
|
|
39
42
|
} from "./types/vfs";
|
|
40
43
|
export type { VfsOptions, VfsPersistenceMode } from "./VirtualFileSystem/index";
|
|
41
|
-
export type { ShellProperties } from "./VirtualShell/index";
|
|
44
|
+
export type { ShellProperties, VirtualShellVfsLike, VirtualShellVfsOptions } from "./VirtualShell/index";
|
|
42
45
|
|
|
43
46
|
export type {
|
|
44
47
|
InstalledPackage, PackageDefinition,
|
|
@@ -60,4 +63,5 @@ export {
|
|
|
60
63
|
getFlag,
|
|
61
64
|
ifFlag
|
|
62
65
|
} from "./commands/command-helpers";
|
|
66
|
+
export type { ArgParseOptions } from "./commands/command-helpers";
|
|
63
67
|
|