@dotrino/geo 0.8.0 → 0.9.1

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/LICENSE CHANGED
File without changes
package/README.md CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotrino/geo",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "Dotrino geo index client (geo.dotrino.com): vault-signed georeferenced pins, radius queries (PostGIS)",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/canonical.js CHANGED
File without changes
package/src/geohash.js CHANGED
File without changes
package/src/index.d.ts CHANGED
File without changes
package/src/index.js CHANGED
@@ -45,6 +45,11 @@ export function createGeoClient ({ signData, getPublicKeyJwk, baseUrl = DEFAULT_
45
45
  const doFetch = f || (typeof fetch !== 'undefined' ? fetch.bind(globalThis) : null)
46
46
  if (!doFetch) throw new Error('dotrino-geo: no fetch available; inject it in opts.fetch')
47
47
  const base = baseUrl.replace(/\/+$/, '')
48
+ // PARA QUIÉN va lo que firmamos. Sale del `baseUrl` y no de una constante: quien
49
+ // autohospeda su índice tiene otro destinatario, y tenerlo fijo haría que un pin firmado
50
+ // para el nuestro sirviera ante el suyo — que es justo lo que el destinatario evita.
51
+ // Si el `baseUrl` no es una URL, revienta AQUÍ, al crear el cliente, y no al publicar.
52
+ const aud = new URL(base).origin
48
53
 
49
54
  /**
50
55
  * Publica (o reemplaza) el pin de esta identidad.
@@ -68,6 +73,7 @@ export function createGeoClient ({ signData, getPublicKeyJwk, baseUrl = DEFAULT_
68
73
  const ts = now ?? Date.now()
69
74
  const data = {
70
75
  publickey,
76
+ aud,
71
77
  lat: round(lat, 6),
72
78
  lng: round(lng, 6),
73
79
  geohash: encodeGeohash(lat, lng, geohashPrecision),
@@ -77,18 +83,7 @@ export function createGeoClient ({ signData, getPublicKeyJwk, baseUrl = DEFAULT_
77
83
  }
78
84
  const cleanTags = normalizeTags(tags)
79
85
  if (cleanTags.length) data.tags = cleanTags
80
- const firma = await signData(data)
81
- // Un vault viejo devuelve solo la firma; uno nuevo, el paquete con quién firmó y la
82
- // cadena que prueba que ese firmante habla por esta identidad.
83
- const sobre = typeof firma === 'string'
84
- ? { data, signature: firma }
85
- : { data, signature: firma.signature, ...(firma.publickey ? { signer: firma.publickey } : {}), ...(firma.chain?.length ? { chain: firma.chain } : {}) }
86
- const res = await doFetch(`${base}/pins`, {
87
- method: 'PUT',
88
- headers: { 'content-type': 'application/json' },
89
- body: JSON.stringify(sobre)
90
- })
91
- return handle(res)
86
+ return sendSigned('PUT', data)
92
87
  }
93
88
 
94
89
  /**
@@ -122,12 +117,26 @@ export function createGeoClient ({ signData, getPublicKeyJwk, baseUrl = DEFAULT_
122
117
  */
123
118
  async function removePin ({ now } = {}) {
124
119
  const publickey = await getPublicKeyJwk()
125
- const data = { publickey, action: 'remove', issuedAt: now ?? Date.now() }
126
- const signature = await signData(data)
120
+ const data = { publickey, aud, action: 'remove', issuedAt: now ?? Date.now() }
121
+ // MANDABA EL PAQUETE ENTERO EN `signature`. `signData` devuelve `{signature, publickey,
122
+ // chain}` desde hace versiones, y aquí se metía ese objeto donde el servidor espera la
123
+ // firma en base64: retirar un pin antes de que expirara respondía 401 siempre. Y sin la
124
+ // cadena tampoco se podía retirar el pin desde un aparato que no fuera el de la llave.
125
+ return sendSigned('DELETE', data)
126
+ }
127
+
128
+ /** Firma `data` y lo manda a /pins: el mismo sobre para publicar y para retirar. */
129
+ async function sendSigned (method, data) {
130
+ const sig = await signData(data)
131
+ // Un vault viejo devuelve solo la firma; uno nuevo, el paquete con quién firmó y la
132
+ // cadena que prueba que ese firmante habla por esta identidad.
133
+ const envelope = typeof sig === 'string'
134
+ ? { data, signature: sig }
135
+ : { data, signature: sig.signature, ...(sig.publickey ? { signer: sig.publickey } : {}), ...(sig.chain?.length ? { chain: sig.chain } : {}) }
127
136
  const res = await doFetch(`${base}/pins`, {
128
- method: 'DELETE',
137
+ method,
129
138
  headers: { 'content-type': 'application/json' },
130
- body: JSON.stringify({ data, signature })
139
+ body: JSON.stringify(envelope)
131
140
  })
132
141
  return handle(res)
133
142
  }