autopass 3.2.0 → 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 CHANGED
@@ -83,7 +83,7 @@ Add a writer explictly.
83
83
 
84
84
  Get the local writer key.
85
85
 
86
- #### `inv = await pass.createInvite()`
86
+ #### `inv = await pass.createInvite({ readOnly })`
87
87
 
88
88
  Get invite to add a writer.
89
89
 
package/index.js CHANGED
@@ -70,14 +70,27 @@ class AutopassPairer extends ReadyResource {
70
70
 
71
71
  await this.pass.deleteInvite()
72
72
  }
73
+ const readOnly = JSON.parse(result.data.toString()).readOnly
73
74
  this.swarm = null
74
75
  this.store = null
75
- if (this.onresolve) this._whenWritable()
76
+ if (this.onresolve && readOnly) {
77
+ this._whenReadable()
78
+ } else if (this.onresolve) {
79
+ this._whenWritable()
80
+ }
76
81
  this.candidate.close().catch(noop)
77
82
  }
78
83
  })
79
84
  }
80
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
+
81
94
  _whenWritable() {
82
95
  if (this.pass.base.writable) return
83
96
  const check = () => {
@@ -238,14 +251,23 @@ class Autopass extends ReadyResource {
238
251
 
239
252
  async createInvite(opts) {
240
253
  if (this.opened === false) await this.ready()
254
+ const readOnly = opts?.readOnly ? true : false
241
255
  const existing = await this.base.view.findOne('@autopass/invite', {})
242
- if (existing) {
256
+
257
+ if (existing && existing.readOnly !== readOnly) {
258
+ await this.deleteInvite()
259
+ } else if (existing) {
243
260
  if (this.member) await this.member.flushed()
244
261
  return z32.encode(existing.invite)
245
262
  }
246
- const { id, invite, publicKey, expires } = BlindPairing.createInvite(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
+ }
268
+ )
247
269
 
248
- const record = { id, invite, publicKey, expires }
270
+ const record = { id, invite, publicKey, expires, readOnly, additional }
249
271
  await this.base.append(encode('@autopass/add-invite', record))
250
272
  if (this.member) await this.member.flushed()
251
273
  return z32.encode(record.invite)
@@ -313,11 +335,15 @@ class Autopass extends ReadyResource {
313
335
  if (inv === null || !b4a.equals(inv.id, id)) {
314
336
  return
315
337
  }
338
+ const readOnly = inv.readOnly
316
339
  candidate.open(inv.publicKey)
317
- await this.addWriter(candidate.userData)
340
+ if (!readOnly) {
341
+ await this.addWriter(candidate.userData)
342
+ }
318
343
  candidate.confirm({
319
344
  key: this.base.key,
320
- encryptionKey: this.base.encryptionKey
345
+ encryptionKey: this.base.encryptionKey,
346
+ additional: inv.additional
321
347
  })
322
348
  await this.deleteInvite()
323
349
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autopass",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "brittle": "npx brittle test.js",
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
  })
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(version, keyBuf, valueBuf) {
21
+ function collection0_reconstruct(schemaVersion, keyBuf, valueBuf) {
20
22
  const key = collection0_key.decode(keyBuf)
21
- setVersion(version)
22
- const record = c.decode(collection0_enc, valueBuf)
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(version, record) {
51
- setVersion(version)
52
- return c.encode(collection0_enc, record)
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(version, keyBuf, valueBuf) {
81
+ function collection1_reconstruct(schemaVersion, keyBuf, valueBuf) {
73
82
  const key = collection1_key.decode(keyBuf)
74
- setVersion(version)
75
- const record = c.decode(collection1_enc, valueBuf)
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(version, record) {
104
- setVersion(version)
105
- return c.encode(collection1_enc, record)
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(version, keyBuf, valueBuf) {
141
+ function collection2_reconstruct(schemaVersion, keyBuf, valueBuf) {
126
142
  const key = collection2_key.decode(keyBuf)
127
- setVersion(version)
128
- const record = c.decode(collection2_enc, valueBuf)
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(version, record) {
157
- setVersion(version)
158
- return c.encode(collection2_enc, record)
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(version, keyBuf, valueBuf) {
201
+ function collection3_reconstruct(schemaVersion, keyBuf, valueBuf) {
179
202
  const key = collection3_key.decode(keyBuf)
180
- setVersion(version)
181
- const record = c.decode(collection3_enc, valueBuf)
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(version, record) {
210
- setVersion(version)
211
- return c.encode(collection3_enc, record)
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(version, keyBuf, valueBuf) {
261
+ function collection4_reconstruct(schemaVersion, keyBuf, valueBuf) {
232
262
  const key = collection4_key.decode(keyBuf)
233
- setVersion(version)
234
- const record = c.decode(collection4_enc, valueBuf)
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(version, record) {
263
- setVersion(version)
264
- return c.encode(collection4_enc, record)
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(version, keyBuf, valueBuf) {
321
+ function collection5_reconstruct(schemaVersion, keyBuf, valueBuf) {
285
322
  const key = collection5_key.decode(keyBuf)
286
- setVersion(version)
287
- const record = c.decode(collection5_enc, valueBuf)
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(version, record) {
316
- setVersion(version)
317
- return c.encode(collection5_enc, record)
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(version, keyBuf, valueBuf) {
381
+ function collection6_reconstruct(schemaVersion, keyBuf, valueBuf) {
338
382
  const key = collection6_key.decode(keyBuf)
339
- setVersion(version)
340
- const record = c.decode(collection6_enc, valueBuf)
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(version, record) {
369
- setVersion(version)
370
- return c.encode(collection6_enc, record)
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) {
@@ -1,12 +1,12 @@
1
1
  // This file is autogenerated by the hyperschema compiler
2
- // Schema Version: 1
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 = 1
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/records/hyperdb#0
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 encoding8 = {
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 encoding9 = {
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 encoding10 = encoding9
252
+ const encoding11 = encoding10
210
253
 
211
254
  // @autopass/delete/hyperdb#4
212
- const encoding11 = encoding9
255
+ const encoding12 = encoding10
213
256
 
214
257
  // @autopass/del-invite/hyperdb#5
215
- const encoding12 = {
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 encoding13 = encoding9
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/records/hyperdb#0':
313
+ case '@autopass/additional-invite-data':
266
314
  return encoding7
267
- case '@autopass/invite/hyperdb#1':
315
+ case '@autopass/records/hyperdb#0':
268
316
  return encoding8
269
- case '@autopass/mirrors/hyperdb#2':
317
+ case '@autopass/invite/hyperdb#1':
270
318
  return encoding9
271
- case '@autopass/writer/hyperdb#3':
319
+ case '@autopass/mirrors/hyperdb#2':
272
320
  return encoding10
273
- case '@autopass/delete/hyperdb#4':
321
+ case '@autopass/writer/hyperdb#3':
274
322
  return encoding11
275
- case '@autopass/del-invite/hyperdb#5':
323
+ case '@autopass/delete/hyperdb#4':
276
324
  return encoding12
277
- case '@autopass/del-mirror/hyperdb#6':
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
  }
@@ -1,12 +1,12 @@
1
1
  // This file is autogenerated by the hyperschema compiler
2
- // Schema Version: 1
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 = 1
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
  }
@@ -1,12 +1,12 @@
1
1
  // This file is autogenerated by the hyperschema compiler
2
- // Schema Version: 1
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 = 1
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
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": 1,
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": -1,
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
@@ -23,8 +23,8 @@ test('invites', async function (t) {
23
23
  const tn = await testnet(10, t)
24
24
 
25
25
  const a = await create(t, { bootstrap: tn.bootstrap })
26
- t.teardown(() => {
27
- a.close()
26
+ t.teardown(async () => {
27
+ await a.close()
28
28
  })
29
29
 
30
30
  const onUpdate = function () {
@@ -43,7 +43,7 @@ test('invites', async function (t) {
43
43
  const b = await p.finished()
44
44
  await b.ready()
45
45
 
46
- t.teardown(() => b.close())
46
+ t.teardown(async () => await b.close())
47
47
  b.on('update', function () {
48
48
  if (b.base.system.members === 2) t.pass('b has two members')
49
49
  })
@@ -55,8 +55,8 @@ test('invites', async function (t) {
55
55
  const tn = await testnet(10, t)
56
56
 
57
57
  const a = await create(t, { bootstrap: tn.bootstrap })
58
- t.teardown(() => {
59
- a.close()
58
+ t.teardown(async () => {
59
+ await a.close()
60
60
  })
61
61
 
62
62
  const updateListener = function () {
@@ -75,12 +75,32 @@ test('invites', async function (t) {
75
75
  const b = await p.finished()
76
76
  await b.ready()
77
77
 
78
- t.teardown(() => b.close())
78
+ t.teardown(async () => await b.close())
79
79
  b.on('update', function () {
80
80
  if (b.base.system.members === 2) t.pass('b has two members')
81
81
  })
82
82
  })
83
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
+
84
104
  test('blind encryption', async function (t) {
85
105
  t.plan(4)
86
106
 
@@ -91,8 +111,8 @@ test('blind encryption', async function (t) {
91
111
  bootstrap: tn.bootstrap,
92
112
  blindEncryption: new BlindEncryptionSodium(password)
93
113
  })
94
- t.teardown(() => {
95
- a.close()
114
+ t.teardown(async () => {
115
+ await a.close()
96
116
  })
97
117
 
98
118
  const updateListener = function () {
@@ -122,7 +142,7 @@ test('blind encryption', async function (t) {
122
142
  t.absent(encryptionKeyBuffer)
123
143
  t.ok(encryptionKeyEncryptedBuffer)
124
144
 
125
- t.teardown(() => b.close())
145
+ t.teardown(async () => await b.close())
126
146
  b.on('update', function () {
127
147
  if (b.base.system.members === 2) t.pass('b has two members')
128
148
  })
@@ -135,12 +155,12 @@ test('suspend and resume', async function (t) {
135
155
 
136
156
  const a = await create(t, { bootstrap: tn.bootstrap })
137
157
  const inv = await a.createInvite()
138
- t.teardown(() => a.close())
158
+ t.teardown(async () => await a.close())
139
159
 
140
160
  const p = await pair(t, inv, { bootstrap: tn.bootstrap })
141
161
  const b = await p.finished()
142
162
  await b.ready()
143
- t.teardown(() => b.close())
163
+ t.teardown(async () => await b.close())
144
164
 
145
165
  await new Promise((resolve) => {
146
166
  const check = () => {