@dotrino/vault 0.6.0 → 0.8.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.6.0",
3
+ "version": "0.8.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",
@@ -42,7 +42,7 @@
42
42
  "pairing"
43
43
  ],
44
44
  "peerDependencies": {
45
- "@dotrino/identity": ">=0.25.0",
45
+ "@dotrino/identity": ">=0.30.0",
46
46
  "@dotrino/proxy-client": ">=0.6.0"
47
47
  },
48
48
  "license": "MIT",
package/src/enroll.js CHANGED
@@ -50,6 +50,19 @@ const SCOPE_TO_CAP = { 'vault:sign': 'sign', 'vault:store': 'store', 'vault:read
50
50
  export const scopeToCaps = (scope) =>
51
51
  (Array.isArray(scope) ? scope : [scope]).map((s) => SCOPE_TO_CAP[s]).filter(Boolean)
52
52
 
53
+ /**
54
+ * El CN de un servicio sale de su scope: `vault:secrets:proxy` ⇒ CN `proxy`. Con CN, el
55
+ * miembro entra al acta como SERVICIO —solo abre su propio cajón— en vez de como un
56
+ * dispositivo del usuario. Es la frontera, y vive en el acta para que se pueda comprobar.
57
+ */
58
+ export function scopeToCn (scope) {
59
+ for (const s of (Array.isArray(scope) ? scope : [scope])) {
60
+ const m = /^vault:secrets:([a-z0-9-]{1,32})$/.exec(String(s || ''))
61
+ if (m) return m[1]
62
+ }
63
+ return null
64
+ }
65
+
53
66
  /** Token aleatorio de 128 bits en hex. */
54
67
  export function randToken () {
55
68
  const b = crypto.getRandomValues(new Uint8Array(16))
@@ -158,6 +171,9 @@ export function createEnrollDesk ({
158
171
  pend.dpub = d.dpub
159
172
  pend.deviceId = deviceId
160
173
  pend.commit = d.commit
174
+ // Llave de CIFRADO del dispositivo: con ella se le envuelve la clave de contenido del
175
+ // perfil al admitirlo. Sin ella entra, pero no podrá leer lo que haya guardado.
176
+ if (typeof d.encPub === 'string') pend.encPub = d.encPub
161
177
  // Certificado de continuidad (opcional): lo firma la identidad que se une, con su
162
178
  // propia llave. Se comprueba aquí y se guarda con el miembro al aprobar.
163
179
  if (d.continuity) {
@@ -212,8 +228,9 @@ export function createEnrollDesk ({
212
228
  let acta = null
213
229
  try {
214
230
  if (typeof identity.admitMember === 'function') {
215
- const caps = scopeToCaps(pend.scope)
216
- if (caps.length) await identity.admitMember({ pub: pend.dpub, label: pend.label || '', caps, cert, continuity: pend.continuity || null })
231
+ const cn = scopeToCn(pend.scope)
232
+ const caps = cn ? ['secrets'] : scopeToCaps(pend.scope)
233
+ if (caps.length) await identity.admitMember({ pub: pend.dpub, encPub: pend.encPub || null, label: pend.label || '', cn, caps, cert, continuity: pend.continuity || null })
217
234
  }
218
235
  acta = (await identity.profileActa?.())?.acta || null
219
236
  } catch (e) { log('[vault] no se pudo admitir en el acta:', e.message) }
package/src/service.js CHANGED
@@ -249,7 +249,7 @@ export async function waitForSecrets ({ dir, ns, proxyUrl, masterPubkey, device,
249
249
  } catch (e) {
250
250
  // Lo NO transitorio no se arregla reintentando: falta de enrolamiento,
251
251
  // cert revocado/vencido o scope equivocado exigen re-emparejar → se corta.
252
- if (/sin enrolar|ns inválido|no autorizado: (revoked|expired|scope|untrusted-issuer|cert-device-mismatch)/.test(e.message)) throw e
252
+ if (/sin enrolar|ns inválido|no autorizado: (revoked|expired|scope|cn|untrusted-issuer|cert-device-mismatch)/.test(e.message)) throw e
253
253
  try { onRetry?.(e, delay) } catch (_) {}
254
254
  await new Promise((r) => setTimeout(r, delay))
255
255
  delay = Math.min(maxRetryMs, Math.round(delay * 1.6))