@tdxvolt/volt-client-grpc 0.20.8 → 0.20.10
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 +30 -227
- package/package.json +3 -2
- package/src/grpc-utils.js +5 -3
- package/src/volt-client-internal.js +6 -220
- package/src/volt-client.js +6 -3
- package/src/volt-proto-literals.js +13 -2
package/lib/index.cjs
CHANGED
|
@@ -15,6 +15,7 @@ var fs = require('fs');
|
|
|
15
15
|
var path = require('path');
|
|
16
16
|
var jwt = require('jsonwebtoken');
|
|
17
17
|
var crypto = require('crypto');
|
|
18
|
+
var voltUtility = require('@tdxvolt/volt-utility');
|
|
18
19
|
|
|
19
20
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
20
21
|
|
|
@@ -135,12 +136,14 @@ function createClient(
|
|
|
135
136
|
address,
|
|
136
137
|
credentials,
|
|
137
138
|
noSerialise,
|
|
138
|
-
voltId,
|
|
139
|
-
serviceId
|
|
139
|
+
voltId = "",
|
|
140
|
+
serviceId = ""
|
|
140
141
|
) {
|
|
141
142
|
let grpcCredentials;
|
|
142
143
|
if (credentials) {
|
|
143
|
-
const relaying =
|
|
144
|
+
const relaying =
|
|
145
|
+
!!credentials.config?.volt?.relay &&
|
|
146
|
+
!Array.isArray(credentials.config?.volt?.relay);
|
|
144
147
|
const ca = relaying
|
|
145
148
|
? credentials.config?.volt?.relay?.ca_pem
|
|
146
149
|
: credentials.cache.ca;
|
|
@@ -1726,6 +1729,7 @@ enum SyncState {
|
|
|
1726
1729
|
SYNC_STATE_SYNCING = 1;
|
|
1727
1730
|
SYNC_STATE_DONE = 2;
|
|
1728
1731
|
SYNC_STATE_UPDATE = 3;
|
|
1732
|
+
SYNC_STATE_AWARENESS = 4;
|
|
1729
1733
|
}
|
|
1730
1734
|
|
|
1731
1735
|
message SyncDocumentStart {
|
|
@@ -1794,7 +1798,8 @@ message GetDocumentJSONResponse {
|
|
|
1794
1798
|
// The current JSON snapshot of the document
|
|
1795
1799
|
string json = 2;
|
|
1796
1800
|
}
|
|
1797
|
-
}
|
|
1801
|
+
}
|
|
1802
|
+
`;
|
|
1798
1803
|
const terminal_api = `syntax = "proto3";
|
|
1799
1804
|
|
|
1800
1805
|
package tdx.volt_api.volt.v1;
|
|
@@ -2737,7 +2742,7 @@ message AuthenticateResponse {
|
|
|
2737
2742
|
// This should be persisted by the client, and submitted with all subsequent API calls as part of the call metadata.
|
|
2738
2743
|
string session_id = 2;
|
|
2739
2744
|
|
|
2740
|
-
// The identity
|
|
2745
|
+
// The 'primary' session identity assigned to this authentication. This will be the DID in DID-based sessions, otherwise it will be the first email-based credential found, if any, otherwise it will be the public key fingerprint.
|
|
2741
2746
|
string identity_did = 3;
|
|
2742
2747
|
|
|
2743
2748
|
// A certificate issued by the volt CA, binding the request public key to the identity.
|
|
@@ -2793,6 +2798,9 @@ message CanAccessResourceResponse {
|
|
|
2793
2798
|
|
|
2794
2799
|
// The policy decision for this access request.
|
|
2795
2800
|
PolicyDecision decision = 6;
|
|
2801
|
+
|
|
2802
|
+
// The session that the access relates to.
|
|
2803
|
+
string session_id = 7;
|
|
2796
2804
|
}
|
|
2797
2805
|
|
|
2798
2806
|
message CheckCompatibilityRequest {
|
|
@@ -3138,6 +3146,9 @@ message GetIdentityResponse {
|
|
|
3138
3146
|
message GetOneTimeTokenRequest {
|
|
3139
3147
|
// Optional token TTL, in seconds. Default is 10 seconds.
|
|
3140
3148
|
int32 ttl = 1;
|
|
3149
|
+
|
|
3150
|
+
// Optional token context.
|
|
3151
|
+
string context = 2;
|
|
3141
3152
|
}
|
|
3142
3153
|
|
|
3143
3154
|
message GetOneTimeTokenResponse {
|
|
@@ -3200,6 +3211,9 @@ message GetResourceResponse {
|
|
|
3200
3211
|
message GetResourcesRequest {
|
|
3201
3212
|
repeated string id = 1;
|
|
3202
3213
|
|
|
3214
|
+
// Wildcards permitted.
|
|
3215
|
+
repeated string alias = 16;
|
|
3216
|
+
|
|
3203
3217
|
// Wildcards permitted.
|
|
3204
3218
|
repeated string name = 2;
|
|
3205
3219
|
|
|
@@ -4844,8 +4858,6 @@ class VoltConnection extends EventEmitter__default["default"] {
|
|
|
4844
4858
|
|
|
4845
4859
|
const { publicKeyToPem: publicKeyToPem$1, removeCarriageReturn, signBase64 } = js.voltUtils;
|
|
4846
4860
|
|
|
4847
|
-
const { filter, pick } = lodash__default["default"];
|
|
4848
|
-
|
|
4849
4861
|
const log$2 = debug__default["default"]("volt-client-grpc:volt-client-internal");
|
|
4850
4862
|
|
|
4851
4863
|
function issueAuthenticate(authenticateRequest, ttl) {
|
|
@@ -4918,15 +4930,6 @@ function issueAuthenticate(authenticateRequest, ttl) {
|
|
|
4918
4930
|
});
|
|
4919
4931
|
}
|
|
4920
4932
|
|
|
4921
|
-
function findDIDDocumentService(document, serviceType) {
|
|
4922
|
-
if (!document.service) {
|
|
4923
|
-
return [];
|
|
4924
|
-
}
|
|
4925
|
-
|
|
4926
|
-
const matches = filter(document.service, (svc) => svc.type === serviceType);
|
|
4927
|
-
return matches;
|
|
4928
|
-
}
|
|
4929
|
-
|
|
4930
4933
|
async function authenticateInternal(
|
|
4931
4934
|
noDID = false,
|
|
4932
4935
|
ownDID = false,
|
|
@@ -5189,7 +5192,11 @@ function getVoltAPIClientInternal() {
|
|
|
5189
5192
|
const serviceAddress = this.isRelayed
|
|
5190
5193
|
? this._voltConfig.relay.address
|
|
5191
5194
|
: this._voltConfig.address;
|
|
5192
|
-
log$2(
|
|
5195
|
+
log$2(
|
|
5196
|
+
"creating cached VoltAPI service client on %s for %j",
|
|
5197
|
+
serviceAddress,
|
|
5198
|
+
this._voltConfig
|
|
5199
|
+
);
|
|
5193
5200
|
|
|
5194
5201
|
const serviceDescriptors = getBuiltInServiceDescriptors();
|
|
5195
5202
|
|
|
@@ -5198,9 +5205,7 @@ function getVoltAPIClientInternal() {
|
|
|
5198
5205
|
serviceDescriptors,
|
|
5199
5206
|
serviceAddress,
|
|
5200
5207
|
this._credential,
|
|
5201
|
-
this.isRelayed
|
|
5202
|
-
this._voltConfig?.relay?.cloud ? this._voltConfig.id : "",
|
|
5203
|
-
this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
|
|
5208
|
+
this.isRelayed
|
|
5204
5209
|
);
|
|
5205
5210
|
}
|
|
5206
5211
|
|
|
@@ -5285,211 +5290,6 @@ function streamingCallInternal(methodType, method, request, service) {
|
|
|
5285
5290
|
return call;
|
|
5286
5291
|
}
|
|
5287
5292
|
|
|
5288
|
-
async function fetchVoltConfig(discovery_url) {
|
|
5289
|
-
try {
|
|
5290
|
-
const response = await fetch(discovery_url);
|
|
5291
|
-
|
|
5292
|
-
if (!response.ok) {
|
|
5293
|
-
log$2("fetchVoltConfig - error [%s]", response.status);
|
|
5294
|
-
return null;
|
|
5295
|
-
}
|
|
5296
|
-
|
|
5297
|
-
const fullVoltConfig = await response.json();
|
|
5298
|
-
|
|
5299
|
-
if (!fullVoltConfig || typeof fullVoltConfig !== "object") {
|
|
5300
|
-
log$2("fetchVoltConfig - invalid config resolved from: %s", discovery_url);
|
|
5301
|
-
return null;
|
|
5302
|
-
}
|
|
5303
|
-
|
|
5304
|
-
const voltConfig = pick(
|
|
5305
|
-
fullVoltConfig,
|
|
5306
|
-
"id",
|
|
5307
|
-
"display_name",
|
|
5308
|
-
"public_key",
|
|
5309
|
-
"fingerprint",
|
|
5310
|
-
"address",
|
|
5311
|
-
"http_address",
|
|
5312
|
-
"ca_pem",
|
|
5313
|
-
"relay"
|
|
5314
|
-
);
|
|
5315
|
-
|
|
5316
|
-
log$2("fetchVoltConfig from %s", discovery_url);
|
|
5317
|
-
|
|
5318
|
-
return voltConfig;
|
|
5319
|
-
} catch (err) {
|
|
5320
|
-
log$2("fetchVoltConfig - %s error [%s]", discovery_url, err.message);
|
|
5321
|
-
return null;
|
|
5322
|
-
}
|
|
5323
|
-
}
|
|
5324
|
-
|
|
5325
|
-
async function fetchVoltConfigFromDIDInternal(volt_did, registryUrl) {
|
|
5326
|
-
try {
|
|
5327
|
-
const didResolution = getDIDResolutionURL(volt_did, registryUrl);
|
|
5328
|
-
if (!didResolution) {
|
|
5329
|
-
throw new Error(`Invalid Volt DID: ${volt_did}`);
|
|
5330
|
-
}
|
|
5331
|
-
|
|
5332
|
-
const response = await fetch(didResolution);
|
|
5333
|
-
|
|
5334
|
-
if (!response.ok) {
|
|
5335
|
-
throw new Error(`HTTP error, status: ${response.status}`);
|
|
5336
|
-
}
|
|
5337
|
-
|
|
5338
|
-
const didDocument = await response.json();
|
|
5339
|
-
const voltConfigServices = findDIDDocumentService(
|
|
5340
|
-
didDocument,
|
|
5341
|
-
constants.didServiceType.voltConfig
|
|
5342
|
-
);
|
|
5343
|
-
if (voltConfigServices.length !== 1) {
|
|
5344
|
-
log$2(
|
|
5345
|
-
"Unexpected number of Volt configuration endpoints found in DID document for %s, services found: %d",
|
|
5346
|
-
volt_did,
|
|
5347
|
-
voltConfigServices.length
|
|
5348
|
-
);
|
|
5349
|
-
}
|
|
5350
|
-
|
|
5351
|
-
log$2("resolved DID from %s", didResolution);
|
|
5352
|
-
|
|
5353
|
-
const serviceEndpoint = voltConfigServices[0].serviceEndpoint;
|
|
5354
|
-
const voltConfig = await fetchVoltConfig.call(this, serviceEndpoint);
|
|
5355
|
-
if (!voltConfig) {
|
|
5356
|
-
throw new Error(`failed to resolve Volt config from ${serviceEndpoint}`);
|
|
5357
|
-
}
|
|
5358
|
-
|
|
5359
|
-
return voltConfig;
|
|
5360
|
-
} catch (err) {
|
|
5361
|
-
throw new Error(
|
|
5362
|
-
`Failure fetching Volt config from DID document ${volt_did}: ${err.message}`
|
|
5363
|
-
);
|
|
5364
|
-
}
|
|
5365
|
-
}
|
|
5366
|
-
|
|
5367
|
-
async function fetchVoltConfigFromDID(volt_did, registryListIn) {
|
|
5368
|
-
let registryList;
|
|
5369
|
-
if (!registryListIn) {
|
|
5370
|
-
// If no registry list is provided, use the default registry list.
|
|
5371
|
-
registryList = constants.defaultRegistryList;
|
|
5372
|
-
} else {
|
|
5373
|
-
// If a registry list is provided, merge it with the default registry list.
|
|
5374
|
-
registryList = Array.from(
|
|
5375
|
-
new Set(registryListIn.concat(constants.defaultRegistryList))
|
|
5376
|
-
);
|
|
5377
|
-
}
|
|
5378
|
-
|
|
5379
|
-
let voltConfig;
|
|
5380
|
-
for (let registryUrl of registryList) {
|
|
5381
|
-
try {
|
|
5382
|
-
voltConfig = await fetchVoltConfigFromDIDInternal.call(
|
|
5383
|
-
this,
|
|
5384
|
-
volt_did,
|
|
5385
|
-
registryUrl
|
|
5386
|
-
);
|
|
5387
|
-
|
|
5388
|
-
// If we've found a config, break out of the loop.
|
|
5389
|
-
break;
|
|
5390
|
-
} catch (err) {
|
|
5391
|
-
log$2("unable to fetch Volt config from %s: %s", registryUrl, err.message);
|
|
5392
|
-
}
|
|
5393
|
-
}
|
|
5394
|
-
|
|
5395
|
-
if (!voltConfig) {
|
|
5396
|
-
log$2("failed to fetch Volt config for %s from any registry", volt_did);
|
|
5397
|
-
}
|
|
5398
|
-
|
|
5399
|
-
return voltConfig;
|
|
5400
|
-
}
|
|
5401
|
-
|
|
5402
|
-
async function resolveVoltConfig(cfg, didRegistryList) {
|
|
5403
|
-
// Start by resolving the relay if one is specified.
|
|
5404
|
-
let relay = cfg?.relay?.http_address || cfg?.relay;
|
|
5405
|
-
if (relay) {
|
|
5406
|
-
relay = await resolveVoltConfig.call(this, relay, didRegistryList);
|
|
5407
|
-
}
|
|
5408
|
-
|
|
5409
|
-
let voltDID = "";
|
|
5410
|
-
let voltHttpAddress = "";
|
|
5411
|
-
|
|
5412
|
-
if (typeof cfg === "string") {
|
|
5413
|
-
// If the configuration is a string, determine if it is a DID or HTTP address.
|
|
5414
|
-
if (cfg.indexOf("did:") === 0) {
|
|
5415
|
-
voltDID = cfg;
|
|
5416
|
-
} else {
|
|
5417
|
-
voltHttpAddress = cfg;
|
|
5418
|
-
}
|
|
5419
|
-
cfg = {};
|
|
5420
|
-
} else if (typeof cfg === "object") {
|
|
5421
|
-
voltDID = cfg.id;
|
|
5422
|
-
voltHttpAddress = cfg.http_address;
|
|
5423
|
-
} else {
|
|
5424
|
-
throw new Error("configuration is missing the 'volt' object");
|
|
5425
|
-
}
|
|
5426
|
-
|
|
5427
|
-
let resolvedConfig;
|
|
5428
|
-
|
|
5429
|
-
if (relay) {
|
|
5430
|
-
if (!voltDID) {
|
|
5431
|
-
throw new Error("relay specified but no Volt DID provided");
|
|
5432
|
-
}
|
|
5433
|
-
|
|
5434
|
-
// Build the sub-domain URL for the Volt discovery service by inserting the volt DID into the relay URL.
|
|
5435
|
-
const relayURL = relay.http_address;
|
|
5436
|
-
const relayParts = relayURL.split("://");
|
|
5437
|
-
const subdomain = voltDID.substring(constants.voltDIDPrefix.length);
|
|
5438
|
-
voltHttpAddress = `${relayParts[0]}://${subdomain}.${relayParts[1]}`;
|
|
5439
|
-
} else if (voltDID) {
|
|
5440
|
-
resolvedConfig = await fetchVoltConfigFromDID.call(
|
|
5441
|
-
this,
|
|
5442
|
-
voltDID,
|
|
5443
|
-
didRegistryList
|
|
5444
|
-
);
|
|
5445
|
-
}
|
|
5446
|
-
|
|
5447
|
-
if (!resolvedConfig && voltHttpAddress) {
|
|
5448
|
-
try {
|
|
5449
|
-
resolvedConfig = await fetchVoltConfig.call(
|
|
5450
|
-
this,
|
|
5451
|
-
`${voltHttpAddress}/discover`
|
|
5452
|
-
);
|
|
5453
|
-
|
|
5454
|
-
// Update the http address in the resolved config to the one we used to
|
|
5455
|
-
// fetch it, since we may have used the relay rather than local address.
|
|
5456
|
-
resolvedConfig.http_address = voltHttpAddress;
|
|
5457
|
-
} catch (err) {
|
|
5458
|
-
log$2(
|
|
5459
|
-
"failed to resolve Volt configuration %s [%s]",
|
|
5460
|
-
voltHttpAddress,
|
|
5461
|
-
err.message
|
|
5462
|
-
);
|
|
5463
|
-
}
|
|
5464
|
-
}
|
|
5465
|
-
|
|
5466
|
-
if (!resolvedConfig) {
|
|
5467
|
-
if (cfg.address && cfg.ca_pem) {
|
|
5468
|
-
log$2(
|
|
5469
|
-
"unable to resolve %s / %s, using existing configuration",
|
|
5470
|
-
voltDID,
|
|
5471
|
-
voltHttpAddress
|
|
5472
|
-
);
|
|
5473
|
-
} else {
|
|
5474
|
-
throw new Error(
|
|
5475
|
-
`failed to resolve Volt ${voltDID} / ${voltHttpAddress} and no existing configuration`
|
|
5476
|
-
);
|
|
5477
|
-
}
|
|
5478
|
-
} else {
|
|
5479
|
-
log$2("resolved config from: %s", voltDID || voltHttpAddress);
|
|
5480
|
-
log$2(JSON.stringify(resolvedConfig, null, 2));
|
|
5481
|
-
|
|
5482
|
-
cfg = {
|
|
5483
|
-
...cfg,
|
|
5484
|
-
...resolvedConfig
|
|
5485
|
-
};
|
|
5486
|
-
}
|
|
5487
|
-
|
|
5488
|
-
cfg.relay = relay;
|
|
5489
|
-
|
|
5490
|
-
return cfg;
|
|
5491
|
-
}
|
|
5492
|
-
|
|
5493
5293
|
/* eslint-disable no-underscore-dangle */
|
|
5494
5294
|
|
|
5495
5295
|
const {
|
|
@@ -5748,6 +5548,8 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
5748
5548
|
* @param {boolean} [options.waitForAuth] - whether to block and poll on 'prompt' authenticate decisions. Default is true.
|
|
5749
5549
|
*/
|
|
5750
5550
|
async initialise(config, options = {}) {
|
|
5551
|
+
log("initialise ", config, options);
|
|
5552
|
+
|
|
5751
5553
|
const { ownDID, noDID, didRegistryList, exchangeToken, extraConfig } =
|
|
5752
5554
|
options;
|
|
5753
5555
|
const waitForAuth =
|
|
@@ -5799,14 +5601,15 @@ class VoltClient extends EventEmitter__default["default"] {
|
|
|
5799
5601
|
throw new Error("client_name property required in config");
|
|
5800
5602
|
}
|
|
5801
5603
|
|
|
5802
|
-
this._config.volt = await resolveVoltConfig
|
|
5803
|
-
this,
|
|
5604
|
+
this._config.volt = await voltUtility.resolveVoltConfig(
|
|
5804
5605
|
this._config.volt,
|
|
5805
5606
|
didRegistryList
|
|
5806
5607
|
);
|
|
5807
5608
|
|
|
5808
5609
|
this._voltConfig = this._config.volt;
|
|
5809
5610
|
|
|
5611
|
+
log("config is ", this._voltConfig);
|
|
5612
|
+
|
|
5810
5613
|
if (!this._voltConfig.id || typeof this._voltConfig.id !== "string") {
|
|
5811
5614
|
throw new Error("'id' property is missing in Volt configuration");
|
|
5812
5615
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.20.
|
|
6
|
+
"version": "0.20.10",
|
|
7
7
|
"description": "tdx Volt library for nodejs clients",
|
|
8
8
|
"type": "module",
|
|
9
9
|
"exports": {
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"author": "toby.ealden@gmail.com",
|
|
34
34
|
"license": "ISC",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@tdxvolt/volt-client-web": "^0.20.
|
|
36
|
+
"@tdxvolt/volt-client-web": "^0.20.10",
|
|
37
|
+
"@tdxvolt/volt-utility": "^0.20.10",
|
|
37
38
|
"debug": "^4.1.1",
|
|
38
39
|
"ip": "^1.1.5",
|
|
39
40
|
"jsonwebtoken": "^8.5.1",
|
package/src/grpc-utils.js
CHANGED
|
@@ -15,12 +15,14 @@ export function createClient(
|
|
|
15
15
|
address,
|
|
16
16
|
credentials,
|
|
17
17
|
noSerialise,
|
|
18
|
-
voltId,
|
|
19
|
-
serviceId
|
|
18
|
+
voltId = "",
|
|
19
|
+
serviceId = ""
|
|
20
20
|
) {
|
|
21
21
|
let grpcCredentials;
|
|
22
22
|
if (credentials) {
|
|
23
|
-
const relaying =
|
|
23
|
+
const relaying =
|
|
24
|
+
!!credentials.config?.volt?.relay &&
|
|
25
|
+
!Array.isArray(credentials.config?.volt?.relay);
|
|
24
26
|
const ca = relaying
|
|
25
27
|
? credentials.config?.volt?.relay?.ca_pem
|
|
26
28
|
: credentials.cache.ca;
|
|
@@ -4,7 +4,6 @@ import debug from "debug";
|
|
|
4
4
|
import ip from "ip";
|
|
5
5
|
import lodash from "lodash";
|
|
6
6
|
import { v4 as generateId } from "uuid";
|
|
7
|
-
import { constants } from "./constants.js";
|
|
8
7
|
import GRPCCall from "./grpc-call.js";
|
|
9
8
|
import { createClient as createGrpcClient } from "./grpc-utils.js";
|
|
10
9
|
import {
|
|
@@ -12,7 +11,6 @@ import {
|
|
|
12
11
|
getServiceDescriptors
|
|
13
12
|
} from "./proto-utils.js";
|
|
14
13
|
import RpcInvocation from "./rpc-invocation.js";
|
|
15
|
-
import * as voltUtils from "./utils.js";
|
|
16
14
|
import VoltConnection from "./volt-connection.js";
|
|
17
15
|
|
|
18
16
|
const { publicKeyToPem, removeCarriageReturn, signBase64 } = voltClientUtils;
|
|
@@ -91,15 +89,6 @@ function issueAuthenticate(authenticateRequest, ttl) {
|
|
|
91
89
|
});
|
|
92
90
|
}
|
|
93
91
|
|
|
94
|
-
function findDIDDocumentService(document, serviceType) {
|
|
95
|
-
if (!document.service) {
|
|
96
|
-
return [];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const matches = filter(document.service, (svc) => svc.type === serviceType);
|
|
100
|
-
return matches;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
92
|
export async function authenticateInternal(
|
|
104
93
|
noDID = false,
|
|
105
94
|
ownDID = false,
|
|
@@ -362,7 +351,11 @@ export function getVoltAPIClientInternal() {
|
|
|
362
351
|
const serviceAddress = this.isRelayed
|
|
363
352
|
? this._voltConfig.relay.address
|
|
364
353
|
: this._voltConfig.address;
|
|
365
|
-
log(
|
|
354
|
+
log(
|
|
355
|
+
"creating cached VoltAPI service client on %s for %j",
|
|
356
|
+
serviceAddress,
|
|
357
|
+
this._voltConfig
|
|
358
|
+
);
|
|
366
359
|
|
|
367
360
|
const serviceDescriptors = getBuiltInServiceDescriptors();
|
|
368
361
|
|
|
@@ -371,9 +364,7 @@ export function getVoltAPIClientInternal() {
|
|
|
371
364
|
serviceDescriptors,
|
|
372
365
|
serviceAddress,
|
|
373
366
|
this._credential,
|
|
374
|
-
this.isRelayed
|
|
375
|
-
this._voltConfig?.relay?.cloud ? this._voltConfig.id : "",
|
|
376
|
-
this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
|
|
367
|
+
this.isRelayed
|
|
377
368
|
);
|
|
378
369
|
}
|
|
379
370
|
|
|
@@ -457,208 +448,3 @@ export function streamingCallInternal(methodType, method, request, service) {
|
|
|
457
448
|
|
|
458
449
|
return call;
|
|
459
450
|
}
|
|
460
|
-
|
|
461
|
-
export async function fetchVoltConfig(discovery_url) {
|
|
462
|
-
try {
|
|
463
|
-
const response = await fetch(discovery_url);
|
|
464
|
-
|
|
465
|
-
if (!response.ok) {
|
|
466
|
-
log("fetchVoltConfig - error [%s]", response.status);
|
|
467
|
-
return null;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
const fullVoltConfig = await response.json();
|
|
471
|
-
|
|
472
|
-
if (!fullVoltConfig || typeof fullVoltConfig !== "object") {
|
|
473
|
-
log("fetchVoltConfig - invalid config resolved from: %s", discovery_url);
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
const voltConfig = pick(
|
|
478
|
-
fullVoltConfig,
|
|
479
|
-
"id",
|
|
480
|
-
"display_name",
|
|
481
|
-
"public_key",
|
|
482
|
-
"fingerprint",
|
|
483
|
-
"address",
|
|
484
|
-
"http_address",
|
|
485
|
-
"ca_pem",
|
|
486
|
-
"relay"
|
|
487
|
-
);
|
|
488
|
-
|
|
489
|
-
log("fetchVoltConfig from %s", discovery_url);
|
|
490
|
-
|
|
491
|
-
return voltConfig;
|
|
492
|
-
} catch (err) {
|
|
493
|
-
log("fetchVoltConfig - %s error [%s]", discovery_url, err.message);
|
|
494
|
-
return null;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
async function fetchVoltConfigFromDIDInternal(volt_did, registryUrl) {
|
|
499
|
-
try {
|
|
500
|
-
const didResolution = voltUtils.getDIDResolutionURL(volt_did, registryUrl);
|
|
501
|
-
if (!didResolution) {
|
|
502
|
-
throw new Error(`Invalid Volt DID: ${volt_did}`);
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
const response = await fetch(didResolution);
|
|
506
|
-
|
|
507
|
-
if (!response.ok) {
|
|
508
|
-
throw new Error(`HTTP error, status: ${response.status}`);
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
const didDocument = await response.json();
|
|
512
|
-
const voltConfigServices = findDIDDocumentService(
|
|
513
|
-
didDocument,
|
|
514
|
-
constants.didServiceType.voltConfig
|
|
515
|
-
);
|
|
516
|
-
if (voltConfigServices.length !== 1) {
|
|
517
|
-
log(
|
|
518
|
-
"Unexpected number of Volt configuration endpoints found in DID document for %s, services found: %d",
|
|
519
|
-
volt_did,
|
|
520
|
-
voltConfigServices.length
|
|
521
|
-
);
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
log("resolved DID from %s", didResolution);
|
|
525
|
-
|
|
526
|
-
const serviceEndpoint = voltConfigServices[0].serviceEndpoint;
|
|
527
|
-
const voltConfig = await fetchVoltConfig.call(this, serviceEndpoint);
|
|
528
|
-
if (!voltConfig) {
|
|
529
|
-
throw new Error(`failed to resolve Volt config from ${serviceEndpoint}`);
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
return voltConfig;
|
|
533
|
-
} catch (err) {
|
|
534
|
-
throw new Error(
|
|
535
|
-
`Failure fetching Volt config from DID document ${volt_did}: ${err.message}`
|
|
536
|
-
);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
export async function fetchVoltConfigFromDID(volt_did, registryListIn) {
|
|
541
|
-
let registryList;
|
|
542
|
-
if (!registryListIn) {
|
|
543
|
-
// If no registry list is provided, use the default registry list.
|
|
544
|
-
registryList = constants.defaultRegistryList;
|
|
545
|
-
} else {
|
|
546
|
-
// If a registry list is provided, merge it with the default registry list.
|
|
547
|
-
registryList = Array.from(
|
|
548
|
-
new Set(registryListIn.concat(constants.defaultRegistryList))
|
|
549
|
-
);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
let voltConfig;
|
|
553
|
-
for (let registryUrl of registryList) {
|
|
554
|
-
try {
|
|
555
|
-
voltConfig = await fetchVoltConfigFromDIDInternal.call(
|
|
556
|
-
this,
|
|
557
|
-
volt_did,
|
|
558
|
-
registryUrl
|
|
559
|
-
);
|
|
560
|
-
|
|
561
|
-
// If we've found a config, break out of the loop.
|
|
562
|
-
break;
|
|
563
|
-
} catch (err) {
|
|
564
|
-
log("unable to fetch Volt config from %s: %s", registryUrl, err.message);
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
if (!voltConfig) {
|
|
569
|
-
log("failed to fetch Volt config for %s from any registry", volt_did);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
return voltConfig;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
export async function resolveVoltConfig(cfg, didRegistryList) {
|
|
576
|
-
// Start by resolving the relay if one is specified.
|
|
577
|
-
let relay = cfg?.relay?.http_address || cfg?.relay;
|
|
578
|
-
if (relay) {
|
|
579
|
-
relay = await resolveVoltConfig.call(this, relay, didRegistryList);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
let voltDID = "";
|
|
583
|
-
let voltHttpAddress = "";
|
|
584
|
-
|
|
585
|
-
if (typeof cfg === "string") {
|
|
586
|
-
// If the configuration is a string, determine if it is a DID or HTTP address.
|
|
587
|
-
if (cfg.indexOf("did:") === 0) {
|
|
588
|
-
voltDID = cfg;
|
|
589
|
-
} else {
|
|
590
|
-
voltHttpAddress = cfg;
|
|
591
|
-
}
|
|
592
|
-
cfg = {};
|
|
593
|
-
} else if (typeof cfg === "object") {
|
|
594
|
-
voltDID = cfg.id;
|
|
595
|
-
voltHttpAddress = cfg.http_address;
|
|
596
|
-
} else {
|
|
597
|
-
throw new Error("configuration is missing the 'volt' object");
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
let resolvedConfig;
|
|
601
|
-
|
|
602
|
-
if (relay) {
|
|
603
|
-
if (!voltDID) {
|
|
604
|
-
throw new Error("relay specified but no Volt DID provided");
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// Build the sub-domain URL for the Volt discovery service by inserting the volt DID into the relay URL.
|
|
608
|
-
const relayURL = relay.http_address;
|
|
609
|
-
const relayParts = relayURL.split("://");
|
|
610
|
-
const subdomain = voltDID.substring(constants.voltDIDPrefix.length);
|
|
611
|
-
voltHttpAddress = `${relayParts[0]}://${subdomain}.${relayParts[1]}`;
|
|
612
|
-
} else if (voltDID) {
|
|
613
|
-
resolvedConfig = await fetchVoltConfigFromDID.call(
|
|
614
|
-
this,
|
|
615
|
-
voltDID,
|
|
616
|
-
didRegistryList
|
|
617
|
-
);
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
if (!resolvedConfig && voltHttpAddress) {
|
|
621
|
-
try {
|
|
622
|
-
resolvedConfig = await fetchVoltConfig.call(
|
|
623
|
-
this,
|
|
624
|
-
`${voltHttpAddress}/discover`
|
|
625
|
-
);
|
|
626
|
-
|
|
627
|
-
// Update the http address in the resolved config to the one we used to
|
|
628
|
-
// fetch it, since we may have used the relay rather than local address.
|
|
629
|
-
resolvedConfig.http_address = voltHttpAddress;
|
|
630
|
-
} catch (err) {
|
|
631
|
-
log(
|
|
632
|
-
"failed to resolve Volt configuration %s [%s]",
|
|
633
|
-
voltHttpAddress,
|
|
634
|
-
err.message
|
|
635
|
-
);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
if (!resolvedConfig) {
|
|
640
|
-
if (cfg.address && cfg.ca_pem) {
|
|
641
|
-
log(
|
|
642
|
-
"unable to resolve %s / %s, using existing configuration",
|
|
643
|
-
voltDID,
|
|
644
|
-
voltHttpAddress
|
|
645
|
-
);
|
|
646
|
-
} else {
|
|
647
|
-
throw new Error(
|
|
648
|
-
`failed to resolve Volt ${voltDID} / ${voltHttpAddress} and no existing configuration`
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
} else {
|
|
652
|
-
log("resolved config from: %s", voltDID || voltHttpAddress);
|
|
653
|
-
log(JSON.stringify(resolvedConfig, null, 2));
|
|
654
|
-
|
|
655
|
-
cfg = {
|
|
656
|
-
...cfg,
|
|
657
|
-
...resolvedConfig
|
|
658
|
-
};
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
cfg.relay = relay;
|
|
662
|
-
|
|
663
|
-
return cfg;
|
|
664
|
-
}
|
package/src/volt-client.js
CHANGED
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
authenticateInternal,
|
|
8
8
|
connectInternal,
|
|
9
9
|
getVoltAPIClientInternal,
|
|
10
|
-
resolveVoltConfig,
|
|
11
10
|
streamingCallInternal,
|
|
12
11
|
unaryCallInternal
|
|
13
12
|
} from "./volt-client-internal.js";
|
|
14
13
|
import { VoltCredential } from "./volt-credential.js";
|
|
14
|
+
import { resolveVoltConfig } from "@tdxvolt/volt-utility";
|
|
15
15
|
|
|
16
16
|
const { readFile } = fs.promises;
|
|
17
17
|
const log = debug("volt-client-grpc:volt-client");
|
|
@@ -88,6 +88,8 @@ export class VoltClient extends EventEmitter {
|
|
|
88
88
|
* @param {boolean} [options.waitForAuth] - whether to block and poll on 'prompt' authenticate decisions. Default is true.
|
|
89
89
|
*/
|
|
90
90
|
async initialise(config, options = {}) {
|
|
91
|
+
log("initialise ", config, options);
|
|
92
|
+
|
|
91
93
|
const { ownDID, noDID, didRegistryList, exchangeToken, extraConfig } =
|
|
92
94
|
options;
|
|
93
95
|
const waitForAuth =
|
|
@@ -139,14 +141,15 @@ export class VoltClient extends EventEmitter {
|
|
|
139
141
|
throw new Error("client_name property required in config");
|
|
140
142
|
}
|
|
141
143
|
|
|
142
|
-
this._config.volt = await resolveVoltConfig
|
|
143
|
-
this,
|
|
144
|
+
this._config.volt = await resolveVoltConfig(
|
|
144
145
|
this._config.volt,
|
|
145
146
|
didRegistryList
|
|
146
147
|
);
|
|
147
148
|
|
|
148
149
|
this._voltConfig = this._config.volt;
|
|
149
150
|
|
|
151
|
+
log("config is ", this._voltConfig);
|
|
152
|
+
|
|
150
153
|
if (!this._voltConfig.id || typeof this._voltConfig.id !== "string") {
|
|
151
154
|
throw new Error("'id' property is missing in Volt configuration");
|
|
152
155
|
}
|
|
@@ -1181,6 +1181,7 @@ enum SyncState {
|
|
|
1181
1181
|
SYNC_STATE_SYNCING = 1;
|
|
1182
1182
|
SYNC_STATE_DONE = 2;
|
|
1183
1183
|
SYNC_STATE_UPDATE = 3;
|
|
1184
|
+
SYNC_STATE_AWARENESS = 4;
|
|
1184
1185
|
}
|
|
1185
1186
|
|
|
1186
1187
|
message SyncDocumentStart {
|
|
@@ -1249,7 +1250,8 @@ message GetDocumentJSONResponse {
|
|
|
1249
1250
|
// The current JSON snapshot of the document
|
|
1250
1251
|
string json = 2;
|
|
1251
1252
|
}
|
|
1252
|
-
}
|
|
1253
|
+
}
|
|
1254
|
+
`;
|
|
1253
1255
|
export const terminal_api = `syntax = "proto3";
|
|
1254
1256
|
|
|
1255
1257
|
package tdx.volt_api.volt.v1;
|
|
@@ -2192,7 +2194,7 @@ message AuthenticateResponse {
|
|
|
2192
2194
|
// This should be persisted by the client, and submitted with all subsequent API calls as part of the call metadata.
|
|
2193
2195
|
string session_id = 2;
|
|
2194
2196
|
|
|
2195
|
-
// The identity
|
|
2197
|
+
// The 'primary' session identity assigned to this authentication. This will be the DID in DID-based sessions, otherwise it will be the first email-based credential found, if any, otherwise it will be the public key fingerprint.
|
|
2196
2198
|
string identity_did = 3;
|
|
2197
2199
|
|
|
2198
2200
|
// A certificate issued by the volt CA, binding the request public key to the identity.
|
|
@@ -2248,6 +2250,9 @@ message CanAccessResourceResponse {
|
|
|
2248
2250
|
|
|
2249
2251
|
// The policy decision for this access request.
|
|
2250
2252
|
PolicyDecision decision = 6;
|
|
2253
|
+
|
|
2254
|
+
// The session that the access relates to.
|
|
2255
|
+
string session_id = 7;
|
|
2251
2256
|
}
|
|
2252
2257
|
|
|
2253
2258
|
message CheckCompatibilityRequest {
|
|
@@ -2593,6 +2598,9 @@ message GetIdentityResponse {
|
|
|
2593
2598
|
message GetOneTimeTokenRequest {
|
|
2594
2599
|
// Optional token TTL, in seconds. Default is 10 seconds.
|
|
2595
2600
|
int32 ttl = 1;
|
|
2601
|
+
|
|
2602
|
+
// Optional token context.
|
|
2603
|
+
string context = 2;
|
|
2596
2604
|
}
|
|
2597
2605
|
|
|
2598
2606
|
message GetOneTimeTokenResponse {
|
|
@@ -2655,6 +2663,9 @@ message GetResourceResponse {
|
|
|
2655
2663
|
message GetResourcesRequest {
|
|
2656
2664
|
repeated string id = 1;
|
|
2657
2665
|
|
|
2666
|
+
// Wildcards permitted.
|
|
2667
|
+
repeated string alias = 16;
|
|
2668
|
+
|
|
2658
2669
|
// Wildcards permitted.
|
|
2659
2670
|
repeated string name = 2;
|
|
2660
2671
|
|