libves 2.3.1 → 2.16.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/libVES.node.js +822 -87
- package/package.json +1 -1
- package/libves-2.3.1.tgz +0 -0
package/libVES.node.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
*
|
|
28
28
|
* @title libVES
|
|
29
29
|
* @dev A JavaScript end-to-end encryption interface to VESvault REST API
|
|
30
|
-
* @version 2.
|
|
30
|
+
* @version 2.16
|
|
31
31
|
*
|
|
32
32
|
* @dev Official source code: https://github.com/vesvault/libVES
|
|
33
33
|
*
|
|
@@ -54,17 +54,20 @@ if (typeof(libVES) != 'function') function libVES(optns) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
libVES.prototype = {
|
|
57
|
+
constructor: libVES,
|
|
57
58
|
apiUrl: 'https://api.ves.host/v1/',
|
|
59
|
+
pollUrl: 'https://poll.ves.host/v1/',
|
|
58
60
|
wwwUrl: 'https://www.vesvault.com/',
|
|
59
61
|
keyAlgo: 'ECDH',
|
|
62
|
+
keyOptions: {namedCurve: 'P-521'},
|
|
60
63
|
textCipher: 'AES256GCMp',
|
|
61
64
|
defaultHash: 'SHA256',
|
|
62
|
-
|
|
65
|
+
propagators: [],
|
|
63
66
|
request: function(method,uri,body,optns) {
|
|
64
67
|
if (!optns) optns = {};
|
|
65
68
|
return new Promise(function(resolve,reject) {
|
|
66
69
|
var xhr = new XMLHttpRequest();
|
|
67
|
-
xhr.open(method,this.apiUrl + uri);
|
|
70
|
+
xhr.open(method, (uri.match(/^https\:/) ? uri : this.apiUrl + uri));
|
|
68
71
|
if (optns.abortFn) optns.abortFn(function() {
|
|
69
72
|
return xhr.abort();
|
|
70
73
|
});
|
|
@@ -183,7 +186,7 @@ libVES.prototype = {
|
|
|
183
186
|
return flow.setValue(undefined).then(function() {
|
|
184
187
|
return flow.addToken(url).then(function(url) {
|
|
185
188
|
document.location.replace(url);
|
|
186
|
-
throw
|
|
189
|
+
throw new libVES.Error('Redirect', 'Starting VES Authorization...');
|
|
187
190
|
});
|
|
188
191
|
});
|
|
189
192
|
});
|
|
@@ -294,13 +297,16 @@ libVES.prototype = {
|
|
|
294
297
|
var self = this;
|
|
295
298
|
return this.getVaultKey().then(function(k) {
|
|
296
299
|
return k.getId().then(function(kid) {
|
|
297
|
-
return k.getVaultEntries().then(function(ves) {
|
|
300
|
+
return k.getVaultEntries({type: true, deleted: true, file: {creator: true, externals: true}, vaultKey: {type: true, user: true}}).then(function(ves) {
|
|
298
301
|
var vis = {};
|
|
299
302
|
var vlst = [];
|
|
300
303
|
for (var i = 0; i < ves.length; i++) {
|
|
301
304
|
var viid = ves[i].vaultItem.id;
|
|
302
305
|
if (!vis[viid]) {
|
|
303
|
-
var vi =
|
|
306
|
+
var vi = ves[i].vaultItem;
|
|
307
|
+
if (!vi.file) vi.file = undefined;
|
|
308
|
+
if (!vi.vaultKey) vi.vaultKey = undefined;
|
|
309
|
+
vi = vis[viid] = self.getItem(vi);
|
|
304
310
|
vlst.push(vi);
|
|
305
311
|
vi.vaultEntryByKey[kid] = ves[i];
|
|
306
312
|
}
|
|
@@ -356,7 +362,7 @@ libVES.prototype = {
|
|
|
356
362
|
},
|
|
357
363
|
vaultRefToUser: function(ext) {
|
|
358
364
|
var email = ext.externalId ? ext.externalId.replace(/\!.*/, '') : '';
|
|
359
|
-
if (!email.match(/\@/)) throw
|
|
365
|
+
if (!email.match(/\@/)) throw new libVES.Error('NotFound', 'externalId is not an email for non-existing vault');
|
|
360
366
|
return new libVES.User({email: email}, self);
|
|
361
367
|
}
|
|
362
368
|
};
|
|
@@ -426,10 +432,18 @@ libVES.prototype = {
|
|
|
426
432
|
var key = new libVES.VaultKey({type: 'temp', algo: this.keyAlgo, user: usr}, self);
|
|
427
433
|
var veskey = this.generateVESkey(usr);
|
|
428
434
|
return key.generate(veskey, optns).then(function(k) {
|
|
429
|
-
if (self.e2e && self.e2e.length) usr.e2e = self.getVESkeyE2E(veskey, usr);
|
|
430
435
|
key.setField('vaultItems', veskey.then(function(v) {
|
|
431
436
|
var vi = new libVES.VaultItem({type: 'password'}, self);
|
|
432
|
-
return
|
|
437
|
+
return usr.getActiveVaultKeys().then(function() {
|
|
438
|
+
return [self.me(), self.getVaultKey(), usr];
|
|
439
|
+
}).catch(function(e) {
|
|
440
|
+
if (e.code != 'NotFound') throw e;
|
|
441
|
+
var sh = self.type == 'secondary' ? [self.me(), self.getVaultKey()] : [self.me()];
|
|
442
|
+
if (self.propagators) for (var i = 0; i < self.propagators.length; i++) sh.push(self.propagators[i]);
|
|
443
|
+
return sh;
|
|
444
|
+
}).then(function(sh) {
|
|
445
|
+
return Promise.all(sh);
|
|
446
|
+
}).then(function(sh) {
|
|
433
447
|
return vi.shareWith(sh, v, false).then(function() {
|
|
434
448
|
return [vi];
|
|
435
449
|
});
|
|
@@ -444,18 +458,6 @@ libVES.prototype = {
|
|
|
444
458
|
crypto.getRandomValues(buf);
|
|
445
459
|
return Promise.resolve(libVES.Util.ByteArrayToB64(buf));
|
|
446
460
|
},
|
|
447
|
-
getVESkeyE2E: function(veskey,usr) {
|
|
448
|
-
var self = this;
|
|
449
|
-
return veskey.then(function(v) {
|
|
450
|
-
return libVES.getModule(libVES.E2E,['Dialog','TempKey']).then(function(cls) {
|
|
451
|
-
return new cls({
|
|
452
|
-
user: usr,
|
|
453
|
-
e2e: self.e2e,
|
|
454
|
-
tempKey: v
|
|
455
|
-
});
|
|
456
|
-
});
|
|
457
|
-
});
|
|
458
|
-
},
|
|
459
461
|
setVESkey: function(veskey,lost,options) {
|
|
460
462
|
var self = this;
|
|
461
463
|
return this.me().then(function(me) {
|
|
@@ -651,7 +653,7 @@ libVES.prototype = {
|
|
|
651
653
|
return Promise.resolve(shareWith || self.getFileItem(fileRef).then(function(vi) {
|
|
652
654
|
return vi.getShareList();
|
|
653
655
|
}).catch(function(e) {
|
|
654
|
-
return self.usersToKeys([{domain:
|
|
656
|
+
return self.usersToKeys([{domain: VES.domain, externalId: VES.externalId}]);
|
|
655
657
|
})).then(function(shareWith) {
|
|
656
658
|
return vaultItem.shareWith(shareWith,value);
|
|
657
659
|
});
|
|
@@ -674,8 +676,8 @@ libVES.prototype = {
|
|
|
674
676
|
});
|
|
675
677
|
},
|
|
676
678
|
deleteFile: function(fileRef) {
|
|
677
|
-
return this.
|
|
678
|
-
return
|
|
679
|
+
return this.getFileItem(fileRef).then(function(item) {
|
|
680
|
+
return item.delete();
|
|
679
681
|
});
|
|
680
682
|
},
|
|
681
683
|
newSecret: function(cls) {
|
|
@@ -850,9 +852,11 @@ libVES.prototype = {
|
|
|
850
852
|
return vkey.rekey(optns);
|
|
851
853
|
});
|
|
852
854
|
else return vkey.getVaultItems().then(function(vis) {
|
|
853
|
-
return
|
|
854
|
-
return
|
|
855
|
-
|
|
855
|
+
return self.elevateAuth().then(function(optns) {
|
|
856
|
+
return Promise.all(vis.map(function(vi, i) {
|
|
857
|
+
return vi.reshareWith([user], undefined, optns);
|
|
858
|
+
}));
|
|
859
|
+
});
|
|
856
860
|
});
|
|
857
861
|
});
|
|
858
862
|
});
|
|
@@ -864,11 +868,27 @@ libVES.prototype = {
|
|
|
864
868
|
}
|
|
865
869
|
});
|
|
866
870
|
}));
|
|
871
|
+
},
|
|
872
|
+
setKeyAlgo: function(optns) {
|
|
873
|
+
if (typeof(optns) == 'string') {
|
|
874
|
+
this.keyOptions = null;
|
|
875
|
+
return this.keyAlgo = optns;
|
|
876
|
+
}
|
|
877
|
+
var algo = libVES.Algo.fromKeyOptions(optns);
|
|
878
|
+
if (algo) {
|
|
879
|
+
this.keyOptions = optns;
|
|
880
|
+
return this.keyAlgo = algo;
|
|
881
|
+
}
|
|
867
882
|
}
|
|
868
883
|
};
|
|
869
884
|
|
|
870
|
-
libVES.Error = function(code,msg,optns) {
|
|
885
|
+
libVES.Error = function(code, msg, optns) {
|
|
886
|
+
if (libVES.Error[code] && (libVES.Error[code].prototype instanceof libVES.Error)) return new (libVES.Error[code])(msg, optns);
|
|
871
887
|
this.code = code;
|
|
888
|
+
this.init(msg, optns);
|
|
889
|
+
};
|
|
890
|
+
|
|
891
|
+
libVES.Error.prototype.init = function(msg, optns) {
|
|
872
892
|
this.message = msg;
|
|
873
893
|
if (optns) for (var k in optns) this[k] = optns[k];
|
|
874
894
|
};
|
|
@@ -877,6 +897,32 @@ libVES.Error.prototype.toString = function() {
|
|
|
877
897
|
return this.message || this.code;
|
|
878
898
|
};
|
|
879
899
|
|
|
900
|
+
libVES.Error.NotFound = function(msg, optns) {
|
|
901
|
+
this.init(msg, optns);
|
|
902
|
+
};
|
|
903
|
+
libVES.Error.NotFound.prototype = new libVES.Error('NotFound');
|
|
904
|
+
|
|
905
|
+
libVES.Error.InvalidValue = function(msg, optns) {
|
|
906
|
+
this.init(msg, optns);
|
|
907
|
+
};
|
|
908
|
+
libVES.Error.InvalidValue.prototype = new libVES.Error('InvalidValue');
|
|
909
|
+
|
|
910
|
+
libVES.Error.InvalidKey = function(msg, optns) {
|
|
911
|
+
this.init(msg, optns);
|
|
912
|
+
};
|
|
913
|
+
libVES.Error.InvalidKey.prototype = new libVES.Error('InvalidKey');
|
|
914
|
+
|
|
915
|
+
libVES.Error.Redirect = function(msg, optns) {
|
|
916
|
+
this.init(msg, optns);
|
|
917
|
+
};
|
|
918
|
+
libVES.Error.Redirect.prototype = new libVES.Error('Redirect');
|
|
919
|
+
|
|
920
|
+
libVES.Error.Internal = function(msg, optns) {
|
|
921
|
+
this.init(msg, optns);
|
|
922
|
+
};
|
|
923
|
+
libVES.Error.Internal.prototype = new libVES.Error('Internal');
|
|
924
|
+
|
|
925
|
+
|
|
880
926
|
libVES.getModule = function(sectn,mods) {
|
|
881
927
|
var mod;
|
|
882
928
|
if (mods instanceof Array) mod = mods[0];
|
|
@@ -897,6 +943,9 @@ libVES.getModuleFunc = function(sectn,mod,then) {
|
|
|
897
943
|
libVES.loadModule = function(sectn,mod) {
|
|
898
944
|
return Promise.reject(new libVES.Error('Internal',"Cannot load " + sectn + '.' + mod));
|
|
899
945
|
};
|
|
946
|
+
libVES.maxKeyLen = 48896;
|
|
947
|
+
libVES.maxEncDataLen = 32768;
|
|
948
|
+
|
|
900
949
|
|
|
901
950
|
if (!libVES.Domain) libVES.Domain = {};
|
|
902
951
|
|
|
@@ -975,6 +1024,16 @@ libVES.Util = {
|
|
|
975
1024
|
}
|
|
976
1025
|
return rs;
|
|
977
1026
|
},
|
|
1027
|
+
loadWasm: function(src) {
|
|
1028
|
+
return new Promise(function(resolve, reject) {
|
|
1029
|
+
var sc = document.createElement('script');
|
|
1030
|
+
sc.async = false;
|
|
1031
|
+
sc.src = src;
|
|
1032
|
+
sc.onload = resolve;
|
|
1033
|
+
sc.onerror = reject;
|
|
1034
|
+
document.getElementsByTagName('head')[0].appendChild(sc);
|
|
1035
|
+
});
|
|
1036
|
+
},
|
|
978
1037
|
PEM: {
|
|
979
1038
|
toDER: function(pem) {
|
|
980
1039
|
var pp = pem.match(/-----BEGIN.*?-----\s*\r?\n([A-Za-z0-9\/\+\=\s\r\n]*)-----END/);
|
|
@@ -1129,6 +1188,43 @@ libVES.Util = {
|
|
|
1129
1188
|
this.value = rs.join('.');
|
|
1130
1189
|
} else this.value = s;
|
|
1131
1190
|
},
|
|
1191
|
+
Key: {
|
|
1192
|
+
fromDER: function(der, callbk) {
|
|
1193
|
+
var asn = libVES.Util.ASN1.decode(der)[0];
|
|
1194
|
+
if (typeof(asn[0]) == 'number') {
|
|
1195
|
+
var asn2 = libVES.Util.ASN1.decode(asn[2])[0];
|
|
1196
|
+
var pub = libVES.Util.ASN1.decode(asn2[2]);
|
|
1197
|
+
console.log('pub', pub);
|
|
1198
|
+
if (pub) return callbk(pub[0].slice(1), asn2[1], pub[0][0]);
|
|
1199
|
+
else callbk(null, asn2[1]);
|
|
1200
|
+
} else return callbk(asn[1].slice(1), null, asn[1][0]);
|
|
1201
|
+
},
|
|
1202
|
+
pubASN1: function(pub, optns) {
|
|
1203
|
+
var p = new Uint8Array(pub.byteLength + 1);
|
|
1204
|
+
p[0] = optns && optns.pubBits ? optns.pubBits : 0;
|
|
1205
|
+
p.set(new Uint8Array(pub), 1);
|
|
1206
|
+
p.ASN1type = 3;
|
|
1207
|
+
return p;
|
|
1208
|
+
},
|
|
1209
|
+
toPKCS: function(pub, priv, asn1hdr, optns) {
|
|
1210
|
+
if (priv) {
|
|
1211
|
+
var seq = [1, priv];
|
|
1212
|
+
if (pub) {
|
|
1213
|
+
p = libVES.Util.ASN1.encode([libVES.Util.Key.pubASN1(pub, optns)]);
|
|
1214
|
+
p.ASN1type = 0xa1;
|
|
1215
|
+
seq.push(p);
|
|
1216
|
+
}
|
|
1217
|
+
var buf = libVES.Util.ASN1.encode([seq]);
|
|
1218
|
+
return libVES.Util.ASN1.encode([[0, asn1hdr, buf]]);
|
|
1219
|
+
}
|
|
1220
|
+
return libVES.Util.ASN1.encode([[asn1hdr, libVES.Util.Key.pubASN1(pub, optns)]]);
|
|
1221
|
+
},
|
|
1222
|
+
export: function(pub, priv, asn1hdr, optns) {
|
|
1223
|
+
var pkcs = libVES.Util.Key.toPKCS(pub, priv, asn1hdr, optns);
|
|
1224
|
+
if (priv) return libVES.Util.PKCS8.encode8(pkcs, optns);
|
|
1225
|
+
return libVES.Util.PEM.encode(pkcs, 'PUBLIC KEY');
|
|
1226
|
+
}
|
|
1227
|
+
},
|
|
1132
1228
|
PKCS1: {
|
|
1133
1229
|
import: function(args,chain,optns) {
|
|
1134
1230
|
return chain('container',optns).then(function(der) {
|
|
@@ -1178,7 +1274,17 @@ libVES.Util = {
|
|
|
1178
1274
|
}
|
|
1179
1275
|
},
|
|
1180
1276
|
PKCS8: {
|
|
1181
|
-
encode: function(key,optns) {
|
|
1277
|
+
encode: function(key, optns) {
|
|
1278
|
+
return crypto.subtle.exportKey('pkcs8',key).catch(function(e) {
|
|
1279
|
+
console.log('PKCS8 failed, trying JWK...');
|
|
1280
|
+
return crypto.subtle.exportKey('jwk', key).then(function(jwk) {
|
|
1281
|
+
return libVES.Util.PKCS8.fromJWK(jwk);
|
|
1282
|
+
});
|
|
1283
|
+
}).then(function(pkcs8) {
|
|
1284
|
+
return libVES.Util.PKCS8.encode8(pkcs8, optns);
|
|
1285
|
+
});
|
|
1286
|
+
},
|
|
1287
|
+
encode8: function(pkcs8, optns) {
|
|
1182
1288
|
var ops = {};
|
|
1183
1289
|
for (var k in optns) ops[k] = optns[k];
|
|
1184
1290
|
if (!ops.members) ops.members = [
|
|
@@ -1187,24 +1293,17 @@ libVES.Util = {
|
|
|
1187
1293
|
];
|
|
1188
1294
|
return Promise.all(ops.members).then(function(ms) {
|
|
1189
1295
|
ops.members = ms;
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
}).then(function(
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
if (ops.password) return libVES.Util.PKCS5.export(function(call,optns) {
|
|
1199
|
-
rec[1] = optns.content;
|
|
1200
|
-
return Promise.resolve();
|
|
1201
|
-
},ops).then(function(data) {
|
|
1202
|
-
rec[0] = data;
|
|
1203
|
-
return libVES.Util.PEM.encode(libVES.Util.ASN1.encode([rec]),'ENCRYPTED PRIVATE KEY');
|
|
1204
|
-
});
|
|
1205
|
-
else if (ops.opentext) return libVES.Util.PEM.encode(der,'PRIVATE KEY');
|
|
1206
|
-
else throw new libVES.Error('Internal','No password for key export (opentext=true to export without password?)');
|
|
1296
|
+
ops.content = pkcs8;
|
|
1297
|
+
var rec = [];
|
|
1298
|
+
if (ops.password) return libVES.Util.PKCS5.export(function(call,optns) {
|
|
1299
|
+
rec[1] = optns.content;
|
|
1300
|
+
return Promise.resolve();
|
|
1301
|
+
},ops).then(function(data) {
|
|
1302
|
+
rec[0] = data;
|
|
1303
|
+
return libVES.Util.PEM.encode(libVES.Util.ASN1.encode([rec]),'ENCRYPTED PRIVATE KEY');
|
|
1207
1304
|
});
|
|
1305
|
+
else if (ops.opentext) return libVES.Util.PEM.encode(pkcs8,'PRIVATE KEY');
|
|
1306
|
+
else throw new libVES.Error('Internal','No password for key export (opentext=true to export without password?)');
|
|
1208
1307
|
});
|
|
1209
1308
|
},
|
|
1210
1309
|
fromJWK: function(jwk) {
|
|
@@ -1308,13 +1407,18 @@ libVES.Util = {
|
|
|
1308
1407
|
EC: {
|
|
1309
1408
|
import: function(args,chain,optns) {
|
|
1310
1409
|
return chain('container',optns).then(function(der) {
|
|
1311
|
-
var
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1410
|
+
var oid = String(args);
|
|
1411
|
+
var curve = libVES.Util.EC.namedCurves[oid] || oid;
|
|
1412
|
+
var a = {name:'ECDH',namedCurve: curve};
|
|
1413
|
+
return crypto.subtle.importKey('spki',der,a,true,[]).catch(function() {
|
|
1414
|
+
return crypto.subtle.importKey('pkcs8',der,a,true,['deriveKey','deriveBits']);
|
|
1415
|
+
}).catch(function(e) {
|
|
1416
|
+
console.log('PKCS8 failed, trying JWK...');
|
|
1417
|
+
var jwk = libVES.Util.PKCS8.toJWK(der);
|
|
1418
|
+
return crypto.subtle.importKey('jwk', jwk, a, true, jwk.key_ops);
|
|
1419
|
+
}).catch(function(e) {
|
|
1420
|
+
console.log('trying WasmECDH...');
|
|
1421
|
+
return libVES.Algo.ECDH.importWasm(curve, der);
|
|
1318
1422
|
});
|
|
1319
1423
|
});
|
|
1320
1424
|
},
|
|
@@ -1399,6 +1503,7 @@ libVES.Util.OID['1.2.840.113549.2.7'] = libVES.getModuleFunc(libVES, ['Util', 'H
|
|
|
1399
1503
|
libVES.Util.OID['1.2.840.113549.2.9'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA256']);
|
|
1400
1504
|
libVES.Util.OID['1.2.840.113549.2.10'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA384']);
|
|
1401
1505
|
libVES.Util.OID['1.2.840.113549.2.11'] = libVES.getModuleFunc(libVES, ['Util', 'Hash', 'SHA512']);
|
|
1506
|
+
libVES.Util.OID['1.3.6.1.4.1.53675.3.5'] = libVES.getModuleFunc(libVES, ['Algo', 'OQS', 'Util']);
|
|
1402
1507
|
|
|
1403
1508
|
libVES.Math = {
|
|
1404
1509
|
pad: function(a,n) {
|
|
@@ -1622,7 +1727,7 @@ libVES.Object.prototype = {
|
|
|
1622
1727
|
if (self.fieldClass[k]) return (clsf = function(v) {
|
|
1623
1728
|
if (v instanceof libVES.Object) return v;
|
|
1624
1729
|
else if (v instanceof Array) return v.map(function(vv) { return clsf(vv); });
|
|
1625
|
-
else return new (self.fieldClass[k])(v,self.VES);
|
|
1730
|
+
else if (v) return new (self.fieldClass[k])(v,self.VES);
|
|
1626
1731
|
})(v);
|
|
1627
1732
|
return v;
|
|
1628
1733
|
};
|
|
@@ -1639,6 +1744,34 @@ libVES.Object.prototype = {
|
|
|
1639
1744
|
return self[fld];
|
|
1640
1745
|
});
|
|
1641
1746
|
},
|
|
1747
|
+
getFields: function(fldlst, force) {
|
|
1748
|
+
var self = this;
|
|
1749
|
+
var flds = {};
|
|
1750
|
+
for (var i = 0; i < this.fieldSets.length; i++) {
|
|
1751
|
+
for (var k in this.fieldSets[i]) if (fldlst[k]) {
|
|
1752
|
+
for (var k in this.fieldSets[i]) if ((force || !this[k]) && !(flds[k] instanceof Object)) flds[k] = this.fieldSets[i][k];
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
for (var k in fldlst) if ((force || !this[k]) && !(flds[k] instanceof Object)) flds[k] = fldlst[k];
|
|
1757
|
+
for (var k in flds) {
|
|
1758
|
+
this.loadFields(flds);
|
|
1759
|
+
break;
|
|
1760
|
+
}
|
|
1761
|
+
var plst = [];
|
|
1762
|
+
for (var k in fldlst) {
|
|
1763
|
+
plst.push(Promise.resolve(this[k]).then(function(v) {
|
|
1764
|
+
if (!(v instanceof libVES.Object)) return v;
|
|
1765
|
+
return v.getFields(fldlst[k], force);
|
|
1766
|
+
}));
|
|
1767
|
+
}
|
|
1768
|
+
var rs = {};
|
|
1769
|
+
return Promise.all(plst).then(function(lst) {
|
|
1770
|
+
var i = 0;
|
|
1771
|
+
for (var k in fldlst) rs[k] = lst[i++];
|
|
1772
|
+
return rs;
|
|
1773
|
+
});
|
|
1774
|
+
},
|
|
1642
1775
|
getField: function(fld,fldlst,force) {
|
|
1643
1776
|
var self = this;
|
|
1644
1777
|
if (!this[fld] || force) {
|
|
@@ -1780,6 +1913,22 @@ libVES.File = function(data,VES,refs) {
|
|
|
1780
1913
|
this.init(data,VES,refs);
|
|
1781
1914
|
};
|
|
1782
1915
|
|
|
1916
|
+
libVES.Event = function(data, VES, refs) {
|
|
1917
|
+
this.init(data, VES, refs);
|
|
1918
|
+
};
|
|
1919
|
+
|
|
1920
|
+
libVES.Session = function(data, VES, refs) {
|
|
1921
|
+
this.init(data, VES, refs);
|
|
1922
|
+
};
|
|
1923
|
+
|
|
1924
|
+
libVES.oldDomain = libVES.Domain;
|
|
1925
|
+
libVES.Domain = function(dom, VES) {
|
|
1926
|
+
this.init({id: (dom ? dom : VES.domain)}, VES);
|
|
1927
|
+
};
|
|
1928
|
+
(function(old) {
|
|
1929
|
+
if (old) for (var k in old) libVES.Domain[k] = old[k];
|
|
1930
|
+
})(libVES.oldDomain);
|
|
1931
|
+
|
|
1783
1932
|
libVES.User.prototype = new libVES.Object({
|
|
1784
1933
|
apiUri: 'users',
|
|
1785
1934
|
fieldList: {id: true, email: true, type: true, firstName: true, lastName: true},
|
|
@@ -1951,12 +2100,14 @@ libVES.VaultKey.prototype = new libVES.Object({
|
|
|
1951
2100
|
});
|
|
1952
2101
|
},
|
|
1953
2102
|
generate: function(veskey,optns) {
|
|
2103
|
+
if (!optns) optns = this.VES.keyOptions;
|
|
1954
2104
|
var self = this;
|
|
2105
|
+
var a;
|
|
1955
2106
|
var wc = optns && optns.privateKey ? libVES.Algo.acquire(optns.privateKey).then(function(wc) {
|
|
1956
2107
|
self.setField('algo',wc.engine.tag);
|
|
1957
2108
|
if (!wc.privateKey) throw new libVES.Error('InvalidValue','Private key expected');
|
|
1958
2109
|
return wc;
|
|
1959
|
-
}) : (optns && optns
|
|
2110
|
+
}) : (optns && (a = libVES.Algo.fromKeyOptions(optns)) ? self.setField('algo', a) : Promise.resolve()).then(function() {
|
|
1960
2111
|
return self.engine().then(function(e) {
|
|
1961
2112
|
return e.generate(optns).then(function(ks) {
|
|
1962
2113
|
ks.engine = e;
|
|
@@ -2102,12 +2253,20 @@ libVES.VaultKey.prototype = new libVES.Object({
|
|
|
2102
2253
|
},
|
|
2103
2254
|
matchVaults: function(vaultKeys) {
|
|
2104
2255
|
return Promise.resolve(false);
|
|
2256
|
+
},
|
|
2257
|
+
getKeyOptions: function() {
|
|
2258
|
+
var self = this;
|
|
2259
|
+
return self.engine().then(function(e) {
|
|
2260
|
+
return self.getPublicCryptoKey().then(function(pub) {
|
|
2261
|
+
return e.getKeyOptions(pub);
|
|
2262
|
+
});
|
|
2263
|
+
});
|
|
2105
2264
|
}
|
|
2106
2265
|
});
|
|
2107
2266
|
|
|
2108
2267
|
libVES.VaultItem.prototype = new libVES.Object({
|
|
2109
2268
|
apiUri: 'vaultItems',
|
|
2110
|
-
fieldList: {id: true},
|
|
2269
|
+
fieldList: {id: true, deleted: true, file: true},
|
|
2111
2270
|
fieldClass: {vaultKey: libVES.VaultKey, file: libVES.File},
|
|
2112
2271
|
fieldSets: [{type: true, meta: true},{vaultEntries: {id: true, encData: true, vaultKey: {id: true, type: true, user: {id: true}, algo: true, externals: {id: true}}}},{vaultKey: true, file: true}],
|
|
2113
2272
|
defaultCipher: 'AES256GCM',
|
|
@@ -2164,6 +2323,9 @@ libVES.VaultItem.prototype = new libVES.Object({
|
|
|
2164
2323
|
getFile: function() {
|
|
2165
2324
|
return this.getField('file');
|
|
2166
2325
|
},
|
|
2326
|
+
getDeleted: function() {
|
|
2327
|
+
return this.getField('deleted');
|
|
2328
|
+
},
|
|
2167
2329
|
parse: function(buf) {
|
|
2168
2330
|
var self = this;
|
|
2169
2331
|
return this.getType().then(function(type) {
|
|
@@ -2228,7 +2390,8 @@ libVES.VaultItem.prototype = new libVES.Object({
|
|
|
2228
2390
|
});
|
|
2229
2391
|
});
|
|
2230
2392
|
}).then(function() {
|
|
2231
|
-
if (save || save === undefined) return self.post().then(function() {
|
|
2393
|
+
if (save || save === undefined) return self.post(undefined, undefined, ((save instanceof Object) ? save : undefined)).then(function() {
|
|
2394
|
+
delete(self.vaultEntries);
|
|
2232
2395
|
return self;
|
|
2233
2396
|
});
|
|
2234
2397
|
return self;
|
|
@@ -2284,6 +2447,12 @@ libVES.VaultItem.prototype = new libVES.Object({
|
|
|
2284
2447
|
return rs;
|
|
2285
2448
|
});
|
|
2286
2449
|
});
|
|
2450
|
+
},
|
|
2451
|
+
delete: function() {
|
|
2452
|
+
var self = this;
|
|
2453
|
+
return self.getId().then(function(id) {
|
|
2454
|
+
return this.VES.post(self.apiUri + '/' + id, {'$op': 'delete'});
|
|
2455
|
+
});
|
|
2287
2456
|
}
|
|
2288
2457
|
});
|
|
2289
2458
|
libVES.VaultItem.Type = {
|
|
@@ -2332,7 +2501,7 @@ libVES.VaultItem.Type.password = libVES.VaultItem.Type.string;
|
|
|
2332
2501
|
|
|
2333
2502
|
libVES.File.prototype = new libVES.Object({
|
|
2334
2503
|
apiUri: 'files',
|
|
2335
|
-
fieldList: {id: true},
|
|
2504
|
+
fieldList: {id: true, externals: true},
|
|
2336
2505
|
fieldClass: {externals: libVES.External, creator: libVES.User},
|
|
2337
2506
|
getExternals: function() {
|
|
2338
2507
|
return this.getField('externals');
|
|
@@ -2358,9 +2527,70 @@ libVES.External.prototype = new libVES.Object({
|
|
|
2358
2527
|
}
|
|
2359
2528
|
});
|
|
2360
2529
|
|
|
2530
|
+
|
|
2531
|
+
libVES.Event.prototype = new libVES.Object({
|
|
2532
|
+
apiUri: 'events',
|
|
2533
|
+
fieldList: {id: true, recordedAt: true, vaultKey: true, vaultItem: true, user: true},
|
|
2534
|
+
fieldClass: {vaultKey: libVES.VaultKey, vaultItem: libVES.VaultItem, user: libVES.User, creator: libVES.User, session: libVES.Session},
|
|
2535
|
+
getType: function() {
|
|
2536
|
+
return this.getField('type');
|
|
2537
|
+
},
|
|
2538
|
+
getVaultKey: function() {
|
|
2539
|
+
return this.getField('vaultKey');
|
|
2540
|
+
},
|
|
2541
|
+
getVaultItem: function() {
|
|
2542
|
+
return this.getField('vaultItem');
|
|
2543
|
+
},
|
|
2544
|
+
getUser: function() {
|
|
2545
|
+
return this.getField('user');
|
|
2546
|
+
},
|
|
2547
|
+
getCreator: function() {
|
|
2548
|
+
return this.getField('creator');
|
|
2549
|
+
},
|
|
2550
|
+
getSession: function() {
|
|
2551
|
+
return this.getField('session');
|
|
2552
|
+
}
|
|
2553
|
+
});
|
|
2554
|
+
|
|
2555
|
+
libVES.Session.prototype = new libVES.Object({
|
|
2556
|
+
apiUri: 'sessions',
|
|
2557
|
+
fieldList: {id: true, createdAt: true, expiresAt: true, vaultKey: true, user: true},
|
|
2558
|
+
fieldClass: {vaultKey: libVES.VaultKey, user: libVES.User},
|
|
2559
|
+
getVaultKey: function() {
|
|
2560
|
+
return this.getField('vaultKey');
|
|
2561
|
+
},
|
|
2562
|
+
getUser: function() {
|
|
2563
|
+
return this.getField('user');
|
|
2564
|
+
},
|
|
2565
|
+
getRemote: function() {
|
|
2566
|
+
return this.getField('remote');
|
|
2567
|
+
},
|
|
2568
|
+
getUserAgent: function() {
|
|
2569
|
+
return this.getField('userAgent');
|
|
2570
|
+
}
|
|
2571
|
+
});
|
|
2572
|
+
|
|
2573
|
+
libVES.Domain.prototype = new libVES.Object({
|
|
2574
|
+
apiUri: 'domains',
|
|
2575
|
+
fieldList: {id: true},
|
|
2576
|
+
fieldClass: {vaultKeys: libVES.VaultKey, vaultItems: libVES.VaultItem, creator: libVES.User},
|
|
2577
|
+
fieldSets: [{vaultItems: {id: true, type: true, file: {creator: true, externals: true}, deleted: true}, vaultKeys: {id: true, type: true, user: {id: true}, algo: true, externals: {id: true}}}],
|
|
2578
|
+
getCreator: function() {
|
|
2579
|
+
return this.getField('creator');
|
|
2580
|
+
},
|
|
2581
|
+
getVaultKeys: function() {
|
|
2582
|
+
return this.getField('vaultKeys');
|
|
2583
|
+
},
|
|
2584
|
+
getVaultItems: function() {
|
|
2585
|
+
return this.getField('vaultItems');
|
|
2586
|
+
}
|
|
2587
|
+
});
|
|
2588
|
+
|
|
2589
|
+
|
|
2361
2590
|
libVES.Algo = {
|
|
2362
2591
|
ECDH: {
|
|
2363
2592
|
tag: 'ECDH',
|
|
2593
|
+
defaultCurve: 'P-521',
|
|
2364
2594
|
decrypt: function(k,buf) {
|
|
2365
2595
|
var b = new Uint8Array(buf);
|
|
2366
2596
|
var data = libVES.Util.ASN1.decode(b);
|
|
@@ -2384,7 +2614,12 @@ libVES.Algo = {
|
|
|
2384
2614
|
return libVES.Algo.ECDH.eKey(k).then(function(eKey) {
|
|
2385
2615
|
return libVES.Algo.ECDH.cipher(eKey.privateKey,k).then(function(ci) {
|
|
2386
2616
|
return Promise.all([
|
|
2387
|
-
|
|
2617
|
+
((k instanceof CryptoKey)
|
|
2618
|
+
? crypto.subtle.exportKey('spki',eKey.publicKey)
|
|
2619
|
+
: libVES.Algo.ECDH.wasm().then(function(wasm) {
|
|
2620
|
+
return libVES.Util.Key.toPKCS(wasm.getpub(eKey.publicKey), null, libVES.Algo.ECDH.asn1hdr(wasm.getoid(eKey.publicKey)));
|
|
2621
|
+
})
|
|
2622
|
+
),
|
|
2388
2623
|
ci.encrypt(buf,true)
|
|
2389
2624
|
]).then(function(bufs) {
|
|
2390
2625
|
var buf = new Uint8Array(bufs[0].byteLength + bufs[1].byteLength);
|
|
@@ -2399,21 +2634,32 @@ libVES.Algo = {
|
|
|
2399
2634
|
});
|
|
2400
2635
|
},
|
|
2401
2636
|
eKey: function(pub) {
|
|
2402
|
-
return crypto.subtle.exportKey('jwk',pub).then(function(kdata) {
|
|
2637
|
+
if (pub instanceof CryptoKey) return crypto.subtle.exportKey('jwk',pub).then(function(kdata) {
|
|
2403
2638
|
return crypto.subtle.generateKey({name:'ECDH',namedCurve: kdata.crv},true,['deriveKey','deriveBits']).catch(function(e) {
|
|
2404
2639
|
throw new libVES.Error('InvalidValue','Error generating ECIES ephemeral',{error: e});
|
|
2405
2640
|
});
|
|
2406
2641
|
});
|
|
2642
|
+
return this.wasm().then(function(wasm) {
|
|
2643
|
+
var k = wasm.init(pub.curve);
|
|
2644
|
+
wasm.generate(k);
|
|
2645
|
+
return wasm.privpub(k);
|
|
2646
|
+
});
|
|
2647
|
+
},
|
|
2648
|
+
derive: function(priv, pub) {
|
|
2649
|
+
if (pub instanceof CryptoKey) return Promise.resolve(libVES.Algo.ECDH.curveBytes[pub.algorithm.namedCurve] || crypto.subtle.exportKey('jwk', pub).then(function(jwk) {
|
|
2650
|
+
return jwk.x.length * 3 / 4;
|
|
2651
|
+
})).then(function(len) {
|
|
2652
|
+
return crypto.subtle.deriveBits({name: 'ECDH', public: pub}, priv, 8 * len);
|
|
2653
|
+
});
|
|
2654
|
+
return this.wasm().then(function(wasm) {
|
|
2655
|
+
return wasm.derive(priv, pub);
|
|
2656
|
+
});
|
|
2407
2657
|
},
|
|
2408
|
-
cipher: function(priv,pub) {
|
|
2658
|
+
cipher: function(priv, pub) {
|
|
2409
2659
|
return libVES.getModule(libVES.Cipher,'AES256GCMp').then(function(m) {
|
|
2410
|
-
return
|
|
2411
|
-
return
|
|
2412
|
-
|
|
2413
|
-
return crypto.subtle.deriveBits({name:'ECDH',public:pub},priv,8 * len).then(function(raw) {
|
|
2414
|
-
return crypto.subtle.digest({name:'SHA-384'},raw).then(function(buf) {
|
|
2415
|
-
return new m(new Uint8Array(buf).slice(0,m.prototype.keySize + m.prototype.ivSize));
|
|
2416
|
-
});
|
|
2660
|
+
return libVES.Algo.ECDH.derive(priv, pub).then(function(raw) {
|
|
2661
|
+
return crypto.subtle.digest({name:'SHA-384'},raw).then(function(buf) {
|
|
2662
|
+
return new m(new Uint8Array(buf).slice(0,m.prototype.keySize + m.prototype.ivSize));
|
|
2417
2663
|
});
|
|
2418
2664
|
});
|
|
2419
2665
|
});
|
|
@@ -2448,13 +2694,22 @@ libVES.Algo = {
|
|
|
2448
2694
|
}).then(function(der) {
|
|
2449
2695
|
return libVES.Util.PEM.encode(der, 'PUBLIC KEY');
|
|
2450
2696
|
});
|
|
2451
|
-
}
|
|
2697
|
+
} else return this.wasm().then(function(wasm) {
|
|
2698
|
+
return libVES.Util.Key.export(wasm.getpub(data), wasm.getpriv(data), libVES.Algo.ECDH.asn1hdr(wasm.getoid(data)), optns);
|
|
2699
|
+
});
|
|
2452
2700
|
throw new libVES.Error('Internal', "Unknown type of key object");
|
|
2453
2701
|
},
|
|
2454
2702
|
generate: function(optns) {
|
|
2455
|
-
var op = {name:'ECDH', namedCurve:
|
|
2703
|
+
var op = {name: 'ECDH', namedCurve: this.defaultCurve};
|
|
2456
2704
|
if (optns) for (var k in optns) op[k] = optns[k];
|
|
2457
|
-
return crypto.subtle.generateKey(op,true,['deriveKey','deriveBits'])
|
|
2705
|
+
return crypto.subtle.generateKey(op, true, ['deriveKey', 'deriveBits']).catch(function(e) {
|
|
2706
|
+
console.log('ECDH generateKey failed, trying wasm...', e, op);
|
|
2707
|
+
return libVES.Algo.ECDH.wasm().then(function(wasm) {
|
|
2708
|
+
var k = wasm.init(op.namedCurve);
|
|
2709
|
+
if (!k || !wasm.generate(k)) throw new libVES.Error('InvalidValue', 'WasmECDH key generation error (unsupported curve?)');
|
|
2710
|
+
return wasm.privpub(k);
|
|
2711
|
+
});
|
|
2712
|
+
});
|
|
2458
2713
|
},
|
|
2459
2714
|
getPublic: function(priv) {
|
|
2460
2715
|
return crypto.subtle.exportKey('jwk',priv).then(function(k) {
|
|
@@ -2467,7 +2722,48 @@ libVES.Algo = {
|
|
|
2467
2722
|
y: k.y
|
|
2468
2723
|
},{name:'ECDH'},true,[]);
|
|
2469
2724
|
});
|
|
2470
|
-
}
|
|
2725
|
+
},
|
|
2726
|
+
getKeyOptions: function(key) {
|
|
2727
|
+
if (key instanceof CryptoKey) return crypto.subtle.exportKey('jwk', key).then(function(k) {
|
|
2728
|
+
return {namedCurve: k.crv};
|
|
2729
|
+
});
|
|
2730
|
+
return {namedCurve: k.curve};
|
|
2731
|
+
},
|
|
2732
|
+
asn1hdr: function(oid) {
|
|
2733
|
+
return [new libVES.Util.OID(this.OID), new libVES.Util.OID(oid)];
|
|
2734
|
+
},
|
|
2735
|
+
wasm: function() {
|
|
2736
|
+
if (!this.wasmP) this.wasmP = (typeof(WasmECDH) == 'function' ? Promise.resolve()
|
|
2737
|
+
: libVES.Util.loadWasm(WasmECDHinit.baseUrl + 'WasmECDH.js')
|
|
2738
|
+
).then(function() {
|
|
2739
|
+
return WasmECDH(WasmECDHinit);
|
|
2740
|
+
});
|
|
2741
|
+
return this.wasmP;
|
|
2742
|
+
},
|
|
2743
|
+
importWasm: function(curve, der) {
|
|
2744
|
+
return libVES.Algo.ECDH.wasm().then(function(wasm) {
|
|
2745
|
+
return libVES.Util.Key.fromDER(der, function(pub, priv, pubBits) {
|
|
2746
|
+
var k = wasm.init(curve);
|
|
2747
|
+
if (!k) return null;
|
|
2748
|
+
if (pub) wasm.setpub(k, pub);
|
|
2749
|
+
if (priv) wasm.setpriv(k, priv);
|
|
2750
|
+
return k;
|
|
2751
|
+
});
|
|
2752
|
+
});
|
|
2753
|
+
},
|
|
2754
|
+
getMethods: function() {
|
|
2755
|
+
var crvs = ['P-256', 'P-384', 'P-521'];
|
|
2756
|
+
return this.wasm().then(function(wasm) {
|
|
2757
|
+
return crvs.concat(wasm.getcurves());
|
|
2758
|
+
}).catch(function(e) {
|
|
2759
|
+
return crvs;
|
|
2760
|
+
}).then(function(crvs) {
|
|
2761
|
+
return crvs.map(function(algo) {
|
|
2762
|
+
return {namedCurve: algo};
|
|
2763
|
+
});
|
|
2764
|
+
});
|
|
2765
|
+
},
|
|
2766
|
+
OID: '1.2.840.10045.2.1'
|
|
2471
2767
|
},
|
|
2472
2768
|
RSA: {
|
|
2473
2769
|
tag: 'RSA',
|
|
@@ -2526,7 +2822,7 @@ libVES.Algo = {
|
|
|
2526
2822
|
throw new libVES.Error('Internal',"Unknown type of key object");
|
|
2527
2823
|
},
|
|
2528
2824
|
generate: function(optns) {
|
|
2529
|
-
var op = {name:'RSA-OAEP', modulusLength:
|
|
2825
|
+
var op = {name:'RSA-OAEP', modulusLength:4096, publicExponent:new Uint8Array([1,0,1]), hash:'SHA-256'};
|
|
2530
2826
|
if (optns) for (var k in optns) op[k] = optns[k];
|
|
2531
2827
|
return crypto.subtle.generateKey(op,true,['decrypt','encrypt']);
|
|
2532
2828
|
},
|
|
@@ -2539,9 +2835,25 @@ libVES.Algo = {
|
|
|
2539
2835
|
key_ops: ['encrypt'],
|
|
2540
2836
|
kty: 'RSA',
|
|
2541
2837
|
n: k.n
|
|
2542
|
-
},{name:'RSA-OAEP',hash:'SHA-
|
|
2838
|
+
},{name:'RSA-OAEP',hash:'SHA-256'},true,['encrypt']);
|
|
2543
2839
|
});
|
|
2544
|
-
}
|
|
2840
|
+
},
|
|
2841
|
+
getKeyOptions: function(key) {
|
|
2842
|
+
return crypto.subtle.exportKey('jwk', key).then(function(k) {
|
|
2843
|
+
return {modulusLength: ((k.n.length * 6) >> 3) * 8, publicExponent: libVES.Util.B64ToByteArray(k.e)};
|
|
2844
|
+
});
|
|
2845
|
+
},
|
|
2846
|
+
getMethods: function() {
|
|
2847
|
+
var bits = [];
|
|
2848
|
+
var s = 128;
|
|
2849
|
+
for (var i = 640; i <= 16384; i += s) {
|
|
2850
|
+
bits.push(i);
|
|
2851
|
+
if (i / s >= 8) s <<= 1;
|
|
2852
|
+
}
|
|
2853
|
+
return Promise.resolve(bits.map(function(b) {
|
|
2854
|
+
return {modulusLength: b};
|
|
2855
|
+
}));
|
|
2856
|
+
},
|
|
2545
2857
|
},
|
|
2546
2858
|
RSA_PKCS1_15: {
|
|
2547
2859
|
tag: 'RSA_PKCS1_15',
|
|
@@ -2578,9 +2890,107 @@ libVES.Algo = {
|
|
|
2578
2890
|
}
|
|
2579
2891
|
});
|
|
2580
2892
|
},
|
|
2893
|
+
fromKeyOptions: function(optns) {
|
|
2894
|
+
if (optns.namedCurve) return 'ECDH';
|
|
2895
|
+
if (optns.oqsAlgo) return 'OQS';
|
|
2896
|
+
if (optns.modulusLength) return 'RSA';
|
|
2897
|
+
},
|
|
2581
2898
|
toString: function() {
|
|
2582
2899
|
return 'libVES.Algo';
|
|
2583
|
-
}
|
|
2900
|
+
},
|
|
2901
|
+
all: ['RSA', 'ECDH']
|
|
2902
|
+
};
|
|
2903
|
+
|
|
2904
|
+
WasmECDHinit = {
|
|
2905
|
+
Key: function() {},
|
|
2906
|
+
init: function(curve) {
|
|
2907
|
+
var a = new Uint8Array(libVES.Util.StringToByteArray(curve));
|
|
2908
|
+
var arg1 = this.buf(a.byteLength + 1);
|
|
2909
|
+
arg1.set(a);
|
|
2910
|
+
arg1.set([0], a.byteLength);
|
|
2911
|
+
var ptr = this._WasmECDH_new(arg1.byteOffset);
|
|
2912
|
+
if (!ptr) return null;
|
|
2913
|
+
var key = new this.Key();
|
|
2914
|
+
key.ptr = ptr;
|
|
2915
|
+
key.curve = this.getcurve(key);
|
|
2916
|
+
return key;
|
|
2917
|
+
},
|
|
2918
|
+
buf: function(len) {
|
|
2919
|
+
return new Uint8Array(this.asm.memory.buffer, this._WasmECDH_buf, len);
|
|
2920
|
+
},
|
|
2921
|
+
str: function(ptr) {
|
|
2922
|
+
if (!ptr) return null;
|
|
2923
|
+
var b = new Uint8Array(this.asm.memory.buffer, ptr);
|
|
2924
|
+
return libVES.Util.ByteArrayToString(b.slice(0, b.indexOf(0)));
|
|
2925
|
+
},
|
|
2926
|
+
generate: function(key) {
|
|
2927
|
+
key.private = true;
|
|
2928
|
+
return this._WasmECDH_generate(key.ptr);
|
|
2929
|
+
},
|
|
2930
|
+
setpub: function(key, pub) {
|
|
2931
|
+
var arg1 = this.buf(pub.byteLength);
|
|
2932
|
+
arg1.set(pub);
|
|
2933
|
+
return this._WasmECDH_setpub(key.ptr, arg1.byteOffset, arg1.byteLength);
|
|
2934
|
+
},
|
|
2935
|
+
setpriv: function(key, priv) {
|
|
2936
|
+
key.private = true;
|
|
2937
|
+
var arg1 = this.buf(priv.byteLength);
|
|
2938
|
+
arg1.set(priv);
|
|
2939
|
+
return this._WasmECDH_setpriv(key.ptr, arg1.byteOffset, arg1.byteLength);
|
|
2940
|
+
},
|
|
2941
|
+
getpub: function(key) {
|
|
2942
|
+
var l = this._WasmECDH_getpub(key.ptr);
|
|
2943
|
+
if (l <= 0) return null;
|
|
2944
|
+
var rs = new Uint8Array(l);
|
|
2945
|
+
rs.set(this.buf(l));
|
|
2946
|
+
return rs;
|
|
2947
|
+
},
|
|
2948
|
+
getpriv: function(key) {
|
|
2949
|
+
if (!key.private) return null;
|
|
2950
|
+
var l = this._WasmECDH_getpriv(key.ptr);
|
|
2951
|
+
if (l <= 0) return null;
|
|
2952
|
+
var rs = new Uint8Array(l);
|
|
2953
|
+
rs.set(this.buf(l));
|
|
2954
|
+
return rs;
|
|
2955
|
+
},
|
|
2956
|
+
getcurve: function(key) {
|
|
2957
|
+
return this.str(this._WasmECDH_getcurve(key.ptr));
|
|
2958
|
+
},
|
|
2959
|
+
getoid: function(key) {
|
|
2960
|
+
return this.str(this._WasmECDH_getoid(key.ptr));
|
|
2961
|
+
},
|
|
2962
|
+
derive: function(priv, pub) {
|
|
2963
|
+
var l = this._WasmECDH_derive(priv.ptr, pub.ptr);
|
|
2964
|
+
if (l <= 0) return null;
|
|
2965
|
+
var rs = new Uint8Array(l);
|
|
2966
|
+
rs.set(this.buf(l));
|
|
2967
|
+
return rs;
|
|
2968
|
+
},
|
|
2969
|
+
privpub: function(priv) {
|
|
2970
|
+
var pub = new this.Key();
|
|
2971
|
+
pub.ptr = priv.ptr;
|
|
2972
|
+
pub.curve = priv.curve;
|
|
2973
|
+
return {privateKey: priv, publicKey: pub};
|
|
2974
|
+
},
|
|
2975
|
+
free: function(key) {
|
|
2976
|
+
this._WasmECDH_free(key.ptr);
|
|
2977
|
+
},
|
|
2978
|
+
getcurves: function() {
|
|
2979
|
+
var lst = this._WasmECDH_listinit(1024);
|
|
2980
|
+
var crvs = [];
|
|
2981
|
+
var c;
|
|
2982
|
+
for (var i = 0; (c = this._WasmECDH_listget(lst, i)); i++) {
|
|
2983
|
+
var crv = this.str(c);
|
|
2984
|
+
if (crv == '') continue;
|
|
2985
|
+
crvs.push(crv);
|
|
2986
|
+
}
|
|
2987
|
+
this._WasmECDH_listfree(lst);
|
|
2988
|
+
return crvs;
|
|
2989
|
+
},
|
|
2990
|
+
locateFile: function(file) {
|
|
2991
|
+
return this.baseUrl + file;
|
|
2992
|
+
},
|
|
2993
|
+
baseUrl: 'https://ves.host/pub/'
|
|
2584
2994
|
};
|
|
2585
2995
|
|
|
2586
2996
|
libVES.Cipher = function(data) {
|
|
@@ -3128,10 +3538,14 @@ libVES.Recovery.prototype = {
|
|
|
3128
3538
|
return this.getMyToken().then(function(tkn) {
|
|
3129
3539
|
if (!tkn) throw new libVES.Error('InvalidValue','No assistance available');
|
|
3130
3540
|
return self.vaultKey.getUser().then(function(user) {
|
|
3131
|
-
return
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
return
|
|
3541
|
+
return self.vaultKey.VES.elevateAuth().catch(function(e) {
|
|
3542
|
+
return undefined;
|
|
3543
|
+
}).then(function(optns) {
|
|
3544
|
+
return tkn.vaultItem.shareWith((assist ? [tkn.user,user] : [tkn.user]), undefined, optns).then(function() {
|
|
3545
|
+
self.tokens = undefined;
|
|
3546
|
+
self.vaultKey.vaultItems = undefined;
|
|
3547
|
+
return true;
|
|
3548
|
+
});
|
|
3135
3549
|
});
|
|
3136
3550
|
});
|
|
3137
3551
|
});
|
|
@@ -3380,7 +3794,7 @@ libVES.Flow.prototype.pubJWK = function(org) {
|
|
|
3380
3794
|
return libVES.Flow.jwkPub(jwk);
|
|
3381
3795
|
});
|
|
3382
3796
|
}) : Promise.resolve(sessionStorage['VESflow|' + org]).then(function(k) {
|
|
3383
|
-
if (!k) throw
|
|
3797
|
+
if (!k) throw new libVES.Error('NotFound', 'No public key stored for ' + org);
|
|
3384
3798
|
return JSON.parse(k);
|
|
3385
3799
|
}));
|
|
3386
3800
|
};
|
|
@@ -3407,7 +3821,7 @@ libVES.Flow.prototype.cipher = function(url) {
|
|
|
3407
3821
|
libVES.Flow.prototype.encrypt = function(url, val) {
|
|
3408
3822
|
var self = this;
|
|
3409
3823
|
return Promise.resolve(val || this.value()).then(function(val) {
|
|
3410
|
-
if (val == null) throw
|
|
3824
|
+
if (val == null) throw new libVES.Error('NoData', 'Empty value');
|
|
3411
3825
|
return self.cipher(url).then(function(ci) {
|
|
3412
3826
|
var iv = new Uint8Array(12);
|
|
3413
3827
|
crypto.getRandomValues(iv);
|
|
@@ -3498,7 +3912,7 @@ libVES.Flow.prototype.recv = function(dval) {
|
|
|
3498
3912
|
tk = t;
|
|
3499
3913
|
return true;
|
|
3500
3914
|
});
|
|
3501
|
-
if (tk == null) throw
|
|
3915
|
+
if (tk == null) throw new libVES.Error('NotFound', 'No valid token in the source url');
|
|
3502
3916
|
return Promise.resolve(self.source(src)).then(function() {
|
|
3503
3917
|
if (dval) for (var k in dval) if (tk[k] === undefined) tk[k] = dval[k];
|
|
3504
3918
|
return self.recvToken(tk);
|
|
@@ -3509,7 +3923,7 @@ libVES.Flow.prototype.recv = function(dval) {
|
|
|
3509
3923
|
libVES.Flow.prototype.recvToken = function(tk) {
|
|
3510
3924
|
var org = libVES.Flow.toOrigin(tk.url);
|
|
3511
3925
|
if (org != this.origin && tk.key) sessionStorage['VESflow|' + org] = JSON.stringify(tk.key);
|
|
3512
|
-
if (!tk.enc) return Promise.reject(
|
|
3926
|
+
if (!tk.enc) return Promise.reject(new libVES.Error('Incomplete', 'Missing encrypted data', {url: tk.url}));
|
|
3513
3927
|
return this.decrypt(tk.enc, org);
|
|
3514
3928
|
};
|
|
3515
3929
|
|
|
@@ -3524,7 +3938,7 @@ libVES.Flow.prototype.get = function() {
|
|
|
3524
3938
|
self.url = document.location.href;
|
|
3525
3939
|
return self.addToken(e.url).then(function(url) {
|
|
3526
3940
|
document.location.replace(url);
|
|
3527
|
-
throw
|
|
3941
|
+
throw new libVES.Error('Redirect', 'Completing the key exchange');
|
|
3528
3942
|
});
|
|
3529
3943
|
}
|
|
3530
3944
|
if (!data) throw e;
|
|
@@ -3538,13 +3952,13 @@ libVES.Flow.prototype.store = function(url) {
|
|
|
3538
3952
|
this.sent = 1;
|
|
3539
3953
|
return Promise.resolve(sessionStorage['VESflow.' + this.name + '>' + libVES.Flow.toOrigin(url)] = history.state['VESflow.' + this.name]);
|
|
3540
3954
|
}
|
|
3541
|
-
return Promise.reject(
|
|
3955
|
+
return Promise.reject(new libVES.Error('NotFound', 'Value is not set'));
|
|
3542
3956
|
};
|
|
3543
3957
|
|
|
3544
3958
|
libVES.Flow.prototype.fetch = function(url) {
|
|
3545
3959
|
var self = this;
|
|
3546
3960
|
return Promise.resolve(sessionStorage['VESflow.' + self.name + '>' + libVES.Flow.toOrigin(url)]).then(function(ctext) {
|
|
3547
|
-
if (!ctext) throw
|
|
3961
|
+
if (!ctext) throw new libVES.Error('NotFound', 'Not in the session storage');
|
|
3548
3962
|
return self.decrypt(ctext).then(function(data) {
|
|
3549
3963
|
self.erase(url);
|
|
3550
3964
|
return data;
|
|
@@ -3660,4 +4074,325 @@ libVES.Auth.prototype.verify = function(token, auth) {
|
|
|
3660
4074
|
});
|
|
3661
4075
|
};
|
|
3662
4076
|
|
|
4077
|
+
|
|
4078
|
+
libVES.Algo.OQS = {
|
|
4079
|
+
tag: 'OQS',
|
|
4080
|
+
wasm: function() {
|
|
4081
|
+
if (!this.wasmP) this.wasmP = (typeof(WasmOQS) == 'function' ? Promise.resolve()
|
|
4082
|
+
: libVES.Util.loadWasm(WasmOQSinit.baseUrl + 'WasmOQS.js')
|
|
4083
|
+
).then(function() {
|
|
4084
|
+
return WasmOQS(WasmOQSinit);
|
|
4085
|
+
});
|
|
4086
|
+
return this.wasmP;
|
|
4087
|
+
},
|
|
4088
|
+
checkLimits: function(k) {
|
|
4089
|
+
return k.pub.byteLength + k.priv.byteLength <= libVES.maxKeyLen && k.ctextlen + 64 <= libVES.maxEncDataLen;
|
|
4090
|
+
},
|
|
4091
|
+
decrypt: function(k,buf) {
|
|
4092
|
+
return this.wasm().then(function(wasm) {
|
|
4093
|
+
var b = new Uint8Array(buf);
|
|
4094
|
+
if (b.byteLength <= k.ctextlen) throw new libVES.Error('InvalidValue', 'Ciphertext is too short');
|
|
4095
|
+
var secret = wasm.decaps(k, b.slice(0, k.ctextlen));
|
|
4096
|
+
if (!secret) throw new libVES.Error('InvalidValue', 'OQS decryption error');
|
|
4097
|
+
return libVES.Algo.OQS.cipher(secret).then(function(ci) {
|
|
4098
|
+
return ci.decrypt(b.slice(k.ctextlen), true).catch(function(e) {
|
|
4099
|
+
if (e instanceof libVES.Error) throw e;
|
|
4100
|
+
throw new libVES.Error('InvalidValue', 'Error decrypting ECIES payload: Invalid ciphertext?',{error:e});
|
|
4101
|
+
});
|
|
4102
|
+
}).catch(function(e) {
|
|
4103
|
+
if (e instanceof libVES.Error) throw e;
|
|
4104
|
+
throw new libVES.Error('InvalidValue', 'Error negotiating ECIES cipher key: Invalid ciphertext?',{error:e});
|
|
4105
|
+
});
|
|
4106
|
+
})
|
|
4107
|
+
},
|
|
4108
|
+
encrypt: function(k, buf) {
|
|
4109
|
+
return this.wasm().then(function(wasm) {
|
|
4110
|
+
var ctext = wasm.encaps(k);
|
|
4111
|
+
if (!ctext) throw new libVES.Error('InvalidValue', 'Error generating OQS secret');
|
|
4112
|
+
return libVES.Algo.OQS.cipher(wasm.decaps(k)).then(function(ci) {
|
|
4113
|
+
return ci.encrypt(buf, true).then(function(ctext2) {
|
|
4114
|
+
var buf = new Uint8Array(ctext.byteLength + ctext2.byteLength);
|
|
4115
|
+
buf.set(new Uint8Array(ctext),0);
|
|
4116
|
+
buf.set(new Uint8Array(ctext2),ctext.byteLength);
|
|
4117
|
+
return buf;
|
|
4118
|
+
});
|
|
4119
|
+
}).catch(function(e) {
|
|
4120
|
+
if (e instanceof libVES.Error) throw e;
|
|
4121
|
+
throw new libVES.Error('InvalidValue', 'Error generating ECIES cipher',{error:e});
|
|
4122
|
+
});
|
|
4123
|
+
});
|
|
4124
|
+
},
|
|
4125
|
+
cipher: function(secret) {
|
|
4126
|
+
return libVES.getModule(libVES.Cipher,'AES256GCMp').then(function(m) {
|
|
4127
|
+
return crypto.subtle.digest({name:'SHA-384'}, secret).then(function(buf) {
|
|
4128
|
+
return new m(new Uint8Array(buf).slice(0, m.prototype.keySize + m.prototype.ivSize));
|
|
4129
|
+
});
|
|
4130
|
+
});
|
|
4131
|
+
},
|
|
4132
|
+
import: function(data,optns) {
|
|
4133
|
+
return libVES.Util.PEM.import(data,optns);
|
|
4134
|
+
},
|
|
4135
|
+
export: function(data, optns) {
|
|
4136
|
+
if (!data || !data.ptr) throw new libVES.Error('Internal', "Unknown type of key object");
|
|
4137
|
+
var oid = [new libVES.Util.OID(libVES.Algo.OQS.OID), libVES.Util.StringToByteArray(data.algo)];
|
|
4138
|
+
return libVES.Util.Key.export(data.pub, data.priv, oid, optns);
|
|
4139
|
+
},
|
|
4140
|
+
generate: function(optns) {
|
|
4141
|
+
var algo = optns ? optns.oqsAlgo : null;
|
|
4142
|
+
if (!algo) algo = this.defaultAlgo;
|
|
4143
|
+
return this.wasm().then(function(wasm) {
|
|
4144
|
+
var k = wasm.init(algo, true);
|
|
4145
|
+
if (!k) throw new libVES.Error('InvalidValue', 'OQS key init failed');
|
|
4146
|
+
if (!libVES.Algo.OQS.checkLimits(k)) throw wasm.free(k), new libVES.Error('Internal', 'OQS key is too large for VES');
|
|
4147
|
+
if (!wasm.generate(k)) throw wasm.free(k), new libVES.Error('Internal', 'OQS generate failed');
|
|
4148
|
+
var pub = new wasm.Key(k.algo);
|
|
4149
|
+
for (var i in k) if (i != 'priv') pub[i] = k[i];
|
|
4150
|
+
return {privateKey: k, publicKey: pub};
|
|
4151
|
+
});
|
|
4152
|
+
},
|
|
4153
|
+
getKeyOptions: function(key) {
|
|
4154
|
+
return {oqsAlgo: k.algo};
|
|
4155
|
+
},
|
|
4156
|
+
getMethods: function() {
|
|
4157
|
+
return this.wasm().then(function(wasm) {
|
|
4158
|
+
return wasm.getalgos().filter(function(algo) {
|
|
4159
|
+
var k = wasm.init(algo, true);
|
|
4160
|
+
if (!k) return false;
|
|
4161
|
+
var f = libVES.Algo.OQS.checkLimits(k);
|
|
4162
|
+
wasm.free(k);
|
|
4163
|
+
return f;
|
|
4164
|
+
}).map(function(algo) {
|
|
4165
|
+
return {oqsAlgo: algo};
|
|
4166
|
+
});
|
|
4167
|
+
});
|
|
4168
|
+
},
|
|
4169
|
+
Util: {
|
|
4170
|
+
import: function(args,chain,optns) {
|
|
4171
|
+
var algo = libVES.Util.ByteArrayToString(args);
|
|
4172
|
+
return chain('container').then(function(der) {
|
|
4173
|
+
return libVES.Util.Key.fromDER(der, function(pub, priv, pubBits) {
|
|
4174
|
+
return libVES.Algo.OQS.wasm().then(function(wasm) {
|
|
4175
|
+
var k = wasm.init(algo, !!priv);
|
|
4176
|
+
if (!k) throw new libVES.Error('InvalidValue', 'OQS key init failed (bad algo?)');
|
|
4177
|
+
var s = function(dst, src) {
|
|
4178
|
+
if (!dst || !src || dst.byteLength != src.byteLength) throw wasm.free(k), new libVES.Error('InvalidValue', 'Incorrect OQS key size');
|
|
4179
|
+
dst.set(src, 0);
|
|
4180
|
+
};
|
|
4181
|
+
if (priv) s(k.priv, priv);
|
|
4182
|
+
s(k.pub, pub);
|
|
4183
|
+
return k;
|
|
4184
|
+
});
|
|
4185
|
+
});
|
|
4186
|
+
});
|
|
4187
|
+
}
|
|
4188
|
+
},
|
|
4189
|
+
OID: '1.3.6.1.4.1.53675.3.5',
|
|
4190
|
+
defaultAlgo: 'Kyber768'
|
|
4191
|
+
};
|
|
4192
|
+
libVES.Algo.all.push('OQS');
|
|
4193
|
+
|
|
4194
|
+
var WasmOQSinit = {
|
|
4195
|
+
Key: function(algo) {
|
|
4196
|
+
this.algo = algo;
|
|
4197
|
+
},
|
|
4198
|
+
init: function(algo, fpriv) {
|
|
4199
|
+
var a = new Uint8Array(libVES.Util.StringToByteArray(algo));
|
|
4200
|
+
var arg1 = new Uint8Array(this.asm.memory.buffer, 16, 48);
|
|
4201
|
+
arg1.set(a);
|
|
4202
|
+
arg1.set([0], a.byteLength);
|
|
4203
|
+
var ptr = this._WasmOQS_new(arg1.byteOffset, fpriv);
|
|
4204
|
+
if (!ptr) return null;
|
|
4205
|
+
var key = new this.Key(algo);
|
|
4206
|
+
key.ptr = ptr;
|
|
4207
|
+
var priv = this._WasmOQS_priv(ptr);
|
|
4208
|
+
if (priv) key.priv = new Uint8Array(this.asm.memory.buffer, priv, this._WasmOQS_privlen(ptr));
|
|
4209
|
+
key.pub = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_pub(ptr), this._WasmOQS_publen(ptr));
|
|
4210
|
+
key.secretlen = this._WasmOQS_decaps(key.ptr, null, null);
|
|
4211
|
+
key.ctextlen = this._WasmOQS_encaps(key.ptr, null, null);
|
|
4212
|
+
return key;
|
|
4213
|
+
},
|
|
4214
|
+
generate: function(key) {
|
|
4215
|
+
return this._WasmOQS_generate(key.ptr) >= 0;
|
|
4216
|
+
},
|
|
4217
|
+
encaps: function(key) {
|
|
4218
|
+
var arg1 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_secretbuf, this._WasmOQS_decaps(key.ptr, null, null));
|
|
4219
|
+
var arg2 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_ctextbuf, this._WasmOQS_encaps(key.ptr, null, null));
|
|
4220
|
+
if (this._WasmOQS_encaps(key.ptr, arg2.byteOffset, arg1.byteOffset) <= 0) return null;
|
|
4221
|
+
key.secret = new Uint8Array(arg1.byteLength);
|
|
4222
|
+
key.secret.set(arg1);
|
|
4223
|
+
var ctext = new Uint8Array(arg2.byteLength);
|
|
4224
|
+
ctext.set(arg2);
|
|
4225
|
+
return ctext;
|
|
4226
|
+
},
|
|
4227
|
+
decaps: function(key, ctext) {
|
|
4228
|
+
var arg1 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_secretbuf, this._WasmOQS_decaps(key.ptr, null, null));
|
|
4229
|
+
if (ctext) {
|
|
4230
|
+
if (ctext.byteLength != this._WasmOQS_encaps(key.ptr, null, null)) return null;
|
|
4231
|
+
var arg2 = new Uint8Array(this.asm.memory.buffer, this._WasmOQS_ctextbuf, ctext.byteLength);
|
|
4232
|
+
arg2.set(ctext);
|
|
4233
|
+
if (this._WasmOQS_decaps(key.ptr, arg1.byteOffset, arg2.byteOffset) <= 0) return null;
|
|
4234
|
+
}
|
|
4235
|
+
var secret = new Uint8Array(arg1.byteLength);
|
|
4236
|
+
secret.set(arg1);
|
|
4237
|
+
return secret;
|
|
4238
|
+
},
|
|
4239
|
+
free: function(key) {
|
|
4240
|
+
this._WasmOQS_free(key.ptr);
|
|
4241
|
+
delete(key.ptr);
|
|
4242
|
+
},
|
|
4243
|
+
getalgos: function() {
|
|
4244
|
+
var algos = [];
|
|
4245
|
+
var a;
|
|
4246
|
+
for (var i = 0; a = this._WasmOQS_enumalgo(i); i++) {
|
|
4247
|
+
var s = new Uint8Array(this.asm.memory.buffer, a);
|
|
4248
|
+
var p = s.indexOf(0);
|
|
4249
|
+
if (!p) continue;
|
|
4250
|
+
algos.push(libVES.Util.ByteArrayToString(s.slice(0, p)));
|
|
4251
|
+
}
|
|
4252
|
+
return algos;
|
|
4253
|
+
},
|
|
4254
|
+
test: function(algo) {
|
|
4255
|
+
var k = this.init(algo, 1);
|
|
4256
|
+
this.generate(k);
|
|
4257
|
+
var ctext = this.encaps(k);
|
|
4258
|
+
var secret = this.decaps(k);
|
|
4259
|
+
console.log(secret);
|
|
4260
|
+
var secret2 = this.decaps(k, ctext);
|
|
4261
|
+
console.log(secret2);
|
|
4262
|
+
},
|
|
4263
|
+
locateFile: function(file) {
|
|
4264
|
+
return this.baseUrl + file;
|
|
4265
|
+
},
|
|
4266
|
+
baseUrl: 'https://ves.host/pub/'
|
|
4267
|
+
};
|
|
4268
|
+
|
|
4269
|
+
|
|
4270
|
+
|
|
4271
|
+
libVES.Watch = function(obj, optns) {
|
|
4272
|
+
if (obj instanceof libVES) obj = obj.domain ? (obj.externalId ? obj.getVaultKey() : new libVES.Domain(null, obj)) : obj.me();
|
|
4273
|
+
var self = this;
|
|
4274
|
+
this.object = Promise.resolve(obj).then(function(o) {
|
|
4275
|
+
if (o instanceof libVES.VaultKey) {
|
|
4276
|
+
self.uri = 'vaultKeys/';
|
|
4277
|
+
} else if (o instanceof libVES.VaultItem) {
|
|
4278
|
+
self.uri = 'vaultItems/';
|
|
4279
|
+
} else if (o instanceof libVES.User) {
|
|
4280
|
+
self.uri = 'users/';
|
|
4281
|
+
} else if (o instanceof libVES.Domain) {
|
|
4282
|
+
self.uri = 'domains/';
|
|
4283
|
+
} else {
|
|
4284
|
+
throw new libVES.Error('Internal', 'Watchable object expected');
|
|
4285
|
+
}
|
|
4286
|
+
self.VES = o.VES;
|
|
4287
|
+
return o;
|
|
4288
|
+
});
|
|
4289
|
+
if (optns) for (var k in optns) this[k] = optns[k];
|
|
4290
|
+
};
|
|
4291
|
+
|
|
4292
|
+
libVES.Watch.prototype = {
|
|
4293
|
+
fields: {vaultKey: {id: true, user: true, externals: true, creator: true}, vaultItem: {id: true, vaultKey: true, file: {externals: true, creator: true}}, session: {id: true, userAgent: true, remote: true, createdAt: true, expiresAt: true}},
|
|
4294
|
+
state: 'idle',
|
|
4295
|
+
timeout: 900,
|
|
4296
|
+
getEvents: function(start, ct, poll) {
|
|
4297
|
+
var self = this;
|
|
4298
|
+
return self.object.then(function(o) {
|
|
4299
|
+
return o.getId().then(function(id) {
|
|
4300
|
+
return (poll ? self.VES.pollUrl : '') + self.uri + id
|
|
4301
|
+
+ '?fields=events(' + self.VES.uriListFields(self.fields) + ')%5B' + start + (ct >= 0 ? '%2B' : '') + ct + '%5D'
|
|
4302
|
+
+ (poll ? '&poll=' + self.timeout : '');
|
|
4303
|
+
});
|
|
4304
|
+
}).then(function(url) {
|
|
4305
|
+
return self.VES.get(url);
|
|
4306
|
+
}).then(function(res) {
|
|
4307
|
+
if (!res.events) return null;
|
|
4308
|
+
return res.events.map(function(e, i) {
|
|
4309
|
+
return new libVES.Event(e, self.VES);
|
|
4310
|
+
});
|
|
4311
|
+
});
|
|
4312
|
+
},
|
|
4313
|
+
setState: function(st) {
|
|
4314
|
+
if (this.statefn) try {
|
|
4315
|
+
this.statefn(st, this);
|
|
4316
|
+
} catch(e) {}
|
|
4317
|
+
this.state = st;
|
|
4318
|
+
},
|
|
4319
|
+
setBusy: function(busy) {
|
|
4320
|
+
this.busy = busy;
|
|
4321
|
+
if (!busy && this.state == 'stop') this.setState('idle');
|
|
4322
|
+
},
|
|
4323
|
+
start: function(pos) {
|
|
4324
|
+
if (!this.eventfn) throw new libVES.Error('InvalidValue', 'eventfn is not set');
|
|
4325
|
+
if (this.busy) throw new libVES.Error('Internal', 'Watch instance is busy');
|
|
4326
|
+
var self = this;
|
|
4327
|
+
self.setBusy(true);
|
|
4328
|
+
this.setState('read');
|
|
4329
|
+
if (pos < 0) {
|
|
4330
|
+
this.next = 0;
|
|
4331
|
+
return this.getEvents(0, pos).then(function(evs) {
|
|
4332
|
+
self.setBusy(false);
|
|
4333
|
+
return self.received(evs.reverse());
|
|
4334
|
+
});
|
|
4335
|
+
} else {
|
|
4336
|
+
this.next = pos;
|
|
4337
|
+
return this.getEvents(pos, 0).then(function(evs) {
|
|
4338
|
+
self.setBusy(false);
|
|
4339
|
+
return self.received(evs);
|
|
4340
|
+
});
|
|
4341
|
+
}
|
|
4342
|
+
},
|
|
4343
|
+
active: function() {
|
|
4344
|
+
return this.state == 'read' || this.state == 'poll';
|
|
4345
|
+
},
|
|
4346
|
+
received: function(evs) {
|
|
4347
|
+
var self = this;
|
|
4348
|
+
var p;
|
|
4349
|
+
if (evs && evs.length) p = evs.reduce(function(v, e) {
|
|
4350
|
+
if (self.active()) try {
|
|
4351
|
+
self.eventfn(e, self);
|
|
4352
|
+
} catch(e) {
|
|
4353
|
+
console.log(e);
|
|
4354
|
+
}
|
|
4355
|
+
return e;
|
|
4356
|
+
}, null).getId().then(function(id) {
|
|
4357
|
+
self.next = id + 1;
|
|
4358
|
+
});
|
|
4359
|
+
else {
|
|
4360
|
+
p = Promise.resolve(null);
|
|
4361
|
+
if (this.state == 'read') this.setState('poll');
|
|
4362
|
+
}
|
|
4363
|
+
return p.then(function() {
|
|
4364
|
+
return self.request();
|
|
4365
|
+
});
|
|
4366
|
+
},
|
|
4367
|
+
request: function() {
|
|
4368
|
+
if (this.busy || !this.active()) return;
|
|
4369
|
+
var self = this;
|
|
4370
|
+
self.setBusy(true);
|
|
4371
|
+
return self.getEvents(self.next, 0, (self.state == 'poll')).then(function(evs) {
|
|
4372
|
+
self.setBusy(false);
|
|
4373
|
+
self.received(evs);
|
|
4374
|
+
}).catch(function(e) {
|
|
4375
|
+
self.setBusy(false);
|
|
4376
|
+
if (self.errorfn) try {
|
|
4377
|
+
self.errorfn(e, self);
|
|
4378
|
+
} catch(e) {
|
|
4379
|
+
console.log(e);
|
|
4380
|
+
}
|
|
4381
|
+
return self.retry();
|
|
4382
|
+
});
|
|
4383
|
+
},
|
|
4384
|
+
retry: function() {
|
|
4385
|
+
var self = this;
|
|
4386
|
+
return new Promise(function(resolve, reject) {
|
|
4387
|
+
window.setTimeout(function() {
|
|
4388
|
+
resolve(self.request());
|
|
4389
|
+
}, 1000);
|
|
4390
|
+
});
|
|
4391
|
+
},
|
|
4392
|
+
stop: function() {
|
|
4393
|
+
this.setState(this.busy ? 'stop' : 'idle');
|
|
4394
|
+
}
|
|
4395
|
+
};
|
|
4396
|
+
libVES.version = '2.16';
|
|
4397
|
+
|
|
3663
4398
|
module.exports = libVES;
|
package/package.json
CHANGED
package/libves-2.3.1.tgz
DELETED
|
Binary file
|