@dotrino/identity 0.58.0 → 0.60.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/identity",
3
- "version": "0.58.0",
3
+ "version": "0.60.0",
4
4
  "description": "Identidad y rating de usuarios compartidos entre apps de Dotrino (vault iframe + postMessage)",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -56,7 +56,7 @@
56
56
  "url": "git+https://github.com/imdotrino/dotrino-identity.git"
57
57
  },
58
58
  "dependencies": {
59
- "@dotrino/proxy-client": "0.10.1"
59
+ "@dotrino/proxy-client": "^0.11.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "fake-indexeddb": "^6.2.5",
package/src/index.js CHANGED
@@ -404,6 +404,24 @@ export class Identity {
404
404
  return this._call('vaultAdmin', { op, ...(args || {}) }, 20000)
405
405
  }
406
406
 
407
+ /**
408
+ * PEDIDOS DE APROBACIÓN de la bóveda (cajones con `approval`): `op` = `approvals` ·
409
+ * `approve` · `deny` (estos dos con `{ id }`). Requiere `vault:approve` en el cert.
410
+ */
411
+ async vaultApprovals (op, args) {
412
+ return this._call('vaultApprovals', { op, ...(args || {}) }, 20000)
413
+ }
414
+
415
+ /** Registra el token de push de la app nativa (FCM/APNs) bajo la llave de este aparato. */
416
+ async registerPush (args) {
417
+ return this._call('registerPush', args || {}, 20000)
418
+ }
419
+
420
+ /** ¿El cert de este dispositivo le permite aprobar pedidos de la bóveda? */
421
+ async canApproveVault () {
422
+ return this._call('canApproveVault', {}, 20000)
423
+ }
424
+
407
425
  /** ¿El cert de este dispositivo le permite administrar el perfil a distancia? */
408
426
  async canAdminVault () {
409
427
  return this._call('canAdminVault', {}, 20000)
package/vault/core.js CHANGED
@@ -21,8 +21,8 @@
21
21
  import { signDelegationWith, MAX_DELEGATION_MS, DEFAULT_DELEGATION_MS } from './capabilities.js'
22
22
  import * as Acta from './acta.js'
23
23
  import * as Content from './content.js'
24
- import { pubkeyId as pubkeyIdOf } from './capabilities.js'
25
- import { enrollDevice as remoteEnroll, requestSign as remoteSign, requestStore as remoteStore, requestDevices as remoteDevices, requestRenew as remoteRenew, requestAdmin as remoteAdmin, requestRenounce as remoteRenounce, checkMembership as remoteCheck } from './remote.js'
24
+ import { pubkeyId as pubkeyIdOf, signWithDevice } from './capabilities.js'
25
+ import { enrollDevice as remoteEnroll, requestSign as remoteSign, requestStore as remoteStore, requestDevices as remoteDevices, requestRenew as remoteRenew, requestAdmin as remoteAdmin, requestApproval as remoteApproval, requestRenounce as remoteRenounce, checkMembership as remoteCheck } from './remote.js'
26
26
 
27
27
  export const KEY_STORAGE = 'dotrino.identity.keypair'
28
28
  export const ENC_KEY_STORAGE = 'dotrino.identity.enc-keypair'
@@ -1956,6 +1956,48 @@ export async function createIdentityCore ({ kv: rawKv, peers, makeSync = null, k
1956
1956
  catch (e) { return handleVaultError(e) }
1957
1957
  },
1958
1958
 
1959
+ /**
1960
+ * PEDIDOS DE APROBACIÓN: lo que le toca al teléfono cuando un cajón de la bóveda exige
1961
+ * el visto bueno por uso. `op`: `approvals` (listar) · `approve` · `deny` (con `id`).
1962
+ * Requiere `vault:approve` en el cert, que se concede a mano (`caps <ID> +aprueba`).
1963
+ */
1964
+ async vaultApprovals ({ op, id } = {}) {
1965
+ const v = loadVaultCert(); const device = loadVaultDevice()
1966
+ if (!v?.cert || !device) throw new Error('this device is not paired with a vault')
1967
+ maybeRenewVaultCert()
1968
+ try { return await remoteApproval({ master: v.master, proxy: v.proxy, device, cert: v.cert, op, id, onRevoked: wipeVaultLink }) }
1969
+ catch (e) { return handleVaultError(e) }
1970
+ },
1971
+
1972
+ /**
1973
+ * PUSH DE LA APP NATIVA: registra el token (FCM/APNs) de este aparato en el proxio,
1974
+ * bajo la llave del dispositivo, para que la bóveda pueda «timbrarlo» cuando haya
1975
+ * un pedido. La app nativa le pasa el token a la página; la página lo trae aquí.
1976
+ */
1977
+ async registerPush ({ kind = 'fcm', token } = {}) {
1978
+ const device = loadVaultDevice()
1979
+ if (!device) throw new Error('this device is not paired with a vault')
1980
+ if (typeof token !== 'string' || !token) throw new Error('registerPush requires a token')
1981
+ const v = loadVaultCert()
1982
+ const { WebSocketProxyClient } = await import('@dotrino/proxy-client')
1983
+ const client = new WebSocketProxyClient({ url: v?.proxy || 'wss://proxy.dotrino.com', enableWebRTC: false, autoReconnect: false })
1984
+ await client.connect()
1985
+ try {
1986
+ await client.registerPushToken({
1987
+ publicKey: device.publickey, token, kind,
1988
+ sign: async (data) => (await signWithDevice({ privateJwk: device.privateJwk, privateKey: device.privateKey, publickey: device.publickey, data })).signature
1989
+ })
1990
+ return { ok: true, kind }
1991
+ } finally { try { client.close() } catch (_) {} }
1992
+ },
1993
+
1994
+ /** ¿Puede ESTE dispositivo aprobar pedidos? Mismo criterio que `canAdminVault`. */
1995
+ async canApproveVault () {
1996
+ if (certDesfasadoDelActa()) { try { await renovarCert() } catch (_) {} }
1997
+ const v = loadVaultCert()
1998
+ return !!v?.cert && (v.cert.scope || []).includes('vault:approve')
1999
+ },
2000
+
1959
2001
  /**
1960
2002
  * ¿Puede ESTE dispositivo administrar el perfil a distancia? Sale del scope del
1961
2003
  * cert que le dio la bóveda, no de una preferencia: la interfaz pregunta para
package/vault/remote.js CHANGED
@@ -395,6 +395,21 @@ export async function requestAdmin ({ master, proxy, device, cert, op, onRevoked
395
395
  return res.result
396
396
  }
397
397
 
398
+ /**
399
+ * PEDIDOS DE APROBACIÓN (cajones con `approval`): `approvals` (listar) · `approve` ·
400
+ * `deny`. Van por `vault.secrets`, firmados por un aparato cuyo cert lleve
401
+ * `vault:approve` — que, como `admin`, no se recibe al emparejar: se concede a mano.
402
+ * La bóveda contesta un cuerpo firmado por la maestra (`{ op, items | ok }`).
403
+ */
404
+ export async function requestApproval ({ master, proxy, device, cert, op, id, onRevoked } = {}) {
405
+ const res = await vaultRpc({
406
+ master, proxy, device, cert, onRevoked,
407
+ sendType: MSG.SECRETS, okType: MSG.SECRETS_RESULT,
408
+ data: id ? { op, id } : { op }
409
+ })
410
+ return res.body
411
+ }
412
+
398
413
  /**
399
414
  * ¿Es AUTÉNTICO este `vault.admin.event` (entró o salió alguien del perfil)? Solo si va
400
415
  * firmado por la maestra PINEADA. Un aviso sin firma no se muestra: si no, cualquiera