instar 1.3.1596 → 1.3.1598
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/dashboard/desktop.css +8 -0
- package/dashboard/desktop.html +10 -0
- package/dashboard/desktop.js +98 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +10 -7
- package/dist/commands/server.js.map +1 -1
- package/dist/core/DesktopAccessAudit.d.ts +3 -1
- package/dist/core/DesktopAccessAudit.d.ts.map +1 -1
- package/dist/core/DesktopAccessAudit.js +1 -0
- package/dist/core/DesktopAccessAudit.js.map +1 -1
- package/dist/core/DesktopAead.d.ts +8 -1
- package/dist/core/DesktopAead.d.ts.map +1 -1
- package/dist/core/DesktopAead.js +18 -1
- package/dist/core/DesktopAead.js.map +1 -1
- package/dist/core/DesktopHost.d.ts +26 -1
- package/dist/core/DesktopHost.d.ts.map +1 -1
- package/dist/core/DesktopHost.js.map +1 -1
- package/dist/core/DesktopLockState.d.ts +38 -0
- package/dist/core/DesktopLockState.d.ts.map +1 -0
- package/dist/core/DesktopLockState.js +43 -0
- package/dist/core/DesktopLockState.js.map +1 -0
- package/dist/core/DesktopLockedController.d.ts +138 -0
- package/dist/core/DesktopLockedController.d.ts.map +1 -0
- package/dist/core/DesktopLockedController.js +442 -0
- package/dist/core/DesktopLockedController.js.map +1 -0
- package/dist/core/DesktopOperatorAssertion.d.ts +39 -0
- package/dist/core/DesktopOperatorAssertion.d.ts.map +1 -1
- package/dist/core/DesktopOperatorAssertion.js +49 -0
- package/dist/core/DesktopOperatorAssertion.js.map +1 -1
- package/dist/core/DesktopProvenVersions.d.ts +19 -0
- package/dist/core/DesktopProvenVersions.d.ts.map +1 -0
- package/dist/core/DesktopProvenVersions.js +8 -0
- package/dist/core/DesktopProvenVersions.js.map +1 -0
- package/dist/core/DirectDesktopAccess.d.ts +20 -1
- package/dist/core/DirectDesktopAccess.d.ts.map +1 -1
- package/dist/core/DirectDesktopAccess.js +263 -10
- package/dist/core/DirectDesktopAccess.js.map +1 -1
- package/dist/core/MacDesktopHost.d.ts +32 -1
- package/dist/core/MacDesktopHost.d.ts.map +1 -1
- package/dist/core/MacDesktopHost.js +115 -37
- package/dist/core/MacDesktopHost.js.map +1 -1
- package/dist/core/MultiMachineCoordinator.d.ts +11 -2
- package/dist/core/MultiMachineCoordinator.d.ts.map +1 -1
- package/dist/core/MultiMachineCoordinator.js +15 -4
- package/dist/core/MultiMachineCoordinator.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +12 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/WriteDomainRegistry.d.ts.map +1 -1
- package/dist/core/WriteDomainRegistry.js +8 -0
- package/dist/core/WriteDomainRegistry.js.map +1 -1
- package/dist/core/types.d.ts +6 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/messaging/telegram-origin/OriginAwareness.d.ts +4 -0
- package/dist/messaging/telegram-origin/OriginAwareness.d.ts.map +1 -1
- package/dist/messaging/telegram-origin/OriginAwareness.js +7 -1
- package/dist/messaging/telegram-origin/OriginAwareness.js.map +1 -1
- package/dist/native/instar-desktop-host +0 -0
- package/dist/native/instar-desktop-host.json +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +1 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +4 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +116 -3
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +2 -1
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/DesktopMeshBroker.d.ts +6 -0
- package/dist/server/DesktopMeshBroker.d.ts.map +1 -1
- package/dist/server/DesktopMeshBroker.js +17 -1
- package/dist/server/DesktopMeshBroker.js.map +1 -1
- package/dist/server/DesktopStreamManager.d.ts +11 -3
- package/dist/server/DesktopStreamManager.d.ts.map +1 -1
- package/dist/server/DesktopStreamManager.js +24 -1
- package/dist/server/DesktopStreamManager.js.map +1 -1
- package/dist/server/leaseRenewalDependencies.d.ts +15 -0
- package/dist/server/leaseRenewalDependencies.d.ts.map +1 -0
- package/dist/server/leaseRenewalDependencies.js +10 -0
- package/dist/server/leaseRenewalDependencies.js.map +1 -0
- package/dist/server/machineRoutes.d.ts +1 -0
- package/dist/server/machineRoutes.d.ts.map +1 -1
- package/dist/server/machineRoutes.js +14 -0
- package/dist/server/machineRoutes.js.map +1 -1
- package/dist/server/routes.d.ts +9 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +99 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/testing/selfActionRegistry.d.ts.map +1 -1
- package/dist/testing/selfActionRegistry.js +58 -0
- package/dist/testing/selfActionRegistry.js.map +1 -1
- package/package.json +1 -1
- package/scripts/build-native-desktop-host.mjs +4 -2
- package/src/data/builtin-manifest.json +66 -66
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/src/scaffold/templates.ts +1 -1
- package/upgrades/1.3.1597.md +20 -0
- package/upgrades/1.3.1598.md +24 -0
- package/upgrades/side-effects/app-conversations-lease-renewal.md +51 -0
- package/upgrades/side-effects/desktop-locked-screen.md +129 -0
package/dashboard/desktop.css
CHANGED
|
@@ -41,3 +41,11 @@ body.desktop-live #localCursor{display:block}
|
|
|
41
41
|
.setup-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
|
|
42
42
|
.setup-note:empty { display: none; }
|
|
43
43
|
.setup-quiet { background: none; border: none; color: inherit; opacity: 0.7; text-decoration: underline; }
|
|
44
|
+
|
|
45
|
+
#lockedPassword{position:absolute;z-index:8;left:max(.5rem,env(safe-area-inset-left));right:max(.5rem,env(safe-area-inset-right));top:max(.5rem,env(safe-area-inset-top));display:grid;gap:.4rem;padding:.6rem;background:#111827f2;border:1px solid #64748b;border-radius:10px;color:#f1f5f9}
|
|
46
|
+
#lockedPassword[hidden],#leaveUnlockedButton[hidden]{display:none}
|
|
47
|
+
#lockedPassword input{width:100%;font-size:16px;padding:.55rem}
|
|
48
|
+
#lockedPassword p{margin:0;font-size:.8rem}
|
|
49
|
+
#leaveUnlockedButton{position:absolute;z-index:8;right:max(.5rem,env(safe-area-inset-right));bottom:4rem;padding:.55rem .8rem}
|
|
50
|
+
#lockedCard{margin-top:.8rem}
|
|
51
|
+
#lockedCard[hidden]{display:none}
|
package/dashboard/desktop.html
CHANGED
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
<label>Machine <select id="machine"></select></label>
|
|
20
20
|
<button id="requestButton">Open selected machine</button>
|
|
21
21
|
<ul id="machineNotes" class="machine-notes" aria-label="Machines that are not ready"></ul>
|
|
22
|
+
<div id="lockedCard" hidden>
|
|
23
|
+
<p id="lockedCardText"></p>
|
|
24
|
+
<button id="lockedToggle" type="button" hidden></button>
|
|
25
|
+
</div>
|
|
22
26
|
</section>
|
|
23
27
|
<section id="setup" hidden>
|
|
24
28
|
<h2>Machines</h2>
|
|
@@ -86,6 +90,12 @@
|
|
|
86
90
|
<button data-remote-key="F11" type="button">F11</button>
|
|
87
91
|
<button data-remote-key="F12" type="button">F12</button>
|
|
88
92
|
</div>
|
|
93
|
+
<form id="lockedPassword" hidden>
|
|
94
|
+
<label>Mac password <input id="lockedPasswordInput" type="password" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" maxlength="256"></label>
|
|
95
|
+
<button type="submit">Unlock</button>
|
|
96
|
+
<p>The machine serving this page and the tunnel provider can read what you type here. The Instar app is safer.</p>
|
|
97
|
+
</form>
|
|
98
|
+
<button id="leaveUnlockedButton" type="button" hidden>Leave unlocked</button>
|
|
89
99
|
<div id="keyboardBar" hidden>
|
|
90
100
|
<label class="type-label" for="typeText">Type on remote desktop</label>
|
|
91
101
|
<input id="typeText" maxlength="64" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false" enterkeyhint="done">
|
package/dashboard/desktop.js
CHANGED
|
@@ -251,7 +251,7 @@ const base64ToBytes = text => Uint8Array.from(atob(text), character => character
|
|
|
251
251
|
function recordIv(direction, sequence) {
|
|
252
252
|
const iv = new Uint8Array(12);
|
|
253
253
|
const view = new DataView(iv.buffer);
|
|
254
|
-
view.setUint32(0,
|
|
254
|
+
view.setUint32(0, { frame: 1, input: 2, control: 3 }[direction]);
|
|
255
255
|
view.setBigUint64(4, sequence);
|
|
256
256
|
return iv;
|
|
257
257
|
}
|
|
@@ -410,11 +410,65 @@ function receiveH264(bytes, epoch) {
|
|
|
410
410
|
timestamp, data }));
|
|
411
411
|
needsVideoKeyframe = false;
|
|
412
412
|
}
|
|
413
|
+
const CONTROL_MARKER = 0xc7;
|
|
414
|
+
let controlSequence = 0n;
|
|
415
|
+
let lockedSealKey = '';
|
|
416
|
+
let lockedScreenState = '';
|
|
417
|
+
let lockedBoxAllowed = false;
|
|
418
|
+
let secretSequence = 0;
|
|
419
|
+
function syncLockedPassword() {
|
|
420
|
+
const show = lockedBoxAllowed && lockedScreenState === 'locked-in-session' && !!lockedSealKey;
|
|
421
|
+
$('lockedPassword').hidden = !show;
|
|
422
|
+
if (!show) $('lockedPasswordInput').value = '';
|
|
423
|
+
}
|
|
424
|
+
function lockedMessage(reason) {
|
|
425
|
+
return { 'relock-pending': 'This Mac is finishing a relock. Try again in a couple of minutes.',
|
|
426
|
+
'attempts-per-request': 'Too many tries in this session.', 'attempts-per-day': 'Too many tries today.',
|
|
427
|
+
'seal-stale': 'The connection changed. Type your password again.',
|
|
428
|
+
aborted: 'Stopped before the password finished. Type it again.',
|
|
429
|
+
'field-dirty': 'Clearing the password field. Try again in a moment.',
|
|
430
|
+
'browser-box-off': 'Password entry from a browser is off for this Mac.',
|
|
431
|
+
'tunnel-not-first-tier': 'Password entry is off while the backup connection is in use.' }[reason]
|
|
432
|
+
?? 'This Mac did not accept that. Try again.';
|
|
433
|
+
}
|
|
434
|
+
async function receiveControl(record) {
|
|
435
|
+
const view = new DataView(record.buffer, record.byteOffset, record.byteLength);
|
|
436
|
+
const sequence = view.getBigUint64(0) & 0x00ff_ffff_ffff_ffffn;
|
|
437
|
+
if (sequence <= controlSequence) throw new Error('Remote control record invalid.');
|
|
438
|
+
const plain = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: recordIv('control', sequence),
|
|
439
|
+
additionalData: recordAad('control') }, aesKey, record.subarray(8));
|
|
440
|
+
controlSequence = sequence;
|
|
441
|
+
const value = JSON.parse(new TextDecoder().decode(plain));
|
|
442
|
+
if (value.type === 'seal') lockedSealKey = value.key;
|
|
443
|
+
if (value.type === 'state') { lockedScreenState = value.state; lockedBoxAllowed = value.box === true; }
|
|
444
|
+
if (value.type === 'secret-result' && value.refused) status(lockedMessage(value.refused));
|
|
445
|
+
if (value.type === 'secret-result' && value.sent) { $('leaveUnlockedButton').hidden = false; }
|
|
446
|
+
if (value.type === 'relock') status(value.phase === 'left-unlocked' ? 'This Mac will stay unlocked.' : 'Relocking has begun.');
|
|
447
|
+
syncLockedPassword();
|
|
448
|
+
}
|
|
449
|
+
/** Sealed for the helper alone: Node and the front carry bytes they cannot read. */
|
|
450
|
+
async function sendLockedPassword(text) {
|
|
451
|
+
const helperKey = lockedSealKey;
|
|
452
|
+
const pair = await crypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveBits']);
|
|
453
|
+
const helper = await crypto.subtle.importKey('raw', base64ToBytes(helperKey), { name: 'ECDH', namedCurve: 'P-256' }, false, []);
|
|
454
|
+
const bits = await crypto.subtle.deriveBits({ name: 'ECDH', public: helper }, pair.privateKey, 256);
|
|
455
|
+
const hkdf = await crypto.subtle.importKey('raw', bits, 'HKDF', false, ['deriveKey']);
|
|
456
|
+
const key = await crypto.subtle.deriveKey({ name: 'HKDF', hash: 'SHA-256', salt: new Uint8Array(0),
|
|
457
|
+
info: encoder.encode(`instar-desktop-secret-v1:${requestId}:${helperKey}`) }, hkdf,
|
|
458
|
+
{ name: 'AES-GCM', length: 256 }, false, ['encrypt']);
|
|
459
|
+
const seq = ++secretSequence;
|
|
460
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
461
|
+
const ct = await crypto.subtle.encrypt({ name: 'AES-GCM', iv,
|
|
462
|
+
additionalData: encoder.encode(JSON.stringify(['instar-desktop-secret-v1', requestId, seq])) }, key, encoder.encode(text));
|
|
463
|
+
const ephemeral = await crypto.subtle.exportKey('raw', pair.publicKey);
|
|
464
|
+
return sendCommand({ type: 'secret', secret: { ephemeral: bytesToBase64(ephemeral), iv: bytesToBase64(iv), ct: bytesToBase64(ct), seq } });
|
|
465
|
+
}
|
|
413
466
|
async function receiveFrame(recordBuffer, epoch) {
|
|
414
467
|
if (!inputEnabled || epoch !== streamEpoch) return;
|
|
415
468
|
if (!aesKey || !(recordBuffer instanceof ArrayBuffer) || recordBuffer.byteLength < 28
|
|
416
469
|
|| recordBuffer.byteLength > 1_600_000) throw new Error('Encrypted frame invalid.');
|
|
417
470
|
const record = new Uint8Array(recordBuffer);
|
|
471
|
+
if (record[0] === CONTROL_MARKER) { await receiveControl(record); return; }
|
|
418
472
|
const sequence = new DataView(recordBuffer).getBigUint64(0);
|
|
419
473
|
// The target may drop an already-encrypted frame under backpressure. A
|
|
420
474
|
// strictly increasing nonce still rejects replay/reordering without treating
|
|
@@ -699,6 +753,7 @@ async function loadTargetsAndMaybeOpen({ open = true } = {}) {
|
|
|
699
753
|
const trustedKey = typeof target.targetSigningPublicKey === 'string'
|
|
700
754
|
? target.targetSigningPublicKey : '';
|
|
701
755
|
option.disabled = !target.ready || !trustedKey;
|
|
756
|
+
setTimeout(() => { void refreshLockedCard(); }, 0);
|
|
702
757
|
option.textContent = option.disabled
|
|
703
758
|
? `${target.label} — ${target.unavailableReason || 'Unavailable right now'}`
|
|
704
759
|
: target.label;
|
|
@@ -817,6 +872,8 @@ async function requestDesktop() {
|
|
|
817
872
|
browserEcdhPublicKey: bytesToBase64(ecdhPublicKey),
|
|
818
873
|
browserNonce: crypto.randomUUID().replaceAll('-', ''),
|
|
819
874
|
videoCodec,
|
|
875
|
+
client: 'browser',
|
|
876
|
+
controlRecords: true,
|
|
820
877
|
});
|
|
821
878
|
requestId = result.requestId;
|
|
822
879
|
const approved = await api(`/desktop/requests/${encodeURIComponent(requestId)}`);
|
|
@@ -875,6 +932,10 @@ async function openStream(result, resume = null) {
|
|
|
875
932
|
sendChain = Promise.resolve();
|
|
876
933
|
receiveChain = Promise.resolve();
|
|
877
934
|
socket.binaryType = 'arraybuffer';
|
|
935
|
+
controlSequence = 0n;
|
|
936
|
+
lockedSealKey = '';
|
|
937
|
+
secretSequence = 0;
|
|
938
|
+
syncLockedPassword();
|
|
878
939
|
return new Promise((resolve, reject) => {
|
|
879
940
|
let opened = false;
|
|
880
941
|
let settled = false;
|
|
@@ -930,8 +991,17 @@ async function openStream(result, resume = null) {
|
|
|
930
991
|
});
|
|
931
992
|
}
|
|
932
993
|
|
|
994
|
+
const LOCK_SCREEN_KEYS = new Set(['Enter', 'Tab', 'Escape', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']);
|
|
995
|
+
/** A password typed at the shield must never leave as plain input. The helper
|
|
996
|
+
* also refuses it, but only this stops it reaching the server at all. */
|
|
997
|
+
function refusedAtLock(action) {
|
|
998
|
+
if (!['locked-in-session', 'locked-by-policy', 'screensaver-or-sleep', 'unknown'].includes(lockedScreenState)) return false;
|
|
999
|
+
if (action.kind === 'type') return true;
|
|
1000
|
+
return action.kind === 'keyDown' && !LOCK_SCREEN_KEYS.has(action.key);
|
|
1001
|
+
}
|
|
933
1002
|
function send(action) {
|
|
934
1003
|
if (!inputEnabled) return Promise.resolve(false);
|
|
1004
|
+
if (refusedAtLock(action)) return Promise.resolve(true);
|
|
935
1005
|
if (screenSwitch && Date.now() - screenSwitch.at >= SCREEN_SWITCH_LIMIT_MS) screenSwitch = null;
|
|
936
1006
|
if (screenSwitch && ['click', 'buttonDown', 'move'].includes(action.kind)) return Promise.resolve(false);
|
|
937
1007
|
return sendCommand({ type: 'input', action });
|
|
@@ -1559,6 +1629,33 @@ $('stopButton').addEventListener('click', async () => {
|
|
|
1559
1629
|
catch { message = 'The viewer closed, but the target has not confirmed revocation. Access expires automatically.'; }
|
|
1560
1630
|
leave(message);
|
|
1561
1631
|
});
|
|
1632
|
+
$('lockedPassword')?.addEventListener('submit', event => {
|
|
1633
|
+
event.preventDefault();
|
|
1634
|
+
const input = $('lockedPasswordInput');
|
|
1635
|
+
const text = input.value;
|
|
1636
|
+
input.value = '';
|
|
1637
|
+
if (text) void sendLockedPassword(text);
|
|
1638
|
+
});
|
|
1639
|
+
const LOCKED_REASONS = { 'unsupported-macos': 'Not available yet: this Mac\u2019s macOS has not passed the crash and Stop tests.' };
|
|
1640
|
+
async function refreshLockedCard() {
|
|
1641
|
+
let rows;
|
|
1642
|
+
try { rows = (await api('/desktop/locked/status?scope=pool')).machines; }
|
|
1643
|
+
catch { $('lockedCard').hidden = true; return; }
|
|
1644
|
+
const row = rows?.find(item => item.machineId === $('machine').value);
|
|
1645
|
+
if (!row) { $('lockedCard').hidden = true; return; }
|
|
1646
|
+
$('lockedCard').hidden = !row.enabled && !!row.refusal;
|
|
1647
|
+
$('lockedCardText').textContent = row.refusal ? LOCKED_REASONS[row.refusal] ?? 'Opening this Mac at its lock screen is unavailable.'
|
|
1648
|
+
: row.enabled ? 'You can open this Mac at its lock screen. It relocks when you finish.' : 'Opening this Mac at its lock screen is off.';
|
|
1649
|
+
$('lockedToggle').hidden = !!row.refusal;
|
|
1650
|
+
$('lockedToggle').textContent = row.enabled ? 'Turn off' : 'Turn on';
|
|
1651
|
+
$('lockedToggle').onclick = async () => {
|
|
1652
|
+
try { await api('/desktop/locked/settings', 'POST', { machineId: row.machineId, enabled: !row.enabled }); }
|
|
1653
|
+
catch (error) { status(error.message); }
|
|
1654
|
+
void refreshLockedCard();
|
|
1655
|
+
};
|
|
1656
|
+
}
|
|
1657
|
+
$('machine')?.addEventListener('change', () => { void refreshLockedCard(); });
|
|
1658
|
+
$('leaveUnlockedButton')?.addEventListener('click', () => { void sendCommand({ type: 'leave-unlocked' }); });
|
|
1562
1659
|
window.addEventListener('beforeunload', () => {
|
|
1563
1660
|
stopping = true;
|
|
1564
1661
|
sendCommand({ type: 'stop' });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/commands/server.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/server.js
CHANGED
|
@@ -4442,16 +4442,19 @@ export async function startServer(options) {
|
|
|
4442
4442
|
onLeasePullTick: () => _leaseHandbackReconciler?.observe(),
|
|
4443
4443
|
});
|
|
4444
4444
|
const machineRole = coordinator.start();
|
|
4445
|
-
// The origin writer
|
|
4446
|
-
// non-development installations
|
|
4447
|
-
//
|
|
4448
|
-
|
|
4449
|
-
|
|
4445
|
+
// The origin writer and native app conversations require a current lease even
|
|
4446
|
+
// on ordinary, non-development installations (without Telegram, the app was
|
|
4447
|
+
// the only surface and its lease lapsed at TTL between 2-minute heartbeats).
|
|
4448
|
+
// Enroll the renewal carrier before lease initialization; this does not bypass
|
|
4449
|
+
// explicit opt-outs or lease fences.
|
|
4450
|
+
const { leaseRenewalDependencies } = await import('../server/leaseRenewalDependencies.js');
|
|
4451
|
+
const leaseRenewalReleases = leaseRenewalDependencies(config).map((name) => coordinator.enrollLeaseRenewalDependency(name));
|
|
4450
4452
|
const releaseOriginLeaseRenewal = () => {
|
|
4451
|
-
|
|
4453
|
+
for (const release of leaseRenewalReleases.splice(0))
|
|
4454
|
+
release();
|
|
4452
4455
|
process.removeListener('exit', releaseOriginLeaseRenewal);
|
|
4453
4456
|
};
|
|
4454
|
-
if (
|
|
4457
|
+
if (leaseRenewalReleases.length > 0)
|
|
4455
4458
|
process.once('exit', releaseOriginLeaseRenewal);
|
|
4456
4459
|
if (coordinator.enabled) {
|
|
4457
4460
|
console.log(pc.green(` Multi-machine: ${pc.bold(machineRole)} (${coordinator.identity.machineId.slice(0, 12)}...)`));
|