git ssb

1+

Dominic / secure-scuttlebutt



Tree: 7d1179b29f604c4ca98619d4d66822474f29955f

Files: 7d1179b29f604c4ca98619d4d66822474f29955f / util.js

4898 bytesRaw
1var Map = require('pull-stream/throughs/map')
2
3// opts standardized to work like levelup api
4function stdopts (opts) {
5 opts = opts || {}
6 opts.keys = opts.keys !== false // default keys to true
7 opts.values = opts.values !== false // default values to true
8 return opts
9}
10
11function msgFmt (keys, values, obj) {
12 if (keys && values) { return obj }
13 if (keys) { return obj.key }
14 if (values) { return obj.value }
15 return null // i guess?
16}
17
18exports.options = stdopts
19exports.format = msgFmt
20
21exports.lo = null
22exports.hi = undefined
23
24exports.wait = function () {
25 var waiting = []
26 var value
27 return {
28 get: function () { return value },
29 set: function (_value) {
30 value = _value
31
32 var l = waiting.length
33 for (var i = 0; i < l; ++i) { waiting[i](null, value) }
34 waiting = waiting.slice(l)
35 },
36 wait: function (cb) {
37 if (value !== undefined) cb(null, value)
38 else waiting.push(cb)
39 }
40 }
41}
42
43/**
44 * Remove metadata from a message value and replace it with the original
45 * content (if any) found in `value.meta.original`. This also deletes the
46 * deprecated `value.private` and such, which still exists for backward-compat.
47 *
48 * @param {object} data - `value` property from message object
49 *
50 * @todo Delete unboxer metadata, which exists for backward-compatibility.
51 *
52 * @returns {object} the original message value, extracted from `value.meta.original`
53 */
54const originalValue = exports.originalValue = function (value) {
55 var copy = {}
56
57 for (let key in value) {
58 if (key !== 'meta' && key !== 'cyphertext' && key !== 'private' && key !== 'unbox') {
59 copy[key] = value[key]
60 }
61 }
62
63 if (value.meta && value.meta.original) {
64 for (let key in value.meta.original) {
65 copy[key] = value.meta.original[key]
66 }
67 }
68
69 return copy
70}
71
72/**
73 * Remove metadata from messages and return *only* the original message, ready
74 * for replication or cryptographic verification.
75 *
76 * @param {object} data - message object with `key` and `value` properties
77 *
78 * @returns {object} the original data, extracted from `data.value.meta.original`
79 */
80var originalData = exports.originalData = function (data) {
81 data.value = originalValue(data.value)
82 return data
83}
84
85/**
86 * Used to make modifications to values during streams, which is dependent on
87 * the `isOriginal` param. If `isOriginal` is truthy, then it passes each `msg`
88 * to `originalData()` and each `msg.value` to `originalValue()`.
89 *
90 * Usually `isOriginal` will be falsy, but if you need to hash or replicate the
91 * value from the stream then you should make sure that `isOriginal` is set to
92 * true. For example, most of the time you want private messages to be unboxed
93 * (decrypted), but if you're replicating those values to another peer then
94 * it's important to make sure that `isOriginal` is truthy.
95 *
96 * @param {boolean} keys - whether keys will be passed through the stream
97 * @param {boolean} values - whether values will be passed through the stream
98 * @param {boolean} isOriginal - whether you want *only* the original data
99 *
100 * @returns {function} a function that can be used to map over a stream
101 */
102exports.Format = exports.formatStream = function (keys, values, isPrivate) {
103 let extract
104
105 if (isPrivate === true) {
106 extract = data => {
107 return keys && values
108 ? data.value
109 : keys
110 ? data.value.key
111 : data.value.value
112 }
113 } else {
114 extract = data => {
115 return keys && values
116 ? originalData(data.value)
117 : keys
118 ? data.value.key
119 : originalValue(data.value.value)
120 }
121 }
122
123 return Map(function (data) {
124 if (data.sync) return data
125 return extract(data)
126 })
127}
128
129/**
130 * Backs up a value from `msg.value` to `msg.value.meta.original` in a simple
131 * and idiomatic way. This works regardless of whether `msg.value.meta` exists
132 * and should be used any time values are modified with `addMap()`.
133 *
134 * @param {object} msgValue - the `value` property of a message (usually `msg.value`)
135 * @param {string} property - name property that should be backed up
136 *
137 * @example
138 * metaBackup({ type: 'post', content: 'hello world', 'content')
139 * // => { meta: { original: { content: 'hello world' } } }
140 *
141 * @example
142 * var msg = { value: { type: 'post', content: 'bar' } }
143 * msg.value.meta = metaBackup(msg.value, 'content')
144 * msg.value.content = 'foo was here'
145 * msg.value.meta.original.content // => 'bar'
146 *
147 * @return {object} a `meta` object with the property backed up.
148 */
149exports.metaBackup = (msgValue, property) => {
150 const original = { [property]: msgValue[property] }
151
152 if (!msgValue.meta) {
153 msgValue.meta = { original }
154 } else if (!msgValue.meta.original) {
155 msgValue.meta.original = original
156 } else if (!msgValue.meta.original[property]) {
157 msgValue.meta.original[property] = original[property]
158 }
159
160 return msgValue.meta
161}
162

Built with git-ssb-web