@dotrino/vaultd 0.73.0 → 0.75.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/lib/src/admin.js CHANGED
@@ -46,7 +46,7 @@
46
46
  export const ADMIN_OPS = Object.freeze([
47
47
  // `pending`, `pair`, `approve` y `reject` NO están, y no es un olvido: agregar aparatos
48
48
  // a distancia se quitó (ver la cabecera). Lo que queda es mirar, quitar y configurar.
49
- 'status', 'revoke', 'audit',
49
+ 'revoke', 'audit',
50
50
  // Variables de entorno: verlas (nombres siempre; valor solo de las públicas) y
51
51
  // ponerles valor (de las dos). Borrar NO está, y es a propósito: un aparato robado
52
52
  // no debe poder dejar sin configuración a los servicios.
@@ -72,7 +72,7 @@ export const ADMIN_OPS = Object.freeze([
72
72
  * Se dejan las de LEER a propósito: si se cortaran todas, la consola no podría ni
73
73
  * enterarse de por qué no funciona y parecería rota. Así puede decir «está cerrada».
74
74
  */
75
- export const ADMIN_OPS_WHILE_LOCKED = Object.freeze(['status', 'audit', 'vars'])
75
+ export const ADMIN_OPS_WHILE_LOCKED = Object.freeze(['audit', 'vars'])
76
76
 
77
77
  /** Cuánto se recuerda un nonce ya usado (el doble de la ventana de frescura). */
78
78
  export const ADMIN_NONCE_TTL_MS = 10 * 60 * 1000
@@ -159,10 +159,6 @@ export function createAdminDesk ({
159
159
  }
160
160
 
161
161
  try {
162
- // Lo mínimo que la consola necesita saber de la bóveda para explicarse: si está
163
- // cerrada, lo que queda (revocar, configurar) no se puede, y hay que decir por qué en
164
- // vez de dejar pulsar un botón para recibir un error.
165
- if (data.op === 'status') return { ok: true, result: { locked: !!isLocked() } }
166
162
 
167
163
  if (data.op === 'audit') {
168
164
  const limit = Math.min(Math.max(Number(data.limit) || 100, 1), AUDIT_MAX)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotrino/vaultd",
3
- "version": "0.73.0",
3
+ "version": "0.75.0",
4
4
  "type": "module",
5
5
  "description": "Certificador personal de Dotrino: daemon headless que custodia la clave maestra y delega capacidades a tus dispositivos por el proxy. Tu CA propia.",
6
6
  "bin": {
@@ -20,7 +20,7 @@
20
20
  "node": ">=20"
21
21
  },
22
22
  "dependencies": {
23
- "@dotrino/identity": "0.73.0",
23
+ "@dotrino/identity": "0.74.0",
24
24
  "@dotrino/passmanager": "^0.9.0",
25
25
  "@dotrino/proxy-client": "^0.13.1",
26
26
  "ws": "^8.18.0"
@@ -44,7 +44,7 @@
44
44
  "!lib/src/types.d.ts"
45
45
  ],
46
46
  "devDependencies": {
47
- "@dotrino/remote-agent": "0.6.0",
47
+ "@dotrino/remote-agent": "0.6.1",
48
48
  "@types/node": "^22.0.0",
49
49
  "typescript": "5.9.3"
50
50
  }
package/src/vault.js CHANGED
@@ -228,7 +228,11 @@ export async function startVault ({ dir = dataDir(), proxyUrl, log = console.log
228
228
  try {
229
229
  const info = await identity.profileActa?.()
230
230
  const acta = info?.acta
231
- if (info?.isMaster && acta && (!acta.sealPub || !sealKeys.has(acta.sealPub))) {
231
+ // CON EL PERFIL ABIERTO. Estrenar la llave de sellado SELLA EL ACTA, y una bóveda
232
+ // cerrada no sella nada — la misma regla que el bloque de abajo. Cerrada se queda sin
233
+ // llave y los sobres salen sin firma (lo que ya pasaba antes de §8.8), y se arregla sola
234
+ // la primera vez que alguien abra el perfil.
235
+ if (info?.isMaster && acta && !isLocked() && (!acta.sealPub || !sealKeys.has(acta.sealPub))) {
232
236
  const r = await identity.rotateSealKey()
233
237
  // Sin `%s`: este `log` va con un prefijo por delante, así que el formato no es lo
234
238
  // primero y `console.log` no lo sustituye (salía «record #%s 2»).
@@ -252,7 +256,14 @@ export async function startVault ({ dir = dataDir(), proxyUrl, log = console.log
252
256
  try {
253
257
  const info = await identity.profileActa?.()
254
258
  const acta = info?.acta
255
- if (acta && !identity.masterLocked) {
259
+ // CON EL PERFIL ABIERTO, y `isLocked()` es la pregunta correcta — no `masterLocked`.
260
+ //
261
+ // Se coló así: en la PRIMERA arrancada tras actualizar, la maestra todavía está guardada
262
+ // en claro (se sella al abrir el perfil), o sea que `masterLocked` es `false` aunque el
263
+ // perfil esté cerrado. Con ese guardián, la bóveda de producción admitió su llave de
264
+ // comunicación y SELLÓ UN ACTA NUEVA (#76 → #77) estando cerrada — justo lo que la regla
265
+ // prohíbe, y encima rotando de paso la llave de sellado sin que nadie lo pidiera.
266
+ if (acta && !isLocked() && !identity.masterLocked) {
256
267
  const pub = await commKey.ensure()
257
268
  const yaEsta = (acta.members || []).some((m) => m?.pub === pub)
258
269
  if (!yaEsta && info?.isMaster) {