@dotrino/identity 0.60.0 → 0.60.2

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.60.0",
3
+ "version": "0.60.2",
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",
package/vault/remote.js CHANGED
@@ -38,6 +38,10 @@ const MSG = {
38
38
  // Renuncia: el miembro se quita capacidades a sí mismo y la bóveda la sella en el acta.
39
39
  RENOUNCE: 'vault.renounce',
40
40
  RENOUNCE_RESULT: 'vault.renounce.result',
41
+ // Pedidos de aprobación y llaves SSH del teléfono: van por el canal de secretos
42
+ // (`op: approvals | approve | deny | ssh.keys | ssh.key.add | ssh.key.rm`).
43
+ SECRETS: 'vault.secrets',
44
+ SECRETS_RESULT: 'vault.secrets.result',
41
45
  ERROR: 'vault.error'
42
46
  }
43
47
  export { MSG as VAULT_MSG }
@@ -1,2 +1 @@
1
- Copia vendorizada de @dotrino/proxy-client@0.10.0 (src/, sin dependencias).
2
- Ver dotrino-identity: el iframe se sirve estatico, transporte self-hosted (no CDN).
1
+ 0.11.0
@@ -1,6 +1,22 @@
1
1
  import { buildSignedChannel, getPublicKeyJwk, signData } from './signature.js'
2
2
  import { WebRTCManager, RTC_TAG, DEFAULT_ICE_SERVERS } from './webrtc.js'
3
3
 
4
+ /**
5
+ * Error con un `code` estable.
6
+ *
7
+ * El contrato es el CODE, no la frase: comprobar por el texto cruza procesos y
8
+ * se rompe en silencio en cuanto alguien lo reescribe o lo traduce.
9
+ *
10
+ * @param {string} mensaje
11
+ * @param {string} code
12
+ * @returns {Error & { code: string }}
13
+ */
14
+ function errorCon (mensaje, code) {
15
+ const e = /** @type {Error & { code: string }} */ (new Error(mensaje))
16
+ e.code = code
17
+ return e
18
+ }
19
+
4
20
  /**
5
21
  * Dotrino WebSocket proxy client.
6
22
  * Minimal API: connection + token + messages + channels (publish/list/count/disconnect)
@@ -84,6 +100,22 @@ export class WebSocketProxyClient {
84
100
  if (this.ws) {
85
101
  try { this.ws.close(1000) } catch (_) {}
86
102
  }
103
+ // Cerrar es una decisión de la app: lo que estuviera en vuelo ya no va a
104
+ // llegar (`close()` apaga autoReconnect, y una reconexión tampoco reenvía
105
+ // las peticiones pendientes). Sin esto, quien esperaba un `publish` se comía
106
+ // los 10 s completos del timeout para enterarse de algo que ya se sabía, y
107
+ // el temporizador mantenía vivo el proceso en Node ese rato.
108
+ this._rejectAllPending(errorCon('Connection closed', 'CONNECTION_CLOSED'))
109
+ }
110
+
111
+ /** Corta en seco todo lo que esperaba respuesta, con su motivo. */
112
+ _rejectAllPending (error) {
113
+ const pendientes = [...this._pending.values()]
114
+ this._pending.clear()
115
+ for (const entry of pendientes) {
116
+ clearTimeout(entry.timer)
117
+ entry.reject(error)
118
+ }
87
119
  }
88
120
 
89
121
  /** Alias for close() to ease migration from older clients. */
@@ -429,6 +461,20 @@ export class WebSocketProxyClient {
429
461
  return sub
430
462
  }
431
463
 
464
+ /**
465
+ * Registrar el TOKEN DE PUSH de una app nativa (FCM en Android; APNs más adelante) bajo
466
+ * esta pubkey, en vez de una PushSubscription del navegador. El proxy lo usa para el
467
+ * mismo timbre sin contenido. Firma del vault, igual que enablePush.
468
+ * @param {{ publicKey:string, sign:Function, token:string, kind?:'fcm' }} opts
469
+ */
470
+ async registerPushToken ({ publicKey, sign, token, kind = 'fcm' } = {}) {
471
+ if (!publicKey || typeof sign !== 'function' || !token) throw new Error('registerPushToken requires { publicKey, sign, token }')
472
+ const data = { op: 'push-subscribe', publickey: publicKey, subscription: JSON.stringify({ kind, token }), ts: Date.now() }
473
+ const signature = await normalizeSignature(sign, data)
474
+ await this._request({ type: 'push-subscribe', data, signature }, 'push-subscribed')
475
+ return { kind, token }
476
+ }
477
+
432
478
  /**
433
479
  * Desactivar Web Push: cancela la PushSubscription local y la borra del proxy.
434
480
  * @param {Object} opts
@@ -738,7 +784,7 @@ export class WebSocketProxyClient {
738
784
 
739
785
  _sendRaw (frame) {
740
786
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
741
- throw new Error('WebSocket not connected')
787
+ throw errorCon('WebSocket not connected', 'NOT_CONNECTED')
742
788
  }
743
789
  this.ws.send(JSON.stringify(frame))
744
790
  }
@@ -749,7 +795,7 @@ export class WebSocketProxyClient {
749
795
  const out = { ...frame, id }
750
796
  const timer = setTimeout(() => {
751
797
  this._pending.delete(id)
752
- reject(new Error(`Timeout waiting for ${expectedType}`))
798
+ reject(errorCon(`Timeout waiting for ${expectedType}`, 'REQUEST_TIMEOUT'))
753
799
  }, 10000)
754
800
  this._pending.set(id, { resolve, reject, timer, expectedType, channelKey })
755
801
  try {