autopass 3.3.0 → 3.4.1
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 +19 -2
- package/index.js +33 -20
- package/package.json +4 -3
- package/schema.js +31 -10
- package/spec/db/db.json +22 -8
- package/spec/db/index.js +76 -70
- package/spec/db/messages.js +121 -30
- package/spec/hyperdispatch/dispatch.json +1 -1
- package/spec/hyperdispatch/index.js +8 -8
- package/spec/hyperdispatch/messages.js +67 -6
- package/spec/schema/index.js +67 -6
- package/spec/schema/schema.json +44 -2
- package/test.js +50 -8
|
@@ -7,7 +7,7 @@ const { version, getEncoding, setVersion } = require('./messages.js')
|
|
|
7
7
|
const defaultVersion = version
|
|
8
8
|
|
|
9
9
|
class Router {
|
|
10
|
-
constructor() {
|
|
10
|
+
constructor () {
|
|
11
11
|
this._handler0 = null
|
|
12
12
|
this._handler1 = null
|
|
13
13
|
this._handler2 = null
|
|
@@ -20,7 +20,7 @@ class Router {
|
|
|
20
20
|
this._missing = 8
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
add(name, handler) {
|
|
23
|
+
add (name, handler) {
|
|
24
24
|
switch (name) {
|
|
25
25
|
case '@autopass/remove-writer':
|
|
26
26
|
this._handler0 = handler
|
|
@@ -52,7 +52,7 @@ class Router {
|
|
|
52
52
|
this._missing--
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
_checkAll() {
|
|
55
|
+
_checkAll () {
|
|
56
56
|
assert(this._handler0 !== null, 'Missing handler for "@autopass/remove-writer"')
|
|
57
57
|
assert(this._handler1 !== null, 'Missing handler for "@autopass/add-writer"')
|
|
58
58
|
assert(this._handler2 !== null, 'Missing handler for "@autopass/put"')
|
|
@@ -63,7 +63,7 @@ class Router {
|
|
|
63
63
|
assert(this._handler7 !== null, 'Missing handler for "@autopass/del-invite"')
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
async dispatch(message, context) {
|
|
66
|
+
async dispatch (message, context) {
|
|
67
67
|
if (this._missing > 0) {
|
|
68
68
|
this._checkAll()
|
|
69
69
|
}
|
|
@@ -95,7 +95,7 @@ class Router {
|
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
function encode(name, message, { version = defaultVersion } = {}) {
|
|
98
|
+
function encode (name, message, { version = defaultVersion } = {}) {
|
|
99
99
|
const state = { buffer: null, start: 0, end: 0 }
|
|
100
100
|
|
|
101
101
|
const route = getRouteByName(name)
|
|
@@ -111,7 +111,7 @@ function encode(name, message, { version = defaultVersion } = {}) {
|
|
|
111
111
|
return state.buffer
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
function decode(buffer, { version = defaultVersion } = {}) {
|
|
114
|
+
function decode (buffer, { version = defaultVersion } = {}) {
|
|
115
115
|
const state = { buffer, start: 0, end: buffer.length }
|
|
116
116
|
|
|
117
117
|
const id = c.uint.decode(state)
|
|
@@ -170,7 +170,7 @@ const route7 = {
|
|
|
170
170
|
enc: getEncoding('@autopass/del-invite')
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
function getRouteByName(name) {
|
|
173
|
+
function getRouteByName (name) {
|
|
174
174
|
switch (name) {
|
|
175
175
|
case '@autopass/remove-writer':
|
|
176
176
|
return route0
|
|
@@ -193,7 +193,7 @@ function getRouteByName(name) {
|
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
-
function getRouteById(id) {
|
|
196
|
+
function getRouteById (id) {
|
|
197
197
|
switch (id) {
|
|
198
198
|
case 0:
|
|
199
199
|
return route0
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// This file is autogenerated by the hyperschema compiler
|
|
2
|
-
// Schema Version:
|
|
2
|
+
// Schema Version: 4
|
|
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 = 4
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -62,15 +62,26 @@ const encoding1 = {
|
|
|
62
62
|
const encoding2 = {
|
|
63
63
|
preencode(state, m) {
|
|
64
64
|
c.buffer.preencode(state, m.key)
|
|
65
|
+
state.end++ // max flag is 2 so always one byte
|
|
66
|
+
|
|
67
|
+
if (version >= 4 && m.name) c.string.preencode(state, m.name)
|
|
65
68
|
},
|
|
66
69
|
encode(state, m) {
|
|
70
|
+
const flags = ((version >= 4 && m.name) ? 1 : 0) | ((version >= 4 && m.readOnly) ? 2 : 0)
|
|
71
|
+
|
|
67
72
|
c.buffer.encode(state, m.key)
|
|
73
|
+
c.uint.encode(state, flags)
|
|
74
|
+
|
|
75
|
+
if (version >= 4 && m.name) c.string.encode(state, m.name)
|
|
68
76
|
},
|
|
69
77
|
decode(state) {
|
|
70
78
|
const r0 = c.buffer.decode(state)
|
|
79
|
+
const flags = state.start < state.end ? c.uint.decode(state) : 0
|
|
71
80
|
|
|
72
81
|
return {
|
|
73
|
-
key: r0
|
|
82
|
+
key: r0,
|
|
83
|
+
name: (version >= 4 && (flags & 1) !== 0) ? c.string.decode(state) : null,
|
|
84
|
+
readOnly: (version >= 4 && (flags & 2) !== 0)
|
|
74
85
|
}
|
|
75
86
|
}
|
|
76
87
|
}
|
|
@@ -104,7 +115,7 @@ const encoding4 = {
|
|
|
104
115
|
if (version >= 3 && m.additional) encoding4_5.preencode(state, m.additional)
|
|
105
116
|
},
|
|
106
117
|
encode(state, m) {
|
|
107
|
-
const flags = (version >= 2 && m.readOnly ? 1 : 0) | (version >= 3 && m.additional ? 2 : 0)
|
|
118
|
+
const flags = ((version >= 2 && m.readOnly) ? 1 : 0) | ((version >= 3 && m.additional) ? 2 : 0)
|
|
108
119
|
|
|
109
120
|
c.buffer.encode(state, m.id)
|
|
110
121
|
c.buffer.encode(state, m.invite)
|
|
@@ -126,8 +137,8 @@ const encoding4 = {
|
|
|
126
137
|
invite: r1,
|
|
127
138
|
publicKey: r2,
|
|
128
139
|
expires: r3,
|
|
129
|
-
readOnly: version >= 2 && (flags & 1) !== 0,
|
|
130
|
-
additional: version >= 3 && (flags & 2) !== 0 ? encoding4_5.decode(state) : null
|
|
140
|
+
readOnly: (version >= 2 && (flags & 1) !== 0),
|
|
141
|
+
additional: (version >= 3 && (flags & 2) !== 0) ? encoding4_5.decode(state) : null
|
|
131
142
|
}
|
|
132
143
|
}
|
|
133
144
|
}
|
|
@@ -173,6 +184,52 @@ const encoding7 = {
|
|
|
173
184
|
}
|
|
174
185
|
}
|
|
175
186
|
|
|
187
|
+
// @autopass/invitee
|
|
188
|
+
const encoding8 = {
|
|
189
|
+
preencode(state, m) {
|
|
190
|
+
c.fixed32.preencode(state, m.key)
|
|
191
|
+
state.end++ // max flag is 1 so always one byte
|
|
192
|
+
|
|
193
|
+
if (version >= 4 && m.name) c.string.preencode(state, m.name)
|
|
194
|
+
},
|
|
195
|
+
encode(state, m) {
|
|
196
|
+
const flags = (version >= 4 && m.name) ? 1 : 0
|
|
197
|
+
|
|
198
|
+
c.fixed32.encode(state, m.key)
|
|
199
|
+
c.uint.encode(state, flags)
|
|
200
|
+
|
|
201
|
+
if (version >= 4 && m.name) c.string.encode(state, m.name)
|
|
202
|
+
},
|
|
203
|
+
decode(state) {
|
|
204
|
+
const r0 = c.fixed32.decode(state)
|
|
205
|
+
const flags = c.uint.decode(state)
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
key: r0,
|
|
209
|
+
name: (version >= 4 && (flags & 1) !== 0) ? c.string.decode(state) : null
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// @autopass/public-invite-metadata
|
|
215
|
+
const encoding9 = {
|
|
216
|
+
preencode(state, m) {
|
|
217
|
+
state.end++ // max flag is 1 so always one byte
|
|
218
|
+
},
|
|
219
|
+
encode(state, m) {
|
|
220
|
+
const flags = (version >= 4 && m.readOnly) ? 1 : 0
|
|
221
|
+
|
|
222
|
+
c.uint.encode(state, flags)
|
|
223
|
+
},
|
|
224
|
+
decode(state) {
|
|
225
|
+
const flags = c.uint.decode(state)
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
readOnly: (version >= 4 && (flags & 1) !== 0)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
176
233
|
// @autopass/invite.additional, deferred due to recusive use
|
|
177
234
|
const encoding4_5 = c.frame(encoding7)
|
|
178
235
|
|
|
@@ -215,6 +272,10 @@ function getEncoding(name) {
|
|
|
215
272
|
return encoding6
|
|
216
273
|
case '@autopass/additional-invite-data':
|
|
217
274
|
return encoding7
|
|
275
|
+
case '@autopass/invitee':
|
|
276
|
+
return encoding8
|
|
277
|
+
case '@autopass/public-invite-metadata':
|
|
278
|
+
return encoding9
|
|
218
279
|
default:
|
|
219
280
|
throw new Error('Encoder not found ' + name)
|
|
220
281
|
}
|
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: 4
|
|
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 = 4
|
|
10
10
|
|
|
11
11
|
// eslint-disable-next-line no-unused-vars
|
|
12
12
|
let version = VERSION
|
|
@@ -62,15 +62,26 @@ const encoding1 = {
|
|
|
62
62
|
const encoding2 = {
|
|
63
63
|
preencode(state, m) {
|
|
64
64
|
c.buffer.preencode(state, m.key)
|
|
65
|
+
state.end++ // max flag is 2 so always one byte
|
|
66
|
+
|
|
67
|
+
if (version >= 4 && m.name) c.string.preencode(state, m.name)
|
|
65
68
|
},
|
|
66
69
|
encode(state, m) {
|
|
70
|
+
const flags = ((version >= 4 && m.name) ? 1 : 0) | ((version >= 4 && m.readOnly) ? 2 : 0)
|
|
71
|
+
|
|
67
72
|
c.buffer.encode(state, m.key)
|
|
73
|
+
c.uint.encode(state, flags)
|
|
74
|
+
|
|
75
|
+
if (version >= 4 && m.name) c.string.encode(state, m.name)
|
|
68
76
|
},
|
|
69
77
|
decode(state) {
|
|
70
78
|
const r0 = c.buffer.decode(state)
|
|
79
|
+
const flags = state.start < state.end ? c.uint.decode(state) : 0
|
|
71
80
|
|
|
72
81
|
return {
|
|
73
|
-
key: r0
|
|
82
|
+
key: r0,
|
|
83
|
+
name: (version >= 4 && (flags & 1) !== 0) ? c.string.decode(state) : null,
|
|
84
|
+
readOnly: (version >= 4 && (flags & 2) !== 0)
|
|
74
85
|
}
|
|
75
86
|
}
|
|
76
87
|
}
|
|
@@ -104,7 +115,7 @@ const encoding4 = {
|
|
|
104
115
|
if (version >= 3 && m.additional) encoding4_5.preencode(state, m.additional)
|
|
105
116
|
},
|
|
106
117
|
encode(state, m) {
|
|
107
|
-
const flags = (version >= 2 && m.readOnly ? 1 : 0) | (version >= 3 && m.additional ? 2 : 0)
|
|
118
|
+
const flags = ((version >= 2 && m.readOnly) ? 1 : 0) | ((version >= 3 && m.additional) ? 2 : 0)
|
|
108
119
|
|
|
109
120
|
c.buffer.encode(state, m.id)
|
|
110
121
|
c.buffer.encode(state, m.invite)
|
|
@@ -126,8 +137,8 @@ const encoding4 = {
|
|
|
126
137
|
invite: r1,
|
|
127
138
|
publicKey: r2,
|
|
128
139
|
expires: r3,
|
|
129
|
-
readOnly: version >= 2 && (flags & 1) !== 0,
|
|
130
|
-
additional: version >= 3 && (flags & 2) !== 0 ? encoding4_5.decode(state) : null
|
|
140
|
+
readOnly: (version >= 2 && (flags & 1) !== 0),
|
|
141
|
+
additional: (version >= 3 && (flags & 2) !== 0) ? encoding4_5.decode(state) : null
|
|
131
142
|
}
|
|
132
143
|
}
|
|
133
144
|
}
|
|
@@ -173,6 +184,52 @@ const encoding7 = {
|
|
|
173
184
|
}
|
|
174
185
|
}
|
|
175
186
|
|
|
187
|
+
// @autopass/invitee
|
|
188
|
+
const encoding8 = {
|
|
189
|
+
preencode(state, m) {
|
|
190
|
+
c.fixed32.preencode(state, m.key)
|
|
191
|
+
state.end++ // max flag is 1 so always one byte
|
|
192
|
+
|
|
193
|
+
if (version >= 4 && m.name) c.string.preencode(state, m.name)
|
|
194
|
+
},
|
|
195
|
+
encode(state, m) {
|
|
196
|
+
const flags = (version >= 4 && m.name) ? 1 : 0
|
|
197
|
+
|
|
198
|
+
c.fixed32.encode(state, m.key)
|
|
199
|
+
c.uint.encode(state, flags)
|
|
200
|
+
|
|
201
|
+
if (version >= 4 && m.name) c.string.encode(state, m.name)
|
|
202
|
+
},
|
|
203
|
+
decode(state) {
|
|
204
|
+
const r0 = c.fixed32.decode(state)
|
|
205
|
+
const flags = c.uint.decode(state)
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
key: r0,
|
|
209
|
+
name: (version >= 4 && (flags & 1) !== 0) ? c.string.decode(state) : null
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// @autopass/public-invite-metadata
|
|
215
|
+
const encoding9 = {
|
|
216
|
+
preencode(state, m) {
|
|
217
|
+
state.end++ // max flag is 1 so always one byte
|
|
218
|
+
},
|
|
219
|
+
encode(state, m) {
|
|
220
|
+
const flags = (version >= 4 && m.readOnly) ? 1 : 0
|
|
221
|
+
|
|
222
|
+
c.uint.encode(state, flags)
|
|
223
|
+
},
|
|
224
|
+
decode(state) {
|
|
225
|
+
const flags = c.uint.decode(state)
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
readOnly: (version >= 4 && (flags & 1) !== 0)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
176
233
|
// @autopass/invite.additional, deferred due to recusive use
|
|
177
234
|
const encoding4_5 = c.frame(encoding7)
|
|
178
235
|
|
|
@@ -215,6 +272,10 @@ function getEncoding(name) {
|
|
|
215
272
|
return encoding6
|
|
216
273
|
case '@autopass/additional-invite-data':
|
|
217
274
|
return encoding7
|
|
275
|
+
case '@autopass/invitee':
|
|
276
|
+
return encoding8
|
|
277
|
+
case '@autopass/public-invite-metadata':
|
|
278
|
+
return encoding9
|
|
218
279
|
default:
|
|
219
280
|
throw new Error('Encoder not found ' + name)
|
|
220
281
|
}
|
package/spec/schema/schema.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
2
|
+
"version": 4,
|
|
3
3
|
"schema": [
|
|
4
4
|
{
|
|
5
5
|
"name": "records",
|
|
@@ -45,13 +45,23 @@
|
|
|
45
45
|
"name": "writer",
|
|
46
46
|
"namespace": "autopass",
|
|
47
47
|
"compact": false,
|
|
48
|
-
"flagsPosition":
|
|
48
|
+
"flagsPosition": 1,
|
|
49
49
|
"fields": [
|
|
50
50
|
{
|
|
51
51
|
"name": "key",
|
|
52
52
|
"required": true,
|
|
53
53
|
"type": "buffer",
|
|
54
54
|
"version": 1
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "name",
|
|
58
|
+
"type": "string",
|
|
59
|
+
"version": 4
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "readOnly",
|
|
63
|
+
"type": "bool",
|
|
64
|
+
"version": 4
|
|
55
65
|
}
|
|
56
66
|
]
|
|
57
67
|
},
|
|
@@ -160,6 +170,38 @@
|
|
|
160
170
|
"version": 3
|
|
161
171
|
}
|
|
162
172
|
]
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"name": "invitee",
|
|
176
|
+
"namespace": "autopass",
|
|
177
|
+
"compact": false,
|
|
178
|
+
"flagsPosition": 1,
|
|
179
|
+
"fields": [
|
|
180
|
+
{
|
|
181
|
+
"name": "key",
|
|
182
|
+
"required": true,
|
|
183
|
+
"type": "fixed32",
|
|
184
|
+
"version": 4
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"name": "name",
|
|
188
|
+
"type": "string",
|
|
189
|
+
"version": 4
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"name": "public-invite-metadata",
|
|
195
|
+
"namespace": "autopass",
|
|
196
|
+
"compact": false,
|
|
197
|
+
"flagsPosition": 0,
|
|
198
|
+
"fields": [
|
|
199
|
+
{
|
|
200
|
+
"name": "readOnly",
|
|
201
|
+
"type": "bool",
|
|
202
|
+
"version": 4
|
|
203
|
+
}
|
|
204
|
+
]
|
|
163
205
|
}
|
|
164
206
|
]
|
|
165
207
|
}
|
package/test.js
CHANGED
|
@@ -44,9 +44,8 @@ test('invites', async function (t) {
|
|
|
44
44
|
await b.ready()
|
|
45
45
|
|
|
46
46
|
t.teardown(async () => await b.close())
|
|
47
|
-
b
|
|
48
|
-
|
|
49
|
-
})
|
|
47
|
+
await updateUntil(b, () => b.base.system.members === 2)
|
|
48
|
+
t.pass('b has two members')
|
|
50
49
|
})
|
|
51
50
|
|
|
52
51
|
test('invites', async function (t) {
|
|
@@ -76,9 +75,41 @@ test('invites', async function (t) {
|
|
|
76
75
|
await b.ready()
|
|
77
76
|
|
|
78
77
|
t.teardown(async () => await b.close())
|
|
79
|
-
b
|
|
80
|
-
|
|
78
|
+
await updateUntil(b, () => b.base.system.members === 2)
|
|
79
|
+
t.pass('b has two members')
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test.solo('invite with name', async function (t) {
|
|
83
|
+
t.plan(3)
|
|
84
|
+
|
|
85
|
+
const tn = await testnet(10, t)
|
|
86
|
+
|
|
87
|
+
const a = await create(t, { bootstrap: tn.bootstrap })
|
|
88
|
+
t.teardown(async () => {
|
|
89
|
+
await a.close()
|
|
81
90
|
})
|
|
91
|
+
|
|
92
|
+
const updateListener = function () {
|
|
93
|
+
if (a.base.system.members === 2) {
|
|
94
|
+
t.pass('a has two members')
|
|
95
|
+
a.removeListener('update', updateListener) // Remove the listener in teardown
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
a.on('update', updateListener)
|
|
100
|
+
|
|
101
|
+
const inv = await a.createInvite()
|
|
102
|
+
|
|
103
|
+
const p = await pair(t, inv, { bootstrap: tn.bootstrap, name: 'maf' })
|
|
104
|
+
|
|
105
|
+
const b = await p.finished()
|
|
106
|
+
await b.ready()
|
|
107
|
+
|
|
108
|
+
t.teardown(async () => await b.close())
|
|
109
|
+
await updateUntil(b, () => b.base.system.members === 2)
|
|
110
|
+
t.pass('b has two members')
|
|
111
|
+
const arr = await b.listWriters().toArray()
|
|
112
|
+
t.is(arr[0].name, 'maf')
|
|
82
113
|
})
|
|
83
114
|
|
|
84
115
|
test('invite resets when createInvite type is different than previous', async function (t) {
|
|
@@ -143,9 +174,8 @@ test('blind encryption', async function (t) {
|
|
|
143
174
|
t.ok(encryptionKeyEncryptedBuffer)
|
|
144
175
|
|
|
145
176
|
t.teardown(async () => await b.close())
|
|
146
|
-
b
|
|
147
|
-
|
|
148
|
-
})
|
|
177
|
+
await updateUntil(b, () => b.base.system.members === 2)
|
|
178
|
+
if (b.base.system.members === 2) t.pass('b has two members')
|
|
149
179
|
})
|
|
150
180
|
|
|
151
181
|
test('suspend and resume', async function (t) {
|
|
@@ -207,3 +237,15 @@ async function pair(t, inv, opts) {
|
|
|
207
237
|
const a = Autopass.pair(new Corestore(dir), inv, opts)
|
|
208
238
|
return a
|
|
209
239
|
}
|
|
240
|
+
|
|
241
|
+
function updateUntil(b, fn) {
|
|
242
|
+
return new Promise((resolve) => {
|
|
243
|
+
if (fn()) return resolve()
|
|
244
|
+
const check = () => {
|
|
245
|
+
if (!fn()) return
|
|
246
|
+
b.off('update', check)
|
|
247
|
+
resolve()
|
|
248
|
+
}
|
|
249
|
+
b.on('update', check)
|
|
250
|
+
})
|
|
251
|
+
}
|