@livedesk/hub 0.1.64 → 0.1.66
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/package.json +1 -1
- package/src/live-desk-update.js +60 -23
- package/src/remote-hub.js +20 -14
package/package.json
CHANGED
package/src/live-desk-update.js
CHANGED
|
@@ -66,9 +66,27 @@ export function isVersionAtLeast(candidate, required) {
|
|
|
66
66
|
return !!cleanVersion(candidate) && !!cleanVersion(required) && compareVersions(candidate, required) >= 0;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function isDedicatedBootstrapFailure(value) {
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
function isDedicatedBootstrapFailure(value) {
|
|
70
|
+
const failure = String(value || '').trim();
|
|
71
|
+
return /^Update worker exited before terminal proof\b/i.test(failure)
|
|
72
|
+
|| failure === 'invalid-update-host-environment-entry';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function describeCommandResultEvidence(result) {
|
|
76
|
+
const data = result?.data;
|
|
77
|
+
if (!data || typeof data !== 'object') return '';
|
|
78
|
+
const evidence = [];
|
|
79
|
+
const shell = String(data.shell || '').trim().toLowerCase();
|
|
80
|
+
if (/^[a-z0-9._-]{1,32}$/.test(shell)) evidence.push(`shell=${shell}`);
|
|
81
|
+
const exitCode = Number(data.exitCode);
|
|
82
|
+
if (Number.isInteger(exitCode) && Math.abs(exitCode) <= 0x7fffffff) evidence.push(`exit=${exitCode}`);
|
|
83
|
+
if (typeof data.timedOut === 'boolean') evidence.push(`timedOut=${data.timedOut}`);
|
|
84
|
+
const durationMs = Number(data.durationMs);
|
|
85
|
+
if (Number.isFinite(durationMs) && durationMs >= 0 && durationMs <= 24 * 60 * 60_000) {
|
|
86
|
+
evidence.push(`durationMs=${Math.round(durationMs)}`);
|
|
87
|
+
}
|
|
88
|
+
return evidence.length > 0 ? ` [${evidence.join(' ')}]` : '';
|
|
89
|
+
}
|
|
72
90
|
|
|
73
91
|
function encodePowerShell(value) {
|
|
74
92
|
return Buffer.from(String(value || ''), 'utf16le').toString('base64');
|
|
@@ -451,16 +469,29 @@ export function createLiveDeskUpdateManager({
|
|
|
451
469
|
return true;
|
|
452
470
|
};
|
|
453
471
|
|
|
454
|
-
const dispatchTarget = (target, device, options = {}) => {
|
|
455
|
-
const dispatchedAtEpochMs = now();
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
472
|
+
const dispatchTarget = (target, device, options = {}) => {
|
|
473
|
+
const dispatchedAtEpochMs = now();
|
|
474
|
+
const requestedDeadlineEpochMs = Date.parse(String(options.deadlineAt || ''));
|
|
475
|
+
const usesExistingDeadline = Number.isFinite(requestedDeadlineEpochMs)
|
|
476
|
+
&& requestedDeadlineEpochMs > 0;
|
|
477
|
+
const remainingExistingDeadlineMs = requestedDeadlineEpochMs - dispatchedAtEpochMs;
|
|
478
|
+
if (usesExistingDeadline && remainingExistingDeadlineMs < 10_000) {
|
|
479
|
+
target.state = 'failed';
|
|
480
|
+
target.error = 'client-update-deadline-insufficient';
|
|
481
|
+
return false;
|
|
482
|
+
}
|
|
483
|
+
const requestedTimeoutMs = usesExistingDeadline
|
|
484
|
+
? Math.min(effectiveTargetTimeoutMs, remainingExistingDeadlineMs)
|
|
485
|
+
: Math.max(
|
|
486
|
+
10_000,
|
|
487
|
+
Math.min(
|
|
488
|
+
effectiveTargetTimeoutMs,
|
|
489
|
+
Number(options.updateTimeoutMs) || effectiveTargetTimeoutMs
|
|
490
|
+
)
|
|
491
|
+
);
|
|
492
|
+
const updateDeadlineEpochMs = usesExistingDeadline
|
|
493
|
+
? requestedDeadlineEpochMs
|
|
494
|
+
: dispatchedAtEpochMs + requestedTimeoutMs;
|
|
464
495
|
const dispatchedSessionId = String(device?.sessionId || '').trim();
|
|
465
496
|
if (!dispatchedSessionId) {
|
|
466
497
|
target.state = 'failed';
|
|
@@ -784,12 +815,18 @@ export function createLiveDeskUpdateManager({
|
|
|
784
815
|
if (!target
|
|
785
816
|
|| target.state !== 'waiting'
|
|
786
817
|
|| !['dedicated', 'legacy-command-run'].includes(target.method)) return;
|
|
787
|
-
const result = event?.result;
|
|
788
|
-
if (event?.error || result?.ok === false || result?.status === 'failed' || result?.status === 'rejected') {
|
|
789
|
-
const
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
818
|
+
const result = event?.result;
|
|
819
|
+
if (event?.error || result?.ok === false || result?.status === 'failed' || result?.status === 'rejected') {
|
|
820
|
+
const failureReason = String(
|
|
821
|
+
event.error || result?.error || result?.message || 'client-update-command-failed'
|
|
822
|
+
).slice(0, 500);
|
|
823
|
+
const failure = (
|
|
824
|
+
failureReason
|
|
825
|
+
+ describeCommandResultEvidence(result)
|
|
826
|
+
).slice(0, 500);
|
|
827
|
+
if (target.method === 'dedicated'
|
|
828
|
+
&& target.bootstrapRetryCount === 0
|
|
829
|
+
&& isDedicatedBootstrapFailure(failureReason)) {
|
|
793
830
|
const retryDevice = connectedClientDevices()
|
|
794
831
|
.find(device => String(device.deviceId || '') === target.deviceId);
|
|
795
832
|
const remainingMs = Date.parse(target.deadlineAt || '') - now();
|
|
@@ -800,10 +837,10 @@ export function createLiveDeskUpdateManager({
|
|
|
800
837
|
target.error = '';
|
|
801
838
|
let retryResult;
|
|
802
839
|
try {
|
|
803
|
-
retryResult = dispatchTarget(target, retryDevice, {
|
|
804
|
-
forceLegacy: true,
|
|
805
|
-
|
|
806
|
-
});
|
|
840
|
+
retryResult = dispatchTarget(target, retryDevice, {
|
|
841
|
+
forceLegacy: true,
|
|
842
|
+
deadlineAt: target.deadlineAt
|
|
843
|
+
});
|
|
807
844
|
} catch (error) {
|
|
808
845
|
target.error = String(error?.message || error || 'client-update-bootstrap-retry-failed').slice(0, 500);
|
|
809
846
|
retryResult = false;
|
package/src/remote-hub.js
CHANGED
|
@@ -9784,25 +9784,31 @@ export function createRemoteHub(options = {}) {
|
|
|
9784
9784
|
return { ok: false, error: 'device-not-connected' };
|
|
9785
9785
|
}
|
|
9786
9786
|
|
|
9787
|
-
const command = safeString(options.command, 20000);
|
|
9788
|
-
if (!command) return { ok: false, error: 'client-update-command-missing' };
|
|
9789
|
-
const commandId = safeString(options.commandId, 128) || crypto.randomUUID();
|
|
9790
|
-
const timeoutMs = clampNumber(options.timeoutMs, 1000, 120000, 30000);
|
|
9791
|
-
const
|
|
9787
|
+
const command = safeString(options.command, 20000);
|
|
9788
|
+
if (!command) return { ok: false, error: 'client-update-command-missing' };
|
|
9789
|
+
const commandId = safeString(options.commandId, 128) || crypto.randomUUID();
|
|
9790
|
+
const timeoutMs = clampNumber(options.timeoutMs, 1000, 120000, 30000);
|
|
9791
|
+
const legacyCommandShell = ['win32', 'windows']
|
|
9792
|
+
.includes(safeString(device.platform, 32).toLowerCase())
|
|
9793
|
+
? 'cmd'
|
|
9794
|
+
: 'auto';
|
|
9795
|
+
const sent = writeJsonLine(device.socket, {
|
|
9792
9796
|
type: 'command',
|
|
9793
9797
|
commandId,
|
|
9794
|
-
command: 'command.run',
|
|
9795
|
-
payload: {
|
|
9796
|
-
command,
|
|
9797
|
-
|
|
9798
|
-
|
|
9798
|
+
command: 'command.run',
|
|
9799
|
+
payload: {
|
|
9800
|
+
command,
|
|
9801
|
+
shell: legacyCommandShell,
|
|
9802
|
+
timeoutMs,
|
|
9803
|
+
permissionMode: 'full-access',
|
|
9799
9804
|
// RemoteFast releases before 0.1.170 read command.run inputs
|
|
9800
9805
|
// from toolArguments, while Node and current Agents accept the
|
|
9801
9806
|
// direct payload fields. Carry both during the update bridge.
|
|
9802
|
-
toolArguments: {
|
|
9803
|
-
command,
|
|
9804
|
-
|
|
9805
|
-
|
|
9807
|
+
toolArguments: {
|
|
9808
|
+
command,
|
|
9809
|
+
shell: legacyCommandShell,
|
|
9810
|
+
timeoutMs
|
|
9811
|
+
}
|
|
9806
9812
|
},
|
|
9807
9813
|
issuedAt: new Date().toISOString()
|
|
9808
9814
|
});
|