remote-dsh 0.5.0 → 0.6.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/bin.js +83 -4
- package/package.json +3 -3
package/dist/bin.js
CHANGED
|
@@ -25,7 +25,8 @@ Usage:
|
|
|
25
25
|
rdsh host leave Unregister this machine from the hub
|
|
26
26
|
rdsh host user ... Manage gateway users (LAN/cloud password auth)
|
|
27
27
|
rdsh hub serve Start the hub server (cloud, multi-host)
|
|
28
|
-
rdsh hub user add|passwd|rm|ls
|
|
28
|
+
rdsh hub user add|passwd|rm|ls|unlock|reset-2fa
|
|
29
|
+
rdsh hub audit ls Audit log (login/2FA/sharing/email events)
|
|
29
30
|
rdsh hub host ls|revoke List / revoke hosts (revoke drops the tunnel instantly)
|
|
30
31
|
rdsh hub service ... Run hub as a systemd/launchd service
|
|
31
32
|
|
|
@@ -60,7 +61,8 @@ Run the hub server or manage it.
|
|
|
60
61
|
|
|
61
62
|
Subcommands:
|
|
62
63
|
serve Start the hub server (TLS required)
|
|
63
|
-
user add|passwd|rm|ls
|
|
64
|
+
user add|passwd|rm|ls|unlock|reset-2fa Manage users (admin creates accounts; unlock / reset-2fa)
|
|
65
|
+
audit ls [--user <n>] [--event <e>] [--since 24h|7d] Query the audit log
|
|
64
66
|
host ls|revoke List / revoke hosts (revoke drops the tunnel instantly)
|
|
65
67
|
service install|status|uninstall Run hub as a systemd/launchd service
|
|
66
68
|
|
|
@@ -436,6 +438,56 @@ async function openHubDb(configPath) {
|
|
|
436
438
|
const config = await loadHubConfig(hubConfigPath);
|
|
437
439
|
return new HubDb(config.dbPath);
|
|
438
440
|
}
|
|
441
|
+
/** `rdsh hub audit ls [--user <name>] [--event <e>] [--since 24h|7d]`。 */
|
|
442
|
+
async function handleHubAudit(args, configPath) {
|
|
443
|
+
const db = await openHubDb(configPath);
|
|
444
|
+
try {
|
|
445
|
+
// 兼容 `audit ls` 与 `audit`(ls 为可选位置参数)
|
|
446
|
+
const opts = args[0] === "ls" ? args.slice(1) : args;
|
|
447
|
+
const filter = {};
|
|
448
|
+
for (let i = 0; i < opts.length; i++) {
|
|
449
|
+
const flag = opts[i];
|
|
450
|
+
if (flag === "--user") {
|
|
451
|
+
const name = opts[++i];
|
|
452
|
+
if (name === undefined)
|
|
453
|
+
throw new Error("missing value for --user");
|
|
454
|
+
const u = db.getUserByName(name);
|
|
455
|
+
if (u === null)
|
|
456
|
+
throw new Error(`user '${name}' not found`);
|
|
457
|
+
filter.userId = u.id;
|
|
458
|
+
}
|
|
459
|
+
else if (flag === "--event") {
|
|
460
|
+
filter.event = opts[++i];
|
|
461
|
+
if (filter.event === undefined)
|
|
462
|
+
throw new Error("missing value for --event");
|
|
463
|
+
}
|
|
464
|
+
else if (flag === "--since") {
|
|
465
|
+
const v = opts[++i];
|
|
466
|
+
if (v === undefined)
|
|
467
|
+
throw new Error("missing value for --since");
|
|
468
|
+
const m = /^(\d+)([hd])$/.exec(v);
|
|
469
|
+
if (m === null)
|
|
470
|
+
throw new Error(`invalid --since '${v}' (use like 24h or 7d)`);
|
|
471
|
+
filter.since = Date.now() - Number(m[1]) * (m[2] === "h" ? 3_600_000 : 86_400_000);
|
|
472
|
+
}
|
|
473
|
+
else {
|
|
474
|
+
throw new Error(`unknown option '${flag}'`);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
const events = db.listAudit(filter);
|
|
478
|
+
if (events.length === 0) {
|
|
479
|
+
console.log("(no events)");
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
for (const e of events) {
|
|
483
|
+
const user = e.userId !== null ? db.getUserById(e.userId) : null;
|
|
484
|
+
console.log(`${new Date(e.createdAt).toISOString()} ${user?.name ?? "-"} ${e.event} ip=${e.ip} ${e.detailJson}`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
finally {
|
|
488
|
+
db.close();
|
|
489
|
+
}
|
|
490
|
+
}
|
|
439
491
|
async function handleHub(args, configPath) {
|
|
440
492
|
const sub = args[0];
|
|
441
493
|
const rest = args.slice(1);
|
|
@@ -457,6 +509,10 @@ async function handleHub(args, configPath) {
|
|
|
457
509
|
await handleHubHost(rest, configPath);
|
|
458
510
|
return;
|
|
459
511
|
}
|
|
512
|
+
case "audit": {
|
|
513
|
+
await handleHubAudit(rest, configPath);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
460
516
|
case "service": {
|
|
461
517
|
const action = rest[0];
|
|
462
518
|
const hubConfigPath = resolveHubConfigPath(configPath);
|
|
@@ -476,7 +532,7 @@ async function handleHub(args, configPath) {
|
|
|
476
532
|
}
|
|
477
533
|
}
|
|
478
534
|
default:
|
|
479
|
-
throw new Error("usage: rdsh hub serve|user|host|service");
|
|
535
|
+
throw new Error("usage: rdsh hub serve|user|host|audit|service");
|
|
480
536
|
}
|
|
481
537
|
}
|
|
482
538
|
function parseHubServeArgs(args, configPath) {
|
|
@@ -572,8 +628,31 @@ async function handleHubUser(args, configPath) {
|
|
|
572
628
|
console.log(`rdsh: user '${name}' removed (their hosts removed)`);
|
|
573
629
|
return;
|
|
574
630
|
}
|
|
631
|
+
case "unlock": {
|
|
632
|
+
const name = args[1];
|
|
633
|
+
if (name === undefined)
|
|
634
|
+
throw new Error("usage: rdsh hub user unlock <name>");
|
|
635
|
+
const user = db.getUserByName(name);
|
|
636
|
+
if (user === null)
|
|
637
|
+
throw new Error(`user '${name}' not found`);
|
|
638
|
+
db.unlockAccount(user.id);
|
|
639
|
+
console.log(`rdsh: user '${name}' unlocked`);
|
|
640
|
+
return;
|
|
641
|
+
}
|
|
642
|
+
case "reset-2fa": {
|
|
643
|
+
const name = args[1];
|
|
644
|
+
if (name === undefined)
|
|
645
|
+
throw new Error("usage: rdsh hub user reset-2fa <name>");
|
|
646
|
+
const user = db.getUserByName(name);
|
|
647
|
+
if (user === null)
|
|
648
|
+
throw new Error(`user '${name}' not found`);
|
|
649
|
+
db.clearTotpSecret(user.id);
|
|
650
|
+
db.bumpVersion(user.id);
|
|
651
|
+
console.log(`rdsh: 2FA reset for '${name}' (their sessions revoked)`);
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
575
654
|
default:
|
|
576
|
-
throw new Error("usage: rdsh hub user add|passwd|ls|rm");
|
|
655
|
+
throw new Error("usage: rdsh hub user add|passwd|ls|rm|unlock|reset-2fa");
|
|
577
656
|
}
|
|
578
657
|
}
|
|
579
658
|
finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "remote-dsh",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Secure remote access for DeepSeek Harness: rdsh serve / rdsh join / rdsh hub",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"node": ">=22"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"rdsh-gateway": "0.
|
|
27
|
-
"rdsh-hub": "0.
|
|
26
|
+
"rdsh-gateway": "0.4.0",
|
|
27
|
+
"rdsh-hub": "0.4.0"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
30
|
"build": "tsc -p tsconfig.json",
|