@mblaney/holster 1.0.23 → 1.0.25

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/src/user.js CHANGED
@@ -60,8 +60,9 @@ const User = (opt, wire) => {
60
60
  const update = {
61
61
  auth: JSON.stringify({enc: enc, salt: salt}),
62
62
  }
63
- const propertySignatures = await SEA.signProperties(update, user.is)
64
- const graph = utils.graph(pub, update, propertySignatures, data.pub)
63
+ const timestamp = Date.now()
64
+ const sig = await SEA.signTimestamp(timestamp, user.is)
65
+ const graph = utils.graph(pub, update, sig, data.pub, timestamp)
65
66
  wire.put(graph, err => {
66
67
  if (err) {
67
68
  done(`error putting ${update} on ${pub}: ${err}`)
@@ -72,15 +73,14 @@ const User = (opt, wire) => {
72
73
  return
73
74
  }
74
75
 
75
- // Migrate old per-node signatures to per-property signatures
76
- // Check if data has per-property signatures
77
- if (
78
- !data._ ||
79
- !data._["s"] ||
80
- Object.keys(data._["s"]).length === 0
81
- ) {
82
- // Data has old per-node signatures, migrate to per-property
83
- // Copy all properties from existing data, excluding metadata
76
+ // Migration: broadcast signed data on login if enabled
77
+ // Can be enabled by setting localStorage.setItem("holster_migrate_signatures", "true")
78
+ const migrationEnabled =
79
+ typeof globalThis.localStorage !== "undefined" &&
80
+ globalThis.localStorage.getItem("holster_migrate_signatures") ===
81
+ "true"
82
+
83
+ if (migrationEnabled) {
84
84
  const migrationData = {}
85
85
  for (const key of Object.keys(data)) {
86
86
  if (
@@ -91,16 +91,15 @@ const User = (opt, wire) => {
91
91
  migrationData[key] = data[key]
92
92
  }
93
93
  }
94
- // Sign each property individually
95
- const propertySignatures = await SEA.signProperties(
96
- migrationData,
97
- user.is,
98
- )
94
+ // Sign the timestamp for migration
95
+ const timestamp = Date.now()
96
+ const sig = await SEA.signTimestamp(timestamp, user.is)
99
97
  const graph = utils.graph(
100
98
  pub,
101
99
  migrationData,
102
- propertySignatures,
100
+ sig,
103
101
  data.pub,
102
+ timestamp,
104
103
  )
105
104
  wire.put(graph, err => {
106
105
  if (err) {
@@ -111,10 +110,9 @@ const User = (opt, wire) => {
111
110
  }
112
111
  done(null)
113
112
  })
114
- return
113
+ } else {
114
+ done(null)
115
115
  }
116
-
117
- return done(null)
118
116
  },
119
117
  {wait: 5000},
120
118
  )
@@ -200,9 +198,10 @@ const User = (opt, wire) => {
200
198
  }
201
199
 
202
200
  const pub = "~" + pair.pub
203
- // Sign each property individually for new account
204
- const propertySignatures = await SEA.signProperties(data, pair)
205
- const graph = utils.graph(pub, data, propertySignatures, pair.pub)
201
+ // Sign the timestamp for new account
202
+ const timestamp = Date.now()
203
+ const sig = await SEA.signTimestamp(timestamp, pair)
204
+ const graph = utils.graph(pub, data, sig, pair.pub, timestamp)
206
205
  wire.put(graph, err => {
207
206
  creating = false
208
207
  if (err) {
@@ -359,10 +358,11 @@ const User = (opt, wire) => {
359
358
  }
360
359
 
361
360
  const data = {username: null, pub: null, epub: null, auth: null}
362
- // Sign each property individually for account deletion
363
- const propertySignatures = await SEA.signProperties(data, user.is)
361
+ // Sign the timestamp for account deletion
362
+ const timestamp = Date.now()
363
+ const sig = await SEA.signTimestamp(timestamp, user.is)
364
364
  const pub = "~" + user.is.pub
365
- const graph = utils.graph(pub, data, propertySignatures, user.is.pub)
365
+ const graph = utils.graph(pub, data, sig, user.is.pub, timestamp)
366
366
  wire.put(graph, err => {
367
367
  if (err) {
368
368
  ack(`error putting null on ${pub}: ${err}`)
package/src/utils.js CHANGED
@@ -80,22 +80,29 @@ export const userPublicKey = "_holster_user_public_key"
80
80
 
81
81
  // graph converts objects to graph format with updated states,
82
82
  // with optional meta data to verify signed data.
83
- export const graph = (soul, data, sig, pub) => {
84
- const timestamp = Date.now()
83
+ export const graph = (soul, data, sig, pub, timestamp) => {
85
84
  const g = {[soul]: {_: {"#": soul, ">": {}}}}
86
85
 
87
86
  for (const [key, value] of Object.entries(data)) {
88
87
  if (key !== "_" && key !== userPublicKey && key !== userSignature) {
89
88
  g[soul][key] = value
90
- g[soul]._[">"][key] = timestamp
89
+ g[soul]._[">"][key] = timestamp || Date.now()
91
90
  }
92
91
  }
93
- // Store per-property signatures in node._["s"]
94
- // sig is an object with per-property signatures
95
- if (sig && pub) {
92
+ // Store signatures in node._["s"]
93
+ // sig can be:
94
+ // - object: per-property signatures (legacy format)
95
+ // - string: timestamp signature (new format)
96
+ if (sig && pub && timestamp) {
96
97
  g[soul]._["s"] = {}
97
- for (const [key, signature] of Object.entries(sig)) {
98
- g[soul]._["s"][key] = signature
98
+ if (typeof sig === "string") {
99
+ // Timestamp signature: store with timestamp as key
100
+ g[soul]._["s"][timestamp] = sig
101
+ } else if (typeof sig === "object") {
102
+ // Per-property signatures: store with property names as keys
103
+ for (const [key, signature] of Object.entries(sig)) {
104
+ g[soul]._["s"][key] = signature
105
+ }
99
106
  }
100
107
  g[soul][userPublicKey] = pub
101
108
  g[soul]._[">"][userPublicKey] = timestamp
package/src/wire.js CHANGED
@@ -354,6 +354,9 @@ const Wire = opt => {
354
354
  const api = send => {
355
355
  return {
356
356
  get: (lex, cb, _opt) => {
357
+ if (lex && typeof lex["."] === "number") {
358
+ lex = {...lex, ".": String(lex["."])}
359
+ }
357
360
  // Mark requested soul as something we want to store
358
361
  if (lex && lex["#"]) {
359
362
  pendingReferences.add(lex["#"])
@@ -403,6 +406,9 @@ const Wire = opt => {
403
406
  }
404
407
  },
405
408
  on: (lex, cb, _get, _opt) => {
409
+ if (lex && typeof lex["."] === "number") {
410
+ lex = {...lex, ".": String(lex["."])}
411
+ }
406
412
  const soul = lex && lex["#"]
407
413
  if (!soul || !cb) return
408
414