@tdxvolt/volt-client-grpc 0.14.134 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +159 -93
- package/package.json +1 -1
- package/src/grpc-utils.js +9 -9
- package/src/rpc-invocation.js +25 -21
- package/src/utils.js +43 -2
- package/src/volt-client-internal.js +23 -19
- package/src/volt-client.js +34 -19
- package/src/volt-connection.js +7 -5
- package/src/volt-credential.js +17 -19
package/lib/index.cjs
CHANGED
|
@@ -114,7 +114,7 @@ const createSecureContextOptions = (cryptoOptions) => {
|
|
|
114
114
|
const tlsOptions = {
|
|
115
115
|
cert: Buffer.from(cryptoOptions.cert),
|
|
116
116
|
ca: Buffer.from(cryptoOptions.ca),
|
|
117
|
-
key: Buffer.from(cryptoOptions.key)
|
|
117
|
+
key: Buffer.from(cryptoOptions.key)
|
|
118
118
|
};
|
|
119
119
|
return tlsOptions;
|
|
120
120
|
};
|
|
@@ -130,7 +130,7 @@ const getServiceAddress = (mdnsService) => {
|
|
|
130
130
|
const ipv4 = lodash__default["default"].find(mdnsService.addresses, (addy) => ip__default["default"].isV4Format(addy));
|
|
131
131
|
const serviceDetails = {
|
|
132
132
|
host: ipv4,
|
|
133
|
-
port: mdnsService.port
|
|
133
|
+
port: mdnsService.port
|
|
134
134
|
};
|
|
135
135
|
|
|
136
136
|
address = `${serviceDetails.host}:${serviceDetails.port}`;
|
|
@@ -207,6 +207,47 @@ const getDIDResolutionURL = (didIn) => {
|
|
|
207
207
|
return `https://${hostName}/api/identity/${didGUID}`;
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
+
const forgePrivateKeyToPem = (decryptedKey) => {
|
|
211
|
+
// Convert a Forge private key to an ASN.1 RSAPrivateKey
|
|
212
|
+
const asnPrivateKey = pki$2.privateKeyToAsn1(decryptedKey);
|
|
213
|
+
|
|
214
|
+
// Wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo
|
|
215
|
+
const privateKeyInfo = pki$2.wrapRsaPrivateKey(asnPrivateKey);
|
|
216
|
+
|
|
217
|
+
// Convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM
|
|
218
|
+
return pki$2.privateKeyInfoToPem(privateKeyInfo);
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const createRSAKey = (passphrase = "") => {
|
|
222
|
+
return new Promise((resolve, reject) => {
|
|
223
|
+
pki$2.rsa.generateKeyPair({ bits: 2048, workers: -1 }, (err, keypair) => {
|
|
224
|
+
if (err) {
|
|
225
|
+
reject(err);
|
|
226
|
+
} else {
|
|
227
|
+
let pem;
|
|
228
|
+
if (passphrase) {
|
|
229
|
+
pem = pki$2.encryptRsaPrivateKey(keypair.privateKey, passphrase);
|
|
230
|
+
} else {
|
|
231
|
+
pem = forgePrivateKeyToPem(keypair.privateKey);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
resolve({ keypair, pem });
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const sha256Base64 = (msg) => {
|
|
241
|
+
const md = forge__default["default"].md.sha256.create();
|
|
242
|
+
md.update(msg);
|
|
243
|
+
return forge__default["default"].util.encode64(md.digest().bytes());
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
const decryptPrivateKey = (pem, passphrase) => {
|
|
247
|
+
const decryptedKey = pki$2.decryptRsaPrivateKey(pem, passphrase);
|
|
248
|
+
return forgePrivateKeyToPem(decryptedKey);
|
|
249
|
+
};
|
|
250
|
+
|
|
210
251
|
var utils = /*#__PURE__*/Object.freeze({
|
|
211
252
|
__proto__: null,
|
|
212
253
|
createSecureContextOptions: createSecureContextOptions,
|
|
@@ -219,7 +260,10 @@ var utils = /*#__PURE__*/Object.freeze({
|
|
|
219
260
|
createPublicKeyFingerprint: createPublicKeyFingerprint,
|
|
220
261
|
signBase64: signBase64,
|
|
221
262
|
verifyBase64: verifyBase64,
|
|
222
|
-
getDIDResolutionURL: getDIDResolutionURL
|
|
263
|
+
getDIDResolutionURL: getDIDResolutionURL,
|
|
264
|
+
createRSAKey: createRSAKey,
|
|
265
|
+
sha256Base64: sha256Base64,
|
|
266
|
+
decryptPrivateKey: decryptPrivateKey
|
|
223
267
|
});
|
|
224
268
|
|
|
225
269
|
/* eslint-disable no-underscore-dangle */
|
|
@@ -237,7 +281,7 @@ function createClient(
|
|
|
237
281
|
credentials,
|
|
238
282
|
noSerialise,
|
|
239
283
|
voltId,
|
|
240
|
-
serviceId
|
|
284
|
+
serviceId
|
|
241
285
|
) {
|
|
242
286
|
let grpcCredentials;
|
|
243
287
|
if (credentials) {
|
|
@@ -251,7 +295,7 @@ function createClient(
|
|
|
251
295
|
grpcCredentials = grpc.credentials.createSsl(
|
|
252
296
|
tlsOptions.ca,
|
|
253
297
|
tlsOptions.key,
|
|
254
|
-
tlsOptions.cert
|
|
298
|
+
tlsOptions.cert
|
|
255
299
|
);
|
|
256
300
|
} else {
|
|
257
301
|
// Cache has no private key, this implies we are connecting without supplying a client certificate.
|
|
@@ -313,7 +357,7 @@ const grpcWrap = (api) => {
|
|
|
313
357
|
// Support class instances and PoJos
|
|
314
358
|
const isClass = api.constructor !== Object;
|
|
315
359
|
const iterate = Object.getOwnPropertyNames(
|
|
316
|
-
isClass ? api.constructor.prototype : api
|
|
360
|
+
isClass ? api.constructor.prototype : api
|
|
317
361
|
);
|
|
318
362
|
|
|
319
363
|
// Wrap each method on the api.
|
|
@@ -327,7 +371,7 @@ const grpcWrap = (api) => {
|
|
|
327
371
|
// Enforce promise results.
|
|
328
372
|
if (!(resultPromise?.then && resultPromise?.catch)) {
|
|
329
373
|
throw new Error(
|
|
330
|
-
`implementation methods must return a Promise [${name}]
|
|
374
|
+
`implementation methods must return a Promise [${name}]`
|
|
331
375
|
);
|
|
332
376
|
}
|
|
333
377
|
|
|
@@ -364,7 +408,7 @@ class GrpcServer {
|
|
|
364
408
|
"grpc.http2.max_pings_without_data": 0,
|
|
365
409
|
"grpc.keepalive_permit_without_calls": 1,
|
|
366
410
|
"grpc.http2.min_ping_interval_without_data_ms": 250,
|
|
367
|
-
"grpc.http2.max_ping_strikes": 0
|
|
411
|
+
"grpc.http2.max_ping_strikes": 0
|
|
368
412
|
});
|
|
369
413
|
|
|
370
414
|
if (tlsOptions) {
|
|
@@ -374,7 +418,7 @@ class GrpcServer {
|
|
|
374
418
|
caList.push(tlsOption.ca);
|
|
375
419
|
certChains.push({
|
|
376
420
|
private_key: tlsOption.key,
|
|
377
|
-
cert_chain: tlsOption.cert
|
|
421
|
+
cert_chain: tlsOption.cert
|
|
378
422
|
});
|
|
379
423
|
});
|
|
380
424
|
|
|
@@ -385,7 +429,7 @@ class GrpcServer {
|
|
|
385
429
|
// The certificate chain(s) we present to the client.
|
|
386
430
|
certChains,
|
|
387
431
|
// Flag indicating if we insist on a client certificate.
|
|
388
|
-
requireClientCert
|
|
432
|
+
requireClientCert
|
|
389
433
|
);
|
|
390
434
|
} else {
|
|
391
435
|
this._credentials = grpc.ServerCredentials.createInsecure();
|
|
@@ -437,7 +481,7 @@ function createServer(
|
|
|
437
481
|
serviceDescriptors,
|
|
438
482
|
routes,
|
|
439
483
|
cryptoCache,
|
|
440
|
-
requireClientCert
|
|
484
|
+
requireClientCert
|
|
441
485
|
) {
|
|
442
486
|
let tlsOptions;
|
|
443
487
|
if (cryptoCache) {
|
|
@@ -448,7 +492,7 @@ function createServer(
|
|
|
448
492
|
serviceDescriptors,
|
|
449
493
|
routes,
|
|
450
494
|
tlsOptions,
|
|
451
|
-
requireClientCert
|
|
495
|
+
requireClientCert
|
|
452
496
|
};
|
|
453
497
|
return new GrpcServer(serverArgs);
|
|
454
498
|
}
|
|
@@ -490,7 +534,7 @@ class VoltCredential {
|
|
|
490
534
|
// Need to unencrypt the private key.
|
|
491
535
|
const decrypted = pki$1.decryptRsaPrivateKey(
|
|
492
536
|
this._cryptoCache.key,
|
|
493
|
-
config.p
|
|
537
|
+
config.p
|
|
494
538
|
);
|
|
495
539
|
if (!decrypted) {
|
|
496
540
|
throw new Error("failed to decrypt key - check passphrase");
|
|
@@ -510,7 +554,7 @@ class VoltCredential {
|
|
|
510
554
|
// Extract Volt public key (used for encrypting Relay payloads).
|
|
511
555
|
this._voltPublicKey = forge__default["default"].pki.publicKeyToPem(voltCert.publicKey);
|
|
512
556
|
this._voltFingerprint = createPublicKeyFingerprint(
|
|
513
|
-
this._voltPublicKey
|
|
557
|
+
this._voltPublicKey
|
|
514
558
|
);
|
|
515
559
|
}
|
|
516
560
|
}
|
|
@@ -555,19 +599,16 @@ class VoltCredential {
|
|
|
555
599
|
return Promise.resolve(this.getKey());
|
|
556
600
|
} else {
|
|
557
601
|
log$5("creating key");
|
|
558
|
-
return
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
resolve(keypair);
|
|
568
|
-
}
|
|
602
|
+
return createRSAKey()
|
|
603
|
+
.then((keyInfo) => {
|
|
604
|
+
log$5("successfully created key");
|
|
605
|
+
this._cryptoCache.key = keyInfo.pem;
|
|
606
|
+
return keyInfo.keypair;
|
|
607
|
+
})
|
|
608
|
+
.catch((err) => {
|
|
609
|
+
log$5("failure creating key [%s]", err.message);
|
|
610
|
+
return Promise.reject(err);
|
|
569
611
|
});
|
|
570
|
-
});
|
|
571
612
|
}
|
|
572
613
|
}
|
|
573
614
|
|
|
@@ -615,7 +656,7 @@ class VoltCredential {
|
|
|
615
656
|
aud: audience,
|
|
616
657
|
iat: Math.floor(Date.now() / 1000) - ttl,
|
|
617
658
|
exp: Math.floor(Date.now() / 1000) + ttl,
|
|
618
|
-
sub: this._cryptoCache.client_id
|
|
659
|
+
sub: this._cryptoCache.client_id
|
|
619
660
|
};
|
|
620
661
|
|
|
621
662
|
let sharedKey;
|
|
@@ -631,13 +672,13 @@ class VoltCredential {
|
|
|
631
672
|
// Sign synchronously.
|
|
632
673
|
const token = jwt__default["default"].sign(payload, this._cryptoCache.key, {
|
|
633
674
|
algorithm: rs256Algorithm,
|
|
634
|
-
keyid: base58Key
|
|
675
|
+
keyid: base58Key
|
|
635
676
|
});
|
|
636
677
|
|
|
637
678
|
// Return the token along with any encryption key details.
|
|
638
679
|
return {
|
|
639
680
|
token,
|
|
640
|
-
sharedKey
|
|
681
|
+
sharedKey
|
|
641
682
|
};
|
|
642
683
|
}
|
|
643
684
|
|
|
@@ -655,7 +696,7 @@ class VoltCredential {
|
|
|
655
696
|
audience || this._voltConfig.id,
|
|
656
697
|
publicKey,
|
|
657
698
|
tunnelling,
|
|
658
|
-
ttl
|
|
699
|
+
ttl
|
|
659
700
|
);
|
|
660
701
|
const metadata = new grpc.Metadata();
|
|
661
702
|
metadata.add(constants.authTokenName, identityToken.token);
|
|
@@ -670,7 +711,7 @@ class VoltCredential {
|
|
|
670
711
|
const privateKey = pki$1.privateKeyFromPem(this._cryptoCache.key);
|
|
671
712
|
clone.credential.key = pki$1.encryptRsaPrivateKey(
|
|
672
713
|
privateKey,
|
|
673
|
-
this._config.p
|
|
714
|
+
this._config.p
|
|
674
715
|
);
|
|
675
716
|
}
|
|
676
717
|
fs__default["default"].writeFileSync(this._configPath, JSON.stringify(clone, null, 2));
|
|
@@ -1212,7 +1253,7 @@ function _cleanUp(immediateReconnect) {
|
|
|
1212
1253
|
this._reconnectTimer = 0;
|
|
1213
1254
|
_doConnect.call(this, this._helloPayload);
|
|
1214
1255
|
},
|
|
1215
|
-
immediateReconnect ? 0 : this._reconnectInterval
|
|
1256
|
+
immediateReconnect ? 0 : this._reconnectInterval
|
|
1216
1257
|
);
|
|
1217
1258
|
}
|
|
1218
1259
|
|
|
@@ -1233,10 +1274,10 @@ function _doConnect(connectHello) {
|
|
|
1233
1274
|
const grpcClient = this._voltClient.getVoltAPIClient();
|
|
1234
1275
|
|
|
1235
1276
|
let helloPayload = connectHello;
|
|
1236
|
-
if (!
|
|
1277
|
+
if (!helloPayload) {
|
|
1237
1278
|
log$3("defaulting hello payload");
|
|
1238
1279
|
helloPayload = {
|
|
1239
|
-
hello: {}
|
|
1280
|
+
hello: {}
|
|
1240
1281
|
};
|
|
1241
1282
|
}
|
|
1242
1283
|
|
|
@@ -1258,6 +1299,8 @@ function _doConnect(connectHello) {
|
|
|
1258
1299
|
|
|
1259
1300
|
// Schedule the next ping.
|
|
1260
1301
|
_startPingTimer.call(this);
|
|
1302
|
+
|
|
1303
|
+
this.emit("ping", response.ping.timestamp);
|
|
1261
1304
|
break;
|
|
1262
1305
|
}
|
|
1263
1306
|
case "acknowledge": {
|
|
@@ -1274,7 +1317,7 @@ function _doConnect(connectHello) {
|
|
|
1274
1317
|
break;
|
|
1275
1318
|
}
|
|
1276
1319
|
case "evt": {
|
|
1277
|
-
log$3("received event %s", response.evt
|
|
1320
|
+
log$3("received event %s", Object.keys(response.evt)[0]);
|
|
1278
1321
|
this.emit("evt", response.evt);
|
|
1279
1322
|
break;
|
|
1280
1323
|
}
|
|
@@ -1318,7 +1361,7 @@ function _startPingTimer() {
|
|
|
1318
1361
|
|
|
1319
1362
|
this._pingTimeoutTimer = setTimeout(
|
|
1320
1363
|
_connectionTimeoutHandler.bind(this),
|
|
1321
|
-
this._timeoutInterval
|
|
1364
|
+
this._timeoutInterval
|
|
1322
1365
|
);
|
|
1323
1366
|
}, this._pingInterval);
|
|
1324
1367
|
}
|
|
@@ -1397,12 +1440,12 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1397
1440
|
deserialisedPayload = this.#payload;
|
|
1398
1441
|
} else if (this.#methodDescriptor) {
|
|
1399
1442
|
deserialisedPayload = this.#methodDescriptor.requestDeserialize(
|
|
1400
|
-
this.#payload
|
|
1443
|
+
this.#payload
|
|
1401
1444
|
);
|
|
1402
1445
|
} else {
|
|
1403
1446
|
log$2("unexpected: no method descriptor");
|
|
1404
1447
|
throw new Error(
|
|
1405
|
-
"no method descriptor - set this before accessing payload"
|
|
1448
|
+
"no method descriptor - set this before accessing payload"
|
|
1406
1449
|
);
|
|
1407
1450
|
}
|
|
1408
1451
|
|
|
@@ -1426,11 +1469,11 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1426
1469
|
// Decrypt the shared key and iv using the private key.
|
|
1427
1470
|
this.#encryptKey = VoltCredential.rsaDecrypt(
|
|
1428
1471
|
this.#voltClient.credential.cache.key,
|
|
1429
|
-
this.#token.sk
|
|
1472
|
+
this.#token.sk
|
|
1430
1473
|
);
|
|
1431
1474
|
this.#encryptIV = VoltCredential.rsaDecrypt(
|
|
1432
1475
|
this.#voltClient.credential.cache.key,
|
|
1433
|
-
this.#token.iv
|
|
1476
|
+
this.#token.iv
|
|
1434
1477
|
);
|
|
1435
1478
|
}
|
|
1436
1479
|
|
|
@@ -1461,7 +1504,7 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1461
1504
|
decryptedPayload = VoltCredential.aesDecrypt(
|
|
1462
1505
|
invoke_request.payload,
|
|
1463
1506
|
this.#encryptKey,
|
|
1464
|
-
this.#encryptIV
|
|
1507
|
+
this.#encryptIV
|
|
1465
1508
|
);
|
|
1466
1509
|
} else {
|
|
1467
1510
|
// No encryption => just use the payload.
|
|
@@ -1482,9 +1525,13 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1482
1525
|
this.#payload = wrappedPayload.method_payload.payload;
|
|
1483
1526
|
this.emit("payload", this);
|
|
1484
1527
|
} else if (wrappedPayload.method_end) {
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1528
|
+
this.#payload = wrappedPayload.method_end;
|
|
1529
|
+
if (wrappedPayload.method_end.error) {
|
|
1530
|
+
// The client has sent an error.
|
|
1531
|
+
this.emit("error", this);
|
|
1532
|
+
} else {
|
|
1533
|
+
this.emit("end", this);
|
|
1534
|
+
}
|
|
1488
1535
|
}
|
|
1489
1536
|
|
|
1490
1537
|
resolve();
|
|
@@ -1498,7 +1545,7 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1498
1545
|
decryptedPayload = VoltCredential.aesDecrypt(
|
|
1499
1546
|
Buffer.from(invoke_request.json_payload, "base64"),
|
|
1500
1547
|
this.#encryptKey,
|
|
1501
|
-
this.#encryptIV
|
|
1548
|
+
this.#encryptIV
|
|
1502
1549
|
);
|
|
1503
1550
|
} else {
|
|
1504
1551
|
// No encryption => just use the payload.
|
|
@@ -1511,12 +1558,12 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1511
1558
|
if (wrappedPayload.method_invoke) {
|
|
1512
1559
|
this.#methodName = wrappedPayload.method_invoke.method_name;
|
|
1513
1560
|
this.#payload = JSON.parse(
|
|
1514
|
-
wrappedPayload.method_invoke.json_request
|
|
1561
|
+
wrappedPayload.method_invoke.json_request
|
|
1515
1562
|
);
|
|
1516
1563
|
this.emit("payload", this);
|
|
1517
1564
|
} else if (wrappedPayload.method_payload) {
|
|
1518
1565
|
this.#payload = JSON.parse(
|
|
1519
|
-
wrappedPayload.method_payload.json_payload
|
|
1566
|
+
wrappedPayload.method_payload.json_payload
|
|
1520
1567
|
);
|
|
1521
1568
|
this.emit("payload", this);
|
|
1522
1569
|
} else if (wrappedPayload.method_end) {
|
|
@@ -1545,7 +1592,7 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1545
1592
|
let responsePayload;
|
|
1546
1593
|
if (this.#isJSON) {
|
|
1547
1594
|
responsePayload = JSON.stringify({
|
|
1548
|
-
method_payload: { json_payload: JSON.stringify(response) }
|
|
1595
|
+
method_payload: { json_payload: JSON.stringify(response) }
|
|
1549
1596
|
});
|
|
1550
1597
|
} else {
|
|
1551
1598
|
// We need to serialise the response, and then wrap it in a RemoteRequest.
|
|
@@ -1553,7 +1600,7 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1553
1600
|
this.#methodDescriptor.responseSerialize(response);
|
|
1554
1601
|
const tunnelMethod = this.#voltClient.getVoltAPIClient().Tunnel;
|
|
1555
1602
|
responsePayload = tunnelMethod.requestSerialize({
|
|
1556
|
-
method_payload: { payload: serialisedResponse }
|
|
1603
|
+
method_payload: { payload: serialisedResponse }
|
|
1557
1604
|
});
|
|
1558
1605
|
}
|
|
1559
1606
|
|
|
@@ -1562,12 +1609,12 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1562
1609
|
responsePayload = VoltCredential.aesEncrypt(
|
|
1563
1610
|
responsePayload,
|
|
1564
1611
|
this.#encryptKey,
|
|
1565
|
-
this.#encryptIV
|
|
1612
|
+
this.#encryptIV
|
|
1566
1613
|
);
|
|
1567
1614
|
}
|
|
1568
1615
|
|
|
1569
1616
|
const invokeResponse = {
|
|
1570
|
-
invoke_id: this.#invokeId
|
|
1617
|
+
invoke_id: this.#invokeId
|
|
1571
1618
|
};
|
|
1572
1619
|
|
|
1573
1620
|
if (this.#isJSON) {
|
|
@@ -1578,7 +1625,7 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1578
1625
|
}
|
|
1579
1626
|
|
|
1580
1627
|
this.#voltConnection.send({
|
|
1581
|
-
invoke_response: invokeResponse
|
|
1628
|
+
invoke_response: invokeResponse
|
|
1582
1629
|
});
|
|
1583
1630
|
}
|
|
1584
1631
|
|
|
@@ -1588,11 +1635,11 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1588
1635
|
let endPayload;
|
|
1589
1636
|
if (errorMessage) {
|
|
1590
1637
|
endPayload = {
|
|
1591
|
-
method_end: { error: errorMessage, ended: true }
|
|
1638
|
+
method_end: { error: errorMessage, ended: true }
|
|
1592
1639
|
};
|
|
1593
1640
|
} else {
|
|
1594
1641
|
endPayload = {
|
|
1595
|
-
method_end: { ended: true }
|
|
1642
|
+
method_end: { ended: true }
|
|
1596
1643
|
};
|
|
1597
1644
|
}
|
|
1598
1645
|
|
|
@@ -1607,13 +1654,13 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1607
1654
|
endPayload = VoltCredential.aesEncrypt(
|
|
1608
1655
|
endPayload,
|
|
1609
1656
|
this.#encryptKey,
|
|
1610
|
-
this.#encryptIV
|
|
1657
|
+
this.#encryptIV
|
|
1611
1658
|
);
|
|
1612
1659
|
}
|
|
1613
1660
|
|
|
1614
1661
|
const invokeResponse = {
|
|
1615
1662
|
invoke_id: this.#invokeId,
|
|
1616
|
-
server_end: true
|
|
1663
|
+
server_end: true
|
|
1617
1664
|
};
|
|
1618
1665
|
|
|
1619
1666
|
if (this.#isJSON) {
|
|
@@ -1623,7 +1670,7 @@ class RpcInvocation extends EventEmitter__default["default"] {
|
|
|
1623
1670
|
}
|
|
1624
1671
|
|
|
1625
1672
|
this.#voltConnection.send({
|
|
1626
|
-
invoke_response: invokeResponse
|
|
1673
|
+
invoke_response: invokeResponse
|
|
1627
1674
|
});
|
|
1628
1675
|
}
|
|
1629
1676
|
}
|
|
@@ -1641,7 +1688,7 @@ const voltServices = [
|
|
|
1641
1688
|
constants.serviceType.sqliteServerAPI,
|
|
1642
1689
|
constants.serviceType.ssiAPI,
|
|
1643
1690
|
constants.serviceType.relayAPI,
|
|
1644
|
-
constants.serviceType.wireAPI
|
|
1691
|
+
constants.serviceType.wireAPI
|
|
1645
1692
|
];
|
|
1646
1693
|
|
|
1647
1694
|
function issueBind(bindRequest, ttl) {
|
|
@@ -1711,13 +1758,13 @@ async function bindInternal() {
|
|
|
1711
1758
|
log$1("attempting to retrieve Relay information from %s", relayURL);
|
|
1712
1759
|
this._voltConfig.relay = await fetchVoltConfig.call(
|
|
1713
1760
|
this,
|
|
1714
|
-
`${relayURL}/discovery
|
|
1761
|
+
`${relayURL}/discovery`
|
|
1715
1762
|
);
|
|
1716
1763
|
if (this._voltConfig.relay.ca_pem) {
|
|
1717
1764
|
log$1(
|
|
1718
1765
|
"Auto-fetched Relay CA %s, remote address %s",
|
|
1719
1766
|
this._voltConfig.relay.ca_pem,
|
|
1720
|
-
this._voltConfig.relay.address
|
|
1767
|
+
this._voltConfig.relay.address
|
|
1721
1768
|
);
|
|
1722
1769
|
} else {
|
|
1723
1770
|
throw new Error("Unable to fetch Relay CA - cannot securely connect.");
|
|
@@ -1730,7 +1777,7 @@ async function bindInternal() {
|
|
|
1730
1777
|
|
|
1731
1778
|
if (!this._credential.cache.ca) {
|
|
1732
1779
|
throw new Error(
|
|
1733
|
-
"No certificate authority found in configuration for target Volt - check configuration"
|
|
1780
|
+
"No certificate authority found in configuration for target Volt - check configuration"
|
|
1734
1781
|
);
|
|
1735
1782
|
}
|
|
1736
1783
|
|
|
@@ -1750,30 +1797,30 @@ async function bindInternal() {
|
|
|
1750
1797
|
binding_name: this._config.client_name,
|
|
1751
1798
|
public_key: publicKeyPem,
|
|
1752
1799
|
host: this._credential.cache.bindIp,
|
|
1753
|
-
x509_credential: []
|
|
1800
|
+
x509_credential: []
|
|
1754
1801
|
};
|
|
1755
1802
|
|
|
1756
1803
|
if (this._credential.cache.cert) {
|
|
1757
1804
|
bindRequest.x509_credential = [
|
|
1758
|
-
this._credential.cache.cert + this._credential.cache.ca
|
|
1805
|
+
this._credential.cache.cert + this._credential.cache.ca
|
|
1759
1806
|
];
|
|
1760
1807
|
}
|
|
1761
1808
|
|
|
1762
1809
|
if (this._voltConfig.challenge_code) {
|
|
1763
1810
|
bindRequest.challenge = signBase64(
|
|
1764
1811
|
keyPair.privateKey,
|
|
1765
|
-
this._voltConfig.challenge_code
|
|
1812
|
+
this._voltConfig.challenge_code
|
|
1766
1813
|
);
|
|
1767
1814
|
} else {
|
|
1768
1815
|
log$1(
|
|
1769
|
-
"****no Volt challenge code available**** => not sending challenge signature"
|
|
1816
|
+
"****no Volt challenge code available**** => not sending challenge signature"
|
|
1770
1817
|
);
|
|
1771
1818
|
}
|
|
1772
1819
|
|
|
1773
1820
|
// For remote connections, add our cloud-issued certificate as an additional credential.
|
|
1774
1821
|
if (this._voltConfig?.relay?.ca_pem && this._credential.cache.cloud_cert) {
|
|
1775
1822
|
bindRequest.x509_credential = bindRequest.x509_credential.concat(
|
|
1776
|
-
this._credential.cache.cloud_cert + this._voltConfig.relay.ca_pem
|
|
1823
|
+
this._credential.cache.cloud_cert + this._voltConfig.relay.ca_pem
|
|
1777
1824
|
);
|
|
1778
1825
|
}
|
|
1779
1826
|
|
|
@@ -1793,7 +1840,7 @@ async function bindInternal() {
|
|
|
1793
1840
|
decision = await issueBind.call(
|
|
1794
1841
|
this,
|
|
1795
1842
|
bindRequest,
|
|
1796
|
-
this._voltConfig.bindRequestTTL
|
|
1843
|
+
this._voltConfig.bindRequestTTL
|
|
1797
1844
|
);
|
|
1798
1845
|
log$1("binding decision: %s", decision);
|
|
1799
1846
|
} while (
|
|
@@ -1854,6 +1901,10 @@ function connectInternal(helloPayload) {
|
|
|
1854
1901
|
this.emit("evt", evt);
|
|
1855
1902
|
});
|
|
1856
1903
|
|
|
1904
|
+
this._voltConnection.on("ping", (ping) => {
|
|
1905
|
+
this.emit("ping", ping);
|
|
1906
|
+
});
|
|
1907
|
+
|
|
1857
1908
|
this._voltConnection.on("invoke_request", (invoke_request) => {
|
|
1858
1909
|
const invokeId = invoke_request.invoke_id;
|
|
1859
1910
|
if (this._activeRPC[invokeId]) {
|
|
@@ -1904,7 +1955,7 @@ function getVoltAPIClientInternal() {
|
|
|
1904
1955
|
this._credential,
|
|
1905
1956
|
this.isRemote && !this.isVoltRelay,
|
|
1906
1957
|
this._voltConfig?.relay?.cloud ? this._voltConfig.id : "",
|
|
1907
|
-
this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
|
|
1958
|
+
this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
|
|
1908
1959
|
);
|
|
1909
1960
|
}
|
|
1910
1961
|
|
|
@@ -1928,7 +1979,7 @@ function getAPIClientInternal(service) {
|
|
|
1928
1979
|
const packageDescriptors = getServiceDescriptorsFromPath(
|
|
1929
1980
|
this._grpc,
|
|
1930
1981
|
fullProtoPath,
|
|
1931
|
-
api
|
|
1982
|
+
api
|
|
1932
1983
|
);
|
|
1933
1984
|
serviceDescriptors = { ...serviceDescriptors, ...packageDescriptors };
|
|
1934
1985
|
}
|
|
@@ -1940,7 +1991,7 @@ function getAPIClientInternal(service) {
|
|
|
1940
1991
|
this._credential,
|
|
1941
1992
|
this.isRemote && !this.isVoltRelay,
|
|
1942
1993
|
this._voltConfig?.relay?.cloud ? this._voltConfig.id : "",
|
|
1943
|
-
this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
|
|
1994
|
+
this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
|
|
1944
1995
|
);
|
|
1945
1996
|
}
|
|
1946
1997
|
|
|
@@ -2022,13 +2073,13 @@ async function fetchVoltConfig(discovery_url) {
|
|
|
2022
2073
|
"ca_pem",
|
|
2023
2074
|
"challenge_code",
|
|
2024
2075
|
"cloud",
|
|
2025
|
-
"relay"
|
|
2076
|
+
"relay"
|
|
2026
2077
|
);
|
|
2027
2078
|
|
|
2028
2079
|
return voltConfig;
|
|
2029
2080
|
} catch (err) {
|
|
2030
2081
|
throw new Error(
|
|
2031
|
-
`Failure loading config from ${discovery_url}: ${err.message}
|
|
2082
|
+
`Failure loading config from ${discovery_url}: ${err.message}`
|
|
2032
2083
|
);
|
|
2033
2084
|
}
|
|
2034
2085
|
}
|
|
@@ -2044,13 +2095,13 @@ async function fetchVoltConfigFromDID(volt_did) {
|
|
|
2044
2095
|
const didDocument = await getJSON(didResolution);
|
|
2045
2096
|
const voltConfigServices = findDIDDocumentService(
|
|
2046
2097
|
didDocument,
|
|
2047
|
-
constants.didServiceType.voltConfig
|
|
2098
|
+
constants.didServiceType.voltConfig
|
|
2048
2099
|
);
|
|
2049
2100
|
if (voltConfigServices.length !== 1) {
|
|
2050
2101
|
log$1(
|
|
2051
2102
|
"Unexpected number of Volt configuration endpoints found in DID document for %s, services found: %d",
|
|
2052
2103
|
volt_did,
|
|
2053
|
-
voltConfigServices.length
|
|
2104
|
+
voltConfigServices.length
|
|
2054
2105
|
);
|
|
2055
2106
|
}
|
|
2056
2107
|
|
|
@@ -2058,7 +2109,7 @@ async function fetchVoltConfigFromDID(volt_did) {
|
|
|
2058
2109
|
return await fetchVoltConfig.call(this, serviceEndpoint);
|
|
2059
2110
|
} catch (err) {
|
|
2060
2111
|
throw new Error(
|
|
2061
|
-
`Failure fetching Volt config from DID document ${volt_did}: ${err.message}
|
|
2112
|
+
`Failure fetching Volt config from DID document ${volt_did}: ${err.message}`
|
|
2062
2113
|
);
|
|
2063
2114
|
}
|
|
2064
2115
|
}
|
|
@@ -2111,7 +2162,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2111
2162
|
try {
|
|
2112
2163
|
if (!config) {
|
|
2113
2164
|
throw new Error(
|
|
2114
|
-
"configPath argument is required to be a non-empty string"
|
|
2165
|
+
"configPath argument is required to be a non-empty string"
|
|
2115
2166
|
);
|
|
2116
2167
|
}
|
|
2117
2168
|
|
|
@@ -2122,13 +2173,13 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2122
2173
|
log("Attempt to load config from file %s", configPath);
|
|
2123
2174
|
try {
|
|
2124
2175
|
const configContents = await readFile(
|
|
2125
|
-
new URL(configPath, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)))
|
|
2176
|
+
new URL(configPath, (typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('index.cjs', document.baseURI).href)))
|
|
2126
2177
|
);
|
|
2127
2178
|
configJSON = JSON.parse(configContents);
|
|
2128
2179
|
} catch (err) {
|
|
2129
2180
|
log("failure loading config file %s [%s]", configPath, err.message);
|
|
2130
2181
|
throw new Error(
|
|
2131
|
-
`failed to load configuration - check JSON format in ${configPath}
|
|
2182
|
+
`failed to load configuration - check JSON format in ${configPath}`
|
|
2132
2183
|
);
|
|
2133
2184
|
}
|
|
2134
2185
|
} else if (typeof config === "object") {
|
|
@@ -2169,14 +2220,14 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2169
2220
|
const didConfig = await fetchVoltConfigFromDID.call(this, voltDID);
|
|
2170
2221
|
this._config = { ...this._config, volt: didConfig };
|
|
2171
2222
|
log("resolved config from DID: %s", JSON.stringify(didConfig, null, 2));
|
|
2172
|
-
} else if (voltHttpAddress) {
|
|
2223
|
+
} else if (voltHttpAddress && !this._config?.volt?.id) {
|
|
2173
2224
|
const discoConfig = await fetchVoltConfig.call(
|
|
2174
2225
|
this,
|
|
2175
|
-
`${voltHttpAddress}/discovery
|
|
2226
|
+
`${voltHttpAddress}/discovery`
|
|
2176
2227
|
);
|
|
2177
2228
|
this._config = {
|
|
2178
2229
|
...this._config,
|
|
2179
|
-
volt: { ...this._config.volt, ...discoConfig }
|
|
2230
|
+
volt: { ...this._config.volt, ...discoConfig }
|
|
2180
2231
|
};
|
|
2181
2232
|
}
|
|
2182
2233
|
|
|
@@ -2220,7 +2271,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2220
2271
|
if (bindErr.message === "invalid arguments") {
|
|
2221
2272
|
// This is usually the result of a missing challenge signature or credential.
|
|
2222
2273
|
log(
|
|
2223
|
-
"failure binding to Volt - did you supply a challenge code or verified credential?"
|
|
2274
|
+
"failure binding to Volt - did you supply a challenge code or verified credential?"
|
|
2224
2275
|
);
|
|
2225
2276
|
throw bindErr;
|
|
2226
2277
|
}
|
|
@@ -2283,7 +2334,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2283
2334
|
if (this.isRemote) {
|
|
2284
2335
|
if (!this._voltConfig?.relay?.address) {
|
|
2285
2336
|
throw new Error(
|
|
2286
|
-
"Remote connection enabled but no Relay address - have you called start()?"
|
|
2337
|
+
"Remote connection enabled but no Relay address - have you called start()?"
|
|
2287
2338
|
);
|
|
2288
2339
|
}
|
|
2289
2340
|
|
|
@@ -2295,14 +2346,14 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2295
2346
|
this._credential,
|
|
2296
2347
|
false,
|
|
2297
2348
|
service.volt_id,
|
|
2298
|
-
service.id
|
|
2349
|
+
service.id
|
|
2299
2350
|
);
|
|
2300
2351
|
} else {
|
|
2301
2352
|
return createClient(
|
|
2302
2353
|
this._grpc,
|
|
2303
2354
|
serviceDescriptors,
|
|
2304
2355
|
service.service_description.address,
|
|
2305
|
-
this._credential
|
|
2356
|
+
this._credential
|
|
2306
2357
|
);
|
|
2307
2358
|
}
|
|
2308
2359
|
}
|
|
@@ -2340,7 +2391,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2340
2391
|
"METHOD_TYPE_BIDI",
|
|
2341
2392
|
method,
|
|
2342
2393
|
request,
|
|
2343
|
-
service
|
|
2394
|
+
service
|
|
2344
2395
|
);
|
|
2345
2396
|
}
|
|
2346
2397
|
|
|
@@ -2350,7 +2401,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2350
2401
|
"METHOD_TYPE_CLIENT_STREAM",
|
|
2351
2402
|
method,
|
|
2352
2403
|
request,
|
|
2353
|
-
service
|
|
2404
|
+
service
|
|
2354
2405
|
);
|
|
2355
2406
|
}
|
|
2356
2407
|
|
|
@@ -2360,7 +2411,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2360
2411
|
"METHOD_TYPE_SERVER_STREAM",
|
|
2361
2412
|
method,
|
|
2362
2413
|
request,
|
|
2363
|
-
service
|
|
2414
|
+
service
|
|
2364
2415
|
);
|
|
2365
2416
|
}
|
|
2366
2417
|
|
|
@@ -2371,12 +2422,12 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2371
2422
|
*/
|
|
2372
2423
|
async RequestAccessBlocking(
|
|
2373
2424
|
targetResourceId,
|
|
2374
|
-
accessType = "VOLT_ACCESS_READ"
|
|
2425
|
+
accessType = "VOLT_ACCESS_READ"
|
|
2375
2426
|
) {
|
|
2376
2427
|
try {
|
|
2377
2428
|
const accessRequest = {
|
|
2378
2429
|
access: accessType,
|
|
2379
|
-
resource_id: targetResourceId
|
|
2430
|
+
resource_id: targetResourceId
|
|
2380
2431
|
};
|
|
2381
2432
|
|
|
2382
2433
|
// This will block while the request is pending.
|
|
@@ -2545,11 +2596,19 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2545
2596
|
const downloadCall = new GRPCCall(
|
|
2546
2597
|
this,
|
|
2547
2598
|
"DownloadFile",
|
|
2548
|
-
"METHOD_TYPE_SERVER_STREAM"
|
|
2599
|
+
"METHOD_TYPE_SERVER_STREAM"
|
|
2549
2600
|
);
|
|
2550
2601
|
return downloadCall.start(grpcClient, request);
|
|
2551
2602
|
}
|
|
2552
2603
|
|
|
2604
|
+
GetFileContent(request) {
|
|
2605
|
+
return unaryCallInternal.call(this, "GetFileContent", request);
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
SetFileContent(request) {
|
|
2609
|
+
return unaryCallInternal.call(this, "SetFileContent", request);
|
|
2610
|
+
}
|
|
2611
|
+
|
|
2553
2612
|
UploadFile(request) {
|
|
2554
2613
|
const grpcClient = this.getVoltAPIClient();
|
|
2555
2614
|
|
|
@@ -2571,7 +2630,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2571
2630
|
const call = new GRPCCall(
|
|
2572
2631
|
this,
|
|
2573
2632
|
"DownloadFile",
|
|
2574
|
-
"METHOD_TYPE_SERVER_STREAM"
|
|
2633
|
+
"METHOD_TYPE_SERVER_STREAM"
|
|
2575
2634
|
);
|
|
2576
2635
|
|
|
2577
2636
|
call.on("data", (response) => {
|
|
@@ -2606,6 +2665,13 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2606
2665
|
});
|
|
2607
2666
|
}
|
|
2608
2667
|
|
|
2668
|
+
/**
|
|
2669
|
+
* SqliteServerAPI
|
|
2670
|
+
*/
|
|
2671
|
+
CreateDatabase(request) {
|
|
2672
|
+
return unaryCallInternal.call(this, "CreateDatabase", request);
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2609
2675
|
/**
|
|
2610
2676
|
* SqliteDatabaseAPI
|
|
2611
2677
|
*/
|
|
@@ -2696,7 +2762,7 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
2696
2762
|
const subscribeCall = new GRPCCall(
|
|
2697
2763
|
this,
|
|
2698
2764
|
"SubscribeWire",
|
|
2699
|
-
"METHOD_TYPE_BIDI"
|
|
2765
|
+
"METHOD_TYPE_BIDI"
|
|
2700
2766
|
);
|
|
2701
2767
|
return subscribeCall.start(grpcClient, request);
|
|
2702
2768
|
}
|