braid-text 0.2.52 → 0.2.54
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/index.js +21 -5
- package/package.json +1 -1
- package/simpleton-client.js +16 -4
- package/test/test.html +50 -0
package/index.js
CHANGED
|
@@ -114,7 +114,7 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
114
114
|
res.setHeader("Current-Version", get_current_version())
|
|
115
115
|
res.setHeader("Version", ascii_ify(x.version.map((x) => JSON.stringify(x)).join(", ")))
|
|
116
116
|
var buffer = Buffer.from(x.body, "utf8")
|
|
117
|
-
res.setHeader("Repr-Digest",
|
|
117
|
+
res.setHeader("Repr-Digest", get_digest(buffer))
|
|
118
118
|
res.setHeader("Content-Length", buffer.length)
|
|
119
119
|
return my_end(200, req.method === "HEAD" ? null : buffer)
|
|
120
120
|
}
|
|
@@ -136,10 +136,8 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
136
136
|
|
|
137
137
|
// this is a sanity/rhobustness check..
|
|
138
138
|
// ..this digest is checked on the client..
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
x["Repr-Digest"] = `sha-256=:${require('crypto').createHash('sha256').update(Buffer.from(resource.val, "utf8")).digest('base64')}:`
|
|
142
|
-
}
|
|
139
|
+
if (x.version && v_eq(x.version, resource.version))
|
|
140
|
+
x["Repr-Digest"] = get_digest(resource.val)
|
|
143
141
|
|
|
144
142
|
res.sendVersion(x)
|
|
145
143
|
},
|
|
@@ -211,6 +209,19 @@ braid_text.serve = async (req, res, options = {}) => {
|
|
|
211
209
|
|
|
212
210
|
var {change_count} = await braid_text.put(resource, { peer, version: req.version, parents: req.parents, patches, body, merge_type })
|
|
213
211
|
|
|
212
|
+
// if Repr-Digest is set,
|
|
213
|
+
// and the request version is also our new current version,
|
|
214
|
+
// then verify the digest..
|
|
215
|
+
if (req.headers['repr-digest'] &&
|
|
216
|
+
v_eq(req.version, resource.version) &&
|
|
217
|
+
req.headers['repr-digest'] !== get_digest(resource.val)) {
|
|
218
|
+
console.log(`repr-digest mismatch!`)
|
|
219
|
+
|
|
220
|
+
// we return a special 550 error code,
|
|
221
|
+
// which simpleton will pick up on to stop retrying
|
|
222
|
+
return done_my_turn(550, "repr-digest mismatch!")
|
|
223
|
+
}
|
|
224
|
+
|
|
214
225
|
if (req.version) got_event(options.key, req.version[0], change_count)
|
|
215
226
|
|
|
216
227
|
res.setHeader("Version", get_current_version())
|
|
@@ -2098,6 +2109,11 @@ function sorted_set_delete(arr, val) {
|
|
|
2098
2109
|
if (arr[i] === val) arr.splice(i, 1)
|
|
2099
2110
|
}
|
|
2100
2111
|
|
|
2112
|
+
function get_digest(s) {
|
|
2113
|
+
if (typeof s === 'string') s = Buffer.from(s, "utf8")
|
|
2114
|
+
return `sha-256=:${require('crypto').createHash('sha256').update(s).digest('base64')}:`
|
|
2115
|
+
}
|
|
2116
|
+
|
|
2101
2117
|
braid_text.get_resource = get_resource
|
|
2102
2118
|
|
|
2103
2119
|
braid_text.encode_filename = encode_filename
|
package/package.json
CHANGED
package/simpleton-client.js
CHANGED
|
@@ -115,8 +115,12 @@ function simpleton_client(url, {
|
|
|
115
115
|
if (update.extra_headers &&
|
|
116
116
|
update.extra_headers["repr-digest"] &&
|
|
117
117
|
update.extra_headers["repr-digest"].startsWith('sha-256=') &&
|
|
118
|
-
update.extra_headers["repr-digest"] !==
|
|
118
|
+
update.extra_headers["repr-digest"] !== await get_digest(prev_state)) {
|
|
119
|
+
console.log('repr-digest mismatch!')
|
|
120
|
+
console.log('repr-digest: ' + update.extra_headers["repr-digest"])
|
|
121
|
+
console.log('state: ' + prev_state)
|
|
119
122
|
throw new Error('repr-digest mismatch')
|
|
123
|
+
}
|
|
120
124
|
|
|
121
125
|
if (on_state) on_state(prev_state)
|
|
122
126
|
}
|
|
@@ -174,10 +178,13 @@ function simpleton_client(url, {
|
|
|
174
178
|
outstanding_changes++
|
|
175
179
|
try {
|
|
176
180
|
var r = await braid_fetch(url, {
|
|
177
|
-
headers: {
|
|
178
|
-
|
|
181
|
+
headers: {
|
|
182
|
+
"Merge-Type": "simpleton",
|
|
183
|
+
"Repr-Digest": await get_digest(prev_state),
|
|
184
|
+
...(content_type ? {"Content-Type": content_type} : {})
|
|
185
|
+
},
|
|
179
186
|
method: "PUT",
|
|
180
|
-
retry: () =>
|
|
187
|
+
retry: (res) => res.status !== 550,
|
|
181
188
|
version, parents, patches,
|
|
182
189
|
peer
|
|
183
190
|
})
|
|
@@ -228,4 +235,9 @@ function simpleton_client(url, {
|
|
|
228
235
|
}
|
|
229
236
|
return state
|
|
230
237
|
}
|
|
238
|
+
|
|
239
|
+
async function get_digest(s) {
|
|
240
|
+
var bytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s))
|
|
241
|
+
return `sha-256=:${btoa(String.fromCharCode(...new Uint8Array(bytes)))}:`
|
|
242
|
+
}
|
|
231
243
|
}
|
package/test/test.html
CHANGED
|
@@ -96,6 +96,56 @@ async function runTest(testName, testFunction, expectedResult) {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
runTest(
|
|
100
|
+
"test PUT digest (good)",
|
|
101
|
+
async () => {
|
|
102
|
+
let key = 'test-' + Math.random().toString(36).slice(2)
|
|
103
|
+
|
|
104
|
+
async function get_digest(s) {
|
|
105
|
+
var bytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s))
|
|
106
|
+
return `sha-256=:${btoa(String.fromCharCode(...new Uint8Array(bytes)))}:`
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let r = await braid_fetch(`/${key}`, {
|
|
110
|
+
method: 'PUT',
|
|
111
|
+
version: ['hi-1'],
|
|
112
|
+
parents: [],
|
|
113
|
+
body: 'xx',
|
|
114
|
+
headers: {
|
|
115
|
+
'Repr-Digest': await get_digest('xx')
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
if (!r.ok) return 'got: ' + r.status
|
|
119
|
+
return 'ok'
|
|
120
|
+
},
|
|
121
|
+
'ok'
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
runTest(
|
|
125
|
+
"test PUT digest (bad)",
|
|
126
|
+
async () => {
|
|
127
|
+
let key = 'test-' + Math.random().toString(36).slice(2)
|
|
128
|
+
|
|
129
|
+
async function get_digest(s) {
|
|
130
|
+
var bytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(s))
|
|
131
|
+
return `sha-256=:${btoa(String.fromCharCode(...new Uint8Array(bytes)))}:`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
let r = await braid_fetch(`/${key}`, {
|
|
135
|
+
method: 'PUT',
|
|
136
|
+
version: ['hi-1'],
|
|
137
|
+
parents: [],
|
|
138
|
+
body: 'xx',
|
|
139
|
+
headers: {
|
|
140
|
+
'Repr-Digest': await get_digest('yy')
|
|
141
|
+
}
|
|
142
|
+
})
|
|
143
|
+
if (!r.ok) return 'got: ' + r.status
|
|
144
|
+
return 'ok'
|
|
145
|
+
},
|
|
146
|
+
'got: 550'
|
|
147
|
+
)
|
|
148
|
+
|
|
99
149
|
runTest(
|
|
100
150
|
"test subscribing and verifying digests [simpleton]",
|
|
101
151
|
async () => {
|