@mblaney/holster 1.0.28 → 1.0.29

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": "@mblaney/holster",
3
- "version": "1.0.28",
3
+ "version": "1.0.29",
4
4
  "description": "Holster is a service that allows synchronising data between devices using Node, Deno, Bun or the browser.",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/src/get.js CHANGED
@@ -32,6 +32,20 @@ const Get = (lex, graph) => {
32
32
  signatures[key] = graph[soul]._["s"][key]
33
33
  }
34
34
  }
35
+
36
+ // Always include userPublicKey for verification, regardless of filter
37
+ if (userPublicKey && typeof graph[soul][userPublicKey] !== "undefined") {
38
+ node[userPublicKey] = graph[soul][userPublicKey]
39
+ node._[">"][userPublicKey] = graph[soul]._[">"][userPublicKey]
40
+ const pkState = graph[soul]._[">"][userPublicKey]
41
+ if (graph[soul]._["s"]) {
42
+ if (graph[soul]._["s"][pkState]) {
43
+ signatures[pkState] = graph[soul]._["s"][pkState]
44
+ } else if (graph[soul]._["s"][userPublicKey]) {
45
+ signatures[userPublicKey] = graph[soul]._["s"][userPublicKey]
46
+ }
47
+ }
48
+ }
35
49
  } else {
36
50
  for (const key of Object.keys(graph[soul])) {
37
51
  // Always include userPublicKey for verification, regardless of filter
package/src/ham.js CHANGED
@@ -130,9 +130,6 @@ Ham.mix = async (change, graph, secure, listen) => {
130
130
  for (const key of Object.keys(node)) {
131
131
  if (key === "_") continue
132
132
 
133
- // Skip metadata fields (including userSignature for old data)
134
- if (key === utils.userSignature || key === utils.userPublicKey) continue
135
-
136
133
  // Properties without signatures in this update are left unchanged
137
134
  if (validProperties.has(soul) && !validProperties.get(soul).has(key)) {
138
135
  continue
package/src/holster.js CHANGED
@@ -522,8 +522,8 @@ const Holster = opt => {
522
522
  }
523
523
 
524
524
  // The nested objects created above will also have rels on the
525
- // parent object, so fetch the node so that the rest of the updates
526
- // can be added.
525
+ // parent object, so fetch the node so that the rest of the
526
+ // updates can be added.
527
527
  wire.get({"#": id}, async msg => {
528
528
  if (msg.err) {
529
529
  _ack(`error getting ${id}: ${msg.err}`)
package/src/wire.js CHANGED
@@ -197,46 +197,6 @@ const Wire = opt => {
197
197
  const rateLimiter = createRateLimiter(isTestEnv)
198
198
  const connectionManager = createConnectionManager(opt.maxConnections || 1000)
199
199
 
200
- // The check function is required because user data must provide a public key
201
- // so that it can be verified. The public key might verify the provided
202
- // signature but not actually match the user under which the data is being
203
- // stored. To avoid this, the current data on a soul needs to be checked to
204
- // make sure the stored public key matches the one provided with the update.
205
- const check = async (data, send, cb) => {
206
- for (const soul of Object.keys(data)) {
207
- const msg = await new Promise(res => {
208
- getWithCallback({"#": soul}, res, send)
209
- })
210
- if (msg.err) {
211
- if (cb) cb(msg.err)
212
- return false
213
- }
214
-
215
- const node = data[soul]
216
- const key = utils.userPublicKey
217
- // If there is no current node then the data is ok to write without
218
- // matching public keys, as the provided soul also needs a rel on the
219
- // parent node which then also requires checking. Otherwise publc keys
220
- // need to match for existing data.
221
- if (!msg.put || !msg.put[soul] || msg.put[soul][key] === node[key]) {
222
- continue
223
- }
224
-
225
- // If a soul exists but does not have a public key, then one should not be
226
- // added because the node is not user data. The above check fails in this
227
- // case if a public key is provided. Note that this is only an error case
228
- // if called via the API, which is when a callback is provided here.
229
- // (The wire spec can fetch and put data on the wire without a signature
230
- // or public key and this can be ignored.)
231
- if (cb) {
232
- cb(`error in wire check public key does not match for soul: ${soul}`)
233
- }
234
- return false
235
- }
236
-
237
- return true
238
- }
239
-
240
200
  const get = (msg, send) => {
241
201
  const ack = Get(msg.get, graph)
242
202
  if (ack) {
@@ -248,16 +208,22 @@ const Wire = opt => {
248
208
  }),
249
209
  )
250
210
  } else {
251
- store.get(msg.get, (err, ack) => {
252
- send(
253
- JSON.stringify({
254
- "#": dup.track(utils.text.random(9)),
255
- "@": msg["#"],
256
- put: ack,
257
- err: err,
258
- }),
259
- )
260
- })
211
+ // Always pass secure to ensure public key is fetched. User data may be
212
+ // requested that requires the public key for verification.
213
+ store.get(
214
+ msg.get,
215
+ (err, ack) => {
216
+ send(
217
+ JSON.stringify({
218
+ "#": dup.track(utils.text.random(9)),
219
+ "@": msg["#"],
220
+ put: ack,
221
+ err: err,
222
+ }),
223
+ )
224
+ },
225
+ {secure: true},
226
+ )
261
227
  }
262
228
  }
263
229
 
@@ -275,8 +241,6 @@ const Wire = opt => {
275
241
  return
276
242
  }
277
243
 
278
- if (!(await check(update.now, send))) return
279
-
280
244
  store.put(update.now, err => {
281
245
  send(
282
246
  JSON.stringify({
@@ -378,8 +342,6 @@ const Wire = opt => {
378
342
  return
379
343
  }
380
344
 
381
- if (!(await check(update.now, send, cb))) return
382
-
383
345
  // Seed pendingReferences with any new references from API calls
384
346
  for (const [soul, node] of Object.entries(update.now)) {
385
347
  if (node && typeof node === "object") {