@dotrino/remote-agent 0.18.0 → 0.18.1
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/protocol.js +5 -0
- package/src/agent.js +21 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dotrino/remote-agent",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "Middleware compartido del ecosistema Dotrino para apps de agente remoto cifrado punto a punto (handshake E2E, emparejamiento SAS con vault, revocación, descubrimiento). Lo consumen dotrino-terminal (PTY) y dotrino-ia (chat con IA).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
package/protocol.js
CHANGED
|
@@ -39,6 +39,11 @@ export const SIGN_SCOPE = 'vault:sign'
|
|
|
39
39
|
/** Vigencia de una sesión inactiva y refresco de la lista de revocados. */
|
|
40
40
|
export const SESSION_TTL_MS = 30 * 60 * 1000
|
|
41
41
|
export const REVOKE_REFRESH_MS = 5 * 60 * 1000
|
|
42
|
+
/**
|
|
43
|
+
* Cuánto se espera a un cliente cuya conexión se fue antes de cerrarle la sesión. Un cliente
|
|
44
|
+
* que reconecta sigue con su sesión desde un token nuevo: si en este plazo manda algo, se queda.
|
|
45
|
+
*/
|
|
46
|
+
export const SESSION_GONE_MS = 20 * 1000
|
|
42
47
|
|
|
43
48
|
/**
|
|
44
49
|
* RENOVACIÓN del cert de esta máquina. El cert dura 30 días; se pide uno fresco
|
package/src/agent.js
CHANGED
|
@@ -27,7 +27,7 @@ import { adoptRecord } from './record.js'
|
|
|
27
27
|
import { installNodeGlobals } from '../node-globals.js'
|
|
28
28
|
import { makeEphemeral, deriveKey, seal, open } from '../e2e.js'
|
|
29
29
|
import { makeCatchUp } from './catch-up.js'
|
|
30
|
-
import { HS, ACK, DATA, PING, PONG, ERROR, VMSG, SIGN_SCOPE, SESSION_TTL_MS, REVOKE_REFRESH_MS } from '../protocol.js'
|
|
30
|
+
import { HS, ACK, DATA, PING, PONG, ERROR, VMSG, SIGN_SCOPE, SESSION_TTL_MS, SESSION_GONE_MS, REVOKE_REFRESH_MS } from '../protocol.js'
|
|
31
31
|
import { loadLink, saveLink, dataDir } from './link.js'
|
|
32
32
|
|
|
33
33
|
/** Sesión cifrada con un dispositivo cliente. La app recibe esto en `onSession`. */
|
|
@@ -88,6 +88,7 @@ class AgentSession {
|
|
|
88
88
|
close () {
|
|
89
89
|
if (this._closed) return
|
|
90
90
|
this._closed = true
|
|
91
|
+
clearTimeout(this._gone)
|
|
91
92
|
for (const h of this._h.close) { try { h() } catch (_) {} }
|
|
92
93
|
}
|
|
93
94
|
}
|
|
@@ -105,6 +106,7 @@ class AgentSession {
|
|
|
105
106
|
* @param {()=>void} [opts.onRevoked] se llamó al auto-borrarse por revocación.
|
|
106
107
|
* @param {()=>void} [opts.onReady] agente listo y escuchando.
|
|
107
108
|
* @param {boolean} [opts.quiet] sin logs.
|
|
109
|
+
* @param {number} [opts.sessionGoneMs] cuánto se espera a un cliente cuya conexión se fue (`SESSION_GONE_MS`).
|
|
108
110
|
* @param {number} [opts.netLogMs] cada cuánto van al log las estadísticas de red (5 min).
|
|
109
111
|
* @param {object} [opts.client] transporte ya conectado (SOLO pruebas).
|
|
110
112
|
*
|
|
@@ -420,9 +422,27 @@ export async function startRemoteAgent (opts = {}) {
|
|
|
420
422
|
if (!s) return send(from, { type: ERROR, code: 'unknown-session', sid: p.sid, error: 'sesión desconocida o expirada' })
|
|
421
423
|
s._exp = Date.now() + SESSION_TTL_MS
|
|
422
424
|
s.from = from
|
|
425
|
+
if (s._gone) { clearTimeout(s._gone); s._gone = null }
|
|
423
426
|
s._ingest(p.env).catch(() => send(from, { type: ERROR, error: 'sobre inválido' }))
|
|
424
427
|
}
|
|
425
428
|
|
|
429
|
+
// LA CONEXIÓN DEL CLIENTE SE FUE: su sesión no se queda 30 minutos. El proxio avisa de que ese
|
|
430
|
+
// token murió (`peer_disconnected`); un token no vuelve, así que quien sigue vivo manda desde
|
|
431
|
+
// otro y la sesión se queda (`handleData`). Si en `SESSION_GONE_MS` no llega nada, se cierra.
|
|
432
|
+
// Antes solo vencía por `SESSION_TTL_MS`: un teléfono que volvía del fondo abría sesión nueva
|
|
433
|
+
// y la vieja seguía enganchada a su consola (seis del mismo aparato en una, el 2026-10-09).
|
|
434
|
+
const goneMs = opts.sessionGoneMs ?? SESSION_GONE_MS
|
|
435
|
+
client.on('peer_disconnected', (token) => {
|
|
436
|
+
for (const [sid, s] of sessions) {
|
|
437
|
+
if (s.from !== token || s._gone) continue
|
|
438
|
+
s._gone = setTimeout(() => {
|
|
439
|
+
s.close(); sessions.delete(sid)
|
|
440
|
+
audit('session-gone', { sid: sid.slice(0, 8) })
|
|
441
|
+
}, goneMs)
|
|
442
|
+
s._gone.unref?.()
|
|
443
|
+
}
|
|
444
|
+
})
|
|
445
|
+
|
|
426
446
|
// POR DÓNDE VA EL TRÁFICO, AL LOG. Un agente no tiene topbar: sin esto, saber si una
|
|
427
447
|
// sesión subió a WebRTC o sigue dando la vuelta por el proxio pedía una prueba aparte.
|
|
428
448
|
// Lo escribe el pilar (`logStats`), que lee los clientes del proceso; aquí solo se enciende.
|