@dotrino/vault 0.79.0 → 0.80.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotrino/vault",
3
- "version": "0.79.0",
3
+ "version": "0.80.0",
4
4
  "description": "Usa ESTE dispositivo (navegador) como bóveda/CA del ecosistema Dotrino: atiende enrolamientos por el proxy y firma certificados de delegación a tus máquinas. Incluye el cliente de SERVICIO (Node): un proyecto se enrola una vez y jala sus credenciales del vault en vez del .env (`import '@dotrino/vault/config'`).",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/admin.js CHANGED
@@ -47,6 +47,9 @@ 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
49
  'revoke', 'audit',
50
+ // Los BLOQUEADOS por un aprobador (`src/blocked.js`): verlos y desbloquearlos. Bloquear a
51
+ // distancia también, por si el administrador llega antes que el teléfono. No toca el acta.
52
+ 'blocked', 'block', 'unblock',
50
53
  // Variables de entorno: verlas (nombres siempre; valor solo de las públicas) y
51
54
  // ponerles valor (de las dos). Borrar NO está, y es a propósito: un aparato robado
52
55
  // no debe poder dejar sin configuración a los servicios.
@@ -96,6 +99,8 @@ export const ADMIN_OPS = Object.freeze([
96
99
  */
97
100
  export const ADMIN_OPS_WHILE_LOCKED = Object.freeze([
98
101
  'audit', 'vars', 'var.set', 'var.setMany', 'var.recipients',
102
+ // Bloquear no sella nada: la lista es de la bóveda, no del acta.
103
+ 'blocked', 'block', 'unblock',
99
104
  // Las dos de abrir, obviamente: son las únicas que solo tienen sentido con el candado
100
105
  // echado. Que estén aquí NO las deja pasar sin más — siguen exigiendo cert, acta, nonce
101
106
  // y frescura como todas, y además la contraseña dentro del sobre.
@@ -147,6 +152,8 @@ export function createAdminDesk ({
147
152
  // este módulo es puro a propósito. `null` en una bóveda que no lo soporte: entonces la
148
153
  // operación existe y contesta que no, en vez de romper con un TypeError.
149
154
  unlockDesk = null,
155
+ // La lista de bloqueados, inyectada como `vars`: `{ list(), set(pub, on, { by }) }`.
156
+ blocked = null,
150
157
  now = () => Date.now()
151
158
  }) {
152
159
  const ops = new Set(ADMIN_OPS)
@@ -333,6 +340,14 @@ export function createAdminDesk ({
333
340
  // usarlo para quitar dejaba un miembro sin certificados al que la bóveda ya nunca le
334
341
  // mandaba el aviso de expulsión (mientras siga en el acta, un papel retirado
335
342
  // significa «renueva»). Ese era el dispositivo fantasma.
343
+ if (data.op === 'blocked' || data.op === 'block' || data.op === 'unblock') {
344
+ if (!blocked) return { ok: false, error: 'admin: this vault cannot block devices' }
345
+ if (data.op === 'blocked') return { ok: true, result: { items: blocked.list() } }
346
+ if (typeof data.sub !== 'string' || !data.sub) return { ok: false, error: `admin: ${data.op} needs the device key (sub)` }
347
+ const r = await blocked.set(data.sub, data.op === 'block', { by })
348
+ audit(`admin.${data.op}`, { by, device: await deviceIdOf(data.sub).catch(() => null) })
349
+ return { ok: true, result: { ok: true, was: r } }
350
+ }
336
351
  if (data.op === 'revoke') {
337
352
  if (data.sub) {
338
353
  const deviceId = await deviceIdOf(String(data.sub)).catch(() => null)
package/src/protocol.js CHANGED
@@ -103,6 +103,13 @@ export const MSG = Object.freeze({
103
103
  // una forma de echar a alguien de su cuenta.
104
104
  LOGIN_CLOSE: 'vault.login.close', // aparato → vault: { data:{op,user,sid,publickey,ts}, signature }
105
105
  LOGIN_CLOSED: 'vault.login.closed', // vault → aparato: { ok }
106
+ // INCIDENTE: un agente de la cuenta (la terminal) avisa de que OTRO aparato de la cuenta
107
+ // se equivocó de clave tres veces seguidas. La bóveda lo apunta como un pedido más
108
+ // (`kind: 'incident'`), timbra a quien aprueba, y el aprobador bloquea o ignora. Bloquear
109
+ // no toca el acta: es una lista de la bóveda (`blocked.json`) que viaja a los agentes con
110
+ // `vault.devices.result` (`blocked`) y se deshace con `dotrino-vault unblock <ID>`.
111
+ INCIDENT: 'vault.incident', // agente → vault: { data:{op:'incident',kind,about,tries,publickey,ts}, signature, cert }
112
+ INCIDENT_RESULT: 'vault.incident.result', // vault → agente: { id, approvers, blocked }
106
113
  ERROR: 'vault.error' // vault → dispositivo: { error }
107
114
  })
108
115