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.
@@ -0,0 +1,427 @@
1
+ /***************************************************************************
2
+ * ___ ___
3
+ * / \ / \ VESvault
4
+ * \__ / \ __/ Encrypt Everything without fear of losing the Key
5
+ * \\ // https://vesvault.com https://ves.host
6
+ * \\ //
7
+ * ___ \\_//
8
+ * / \ / \ libVES.subtle.js
9
+ * \__ / \ __/ Manage and share e2e encrypted items
10
+ * \\ // Real time event tracking
11
+ * \\ // VES PKI and e2e Key Exchange
12
+ * \\_// VES Redundancies and Key Recovery
13
+ * / \
14
+ * \___/
15
+ *
16
+ *
17
+ * (c) 2025 - 2026 VESvault Corp
18
+ * Jim Zubov <jz@vesvault.com>
19
+ *
20
+ * SPDX-License-Identifier: Apache-2.0
21
+ *
22
+ * Licensed under the Apache License, Version 2.0 (the "License");
23
+ * you may not use this file except in compliance with the License.
24
+ * You may obtain a copy of the License in the accompanying LICENSE
25
+ * file, or at http://www.apache.org/licenses/LICENSE-2.0
26
+ *
27
+ * Unless required by applicable law or agreed to in writing, software
28
+ * distributed under the License is distributed on an "AS IS" BASIS,
29
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
30
+ * implied. See the License for the specific language governing
31
+ * permissions and limitations under the License.
32
+ ***************************************************************************/
33
+
34
+ /***************************************************************************
35
+ * @type libVES.Vault
36
+ * libVES.subtle Vault Factory
37
+ * Use "demo" for the public shared VES demo domain
38
+ * Use "x-*" to create your own experimental domain
39
+ * @returns libVES.Vault
40
+ ***************************************************************************/
41
+ let vesDomain = 'demo'
42
+ let vault = libVES.subtle(vesDomain)
43
+
44
+ /***************************************************************************
45
+ * Unlock the Vault
46
+ ***************************************************************************/
47
+ // Unlock a User App Vault using an interactive browser popup
48
+ await vault.unlock()
49
+
50
+ // OR, unlock a User App Vault using locally stored credentials. Make sure
51
+ // the credentials are stored securely
52
+ let credentialUri = 'ves://:demo@demo/demo/'
53
+ await vault.unlock(credentialUri)
54
+
55
+ // OR, unlock an Anonymous App Vault using a secret passPhrase. The Vault ID
56
+ // is uniquely generated from the passphrase.
57
+ let passPhrase = 'passphrase'
58
+ await vault.anonymous(passPhrase)
59
+
60
+ // Check if the Vault is unlocked
61
+ let isUnlocked = await vault.unlocked()
62
+
63
+ /***************************************************************************
64
+ * Get an array of all items stored in the vault
65
+ * @returns Promise(Array(libVES.Item))
66
+ ***************************************************************************/
67
+ let items = await vault.items()
68
+
69
+ /***************************************************************************
70
+ * Create an Item instance
71
+ * @returns libVES.Item
72
+ ***************************************************************************/
73
+ // Create an instance of an item with a specified itemId
74
+ let itemId = 'my-test-item'
75
+ let item = vault.item(itemId)
76
+
77
+ // Create an instance of an item with an automatically assigned itemId
78
+ let item = vault.item()
79
+
80
+ /***************************************************************************
81
+ * Start real time event tracking.
82
+ * Call vault.addEventListener() or define vault.on* event handlers prior to
83
+ * the following call. The handlers are invoked with libVES.CustomEvent
84
+ ***************************************************************************/
85
+ // Start tracking future events without replaying the event history
86
+ await vault.start()
87
+
88
+ // Or, start tracking and replay the past events starting with nextId.
89
+ // Use nextId = 0 to replay all history from the beginning.
90
+ let nextId = 0
91
+ await vault.start(nextId)
92
+
93
+ // Or, start tracking and replay the short history that includes only
94
+ // currently existing items
95
+ await vault.start(false)
96
+
97
+ /***************************************************************************
98
+ * Stop real time event tracking
99
+ ***************************************************************************/
100
+ vault.stop()
101
+
102
+ /***************************************************************************
103
+ * Get the special Item that stores the VESkey (passphrase) to the Vault.
104
+ * The VESkey can be retrieved using item.get() is it is decryptable by the
105
+ * unlocked Vault.
106
+ * @returns Promise(libVES.Item)
107
+ ***************************************************************************/
108
+ let item = await vault.password()
109
+
110
+ /***************************************************************************
111
+ * Get the list of dependent Vaults that are directly unlockable by the
112
+ * current Vault.
113
+ * @returns Promise(Array(libVES.Vault))
114
+ ***************************************************************************/
115
+ let subVaults = await vault.vaults()
116
+
117
+ /***************************************************************************
118
+ * Create an instance of the specific Vault. The vaultId can be a VES URI
119
+ * or a short ID. Use the owner's email address to reference a Vault within
120
+ * the current VES Domain owned by the specific user.
121
+ * @returns libVES.Vault
122
+ ***************************************************************************/
123
+ let vaultId = 'user@acme.com'
124
+ let subVault = vault.vault(vaultId)
125
+
126
+ /***************************************************************************
127
+ * Verify the status of the Vault. This call returns a Promise that resolves
128
+ * to the current vault on success, or throws libVES.Error.
129
+ * The call populates vault.current and vault.owned
130
+ * @returns Promise(libVES.Vault)
131
+ ***************************************************************************/
132
+ let vault = await subVault.verify()
133
+
134
+ /***************************************************************************
135
+ * The following propertiest indicate the status of the Vault. The properies
136
+ * are populated by vault.unlock(), vault.verify(), and in the Vaults
137
+ * returned by item.share()
138
+ ***************************************************************************/
139
+ // The Vault currently exists, and is not in a Lost status
140
+ // @type boolean
141
+ vault.current
142
+
143
+ // The Vault/Subvault is owned by the unlocked Vault.
144
+ // @type boolean
145
+ vault.owner
146
+
147
+ // The Vault has an Admin permission on the Item. This property is populated
148
+ // only in the Vaults returned by item.share()
149
+ // @type boolean
150
+ vault.admin
151
+
152
+ /***************************************************************************
153
+ * Get a VES URI that idenitfies the Vault.
154
+ * @returns string
155
+ ***************************************************************************/
156
+ vault.uri()
157
+
158
+ /***************************************************************************
159
+ * Get a short identifier of the Vault. Note that the short identifier is
160
+ * specific to the selected VES domain. Use vault.uri() to get a full
161
+ * identifier that includes the VES domain.
162
+ * @returns string
163
+ ***************************************************************************/
164
+ vault.short()
165
+
166
+ /***************************************************************************
167
+ * Lock the Vault
168
+ ***************************************************************************/
169
+ // Set the lock timeout in seconds. The Vault will be automatically locked
170
+ // when the timeout expires. Register a handler for an "authexpire" event to
171
+ // catch the expiration before the Vault is locked.
172
+ // Any call to this function overrides the previously set timeout.
173
+ let tmOut = 300
174
+ vault.lock(tmOut)
175
+
176
+ // Lock the Vault immediately
177
+ vault.lock()
178
+
179
+ /***************************************************************************
180
+ * @type libVES.Item
181
+ * Store a value in the item. The value is stored in the VES Repository an
182
+ * e2e encrypted form.
183
+ ***************************************************************************/
184
+ let itemValue = 'secret'
185
+ await item.put(itemValue)
186
+
187
+ /***************************************************************************
188
+ * Retrieve the value stored in the item
189
+ * @returns Promise(string)
190
+ ***************************************************************************/
191
+ let itemValue = await item.get()
192
+
193
+ /***************************************************************************
194
+ * Manage the item sharing with other vaults in an e2e encrypted form
195
+ ***************************************************************************/
196
+ // Share the item with other vaults, keep any existing sharing
197
+ let vaultIds = ['user@acme.com']
198
+ await item.add(vaultIds)
199
+
200
+ // Remove sharing with the specified Vaults.
201
+ // Note: The current Vault can be removed if it doesn't own the Item.
202
+ // Removing will make the Item unaccessible through the current Vault,
203
+ // unless shared again by the Item owner.
204
+ let vaultIds = ['user@acme.com']
205
+ await item.remove(vaultIds)
206
+
207
+ // Replace the list of vaults the Item is shared with. The current Vault is
208
+ // added automatically if not included.
209
+ let vaultIds = ['user@acme.com']
210
+ await item.share(vaultIds)
211
+
212
+ // Get the list of vaults the Item is currently shared with
213
+ // @returns Promise(Array(libVES.Vault))
214
+ let shares = await item.share()
215
+
216
+ // Check whether the item is shared with a specific Vault. Returns null if
217
+ // not shared.
218
+ // @returns Promise(libVES.Vault)
219
+ let vaultId = 'user@acme.com'
220
+ let theShare = await item.shareFor(vaultId)
221
+
222
+ /***************************************************************************
223
+ * Check if the item currently exists and was not deleted.
224
+ * @returns boolean
225
+ ***************************************************************************/
226
+ let exists = await item.exists()
227
+
228
+ /***************************************************************************
229
+ * Delete the item. The item ID can be reused for another item.
230
+ ***************************************************************************/
231
+ await item.delete()
232
+
233
+ /***************************************************************************
234
+ * Start real time event tracking.
235
+ * Call item.addEventListener() or define item.on* event handlers prior to
236
+ * the following call. The handlers are invoked with libVES.CustomEvent
237
+ ***************************************************************************/
238
+
239
+ // Start tracking future events without replaying the event history
240
+ await item.start()
241
+
242
+ // Or, start tracking and replay the past events starting with nextId.
243
+ // Use nextId = 0 to replay all history from the beginning.
244
+ let nextId = 0
245
+ await item.start(nextId)
246
+
247
+ // Or, start tracking and replay the short history that includes only
248
+ // the Vaults the Item is currently shared with
249
+ await item.start(false)
250
+
251
+ /***************************************************************************
252
+ * Stop real time event tracking
253
+ ***************************************************************************/
254
+ item.stop()
255
+
256
+ /***************************************************************************
257
+ * Get a VES URI that idenitfies the Item.
258
+ * @returns string
259
+ ***************************************************************************/
260
+ item.uri()
261
+
262
+ /***************************************************************************
263
+ * Get a short identifier of the Item. Note that the short identifier is
264
+ * specific to the selected VES domain. Use item.uri() to get a full
265
+ * identifier that includes the VES domain.
266
+ * @returns string
267
+ ***************************************************************************/
268
+ item.short()
269
+
270
+ /***************************************************************************
271
+ * Check if the Item value can be retrieved and decrypted by the currently
272
+ * unlocked Vault.
273
+ * @returns boolean
274
+ ***************************************************************************/
275
+ let isReadable = await item.readable()
276
+
277
+ /***************************************************************************
278
+ * Check if the Item value can be overwritten by the currently unlocked
279
+ * Vault.
280
+ * @returns boolean
281
+ ***************************************************************************/
282
+ let isWritable = await item.writable()
283
+
284
+ /***************************************************************************
285
+ * Use the Item as a stream cipher for encrypting and decrypting arbitrary
286
+ * data. If the Item is used for a cipher, the cipher key is stored in the
287
+ * VES repository in an e2e encrypted form, and the Item cannot store any
288
+ * other value.
289
+ * @returns Promise(libVES.ItemCipher)
290
+ ***************************************************************************/
291
+ let itemCipher = await item.cipher()
292
+
293
+
294
+ /***************************************************************************
295
+ * @type libVES.ItemCipher
296
+ * A stream cipher for encrypting arbitrary data. The cipher key is stored
297
+ * in the VES Repository in an e2e encrypted form. The data encrypted by
298
+ * the cipher can be stored at any external storage. The default cipher
299
+ * algorithm is AES256GCM1K, a VES implementation based on AES-256 GCM.
300
+ * The plaintext and ciphertext data can be ArrayBuffer, Uint*Array,
301
+ * Int*Array, Blob or string. The type of the return value of encrypt() and
302
+ * decrypt() conforms to the type of the input value. If the type is string,
303
+ * the ciphertext is Base64 encoded.
304
+ ***************************************************************************/
305
+ // Encrypt the data
306
+ let plainText = 'The secret text'
307
+ let cipherText = await itemCipher.encrypt(plainText)
308
+
309
+ // Decrypt the data
310
+ let plainText = await itemCipher.decrypt(cipherText)
311
+
312
+ /***************************************************************************
313
+ * An arbitrary metadata object associated with the cipher. The metadata is
314
+ * stored in the VES Repository in an e2e encrypted form along with the
315
+ * cipher key.
316
+ ***************************************************************************/
317
+ // Store metadata
318
+ let cipherMeta = {myValue: 'Metadata String'}
319
+ await itemCipher.meta(cipherMeta)
320
+
321
+ // Retrieve metadata
322
+ let cipherMeta = await itemCipher.meta()
323
+
324
+
325
+ /***************************************************************************
326
+ * @type libVES.CustomEvent
327
+ * An event related to a Vault or an Item, current or hitorical. VES stores
328
+ * a history of essential events for all objects.
329
+ *
330
+ * Event types:
331
+ * "authexpire" : the Vault will be imminently locked unless an action
332
+ * is taken. The event handler may call vault.lock(tmOut)
333
+ * to extend the unlocked time by tmOut seconds. This
334
+ * event is real time only, not stored in the history
335
+ * "vaultcreate" : a Vault is created
336
+ * "vaultadd" : the Item that stores the passphrase to a Vault is
337
+ * shared with another Vault
338
+ * "vaultremove" : the Item that stores the passphrase to a Vault is
339
+ * unshared with another Vault
340
+ * "itemcreate" : an Item is created
341
+ * "itemadd" : an Item is shared with a Vault
342
+ * "itemremove" : an Item is unshared with a Vault
343
+ * "itemdelete" : an Item is deleted
344
+ * "itemchange" : an Item has been changed. This event is delivered to
345
+ * each Vault the Item is shared with that are currently
346
+ * listening to real time events. The event does not
347
+ * have historical value and is not guaranteed to be
348
+ * permanently stored by VES.
349
+ * "olditemadd" : a historical (deleted) version of the Item is shared
350
+ * with a Vault. Historical versions are not guaranteed
351
+ * to be permanently stored in the VES Repository.
352
+ * "olditemremove" : a historical version of the Item is unshared with a
353
+ * Vault
354
+ * "sessioncreate" : the vault has been unlocked, a new session is created
355
+ ***************************************************************************/
356
+ vesEvent.type
357
+
358
+ /***************************************************************************
359
+ * Event details dictionary
360
+ ***************************************************************************/
361
+ vesEvent.detail
362
+
363
+ // @type libVES.Item
364
+ // The Item pertaining to the Event. Populated for "item*" and "olditem*"
365
+ // event types.
366
+ vesEvent.detail.item
367
+
368
+ // @type libVES.Vault
369
+ // The Vault pertaining to the event that the Item was shared or unshared
370
+ // with. Populated for "*add" and "*remove" event types.
371
+ vesEvent.detail.share
372
+
373
+ // @type libVES.Vault
374
+ // The Vault pertaining to the Event, the passphrase Item to which was
375
+ // shared or unshared with another Vault, or an action was taken on.
376
+ // Populated for "vault*" and "authexpire" event types.
377
+ vesEvent.detail.vault
378
+
379
+ // @type libVES.Author
380
+ // The Session that authored the changes triggering the Event
381
+ let vesSession = vesEvent.detail.author
382
+
383
+ // @type libVES.Author
384
+ // The Session subject to the Event. Populated only for "session*" event
385
+ // types.
386
+ let vesSession = vesEvent.detail.session
387
+
388
+ // @type int
389
+ // A unique numeric ID of the Event. Not populated on provisional Events
390
+ // (when replay == true).
391
+ vesEvent.detail.id
392
+
393
+ // @type Date
394
+ // The timestamp of the Event. Not populated on provisional Events (when
395
+ // replay == true).
396
+ vesEvent.detail.at
397
+
398
+ // @type boolean
399
+ // If set to true, the Event is provisional, and does not correspond to
400
+ // any Event stored in VES. Provisional events are generated by
401
+ // vault.start(false) or item.start(false) to replay the short history
402
+ // that leads to the current state of the Vault / Item.
403
+ vesEvent.detail.replay
404
+
405
+ /***************************************************************************
406
+ * @type libVES.Author
407
+ * A VES session pertaining to an authenticated App Vault or to a VES User.
408
+ * The details of the session can only be retrieved by a Session with the
409
+ * same owner. Historical Session details are not guaranteed to be
410
+ * permanently stored in VES.
411
+ ***************************************************************************/
412
+
413
+ // @type int
414
+ // A unique numeric Session ID
415
+ vesSession.sessid
416
+
417
+ // @type libVES.Vault
418
+ // The Vault that is authorized for the Session
419
+ vesSession.vault
420
+
421
+ // @type string
422
+ // An IPv4 or IPv6 address of the creator of the Session
423
+ vesSession.remote
424
+
425
+ // @type string
426
+ // A User Agent string passed to the API call that created the Session
427
+ vesSession.userAgent