@dotrino/vault 0.40.0 → 0.42.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.40.0",
3
+ "version": "0.42.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",
@@ -47,7 +47,7 @@
47
47
  "pairing"
48
48
  ],
49
49
  "peerDependencies": {
50
- "@dotrino/identity": ">=0.65.0",
50
+ "@dotrino/identity": ">=0.67.0",
51
51
  "@dotrino/proxy-client": ">=0.13.0"
52
52
  },
53
53
  "license": "MIT",
package/src/enroll.js CHANGED
@@ -30,7 +30,7 @@
30
30
  * `docs/pairing-protocol.md`).
31
31
  */
32
32
  import { verifyDeviceSig, pubkeyId, commitCode } from '@dotrino/identity/capabilities'
33
- import { verifyContinuity } from '@dotrino/identity/acta'
33
+ import { verifyContinuity, canSeal } from '@dotrino/identity/acta'
34
34
 
35
35
  /** Un token de emparejamiento vale 5 min. */
36
36
  export const PAIRING_TTL_MS = 5 * 60 * 1000
@@ -388,9 +388,12 @@ export function createEnrollDesk ({
388
388
  const pend = [...pending.values()].find((x) => x.state === 'AWAITING_ACTA' && (x.from === from || x.dpub))
389
389
  if (!pend) return reply(from, { type: MSG_ERROR, error: 'no adoption awaiting a record' })
390
390
  if (!record || typeof record !== 'object') return reply(from, { type: MSG_ERROR, error: 'record missing or unreadable' })
391
- if (record.sealer !== iss) {
391
+ // Ya no hay campo `sealer`: se le pregunta al PERMISO. Es la misma comprobación —«¿me
392
+ // nombra a mí la que me mandan?»— dicha en el idioma nuevo, y con varios selladores la
393
+ // respuesta puede ser que sí para más de uno, que es lo correcto.
394
+ if (!canSeal(record, iss)) {
392
395
  audit('rejected', { what: 'adopt', reason: 'not-sealer' })
393
- return reply(from, { type: MSG_ERROR, error: 'that record does not name this vault as the sealer' })
396
+ return reply(from, { type: MSG_ERROR, error: 'that record does not let this vault seal it' })
394
397
  }
395
398
  if (record.sealedBy !== pend.dpub) {
396
399
  audit('rejected', { what: 'adopt', reason: 'sealed-by-other' })
package/src/index.js CHANGED
@@ -26,7 +26,7 @@
26
26
  * No reimplementa nada del ecosistema.
27
27
  */
28
28
  import { verifyChain, verifyDeviceSig } from '@dotrino/identity/capabilities'
29
- import { memberCanSign } from '@dotrino/identity/acta'
29
+ import { memberCanScope } from '@dotrino/identity/acta'
30
30
  import { createEnrollDesk, deviceIdOf, DEVICE_TTL_MS, FRESH_WINDOW_MS } from './enroll.js'
31
31
  // Las constantes del protocolo salen del MISMO módulo que usa el daemon: si la lista
32
32
  // local se queda corta, el dispositivo deja de handle mensajes sin que nadie lo note.
@@ -195,6 +195,17 @@ export async function startDeviceVault (identity, { proxyUrl, client: injectedCl
195
195
  send(from, { type: MSG.ERROR, error: 'unauthorized: ' + chk.reason })
196
196
  return null
197
197
  }
198
+ // EL ACTA MANDA, EL PAPEL SOLO ACOMPAÑA. Aquí y no en cada mostrador: el certificado
199
+ // dice a qué se comprometió esta bóveda al conectar el aparato, y el acta lo que puede
200
+ // HOY. Quitarle un permiso sella el acta pero no le retira el papel, que vive hasta 30
201
+ // días, así que sin esto seguiría entrando hasta que lo renovara.
202
+ if (expectedScope) {
203
+ const record = (await identity.profileActa?.().catch(() => null))?.acta || null
204
+ if (record && !memberCanScope(record, chk.device, expectedScope)) {
205
+ send(from, { type: MSG.ERROR, error: 'unauthorized: acta — this member no longer has that permission' })
206
+ return null
207
+ }
208
+ }
198
209
  return chk
199
210
  }
200
211
 
@@ -206,14 +217,6 @@ export async function startDeviceVault (identity, { proxyUrl, client: injectedCl
206
217
  async function handleSign (from, p) {
207
218
  const chk = await authorise(from, p, SCOPE.SIGN)
208
219
  if (!chk) return
209
- // MANDA EL ACTA, NO EL PAPEL. `authorise` mira el certificado, y quitarle `firma` a un
210
- // aparato NO reemite ni revoca su cert: seguiría diciendo `vault:sign` hasta 30 días.
211
- // Sin esto, retirarle el permiso lo cambiaba de firmar él a que firmara la bóveda por
212
- // él — o sea, no se lo retiraba. Mismo arreglo que en el daemon (`src/vault.js`).
213
- const record = (await identity.profileActa?.().catch(() => null))?.acta || null
214
- if (record && !memberCanSign(record, chk.device)) {
215
- return send(from, { type: MSG.ERROR, error: 'unauthorized: acta — this member does not sign' })
216
- }
217
220
  const toSign = p.data?.payload
218
221
  if (toSign == null) return send(from, { type: MSG.ERROR, error: 'data.payload required' })
219
222
  const { signature, publickey } = await identity.signData(toSign)