autopass 3.1.5 → 3.3.0
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/README.md +1 -1
- package/example-password.mjs +34 -0
- package/index.js +36 -9
- package/package.json +3 -2
- package/schema.js +19 -4
- package/spec/db/db.json +14 -0
- package/spec/db/index.js +102 -57
- package/spec/db/messages.js +68 -18
- package/spec/hyperdispatch/index.js +7 -27
- package/spec/hyperdispatch/messages.js +40 -3
- package/spec/schema/index.js +40 -3
- package/spec/schema/schema.json +34 -2
- package/test.js +77 -8
package/README.md
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import BlindEncryptionSodium from 'blind-encryption-sodium'
|
|
2
|
+
import Autopass from './index.js'
|
|
3
|
+
import Corestore from 'corestore'
|
|
4
|
+
import process from 'process'
|
|
5
|
+
import b4a from 'b4a'
|
|
6
|
+
const store = new Corestore('example/' + process.argv[2])
|
|
7
|
+
|
|
8
|
+
let pass = null
|
|
9
|
+
|
|
10
|
+
const password = b4a.alloc(32, 'password')
|
|
11
|
+
|
|
12
|
+
if (process.argv[3]) {
|
|
13
|
+
const pair = Autopass.pair(store, process.argv[3], {
|
|
14
|
+
blindEncryption: new BlindEncryptionSodium(password)
|
|
15
|
+
})
|
|
16
|
+
pass = await pair.finished()
|
|
17
|
+
} else {
|
|
18
|
+
pass = new Autopass(store, {
|
|
19
|
+
blindEncryption: new BlindEncryptionSodium(password)
|
|
20
|
+
})
|
|
21
|
+
await pass.ready()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (pass.base.writable) {
|
|
25
|
+
const inv = await pass.createInvite()
|
|
26
|
+
console.log('invite', inv)
|
|
27
|
+
}
|
|
28
|
+
onupdate()
|
|
29
|
+
pass.on('update', onupdate)
|
|
30
|
+
|
|
31
|
+
function onupdate() {
|
|
32
|
+
console.log('db changed, all entries:')
|
|
33
|
+
pass.list().on('data', console.log)
|
|
34
|
+
}
|
package/index.js
CHANGED
|
@@ -28,6 +28,7 @@ class AutopassPairer extends ReadyResource {
|
|
|
28
28
|
this.onreject = null
|
|
29
29
|
this.pass = null
|
|
30
30
|
this.relayThrough = opts.relayThrough || null
|
|
31
|
+
this.blindEncryption = opts.blindEncryption || null
|
|
31
32
|
|
|
32
33
|
this.ready().catch(noop)
|
|
33
34
|
}
|
|
@@ -63,19 +64,33 @@ class AutopassPairer extends ReadyResource {
|
|
|
63
64
|
key: result.key,
|
|
64
65
|
wakeup: this.wakeup,
|
|
65
66
|
encryptionKey: result.encryptionKey,
|
|
66
|
-
bootstrap: this.bootstrap
|
|
67
|
+
bootstrap: this.bootstrap,
|
|
68
|
+
blindEncryption: this.blindEncryption
|
|
67
69
|
})
|
|
68
70
|
|
|
69
71
|
await this.pass.deleteInvite()
|
|
70
72
|
}
|
|
73
|
+
const readOnly = JSON.parse(result.data.toString()).readOnly
|
|
71
74
|
this.swarm = null
|
|
72
75
|
this.store = null
|
|
73
|
-
if (this.onresolve)
|
|
76
|
+
if (this.onresolve && readOnly) {
|
|
77
|
+
this._whenReadable()
|
|
78
|
+
} else if (this.onresolve) {
|
|
79
|
+
this._whenWritable()
|
|
80
|
+
}
|
|
74
81
|
this.candidate.close().catch(noop)
|
|
75
82
|
}
|
|
76
83
|
})
|
|
77
84
|
}
|
|
78
85
|
|
|
86
|
+
_whenReadable() {
|
|
87
|
+
const check = () => {
|
|
88
|
+
this.pass.base.off('update', check)
|
|
89
|
+
this.onresolve(this.pass)
|
|
90
|
+
}
|
|
91
|
+
this.pass.base.on('update', check)
|
|
92
|
+
}
|
|
93
|
+
|
|
79
94
|
_whenWritable() {
|
|
80
95
|
if (this.pass.base.writable) return
|
|
81
96
|
const check = () => {
|
|
@@ -171,12 +186,13 @@ class Autopass extends ReadyResource {
|
|
|
171
186
|
|
|
172
187
|
// Initialize autobase
|
|
173
188
|
_boot(opts = {}) {
|
|
174
|
-
const { encryptionKey, key, wakeup } = opts
|
|
189
|
+
const { encryptionKey, key, wakeup, blindEncryption } = opts
|
|
175
190
|
|
|
176
191
|
this.base = new Autobase(this.store, key, {
|
|
177
192
|
wakeup,
|
|
178
193
|
encrypt: true,
|
|
179
194
|
encryptionKey,
|
|
195
|
+
blindEncryption,
|
|
180
196
|
open(store) {
|
|
181
197
|
return HyperDB.bee(store.get('view'), db, {
|
|
182
198
|
extension: false,
|
|
@@ -235,16 +251,23 @@ class Autopass extends ReadyResource {
|
|
|
235
251
|
|
|
236
252
|
async createInvite(opts) {
|
|
237
253
|
if (this.opened === false) await this.ready()
|
|
254
|
+
const readOnly = opts?.readOnly ? true : false
|
|
238
255
|
const existing = await this.base.view.findOne('@autopass/invite', {})
|
|
239
|
-
|
|
256
|
+
|
|
257
|
+
if (existing && existing.readOnly !== readOnly) {
|
|
258
|
+
await this.deleteInvite()
|
|
259
|
+
} else if (existing) {
|
|
240
260
|
if (this.member) await this.member.flushed()
|
|
241
261
|
return z32.encode(existing.invite)
|
|
242
262
|
}
|
|
243
|
-
const { id, invite, publicKey, expires } = BlindPairing.createInvite(
|
|
244
|
-
this.base.key
|
|
263
|
+
const { id, invite, publicKey, expires, additional } = BlindPairing.createInvite(
|
|
264
|
+
this.base.key,
|
|
265
|
+
{
|
|
266
|
+
data: Buffer.from(JSON.stringify({ readOnly }))
|
|
267
|
+
}
|
|
245
268
|
)
|
|
246
269
|
|
|
247
|
-
const record = { id, invite, publicKey, expires }
|
|
270
|
+
const record = { id, invite, publicKey, expires, readOnly, additional }
|
|
248
271
|
await this.base.append(encode('@autopass/add-invite', record))
|
|
249
272
|
if (this.member) await this.member.flushed()
|
|
250
273
|
return z32.encode(record.invite)
|
|
@@ -312,11 +335,15 @@ class Autopass extends ReadyResource {
|
|
|
312
335
|
if (inv === null || !b4a.equals(inv.id, id)) {
|
|
313
336
|
return
|
|
314
337
|
}
|
|
338
|
+
const readOnly = inv.readOnly
|
|
315
339
|
candidate.open(inv.publicKey)
|
|
316
|
-
|
|
340
|
+
if (!readOnly) {
|
|
341
|
+
await this.addWriter(candidate.userData)
|
|
342
|
+
}
|
|
317
343
|
candidate.confirm({
|
|
318
344
|
key: this.base.key,
|
|
319
|
-
encryptionKey: this.base.encryptionKey
|
|
345
|
+
encryptionKey: this.base.encryptionKey,
|
|
346
|
+
additional: inv.additional
|
|
320
347
|
})
|
|
321
348
|
await this.deleteInvite()
|
|
322
349
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autopass",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"brittle": "npx brittle test.js",
|
|
@@ -26,12 +26,13 @@
|
|
|
26
26
|
"brittle": "^3.19.0",
|
|
27
27
|
"hyperdht": "^6.23.0",
|
|
28
28
|
"prettier": "^3.6.2",
|
|
29
|
-
"prettier-config-holepunch": "^
|
|
29
|
+
"prettier-config-holepunch": "^2.0.0",
|
|
30
30
|
"test-tmp": "^1.4.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"autobase": "^7.19.4",
|
|
34
34
|
"b4a": "^1.7.1",
|
|
35
|
+
"blind-encryption-sodium": "^1.0.2",
|
|
35
36
|
"blind-pairing": "^2.3.1",
|
|
36
37
|
"blind-peering": "^1.13.0",
|
|
37
38
|
"corestore": "^7.4.7",
|
package/schema.js
CHANGED
|
@@ -62,6 +62,14 @@ template.register({
|
|
|
62
62
|
]
|
|
63
63
|
})
|
|
64
64
|
|
|
65
|
+
template.register({
|
|
66
|
+
name: 'additional-invite-data',
|
|
67
|
+
fields: [
|
|
68
|
+
{ name: 'data', type: 'buffer', required: true },
|
|
69
|
+
{ name: 'signature', type: 'buffer', required: true }
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
|
|
65
73
|
template.register({
|
|
66
74
|
name: 'invite',
|
|
67
75
|
compact: false,
|
|
@@ -85,6 +93,16 @@ template.register({
|
|
|
85
93
|
name: 'expires',
|
|
86
94
|
type: 'int',
|
|
87
95
|
required: true
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'readOnly',
|
|
99
|
+
type: 'bool',
|
|
100
|
+
required: true
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'additional',
|
|
104
|
+
type: '@autopass/additional-invite-data',
|
|
105
|
+
required: false
|
|
88
106
|
}
|
|
89
107
|
]
|
|
90
108
|
})
|
|
@@ -159,10 +177,7 @@ blobs.collections.register({
|
|
|
159
177
|
})
|
|
160
178
|
HyperdbBuilder.toDisk(dbTemplate)
|
|
161
179
|
|
|
162
|
-
const hyperdispatch = Hyperdispatch.from(
|
|
163
|
-
'./spec/schema',
|
|
164
|
-
'./spec/hyperdispatch'
|
|
165
|
-
)
|
|
180
|
+
const hyperdispatch = Hyperdispatch.from('./spec/schema', './spec/hyperdispatch')
|
|
166
181
|
const namespace = hyperdispatch.namespace('autopass')
|
|
167
182
|
namespace.register({
|
|
168
183
|
name: 'remove-writer',
|
package/spec/db/db.json
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
"namespace": "autopass",
|
|
8
8
|
"id": 0,
|
|
9
9
|
"type": 1,
|
|
10
|
+
"version": 0,
|
|
11
|
+
"versionField": null,
|
|
10
12
|
"indexes": [],
|
|
11
13
|
"schema": "@autopass/records",
|
|
12
14
|
"derived": false,
|
|
@@ -18,6 +20,8 @@
|
|
|
18
20
|
"namespace": "autopass",
|
|
19
21
|
"id": 1,
|
|
20
22
|
"type": 1,
|
|
23
|
+
"version": 0,
|
|
24
|
+
"versionField": null,
|
|
21
25
|
"indexes": [],
|
|
22
26
|
"schema": "@autopass/invite",
|
|
23
27
|
"derived": false,
|
|
@@ -29,6 +33,8 @@
|
|
|
29
33
|
"namespace": "autopass",
|
|
30
34
|
"id": 2,
|
|
31
35
|
"type": 1,
|
|
36
|
+
"version": 0,
|
|
37
|
+
"versionField": null,
|
|
32
38
|
"indexes": [],
|
|
33
39
|
"schema": "@autopass/mirrors",
|
|
34
40
|
"derived": false,
|
|
@@ -40,6 +46,8 @@
|
|
|
40
46
|
"namespace": "autopass",
|
|
41
47
|
"id": 3,
|
|
42
48
|
"type": 1,
|
|
49
|
+
"version": 0,
|
|
50
|
+
"versionField": null,
|
|
43
51
|
"indexes": [],
|
|
44
52
|
"schema": "@autopass/writer",
|
|
45
53
|
"derived": false,
|
|
@@ -51,6 +59,8 @@
|
|
|
51
59
|
"namespace": "autopass",
|
|
52
60
|
"id": 4,
|
|
53
61
|
"type": 1,
|
|
62
|
+
"version": 0,
|
|
63
|
+
"versionField": null,
|
|
54
64
|
"indexes": [],
|
|
55
65
|
"schema": "@autopass/delete",
|
|
56
66
|
"derived": false,
|
|
@@ -62,6 +72,8 @@
|
|
|
62
72
|
"namespace": "autopass",
|
|
63
73
|
"id": 5,
|
|
64
74
|
"type": 1,
|
|
75
|
+
"version": 0,
|
|
76
|
+
"versionField": null,
|
|
65
77
|
"indexes": [],
|
|
66
78
|
"schema": "@autopass/del-invite",
|
|
67
79
|
"derived": false,
|
|
@@ -73,6 +85,8 @@
|
|
|
73
85
|
"namespace": "autopass",
|
|
74
86
|
"id": 6,
|
|
75
87
|
"type": 1,
|
|
88
|
+
"version": 0,
|
|
89
|
+
"versionField": null,
|
|
76
90
|
"indexes": [],
|
|
77
91
|
"schema": "@autopass/del-mirror",
|
|
78
92
|
"derived": false,
|
package/spec/db/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperdb compiler
|
|
2
2
|
/* eslint-disable camelcase */
|
|
3
3
|
|
|
4
|
-
const { IndexEncoder, c } = require('hyperdb/runtime')
|
|
4
|
+
const { IndexEncoder, c, b4a } = require('hyperdb/runtime')
|
|
5
5
|
const { version, getEncoding, setVersion } = require('./messages.js')
|
|
6
6
|
|
|
7
|
+
const versions = { schema: version, db: 0 }
|
|
8
|
+
|
|
7
9
|
// '@autopass/records' collection key
|
|
8
10
|
const collection0_key = new IndexEncoder([IndexEncoder.STRING], { prefix: 0 })
|
|
9
11
|
|
|
@@ -16,10 +18,11 @@ function collection0_indexify(record) {
|
|
|
16
18
|
const collection0_enc = getEncoding('@autopass/records/hyperdb#0')
|
|
17
19
|
|
|
18
20
|
// '@autopass/records' reconstruction function
|
|
19
|
-
function collection0_reconstruct(
|
|
21
|
+
function collection0_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
20
22
|
const key = collection0_key.decode(keyBuf)
|
|
21
|
-
setVersion(
|
|
22
|
-
const
|
|
23
|
+
setVersion(schemaVersion)
|
|
24
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
25
|
+
const record = collection0_enc.decode(state)
|
|
23
26
|
record.key = key[0]
|
|
24
27
|
return record
|
|
25
28
|
}
|
|
@@ -35,6 +38,7 @@ function collection0_reconstruct_key(keyBuf) {
|
|
|
35
38
|
const collection0 = {
|
|
36
39
|
name: '@autopass/records',
|
|
37
40
|
id: 0,
|
|
41
|
+
version: 0,
|
|
38
42
|
encodeKey(record) {
|
|
39
43
|
const key = [record.key]
|
|
40
44
|
return collection0_key.encode(key)
|
|
@@ -47,14 +51,19 @@ const collection0 = {
|
|
|
47
51
|
lte: lte ? collection0_indexify(lte) : null
|
|
48
52
|
})
|
|
49
53
|
},
|
|
50
|
-
encodeValue(
|
|
51
|
-
setVersion(
|
|
52
|
-
|
|
54
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
55
|
+
setVersion(schemaVersion)
|
|
56
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
57
|
+
collection0_enc.preencode(state, record)
|
|
58
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
59
|
+
collection0_enc.encode(state, record)
|
|
60
|
+
return state.buffer
|
|
53
61
|
},
|
|
54
62
|
trigger: null,
|
|
55
63
|
reconstruct: collection0_reconstruct,
|
|
56
64
|
reconstructKey: collection0_reconstruct_key,
|
|
57
|
-
indexes: []
|
|
65
|
+
indexes: [],
|
|
66
|
+
decodedVersion: 0
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
// '@autopass/invite' collection key
|
|
@@ -69,10 +78,11 @@ function collection1_indexify(record) {
|
|
|
69
78
|
const collection1_enc = getEncoding('@autopass/invite/hyperdb#1')
|
|
70
79
|
|
|
71
80
|
// '@autopass/invite' reconstruction function
|
|
72
|
-
function collection1_reconstruct(
|
|
81
|
+
function collection1_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
73
82
|
const key = collection1_key.decode(keyBuf)
|
|
74
|
-
setVersion(
|
|
75
|
-
const
|
|
83
|
+
setVersion(schemaVersion)
|
|
84
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
85
|
+
const record = collection1_enc.decode(state)
|
|
76
86
|
record.id = key[0]
|
|
77
87
|
return record
|
|
78
88
|
}
|
|
@@ -88,6 +98,7 @@ function collection1_reconstruct_key(keyBuf) {
|
|
|
88
98
|
const collection1 = {
|
|
89
99
|
name: '@autopass/invite',
|
|
90
100
|
id: 1,
|
|
101
|
+
version: 0,
|
|
91
102
|
encodeKey(record) {
|
|
92
103
|
const key = [record.id]
|
|
93
104
|
return collection1_key.encode(key)
|
|
@@ -100,14 +111,19 @@ const collection1 = {
|
|
|
100
111
|
lte: lte ? collection1_indexify(lte) : null
|
|
101
112
|
})
|
|
102
113
|
},
|
|
103
|
-
encodeValue(
|
|
104
|
-
setVersion(
|
|
105
|
-
|
|
114
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
115
|
+
setVersion(schemaVersion)
|
|
116
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
117
|
+
collection1_enc.preencode(state, record)
|
|
118
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
119
|
+
collection1_enc.encode(state, record)
|
|
120
|
+
return state.buffer
|
|
106
121
|
},
|
|
107
122
|
trigger: null,
|
|
108
123
|
reconstruct: collection1_reconstruct,
|
|
109
124
|
reconstructKey: collection1_reconstruct_key,
|
|
110
|
-
indexes: []
|
|
125
|
+
indexes: [],
|
|
126
|
+
decodedVersion: 0
|
|
111
127
|
}
|
|
112
128
|
|
|
113
129
|
// '@autopass/mirrors' collection key
|
|
@@ -122,10 +138,11 @@ function collection2_indexify(record) {
|
|
|
122
138
|
const collection2_enc = getEncoding('@autopass/mirrors/hyperdb#2')
|
|
123
139
|
|
|
124
140
|
// '@autopass/mirrors' reconstruction function
|
|
125
|
-
function collection2_reconstruct(
|
|
141
|
+
function collection2_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
126
142
|
const key = collection2_key.decode(keyBuf)
|
|
127
|
-
setVersion(
|
|
128
|
-
const
|
|
143
|
+
setVersion(schemaVersion)
|
|
144
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
145
|
+
const record = collection2_enc.decode(state)
|
|
129
146
|
record.key = key[0]
|
|
130
147
|
return record
|
|
131
148
|
}
|
|
@@ -141,6 +158,7 @@ function collection2_reconstruct_key(keyBuf) {
|
|
|
141
158
|
const collection2 = {
|
|
142
159
|
name: '@autopass/mirrors',
|
|
143
160
|
id: 2,
|
|
161
|
+
version: 0,
|
|
144
162
|
encodeKey(record) {
|
|
145
163
|
const key = [record.key]
|
|
146
164
|
return collection2_key.encode(key)
|
|
@@ -153,14 +171,19 @@ const collection2 = {
|
|
|
153
171
|
lte: lte ? collection2_indexify(lte) : null
|
|
154
172
|
})
|
|
155
173
|
},
|
|
156
|
-
encodeValue(
|
|
157
|
-
setVersion(
|
|
158
|
-
|
|
174
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
175
|
+
setVersion(schemaVersion)
|
|
176
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
177
|
+
collection2_enc.preencode(state, record)
|
|
178
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
179
|
+
collection2_enc.encode(state, record)
|
|
180
|
+
return state.buffer
|
|
159
181
|
},
|
|
160
182
|
trigger: null,
|
|
161
183
|
reconstruct: collection2_reconstruct,
|
|
162
184
|
reconstructKey: collection2_reconstruct_key,
|
|
163
|
-
indexes: []
|
|
185
|
+
indexes: [],
|
|
186
|
+
decodedVersion: 0
|
|
164
187
|
}
|
|
165
188
|
|
|
166
189
|
// '@autopass/writer' collection key
|
|
@@ -175,10 +198,11 @@ function collection3_indexify(record) {
|
|
|
175
198
|
const collection3_enc = getEncoding('@autopass/writer/hyperdb#3')
|
|
176
199
|
|
|
177
200
|
// '@autopass/writer' reconstruction function
|
|
178
|
-
function collection3_reconstruct(
|
|
201
|
+
function collection3_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
179
202
|
const key = collection3_key.decode(keyBuf)
|
|
180
|
-
setVersion(
|
|
181
|
-
const
|
|
203
|
+
setVersion(schemaVersion)
|
|
204
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
205
|
+
const record = collection3_enc.decode(state)
|
|
182
206
|
record.key = key[0]
|
|
183
207
|
return record
|
|
184
208
|
}
|
|
@@ -194,6 +218,7 @@ function collection3_reconstruct_key(keyBuf) {
|
|
|
194
218
|
const collection3 = {
|
|
195
219
|
name: '@autopass/writer',
|
|
196
220
|
id: 3,
|
|
221
|
+
version: 0,
|
|
197
222
|
encodeKey(record) {
|
|
198
223
|
const key = [record.key]
|
|
199
224
|
return collection3_key.encode(key)
|
|
@@ -206,14 +231,19 @@ const collection3 = {
|
|
|
206
231
|
lte: lte ? collection3_indexify(lte) : null
|
|
207
232
|
})
|
|
208
233
|
},
|
|
209
|
-
encodeValue(
|
|
210
|
-
setVersion(
|
|
211
|
-
|
|
234
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
235
|
+
setVersion(schemaVersion)
|
|
236
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
237
|
+
collection3_enc.preencode(state, record)
|
|
238
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
239
|
+
collection3_enc.encode(state, record)
|
|
240
|
+
return state.buffer
|
|
212
241
|
},
|
|
213
242
|
trigger: null,
|
|
214
243
|
reconstruct: collection3_reconstruct,
|
|
215
244
|
reconstructKey: collection3_reconstruct_key,
|
|
216
|
-
indexes: []
|
|
245
|
+
indexes: [],
|
|
246
|
+
decodedVersion: 0
|
|
217
247
|
}
|
|
218
248
|
|
|
219
249
|
// '@autopass/delete' collection key
|
|
@@ -228,10 +258,11 @@ function collection4_indexify(record) {
|
|
|
228
258
|
const collection4_enc = getEncoding('@autopass/delete/hyperdb#4')
|
|
229
259
|
|
|
230
260
|
// '@autopass/delete' reconstruction function
|
|
231
|
-
function collection4_reconstruct(
|
|
261
|
+
function collection4_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
232
262
|
const key = collection4_key.decode(keyBuf)
|
|
233
|
-
setVersion(
|
|
234
|
-
const
|
|
263
|
+
setVersion(schemaVersion)
|
|
264
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
265
|
+
const record = collection4_enc.decode(state)
|
|
235
266
|
record.key = key[0]
|
|
236
267
|
return record
|
|
237
268
|
}
|
|
@@ -247,6 +278,7 @@ function collection4_reconstruct_key(keyBuf) {
|
|
|
247
278
|
const collection4 = {
|
|
248
279
|
name: '@autopass/delete',
|
|
249
280
|
id: 4,
|
|
281
|
+
version: 0,
|
|
250
282
|
encodeKey(record) {
|
|
251
283
|
const key = [record.key]
|
|
252
284
|
return collection4_key.encode(key)
|
|
@@ -259,14 +291,19 @@ const collection4 = {
|
|
|
259
291
|
lte: lte ? collection4_indexify(lte) : null
|
|
260
292
|
})
|
|
261
293
|
},
|
|
262
|
-
encodeValue(
|
|
263
|
-
setVersion(
|
|
264
|
-
|
|
294
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
295
|
+
setVersion(schemaVersion)
|
|
296
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
297
|
+
collection4_enc.preencode(state, record)
|
|
298
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
299
|
+
collection4_enc.encode(state, record)
|
|
300
|
+
return state.buffer
|
|
265
301
|
},
|
|
266
302
|
trigger: null,
|
|
267
303
|
reconstruct: collection4_reconstruct,
|
|
268
304
|
reconstructKey: collection4_reconstruct_key,
|
|
269
|
-
indexes: []
|
|
305
|
+
indexes: [],
|
|
306
|
+
decodedVersion: 0
|
|
270
307
|
}
|
|
271
308
|
|
|
272
309
|
// '@autopass/del-invite' collection key
|
|
@@ -281,10 +318,11 @@ function collection5_indexify(record) {
|
|
|
281
318
|
const collection5_enc = getEncoding('@autopass/del-invite/hyperdb#5')
|
|
282
319
|
|
|
283
320
|
// '@autopass/del-invite' reconstruction function
|
|
284
|
-
function collection5_reconstruct(
|
|
321
|
+
function collection5_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
285
322
|
const key = collection5_key.decode(keyBuf)
|
|
286
|
-
setVersion(
|
|
287
|
-
const
|
|
323
|
+
setVersion(schemaVersion)
|
|
324
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
325
|
+
const record = collection5_enc.decode(state)
|
|
288
326
|
record.id = key[0]
|
|
289
327
|
return record
|
|
290
328
|
}
|
|
@@ -300,6 +338,7 @@ function collection5_reconstruct_key(keyBuf) {
|
|
|
300
338
|
const collection5 = {
|
|
301
339
|
name: '@autopass/del-invite',
|
|
302
340
|
id: 5,
|
|
341
|
+
version: 0,
|
|
303
342
|
encodeKey(record) {
|
|
304
343
|
const key = [record.id]
|
|
305
344
|
return collection5_key.encode(key)
|
|
@@ -312,14 +351,19 @@ const collection5 = {
|
|
|
312
351
|
lte: lte ? collection5_indexify(lte) : null
|
|
313
352
|
})
|
|
314
353
|
},
|
|
315
|
-
encodeValue(
|
|
316
|
-
setVersion(
|
|
317
|
-
|
|
354
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
355
|
+
setVersion(schemaVersion)
|
|
356
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
357
|
+
collection5_enc.preencode(state, record)
|
|
358
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
359
|
+
collection5_enc.encode(state, record)
|
|
360
|
+
return state.buffer
|
|
318
361
|
},
|
|
319
362
|
trigger: null,
|
|
320
363
|
reconstruct: collection5_reconstruct,
|
|
321
364
|
reconstructKey: collection5_reconstruct_key,
|
|
322
|
-
indexes: []
|
|
365
|
+
indexes: [],
|
|
366
|
+
decodedVersion: 0
|
|
323
367
|
}
|
|
324
368
|
|
|
325
369
|
// '@autopass/del-mirror' collection key
|
|
@@ -334,10 +378,11 @@ function collection6_indexify(record) {
|
|
|
334
378
|
const collection6_enc = getEncoding('@autopass/del-mirror/hyperdb#6')
|
|
335
379
|
|
|
336
380
|
// '@autopass/del-mirror' reconstruction function
|
|
337
|
-
function collection6_reconstruct(
|
|
381
|
+
function collection6_reconstruct(schemaVersion, keyBuf, valueBuf) {
|
|
338
382
|
const key = collection6_key.decode(keyBuf)
|
|
339
|
-
setVersion(
|
|
340
|
-
const
|
|
383
|
+
setVersion(schemaVersion)
|
|
384
|
+
const state = { start: 0, end: valueBuf.byteLength, buffer: valueBuf }
|
|
385
|
+
const record = collection6_enc.decode(state)
|
|
341
386
|
record.key = key[0]
|
|
342
387
|
return record
|
|
343
388
|
}
|
|
@@ -353,6 +398,7 @@ function collection6_reconstruct_key(keyBuf) {
|
|
|
353
398
|
const collection6 = {
|
|
354
399
|
name: '@autopass/del-mirror',
|
|
355
400
|
id: 6,
|
|
401
|
+
version: 0,
|
|
356
402
|
encodeKey(record) {
|
|
357
403
|
const key = [record.key]
|
|
358
404
|
return collection6_key.encode(key)
|
|
@@ -365,14 +411,19 @@ const collection6 = {
|
|
|
365
411
|
lte: lte ? collection6_indexify(lte) : null
|
|
366
412
|
})
|
|
367
413
|
},
|
|
368
|
-
encodeValue(
|
|
369
|
-
setVersion(
|
|
370
|
-
|
|
414
|
+
encodeValue(schemaVersion, collectionVersion, record) {
|
|
415
|
+
setVersion(schemaVersion)
|
|
416
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
417
|
+
collection6_enc.preencode(state, record)
|
|
418
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
419
|
+
collection6_enc.encode(state, record)
|
|
420
|
+
return state.buffer
|
|
371
421
|
},
|
|
372
422
|
trigger: null,
|
|
373
423
|
reconstruct: collection6_reconstruct,
|
|
374
424
|
reconstructKey: collection6_reconstruct_key,
|
|
375
|
-
indexes: []
|
|
425
|
+
indexes: [],
|
|
426
|
+
decodedVersion: 0
|
|
376
427
|
}
|
|
377
428
|
|
|
378
429
|
const collections = [
|
|
@@ -387,13 +438,7 @@ const collections = [
|
|
|
387
438
|
|
|
388
439
|
const indexes = []
|
|
389
440
|
|
|
390
|
-
module.exports = {
|
|
391
|
-
version,
|
|
392
|
-
collections,
|
|
393
|
-
indexes,
|
|
394
|
-
resolveCollection,
|
|
395
|
-
resolveIndex
|
|
396
|
-
}
|
|
441
|
+
module.exports = { versions, collections, indexes, resolveCollection, resolveIndex }
|
|
397
442
|
|
|
398
443
|
function resolveCollection(name) {
|
|
399
444
|
switch (name) {
|
package/spec/db/messages.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperschema compiler
|
|
2
|
-
// Schema Version:
|
|
2
|
+
// Schema Version: 3
|
|
3
3
|
/* eslint-disable camelcase */
|
|
4
4
|
/* eslint-disable quotes */
|
|
5
5
|
/* eslint-disable space-before-function-paren */
|
|
6
6
|
|
|
7
7
|
const { c } = require('hyperschema/runtime')
|
|
8
8
|
|
|
9
|
-
const VERSION =
|
|
9
|
+
const VERSION = 3
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -99,24 +99,35 @@ const encoding4 = {
|
|
|
99
99
|
c.buffer.preencode(state, m.invite)
|
|
100
100
|
c.buffer.preencode(state, m.publicKey)
|
|
101
101
|
c.int.preencode(state, m.expires)
|
|
102
|
+
state.end++ // max flag is 2 so always one byte
|
|
103
|
+
|
|
104
|
+
if (version >= 3 && m.additional) encoding4_5.preencode(state, m.additional)
|
|
102
105
|
},
|
|
103
106
|
encode(state, m) {
|
|
107
|
+
const flags = (version >= 2 && m.readOnly ? 1 : 0) | (version >= 3 && m.additional ? 2 : 0)
|
|
108
|
+
|
|
104
109
|
c.buffer.encode(state, m.id)
|
|
105
110
|
c.buffer.encode(state, m.invite)
|
|
106
111
|
c.buffer.encode(state, m.publicKey)
|
|
107
112
|
c.int.encode(state, m.expires)
|
|
113
|
+
c.uint.encode(state, flags)
|
|
114
|
+
|
|
115
|
+
if (version >= 3 && m.additional) encoding4_5.encode(state, m.additional)
|
|
108
116
|
},
|
|
109
117
|
decode(state) {
|
|
110
118
|
const r0 = c.buffer.decode(state)
|
|
111
119
|
const r1 = c.buffer.decode(state)
|
|
112
120
|
const r2 = c.buffer.decode(state)
|
|
113
121
|
const r3 = c.int.decode(state)
|
|
122
|
+
const flags = state.start < state.end ? c.uint.decode(state) : 0
|
|
114
123
|
|
|
115
124
|
return {
|
|
116
125
|
id: r0,
|
|
117
126
|
invite: r1,
|
|
118
127
|
publicKey: r2,
|
|
119
|
-
expires: r3
|
|
128
|
+
expires: r3,
|
|
129
|
+
readOnly: version >= 2 && (flags & 1) !== 0,
|
|
130
|
+
additional: version >= 3 && (flags & 2) !== 0 ? encoding4_5.decode(state) : null
|
|
120
131
|
}
|
|
121
132
|
}
|
|
122
133
|
}
|
|
@@ -141,8 +152,29 @@ const encoding5 = {
|
|
|
141
152
|
// @autopass/del-mirror
|
|
142
153
|
const encoding6 = encoding1
|
|
143
154
|
|
|
144
|
-
// @autopass/
|
|
155
|
+
// @autopass/additional-invite-data
|
|
145
156
|
const encoding7 = {
|
|
157
|
+
preencode(state, m) {
|
|
158
|
+
c.buffer.preencode(state, m.data)
|
|
159
|
+
c.buffer.preencode(state, m.signature)
|
|
160
|
+
},
|
|
161
|
+
encode(state, m) {
|
|
162
|
+
c.buffer.encode(state, m.data)
|
|
163
|
+
c.buffer.encode(state, m.signature)
|
|
164
|
+
},
|
|
165
|
+
decode(state) {
|
|
166
|
+
const r0 = c.buffer.decode(state)
|
|
167
|
+
const r1 = c.buffer.decode(state)
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
data: r0,
|
|
171
|
+
signature: r1
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// @autopass/records/hyperdb#0
|
|
177
|
+
const encoding8 = {
|
|
146
178
|
preencode(state, m) {
|
|
147
179
|
state.end++ // max flag is 2 so always one byte
|
|
148
180
|
|
|
@@ -169,33 +201,44 @@ const encoding7 = {
|
|
|
169
201
|
}
|
|
170
202
|
|
|
171
203
|
// @autopass/invite/hyperdb#1
|
|
172
|
-
const
|
|
204
|
+
const encoding9 = {
|
|
173
205
|
preencode(state, m) {
|
|
174
206
|
c.buffer.preencode(state, m.invite)
|
|
175
207
|
c.buffer.preencode(state, m.publicKey)
|
|
176
208
|
c.int.preencode(state, m.expires)
|
|
209
|
+
state.end++ // max flag is 2 so always one byte
|
|
210
|
+
|
|
211
|
+
if (version >= 3 && m.additional) encoding9_5.preencode(state, m.additional)
|
|
177
212
|
},
|
|
178
213
|
encode(state, m) {
|
|
214
|
+
const flags = (version >= 2 && m.readOnly ? 1 : 0) | (version >= 3 && m.additional ? 2 : 0)
|
|
215
|
+
|
|
179
216
|
c.buffer.encode(state, m.invite)
|
|
180
217
|
c.buffer.encode(state, m.publicKey)
|
|
181
218
|
c.int.encode(state, m.expires)
|
|
219
|
+
c.uint.encode(state, flags)
|
|
220
|
+
|
|
221
|
+
if (version >= 3 && m.additional) encoding9_5.encode(state, m.additional)
|
|
182
222
|
},
|
|
183
223
|
decode(state) {
|
|
184
224
|
const r1 = c.buffer.decode(state)
|
|
185
225
|
const r2 = c.buffer.decode(state)
|
|
186
226
|
const r3 = c.int.decode(state)
|
|
227
|
+
const flags = state.start < state.end ? c.uint.decode(state) : 0
|
|
187
228
|
|
|
188
229
|
return {
|
|
189
230
|
id: null,
|
|
190
231
|
invite: r1,
|
|
191
232
|
publicKey: r2,
|
|
192
|
-
expires: r3
|
|
233
|
+
expires: r3,
|
|
234
|
+
readOnly: version >= 2 && (flags & 1) !== 0,
|
|
235
|
+
additional: version >= 3 && (flags & 2) !== 0 ? encoding9_5.decode(state) : null
|
|
193
236
|
}
|
|
194
237
|
}
|
|
195
238
|
}
|
|
196
239
|
|
|
197
240
|
// @autopass/mirrors/hyperdb#2
|
|
198
|
-
const
|
|
241
|
+
const encoding10 = {
|
|
199
242
|
preencode(state, m) {},
|
|
200
243
|
encode(state, m) {},
|
|
201
244
|
decode(state) {
|
|
@@ -206,13 +249,13 @@ const encoding9 = {
|
|
|
206
249
|
}
|
|
207
250
|
|
|
208
251
|
// @autopass/writer/hyperdb#3
|
|
209
|
-
const
|
|
252
|
+
const encoding11 = encoding10
|
|
210
253
|
|
|
211
254
|
// @autopass/delete/hyperdb#4
|
|
212
|
-
const
|
|
255
|
+
const encoding12 = encoding10
|
|
213
256
|
|
|
214
257
|
// @autopass/del-invite/hyperdb#5
|
|
215
|
-
const
|
|
258
|
+
const encoding13 = {
|
|
216
259
|
preencode(state, m) {},
|
|
217
260
|
encode(state, m) {},
|
|
218
261
|
decode(state) {
|
|
@@ -223,7 +266,12 @@ const encoding12 = {
|
|
|
223
266
|
}
|
|
224
267
|
|
|
225
268
|
// @autopass/del-mirror/hyperdb#6
|
|
226
|
-
const
|
|
269
|
+
const encoding14 = encoding10
|
|
270
|
+
|
|
271
|
+
// @autopass/invite.additional, deferred due to recusive use
|
|
272
|
+
const encoding4_5 = c.frame(encoding7)
|
|
273
|
+
// @autopass/invite/hyperdb#1.additional, deferred due to recusive use
|
|
274
|
+
const encoding9_5 = encoding4_5
|
|
227
275
|
|
|
228
276
|
function setVersion(v) {
|
|
229
277
|
version = v
|
|
@@ -262,20 +310,22 @@ function getEncoding(name) {
|
|
|
262
310
|
return encoding5
|
|
263
311
|
case '@autopass/del-mirror':
|
|
264
312
|
return encoding6
|
|
265
|
-
case '@autopass/
|
|
313
|
+
case '@autopass/additional-invite-data':
|
|
266
314
|
return encoding7
|
|
267
|
-
case '@autopass/
|
|
315
|
+
case '@autopass/records/hyperdb#0':
|
|
268
316
|
return encoding8
|
|
269
|
-
case '@autopass/
|
|
317
|
+
case '@autopass/invite/hyperdb#1':
|
|
270
318
|
return encoding9
|
|
271
|
-
case '@autopass/
|
|
319
|
+
case '@autopass/mirrors/hyperdb#2':
|
|
272
320
|
return encoding10
|
|
273
|
-
case '@autopass/
|
|
321
|
+
case '@autopass/writer/hyperdb#3':
|
|
274
322
|
return encoding11
|
|
275
|
-
case '@autopass/
|
|
323
|
+
case '@autopass/delete/hyperdb#4':
|
|
276
324
|
return encoding12
|
|
277
|
-
case '@autopass/del-
|
|
325
|
+
case '@autopass/del-invite/hyperdb#5':
|
|
278
326
|
return encoding13
|
|
327
|
+
case '@autopass/del-mirror/hyperdb#6':
|
|
328
|
+
return encoding14
|
|
279
329
|
default:
|
|
280
330
|
throw new Error('Encoder not found ' + name)
|
|
281
331
|
}
|
|
@@ -47,40 +47,20 @@ class Router {
|
|
|
47
47
|
this._handler7 = handler
|
|
48
48
|
break
|
|
49
49
|
default:
|
|
50
|
-
throw new Error(
|
|
51
|
-
'Cannot register a handler for a nonexistent route: ' + name
|
|
52
|
-
)
|
|
50
|
+
throw new Error('Cannot register a handler for a nonexistent route: ' + name)
|
|
53
51
|
}
|
|
54
52
|
this._missing--
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
_checkAll() {
|
|
58
|
-
assert(
|
|
59
|
-
|
|
60
|
-
'Missing handler for "@autopass/remove-writer"'
|
|
61
|
-
)
|
|
62
|
-
assert(
|
|
63
|
-
this._handler1 !== null,
|
|
64
|
-
'Missing handler for "@autopass/add-writer"'
|
|
65
|
-
)
|
|
56
|
+
assert(this._handler0 !== null, 'Missing handler for "@autopass/remove-writer"')
|
|
57
|
+
assert(this._handler1 !== null, 'Missing handler for "@autopass/add-writer"')
|
|
66
58
|
assert(this._handler2 !== null, 'Missing handler for "@autopass/put"')
|
|
67
|
-
assert(
|
|
68
|
-
|
|
69
|
-
'Missing handler for "@autopass/add-mirror"'
|
|
70
|
-
)
|
|
71
|
-
assert(
|
|
72
|
-
this._handler4 !== null,
|
|
73
|
-
'Missing handler for "@autopass/del-mirror"'
|
|
74
|
-
)
|
|
59
|
+
assert(this._handler3 !== null, 'Missing handler for "@autopass/add-mirror"')
|
|
60
|
+
assert(this._handler4 !== null, 'Missing handler for "@autopass/del-mirror"')
|
|
75
61
|
assert(this._handler5 !== null, 'Missing handler for "@autopass/del"')
|
|
76
|
-
assert(
|
|
77
|
-
|
|
78
|
-
'Missing handler for "@autopass/add-invite"'
|
|
79
|
-
)
|
|
80
|
-
assert(
|
|
81
|
-
this._handler7 !== null,
|
|
82
|
-
'Missing handler for "@autopass/del-invite"'
|
|
83
|
-
)
|
|
62
|
+
assert(this._handler6 !== null, 'Missing handler for "@autopass/add-invite"')
|
|
63
|
+
assert(this._handler7 !== null, 'Missing handler for "@autopass/del-invite"')
|
|
84
64
|
}
|
|
85
65
|
|
|
86
66
|
async dispatch(message, context) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperschema compiler
|
|
2
|
-
// Schema Version:
|
|
2
|
+
// Schema Version: 3
|
|
3
3
|
/* eslint-disable camelcase */
|
|
4
4
|
/* eslint-disable quotes */
|
|
5
5
|
/* eslint-disable space-before-function-paren */
|
|
6
6
|
|
|
7
7
|
const { c } = require('hyperschema/runtime')
|
|
8
8
|
|
|
9
|
-
const VERSION =
|
|
9
|
+
const VERSION = 3
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -99,24 +99,35 @@ const encoding4 = {
|
|
|
99
99
|
c.buffer.preencode(state, m.invite)
|
|
100
100
|
c.buffer.preencode(state, m.publicKey)
|
|
101
101
|
c.int.preencode(state, m.expires)
|
|
102
|
+
state.end++ // max flag is 2 so always one byte
|
|
103
|
+
|
|
104
|
+
if (version >= 3 && m.additional) encoding4_5.preencode(state, m.additional)
|
|
102
105
|
},
|
|
103
106
|
encode(state, m) {
|
|
107
|
+
const flags = (version >= 2 && m.readOnly ? 1 : 0) | (version >= 3 && m.additional ? 2 : 0)
|
|
108
|
+
|
|
104
109
|
c.buffer.encode(state, m.id)
|
|
105
110
|
c.buffer.encode(state, m.invite)
|
|
106
111
|
c.buffer.encode(state, m.publicKey)
|
|
107
112
|
c.int.encode(state, m.expires)
|
|
113
|
+
c.uint.encode(state, flags)
|
|
114
|
+
|
|
115
|
+
if (version >= 3 && m.additional) encoding4_5.encode(state, m.additional)
|
|
108
116
|
},
|
|
109
117
|
decode(state) {
|
|
110
118
|
const r0 = c.buffer.decode(state)
|
|
111
119
|
const r1 = c.buffer.decode(state)
|
|
112
120
|
const r2 = c.buffer.decode(state)
|
|
113
121
|
const r3 = c.int.decode(state)
|
|
122
|
+
const flags = state.start < state.end ? c.uint.decode(state) : 0
|
|
114
123
|
|
|
115
124
|
return {
|
|
116
125
|
id: r0,
|
|
117
126
|
invite: r1,
|
|
118
127
|
publicKey: r2,
|
|
119
|
-
expires: r3
|
|
128
|
+
expires: r3,
|
|
129
|
+
readOnly: version >= 2 && (flags & 1) !== 0,
|
|
130
|
+
additional: version >= 3 && (flags & 2) !== 0 ? encoding4_5.decode(state) : null
|
|
120
131
|
}
|
|
121
132
|
}
|
|
122
133
|
}
|
|
@@ -141,6 +152,30 @@ const encoding5 = {
|
|
|
141
152
|
// @autopass/del-mirror
|
|
142
153
|
const encoding6 = encoding1
|
|
143
154
|
|
|
155
|
+
// @autopass/additional-invite-data
|
|
156
|
+
const encoding7 = {
|
|
157
|
+
preencode(state, m) {
|
|
158
|
+
c.buffer.preencode(state, m.data)
|
|
159
|
+
c.buffer.preencode(state, m.signature)
|
|
160
|
+
},
|
|
161
|
+
encode(state, m) {
|
|
162
|
+
c.buffer.encode(state, m.data)
|
|
163
|
+
c.buffer.encode(state, m.signature)
|
|
164
|
+
},
|
|
165
|
+
decode(state) {
|
|
166
|
+
const r0 = c.buffer.decode(state)
|
|
167
|
+
const r1 = c.buffer.decode(state)
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
data: r0,
|
|
171
|
+
signature: r1
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// @autopass/invite.additional, deferred due to recusive use
|
|
177
|
+
const encoding4_5 = c.frame(encoding7)
|
|
178
|
+
|
|
144
179
|
function setVersion(v) {
|
|
145
180
|
version = v
|
|
146
181
|
}
|
|
@@ -178,6 +213,8 @@ function getEncoding(name) {
|
|
|
178
213
|
return encoding5
|
|
179
214
|
case '@autopass/del-mirror':
|
|
180
215
|
return encoding6
|
|
216
|
+
case '@autopass/additional-invite-data':
|
|
217
|
+
return encoding7
|
|
181
218
|
default:
|
|
182
219
|
throw new Error('Encoder not found ' + name)
|
|
183
220
|
}
|
package/spec/schema/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperschema compiler
|
|
2
|
-
// Schema Version:
|
|
2
|
+
// Schema Version: 3
|
|
3
3
|
/* eslint-disable camelcase */
|
|
4
4
|
/* eslint-disable quotes */
|
|
5
5
|
/* eslint-disable space-before-function-paren */
|
|
6
6
|
|
|
7
7
|
const { c } = require('hyperschema/runtime')
|
|
8
8
|
|
|
9
|
-
const VERSION =
|
|
9
|
+
const VERSION = 3
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -99,24 +99,35 @@ const encoding4 = {
|
|
|
99
99
|
c.buffer.preencode(state, m.invite)
|
|
100
100
|
c.buffer.preencode(state, m.publicKey)
|
|
101
101
|
c.int.preencode(state, m.expires)
|
|
102
|
+
state.end++ // max flag is 2 so always one byte
|
|
103
|
+
|
|
104
|
+
if (version >= 3 && m.additional) encoding4_5.preencode(state, m.additional)
|
|
102
105
|
},
|
|
103
106
|
encode(state, m) {
|
|
107
|
+
const flags = (version >= 2 && m.readOnly ? 1 : 0) | (version >= 3 && m.additional ? 2 : 0)
|
|
108
|
+
|
|
104
109
|
c.buffer.encode(state, m.id)
|
|
105
110
|
c.buffer.encode(state, m.invite)
|
|
106
111
|
c.buffer.encode(state, m.publicKey)
|
|
107
112
|
c.int.encode(state, m.expires)
|
|
113
|
+
c.uint.encode(state, flags)
|
|
114
|
+
|
|
115
|
+
if (version >= 3 && m.additional) encoding4_5.encode(state, m.additional)
|
|
108
116
|
},
|
|
109
117
|
decode(state) {
|
|
110
118
|
const r0 = c.buffer.decode(state)
|
|
111
119
|
const r1 = c.buffer.decode(state)
|
|
112
120
|
const r2 = c.buffer.decode(state)
|
|
113
121
|
const r3 = c.int.decode(state)
|
|
122
|
+
const flags = state.start < state.end ? c.uint.decode(state) : 0
|
|
114
123
|
|
|
115
124
|
return {
|
|
116
125
|
id: r0,
|
|
117
126
|
invite: r1,
|
|
118
127
|
publicKey: r2,
|
|
119
|
-
expires: r3
|
|
128
|
+
expires: r3,
|
|
129
|
+
readOnly: version >= 2 && (flags & 1) !== 0,
|
|
130
|
+
additional: version >= 3 && (flags & 2) !== 0 ? encoding4_5.decode(state) : null
|
|
120
131
|
}
|
|
121
132
|
}
|
|
122
133
|
}
|
|
@@ -141,6 +152,30 @@ const encoding5 = {
|
|
|
141
152
|
// @autopass/del-mirror
|
|
142
153
|
const encoding6 = encoding1
|
|
143
154
|
|
|
155
|
+
// @autopass/additional-invite-data
|
|
156
|
+
const encoding7 = {
|
|
157
|
+
preencode(state, m) {
|
|
158
|
+
c.buffer.preencode(state, m.data)
|
|
159
|
+
c.buffer.preencode(state, m.signature)
|
|
160
|
+
},
|
|
161
|
+
encode(state, m) {
|
|
162
|
+
c.buffer.encode(state, m.data)
|
|
163
|
+
c.buffer.encode(state, m.signature)
|
|
164
|
+
},
|
|
165
|
+
decode(state) {
|
|
166
|
+
const r0 = c.buffer.decode(state)
|
|
167
|
+
const r1 = c.buffer.decode(state)
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
data: r0,
|
|
171
|
+
signature: r1
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// @autopass/invite.additional, deferred due to recusive use
|
|
177
|
+
const encoding4_5 = c.frame(encoding7)
|
|
178
|
+
|
|
144
179
|
function setVersion(v) {
|
|
145
180
|
version = v
|
|
146
181
|
}
|
|
@@ -178,6 +213,8 @@ function getEncoding(name) {
|
|
|
178
213
|
return encoding5
|
|
179
214
|
case '@autopass/del-mirror':
|
|
180
215
|
return encoding6
|
|
216
|
+
case '@autopass/additional-invite-data':
|
|
217
|
+
return encoding7
|
|
181
218
|
default:
|
|
182
219
|
throw new Error('Encoder not found ' + name)
|
|
183
220
|
}
|
package/spec/schema/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 3,
|
|
3
3
|
"schema": [
|
|
4
4
|
{
|
|
5
5
|
"name": "records",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"name": "invite",
|
|
74
74
|
"namespace": "autopass",
|
|
75
75
|
"compact": false,
|
|
76
|
-
"flagsPosition":
|
|
76
|
+
"flagsPosition": 4,
|
|
77
77
|
"fields": [
|
|
78
78
|
{
|
|
79
79
|
"name": "id",
|
|
@@ -98,6 +98,18 @@
|
|
|
98
98
|
"required": true,
|
|
99
99
|
"type": "int",
|
|
100
100
|
"version": 1
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "readOnly",
|
|
104
|
+
"required": false,
|
|
105
|
+
"type": "bool",
|
|
106
|
+
"version": 2
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "additional",
|
|
110
|
+
"required": false,
|
|
111
|
+
"type": "@autopass/additional-invite-data",
|
|
112
|
+
"version": 3
|
|
101
113
|
}
|
|
102
114
|
]
|
|
103
115
|
},
|
|
@@ -128,6 +140,26 @@
|
|
|
128
140
|
"version": 1
|
|
129
141
|
}
|
|
130
142
|
]
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"name": "additional-invite-data",
|
|
146
|
+
"namespace": "autopass",
|
|
147
|
+
"compact": false,
|
|
148
|
+
"flagsPosition": -1,
|
|
149
|
+
"fields": [
|
|
150
|
+
{
|
|
151
|
+
"name": "data",
|
|
152
|
+
"required": true,
|
|
153
|
+
"type": "buffer",
|
|
154
|
+
"version": 3
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"name": "signature",
|
|
158
|
+
"required": true,
|
|
159
|
+
"type": "buffer",
|
|
160
|
+
"version": 3
|
|
161
|
+
}
|
|
162
|
+
]
|
|
131
163
|
}
|
|
132
164
|
]
|
|
133
165
|
}
|
package/test.js
CHANGED
|
@@ -3,6 +3,8 @@ const Autopass = require('./')
|
|
|
3
3
|
const Corestore = require('corestore')
|
|
4
4
|
const testnet = require('hyperdht/testnet')
|
|
5
5
|
const tmp = require('test-tmp')
|
|
6
|
+
const b4a = require('b4a')
|
|
7
|
+
const BlindEncryptionSodium = require('blind-encryption-sodium')
|
|
6
8
|
|
|
7
9
|
test('basic', async function (t) {
|
|
8
10
|
const a = await create(t, { replicate: false })
|
|
@@ -21,8 +23,8 @@ test('invites', async function (t) {
|
|
|
21
23
|
const tn = await testnet(10, t)
|
|
22
24
|
|
|
23
25
|
const a = await create(t, { bootstrap: tn.bootstrap })
|
|
24
|
-
t.teardown(() => {
|
|
25
|
-
a.close()
|
|
26
|
+
t.teardown(async () => {
|
|
27
|
+
await a.close()
|
|
26
28
|
})
|
|
27
29
|
|
|
28
30
|
const onUpdate = function () {
|
|
@@ -41,7 +43,7 @@ test('invites', async function (t) {
|
|
|
41
43
|
const b = await p.finished()
|
|
42
44
|
await b.ready()
|
|
43
45
|
|
|
44
|
-
t.teardown(() => b.close())
|
|
46
|
+
t.teardown(async () => await b.close())
|
|
45
47
|
b.on('update', function () {
|
|
46
48
|
if (b.base.system.members === 2) t.pass('b has two members')
|
|
47
49
|
})
|
|
@@ -53,8 +55,8 @@ test('invites', async function (t) {
|
|
|
53
55
|
const tn = await testnet(10, t)
|
|
54
56
|
|
|
55
57
|
const a = await create(t, { bootstrap: tn.bootstrap })
|
|
56
|
-
t.teardown(() => {
|
|
57
|
-
a.close()
|
|
58
|
+
t.teardown(async () => {
|
|
59
|
+
await a.close()
|
|
58
60
|
})
|
|
59
61
|
|
|
60
62
|
const updateListener = function () {
|
|
@@ -73,7 +75,74 @@ test('invites', async function (t) {
|
|
|
73
75
|
const b = await p.finished()
|
|
74
76
|
await b.ready()
|
|
75
77
|
|
|
76
|
-
t.teardown(() => b.close())
|
|
78
|
+
t.teardown(async () => await b.close())
|
|
79
|
+
b.on('update', function () {
|
|
80
|
+
if (b.base.system.members === 2) t.pass('b has two members')
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('invite resets when createInvite type is different than previous', async function (t) {
|
|
85
|
+
t.plan(1)
|
|
86
|
+
|
|
87
|
+
const tn = await testnet(10, t)
|
|
88
|
+
|
|
89
|
+
const a = await create(t, { bootstrap: tn.bootstrap })
|
|
90
|
+
t.teardown(async () => {
|
|
91
|
+
await a.close()
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const inv = await a.createInvite()
|
|
95
|
+
const invReadOnly = await a.createInvite({ readOnly: true })
|
|
96
|
+
|
|
97
|
+
if (inv !== invReadOnly) {
|
|
98
|
+
t.pass('invite is reset ')
|
|
99
|
+
} else {
|
|
100
|
+
t.fail()
|
|
101
|
+
}
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
test('blind encryption', async function (t) {
|
|
105
|
+
t.plan(4)
|
|
106
|
+
|
|
107
|
+
const password = b4a.alloc(32, 'password')
|
|
108
|
+
const tn = await testnet(10, t)
|
|
109
|
+
|
|
110
|
+
const a = await create(t, {
|
|
111
|
+
bootstrap: tn.bootstrap,
|
|
112
|
+
blindEncryption: new BlindEncryptionSodium(password)
|
|
113
|
+
})
|
|
114
|
+
t.teardown(async () => {
|
|
115
|
+
await a.close()
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
const updateListener = function () {
|
|
119
|
+
if (a.base.system.members === 2) {
|
|
120
|
+
t.pass('a has two members')
|
|
121
|
+
a.removeListener('update', updateListener) // Remove the listener in teardown
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
a.on('update', updateListener)
|
|
126
|
+
|
|
127
|
+
const inv = await a.createInvite()
|
|
128
|
+
|
|
129
|
+
const p = await pair(t, inv, {
|
|
130
|
+
bootstrap: tn.bootstrap,
|
|
131
|
+
blindEncryption: new BlindEncryptionSodium(password)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const b = await p.finished()
|
|
135
|
+
await b.ready()
|
|
136
|
+
|
|
137
|
+
const [encryptionKeyBuffer, encryptionKeyEncryptedBuffer] = await Promise.all([
|
|
138
|
+
b.base.local.getUserData('autobase/encryption'),
|
|
139
|
+
b.base.local.getUserData('autobase/blind-encryption')
|
|
140
|
+
])
|
|
141
|
+
|
|
142
|
+
t.absent(encryptionKeyBuffer)
|
|
143
|
+
t.ok(encryptionKeyEncryptedBuffer)
|
|
144
|
+
|
|
145
|
+
t.teardown(async () => await b.close())
|
|
77
146
|
b.on('update', function () {
|
|
78
147
|
if (b.base.system.members === 2) t.pass('b has two members')
|
|
79
148
|
})
|
|
@@ -86,12 +155,12 @@ test('suspend and resume', async function (t) {
|
|
|
86
155
|
|
|
87
156
|
const a = await create(t, { bootstrap: tn.bootstrap })
|
|
88
157
|
const inv = await a.createInvite()
|
|
89
|
-
t.teardown(() => a.close())
|
|
158
|
+
t.teardown(async () => await a.close())
|
|
90
159
|
|
|
91
160
|
const p = await pair(t, inv, { bootstrap: tn.bootstrap })
|
|
92
161
|
const b = await p.finished()
|
|
93
162
|
await b.ready()
|
|
94
|
-
t.teardown(() => b.close())
|
|
163
|
+
t.teardown(async () => await b.close())
|
|
95
164
|
|
|
96
165
|
await new Promise((resolve) => {
|
|
97
166
|
const check = () => {
|