libves 3.0.2 → 3.2.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/LICENSE +202 -0
- package/NOTICE +4 -0
- package/README.md +153 -418
- package/doc/libVES.subtle.js +427 -0
- package/libVES.js +7907 -0
- package/libVES.node.js +7172 -128
- package/package.json +33 -16
- package/libves-3.0.2.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,424 +1,159 @@
|
|
|
1
|
-
|
|
1
|
+
```
|
|
2
|
+
___ ___
|
|
3
|
+
/ \ / \ VESvault
|
|
4
|
+
\__ / \ __/ Encrypt Everything without fear of losing the Key
|
|
5
|
+
\\ // https://vesvault.com https://ves.host
|
|
6
|
+
\\ //
|
|
7
|
+
___ \\_//
|
|
8
|
+
/ \ / \ libVES: VESvault API library
|
|
9
|
+
\__ / \ __/
|
|
10
|
+
\\ //
|
|
11
|
+
\\ //
|
|
12
|
+
\\_// - Key Management and Exchange
|
|
13
|
+
/ \ - Item Encryption and Sharing
|
|
14
|
+
\___/ - VESrecovery™
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
# libVES.js
|
|
18
|
+
|
|
19
|
+
[](https://github.com/vesvault/libVES/actions/workflows/ci.yml)
|
|
20
|
+
[](https://www.npmjs.com/package/libves)
|
|
21
|
+
[](LICENSE)
|
|
22
|
+
|
|
23
|
+
**End-to-end encryption for the browser and Node — that you can actually recover from.**
|
|
24
|
+
|
|
25
|
+
The official VESvault JavaScript library. It does client-side end-to-end encryption
|
|
26
|
+
with three things most E2E stacks leave you to build (or skip) yourself:
|
|
27
|
+
|
|
28
|
+
- **End-to-end encryption at rest** — data is encrypted in the browser/Node; the server
|
|
29
|
+
only ever stores ciphertext.
|
|
30
|
+
- **Secure item sharing** — share an encrypted value with another user by reference;
|
|
31
|
+
they decrypt it with *their* key, no shared password.
|
|
32
|
+
- **VESrecovery™** — recover from a lost key without weakening the encryption.
|
|
33
|
+
|
|
34
|
+
Also on npm: [`libves`](https://www.npmjs.com/package/libves).
|
|
35
|
+
|
|
36
|
+
## Why VES exists
|
|
37
|
+
|
|
38
|
+
True end-to-end encryption has a brutal failure mode: **lose the key and the data is
|
|
39
|
+
gone forever.** That single problem is why most products quietly fall back to
|
|
40
|
+
server-side encryption, where the provider can read everything.
|
|
2
41
|
|
|
3
|
-
|
|
4
|
-
|
|
42
|
+
VES makes the encryption keys themselves recoverable — through other devices and people
|
|
43
|
+
you trust — **without the VESvault service ever seeing your keys or your plaintext.**
|
|
44
|
+
You get real end-to-end encryption *and* a way back in when a device is lost.
|
|
5
45
|
|
|
6
|
-
|
|
46
|
+
> **Is VESrecovery a backdoor?** No. Recovery re-shares an encrypted key along a trust
|
|
47
|
+
> chain *you* define (your other devices, designated recovery contacts); the server only
|
|
48
|
+
> ever holds ciphertext it cannot decrypt. The mechanism — and its honest trade-offs —
|
|
49
|
+
> are written up in the [VESrecovery design doc](https://github.com/vesvault/libVES.c/blob/master/doc/VESrecovery.md)
|
|
50
|
+
> and at <https://ves.host>. We welcome scrutiny of it.
|
|
7
51
|
|
|
52
|
+
## Quick start
|
|
8
53
|
|
|
54
|
+
```js
|
|
55
|
+
// Open a vault in the shared `demo` domain (use your own identity in place of
|
|
56
|
+
// me@example.com). unlock() runs your app's auth: the VES authorization popup
|
|
57
|
+
// in the browser, or the local key store under Node — see the docs for options.
|
|
58
|
+
const vault = libVES.subtle('//demo/me@example.com');
|
|
59
|
+
await vault.unlock();
|
|
60
|
+
|
|
61
|
+
// Items are addressed by URI. Encrypt + store, then read it back:
|
|
62
|
+
await vault.item('//demo/note-1').put('hello');
|
|
63
|
+
console.log(await vault.item('//demo/note-1').get()); // -> "hello"
|
|
64
|
+
|
|
65
|
+
// Share with another VES user — they decrypt with their own key
|
|
66
|
+
// (their vault must already exist):
|
|
67
|
+
await vault.item('//demo/note-1').share(['//demo/friend@example.com']);
|
|
9
68
|
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
* @returns libVES.Item
|
|
68
|
-
***************************************************************************/
|
|
69
|
-
// Create an instance of an item with a specified itemId
|
|
70
|
-
let itemId = 'my-test-item'
|
|
71
|
-
let item = vault.item(itemId)
|
|
72
|
-
|
|
73
|
-
// Create an instance of an item with an automatically assigned itemId
|
|
74
|
-
let item = vault.item()
|
|
75
|
-
|
|
76
|
-
/***************************************************************************
|
|
77
|
-
* Start real time event tracking.
|
|
78
|
-
* Call vault.addEventListener() or define vault.on* event handlers prior to
|
|
79
|
-
* the following call. The handlers are invoked with libVES.CustomEvent
|
|
80
|
-
***************************************************************************/
|
|
81
|
-
// Start tracking future events without replaying the event history
|
|
82
|
-
await vault.start()
|
|
83
|
-
|
|
84
|
-
// Or, start tracking and replay the past events starting with nextId.
|
|
85
|
-
// Use nextId = 0 to replay all history from the beginning.
|
|
86
|
-
let nextId = 0
|
|
87
|
-
await vault.start(nextId)
|
|
88
|
-
|
|
89
|
-
// Or, start tracking and replay the short history that includes only
|
|
90
|
-
// currently existing items
|
|
91
|
-
await vault.start(false)
|
|
92
|
-
|
|
93
|
-
/***************************************************************************
|
|
94
|
-
* Stop real time event tracking
|
|
95
|
-
***************************************************************************/
|
|
96
|
-
vault.stop()
|
|
97
|
-
|
|
98
|
-
/***************************************************************************
|
|
99
|
-
* Get the special Item that stores the VESkey (passphrase) to the Vault.
|
|
100
|
-
* The VESkey can be retrieved using item.get() is it is decryptable by the
|
|
101
|
-
* unlocked Vault.
|
|
102
|
-
* @returns Promise(libVES.Item)
|
|
103
|
-
***************************************************************************/
|
|
104
|
-
let item = await vault.password()
|
|
105
|
-
|
|
106
|
-
/***************************************************************************
|
|
107
|
-
* Get the list of dependent Vaults that are directly unlockable by the
|
|
108
|
-
* current Vault.
|
|
109
|
-
* @returns Promise(Array(libVES.Vault))
|
|
110
|
-
***************************************************************************/
|
|
111
|
-
let subVaults = await vault.vaults()
|
|
112
|
-
|
|
113
|
-
/***************************************************************************
|
|
114
|
-
* Create an instance of the specific Vault. The vaultId can be a VES URI
|
|
115
|
-
* or a short ID. Use the owner's email address to reference a Vault within
|
|
116
|
-
* the current VES Domain owned by the specific user.
|
|
117
|
-
* @returns libVES.Vault
|
|
118
|
-
***************************************************************************/
|
|
119
|
-
let vaultId = 'user@acme.com'
|
|
120
|
-
let subVault = vault.vault(vaultId)
|
|
121
|
-
|
|
122
|
-
/***************************************************************************
|
|
123
|
-
* Verify the status of the Vault. This call returns a Promise that resolves
|
|
124
|
-
* to the current vault on success, or throws libVES.Error.
|
|
125
|
-
* The call populates vault.current and vault.owned
|
|
126
|
-
* @returns Promise(libVES.Vault)
|
|
127
|
-
***************************************************************************/
|
|
128
|
-
let vault = await subVault.verify()
|
|
129
|
-
|
|
130
|
-
/***************************************************************************
|
|
131
|
-
* The following propertiest indicate the status of the Vault. The properies
|
|
132
|
-
* are populated by vault.unlock(), vault.verify(), and in the Vaults
|
|
133
|
-
* returned by item.share()
|
|
134
|
-
***************************************************************************/
|
|
135
|
-
// The Vault currently exists, and is not in a Lost status
|
|
136
|
-
// @type boolean
|
|
137
|
-
vault.current
|
|
138
|
-
|
|
139
|
-
// The Vault/Subvault is owned by the unlocked Vault.
|
|
140
|
-
// @type boolean
|
|
141
|
-
vault.owner
|
|
142
|
-
|
|
143
|
-
// The Vault has an Admin permission on the Item. This property is populated
|
|
144
|
-
// only in the Vaults returned by item.share()
|
|
145
|
-
// @type boolean
|
|
146
|
-
vault.admin
|
|
147
|
-
|
|
148
|
-
/***************************************************************************
|
|
149
|
-
* Get a VES URI that idenitfies the Vault.
|
|
150
|
-
* @returns string
|
|
151
|
-
***************************************************************************/
|
|
152
|
-
vault.uri()
|
|
153
|
-
|
|
154
|
-
/***************************************************************************
|
|
155
|
-
* Get a short identifier of the Vault. Note that the short identifier is
|
|
156
|
-
* specific to the selected VES domain. Use vault.uri() to get a full
|
|
157
|
-
* identifier that includes the VES domain.
|
|
158
|
-
* @returns string
|
|
159
|
-
***************************************************************************/
|
|
160
|
-
vault.short()
|
|
161
|
-
|
|
162
|
-
/***************************************************************************
|
|
163
|
-
* Lock the Vault
|
|
164
|
-
***************************************************************************/
|
|
165
|
-
// Set the lock timeout in seconds. The Vault will be automatically locked
|
|
166
|
-
// when the timeout expires. Register a handler for an "authexpire" event to
|
|
167
|
-
// catch the expiration before the Vault is locked.
|
|
168
|
-
// Any call to this function overrides the previously set timeout.
|
|
169
|
-
let tmOut = 300
|
|
170
|
-
vault.lock(tmOut)
|
|
171
|
-
|
|
172
|
-
// Lock the Vault immediately
|
|
173
|
-
vault.lock()
|
|
174
|
-
|
|
175
|
-
/***************************************************************************
|
|
176
|
-
* @type libVES.Item
|
|
177
|
-
* Store a value in the item. The value is stored in the VES Repository an
|
|
178
|
-
* e2e encrypted form.
|
|
179
|
-
***************************************************************************/
|
|
180
|
-
let itemValue = 'secret'
|
|
181
|
-
await item.put(itemValue)
|
|
182
|
-
|
|
183
|
-
/***************************************************************************
|
|
184
|
-
* Retrieve the value stored in the item
|
|
185
|
-
* @returns Promise(string)
|
|
186
|
-
***************************************************************************/
|
|
187
|
-
let itemValue = await item.get()
|
|
188
|
-
|
|
189
|
-
/***************************************************************************
|
|
190
|
-
* Manage the item sharing with other vaults in an e2e encrypted form
|
|
191
|
-
***************************************************************************/
|
|
192
|
-
// Share the item with other vaults, keep any existing sharing
|
|
193
|
-
let vaultIds = ['user@acme.com']
|
|
194
|
-
await item.add(vaultIds)
|
|
195
|
-
|
|
196
|
-
// Remove sharing with the specified Vaults.
|
|
197
|
-
// Note: The current Vault can be removed if it doesn't own the Item.
|
|
198
|
-
// Removing will make the Item unaccessible through the current Vault,
|
|
199
|
-
// unless shared again by the Item owner.
|
|
200
|
-
let vaultIds = ['user@acme.com']
|
|
201
|
-
await item.remove(vaultIds)
|
|
202
|
-
|
|
203
|
-
// Replace the list of vaults the Item is shared with. The current Vault is
|
|
204
|
-
// added automatically if not included.
|
|
205
|
-
let vaultIds = ['user@acme.com']
|
|
206
|
-
await item.share(vaultIds)
|
|
207
|
-
|
|
208
|
-
// Get the list of vaults the Item is currently shared with
|
|
209
|
-
// @returns Promise(Array(libVES.Vault))
|
|
210
|
-
let shares = await item.share()
|
|
211
|
-
|
|
212
|
-
// Check whether the item is shared with a specific Vault. Returns null if
|
|
213
|
-
// not shared.
|
|
214
|
-
// @returns Promise(libVES.Vault)
|
|
215
|
-
let vaultId = 'user@acme.com'
|
|
216
|
-
let theShare = await item.shareFor(vaultId)
|
|
217
|
-
|
|
218
|
-
/***************************************************************************
|
|
219
|
-
* Check if the item currently exists and was not deleted.
|
|
220
|
-
* @returns boolean
|
|
221
|
-
***************************************************************************/
|
|
222
|
-
let exists = await item.exists()
|
|
223
|
-
|
|
224
|
-
/***************************************************************************
|
|
225
|
-
* Delete the item. The item ID can be reused for another item.
|
|
226
|
-
***************************************************************************/
|
|
227
|
-
await item.delete()
|
|
228
|
-
|
|
229
|
-
/***************************************************************************
|
|
230
|
-
* Start real time event tracking.
|
|
231
|
-
* Call item.addEventListener() or define item.on* event handlers prior to
|
|
232
|
-
* the following call. The handlers are invoked with libVES.CustomEvent
|
|
233
|
-
***************************************************************************/
|
|
234
|
-
|
|
235
|
-
// Start tracking future events without replaying the event history
|
|
236
|
-
await item.start()
|
|
237
|
-
|
|
238
|
-
// Or, start tracking and replay the past events starting with nextId.
|
|
239
|
-
// Use nextId = 0 to replay all history from the beginning.
|
|
240
|
-
let nextId = 0
|
|
241
|
-
await item.start(nextId)
|
|
242
|
-
|
|
243
|
-
// Or, start tracking and replay the short history that includes only
|
|
244
|
-
// the Vaults the Item is currently shared with
|
|
245
|
-
await item.start(false)
|
|
246
|
-
|
|
247
|
-
/***************************************************************************
|
|
248
|
-
* Stop real time event tracking
|
|
249
|
-
***************************************************************************/
|
|
250
|
-
item.stop()
|
|
251
|
-
|
|
252
|
-
/***************************************************************************
|
|
253
|
-
* Get a VES URI that idenitfies the Item.
|
|
254
|
-
* @returns string
|
|
255
|
-
***************************************************************************/
|
|
256
|
-
item.uri()
|
|
257
|
-
|
|
258
|
-
/***************************************************************************
|
|
259
|
-
* Get a short identifier of the Item. Note that the short identifier is
|
|
260
|
-
* specific to the selected VES domain. Use item.uri() to get a full
|
|
261
|
-
* identifier that includes the VES domain.
|
|
262
|
-
* @returns string
|
|
263
|
-
***************************************************************************/
|
|
264
|
-
item.short()
|
|
265
|
-
|
|
266
|
-
/***************************************************************************
|
|
267
|
-
* Check if the Item value can be retrieved and decrypted by the currently
|
|
268
|
-
* unlocked Vault.
|
|
269
|
-
* @returns boolean
|
|
270
|
-
***************************************************************************/
|
|
271
|
-
let isReadable = await item.readable()
|
|
272
|
-
|
|
273
|
-
/***************************************************************************
|
|
274
|
-
* Check if the Item value can be overwritten by the currently unlocked
|
|
275
|
-
* Vault.
|
|
276
|
-
* @returns boolean
|
|
277
|
-
***************************************************************************/
|
|
278
|
-
let isWritable = await item.writable()
|
|
279
|
-
|
|
280
|
-
/***************************************************************************
|
|
281
|
-
* Use the Item as a stream cipher for encrypting and decrypting arbitrary
|
|
282
|
-
* data. If the Item is used for a cipher, the cipher key is stored in the
|
|
283
|
-
* VES repository in an e2e encrypted form, and the Item cannot store any
|
|
284
|
-
* other value.
|
|
285
|
-
* @returns Promise(libVES.ItemCipher)
|
|
286
|
-
***************************************************************************/
|
|
287
|
-
let itemCipher = await item.cipher()
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
/***************************************************************************
|
|
291
|
-
* @type libVES.ItemCipher
|
|
292
|
-
* A stream cipher for encrypting arbitrary data. The cipher key is stored
|
|
293
|
-
* in the VES Repository in an e2e encrypted form. The data encrypted by
|
|
294
|
-
* the cipher can be stored at any external storage. The default cipher
|
|
295
|
-
* algorithm is AES256GCM1K, a VES implementation based on AES-256 GCM.
|
|
296
|
-
* The plaintext and ciphertext data can be ArrayBuffer, Uint*Array,
|
|
297
|
-
* Int*Array, Blob or string. The type of the return value of encrypt() and
|
|
298
|
-
* decrypt() conforms to the type of the input value. If the type is string,
|
|
299
|
-
* the ciphertext is Base64 encoded.
|
|
300
|
-
***************************************************************************/
|
|
301
|
-
// Encrypt the data
|
|
302
|
-
let plainText = 'The secret text'
|
|
303
|
-
let cipherText = await itemCipher.encrypt(plainText)
|
|
304
|
-
|
|
305
|
-
// Decrypt the data
|
|
306
|
-
let plainText = await itemCipher.decrypt(cipherText)
|
|
307
|
-
|
|
308
|
-
/***************************************************************************
|
|
309
|
-
* An arbitrary metadata object associated with the cipher. The metadata is
|
|
310
|
-
* stored in the VES Repository in an e2e encrypted form along with the
|
|
311
|
-
* cipher key.
|
|
312
|
-
***************************************************************************/
|
|
313
|
-
// Store metadata
|
|
314
|
-
let cipherMeta = {myValue: 'Metadata String'}
|
|
315
|
-
await itemCipher.meta(cipherMeta)
|
|
316
|
-
|
|
317
|
-
// Retrieve metadata
|
|
318
|
-
let cipherMeta = await itemCipher.meta()
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
/***************************************************************************
|
|
322
|
-
* @type libVES.CustomEvent
|
|
323
|
-
* An event related to a Vault or an Item, current or hitorical. VES stores
|
|
324
|
-
* a history of essential events for all objects.
|
|
325
|
-
*
|
|
326
|
-
* Event types:
|
|
327
|
-
* "authexpire" : the Vault will be imminently locked unless an action
|
|
328
|
-
* is taken. The event handler may call vault.lock(tmOut)
|
|
329
|
-
* to extend the unlocked time by tmOut seconds. This
|
|
330
|
-
* event is real time only, not stored in the history
|
|
331
|
-
* "vaultcreate" : a Vault is created
|
|
332
|
-
* "vaultadd" : the Item that stores the passphrase to a Vault is
|
|
333
|
-
* shared with another Vault
|
|
334
|
-
* "vaultremove" : the Item that stores the passphrase to a Vault is
|
|
335
|
-
* unshared with another Vault
|
|
336
|
-
* "itemcreate" : an Item is created
|
|
337
|
-
* "itemadd" : an Item is shared with a Vault
|
|
338
|
-
* "itemremove" : an Item is unshared with a Vault
|
|
339
|
-
* "itemdelete" : an Item is deleted
|
|
340
|
-
* "itemchange" : an Item has been changed. This event is delivered to
|
|
341
|
-
* each Vault the Item is shared with that are currently
|
|
342
|
-
* listening to real time events. The event does not
|
|
343
|
-
* have historical value and is not guaranteed to be
|
|
344
|
-
* permanently stored by VES.
|
|
345
|
-
* "olditemadd" : a historical (deleted) version of the Item is shared
|
|
346
|
-
* with a Vault. Historical versions are not guaranteed
|
|
347
|
-
* to be permanently stored in the VES Repository.
|
|
348
|
-
* "olditemremove" : a historical version of the Item is unshared with a
|
|
349
|
-
* Vault
|
|
350
|
-
* "sessioncreate" : the vault has been unlocked, a new session is created
|
|
351
|
-
***************************************************************************/
|
|
352
|
-
vesEvent.type
|
|
353
|
-
|
|
354
|
-
/***************************************************************************
|
|
355
|
-
* Event details dictionary
|
|
356
|
-
***************************************************************************/
|
|
357
|
-
vesEvent.detail
|
|
358
|
-
|
|
359
|
-
// @type libVES.Item
|
|
360
|
-
// The Item pertaining to the Event. Populated for "item*" and "olditem*"
|
|
361
|
-
// event types.
|
|
362
|
-
vesEvent.detail.item
|
|
363
|
-
|
|
364
|
-
// @type libVES.Vault
|
|
365
|
-
// The Vault pertaining to the event that the Item was shared or unshared
|
|
366
|
-
// with. Populated for "*add" and "*remove" event types.
|
|
367
|
-
vesEvent.detail.share
|
|
368
|
-
|
|
369
|
-
// @type libVES.Vault
|
|
370
|
-
// The Vault pertaining to the Event, the passphrase Item to which was
|
|
371
|
-
// shared or unshared with another Vault, or an action was taken on.
|
|
372
|
-
// Populated for "vault*" and "authexpire" event types.
|
|
373
|
-
vesEvent.detail.vault
|
|
374
|
-
|
|
375
|
-
// @type libVES.Author
|
|
376
|
-
// The Session that authored the changes triggering the Event
|
|
377
|
-
let vesSession = vesEvent.detail.author
|
|
378
|
-
|
|
379
|
-
// @type libVES.Author
|
|
380
|
-
// The Session subject to the Event. Populated only for "session*" event
|
|
381
|
-
// types.
|
|
382
|
-
let vesSession = vesEvent.detail.session
|
|
383
|
-
|
|
384
|
-
// @type int
|
|
385
|
-
// A unique numeric ID of the Event. Not populated on provisional Events
|
|
386
|
-
// (when replay == true).
|
|
387
|
-
vesEvent.detail.id
|
|
388
|
-
|
|
389
|
-
// @type Date
|
|
390
|
-
// The timestamp of the Event. Not populated on provisional Events (when
|
|
391
|
-
// replay == true).
|
|
392
|
-
vesEvent.detail.at
|
|
393
|
-
|
|
394
|
-
// @type boolean
|
|
395
|
-
// If set to true, the Event is provisional, and does not correspond to
|
|
396
|
-
// any Event stored in VES. Provisional events are generated by
|
|
397
|
-
// vault.start(false) or item.start(false) to replay the short history
|
|
398
|
-
// that leads to the current state of the Vault / Item.
|
|
399
|
-
vesEvent.detail.replay
|
|
400
|
-
|
|
401
|
-
/***************************************************************************
|
|
402
|
-
* @type libVES.Author
|
|
403
|
-
* A VES session pertaining to an authenticated App Vault or to a VES User.
|
|
404
|
-
* The details of the session can only be retrieved by a Session with the
|
|
405
|
-
* same owner. Historical Session details are not guaranteed to be
|
|
406
|
-
* permanently stored in VES.
|
|
407
|
-
***************************************************************************/
|
|
408
|
-
|
|
409
|
-
// @type int
|
|
410
|
-
// A unique numeric Session ID
|
|
411
|
-
vesSession.sessid
|
|
412
|
-
|
|
413
|
-
// @type libVES.Vault
|
|
414
|
-
// The Vault that is authorized for the Session
|
|
415
|
-
vesSession.vault
|
|
416
|
-
|
|
417
|
-
// @type string
|
|
418
|
-
// An IPv4 or IPv6 address of the creator of the Session
|
|
419
|
-
vesSession.remote
|
|
420
|
-
|
|
421
|
-
// @type string
|
|
422
|
-
// A User Agent string passed to the API call that created the Session
|
|
423
|
-
vesSession.userAgent
|
|
69
|
+
|
|
70
|
+
`put()` / `get()` / `share()` handle the encryption, key exchange, and API calls for
|
|
71
|
+
you. Full API reference: <https://ves.host/docs/libVES-subtle>.
|
|
72
|
+
|
|
73
|
+
> **Domains.** A VES *domain* (the `demo` above) namespaces vaults and items. It may
|
|
74
|
+
> mirror a DNS domain, but it must be registered in VES first. Two kinds work without
|
|
75
|
+
> registration: **`demo`** — a shared sandbox, used in the examples here — and **`x-…`**
|
|
76
|
+
> — experimental domains (any name beginning with `x-`) that are created automatically
|
|
77
|
+
> on first use, giving you a private namespace to build against. Any other (real DNS)
|
|
78
|
+
> domain returns an error until it is registered through VES Enterprise.
|
|
79
|
+
|
|
80
|
+
Runnable end-to-end examples live in [`tests/`](tests/) (`01-item.js`, `02-share.js`,
|
|
81
|
+
…) and can be run with `node tests/01-item.js` or opened in the browser via
|
|
82
|
+
`tests/index.html`.
|
|
83
|
+
|
|
84
|
+
## Install
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
npm install libves
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or build from source (see below) and load `libVES-<version>.js` with a `<script>` tag.
|
|
91
|
+
|
|
92
|
+
## Building
|
|
93
|
+
|
|
94
|
+
- `node build.js` — produces version-stamped `libVES-<version>.js` (browser) and
|
|
95
|
+
`libVES-<version>.node.js` (Node) for CDN/`<script>` delivery, plus stable `libVES.js`
|
|
96
|
+
and `libVES.node.js` (the npm `browser` / `main` entry points). Cross-platform;
|
|
97
|
+
`Makefile.bat` and `make all` both call it.
|
|
98
|
+
- `node build.js --minify` — also writes `libVES-<version>.min.js` and `libVES.min.js`
|
|
99
|
+
(requires `npm i -D terser`).
|
|
100
|
+
- Requires **Node 18+** (uses the built-in `fetch`).
|
|
101
|
+
|
|
102
|
+
### Wasm builds
|
|
103
|
+
|
|
104
|
+
Post-quantum (ML-KEM via liboqs) and ECDH primitives are compiled to WebAssembly. See
|
|
105
|
+
the comments in [`WasmOQS/Makefile`](WasmOQS/Makefile) and
|
|
106
|
+
[`WasmECDH/Makefile`](WasmECDH/Makefile).
|
|
107
|
+
|
|
108
|
+
## Post-quantum
|
|
109
|
+
|
|
110
|
+
The library supports post-quantum key exchange (ML-KEM / Kyber and other KEMs) via the
|
|
111
|
+
`libVES.Algo.OQS` module and the WasmOQS build. This matters today: "harvest now,
|
|
112
|
+
decrypt later" means data exchanged with classical-only keys can be captured now and
|
|
113
|
+
broken once quantum hardware arrives.
|
|
114
|
+
|
|
115
|
+
## Real-time events
|
|
116
|
+
|
|
117
|
+
`libVES.Vault` and `libVES.Item` are event targets: call `.start()` and add listeners to
|
|
118
|
+
react to activity as it happens — an item shared with you, a key granted or revoked, a new
|
|
119
|
+
session opened.
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
vault.addEventListener('itemadd', (e) => {
|
|
123
|
+
console.log('shared with me:', e.detail.item.uri());
|
|
124
|
+
});
|
|
125
|
+
vault.start(); // begin watching; vault.stop() to end
|
|
424
126
|
```
|
|
127
|
+
|
|
128
|
+
Useful for live UI updates, notifications, and reacting to shares and revocations without
|
|
129
|
+
polling your own state. (`libVES.Watch` is the lower-level long-poll primitive underneath.)
|
|
130
|
+
|
|
131
|
+
## Pricing & terms
|
|
132
|
+
|
|
133
|
+
VES has a **free tier**; paid usage is **priced by volume**. The library is free and
|
|
134
|
+
open source under the Apache License 2.0. See current terms and pricing at
|
|
135
|
+
<https://ves.host/terms_conditions> and <https://vesvault.com>.
|
|
136
|
+
|
|
137
|
+
## Contributing
|
|
138
|
+
|
|
139
|
+
Bug reports and small, focused fixes are welcome via issues and pull requests. Because
|
|
140
|
+
this is security-critical software backed by a hosted service, larger changes — new
|
|
141
|
+
cryptography, API-surface or protocol changes — should **start with an issue** before you
|
|
142
|
+
write code; we can't always merge changes that affect the protocol or the service. See
|
|
143
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) for build, syntax-check, and test details, and our
|
|
144
|
+
[Code of Conduct](CODE_OF_CONDUCT.md).
|
|
145
|
+
|
|
146
|
+
Security issues are different: **please don't open a public issue or PR** — follow
|
|
147
|
+
[SECURITY.md](SECURITY.md).
|
|
148
|
+
|
|
149
|
+
## License
|
|
150
|
+
|
|
151
|
+
Apache License 2.0 — see [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE). Copyright © 2017–2026
|
|
152
|
+
VESvault Corp.
|
|
153
|
+
|
|
154
|
+
## Links
|
|
155
|
+
|
|
156
|
+
- Documentation — <https://ves.host>
|
|
157
|
+
- JavaScript API reference — <https://ves.host/docs/libVES-subtle>
|
|
158
|
+
- npm — <https://www.npmjs.com/package/libves>
|
|
159
|
+
- C library & `ves` CLI — <https://ves.host/docs/libVES-c>
|