@tdxvolt/volt-client-grpc 0.20.8 → 0.20.11

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 CHANGED
@@ -10,6 +10,7 @@ var debug = require('debug');
10
10
  var Protobuf = require('protobufjs');
11
11
  var camelCase = require('lodash.camelcase');
12
12
  var descriptor = require('protobufjs/ext/descriptor/index.js');
13
+ var voltUtility = require('@tdxvolt/volt-utility');
13
14
  var EventEmitter = require('events');
14
15
  var fs = require('fs');
15
16
  var path = require('path');
@@ -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 = !!credentials.config?.volt?.relay && !Array.isArray(credentials.config?.volt?.relay);
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;
@@ -1263,128 +1266,6 @@ message RemoteResponse {
1263
1266
  HttpRequest http_request = 5;
1264
1267
  }
1265
1268
  }
1266
- `;
1267
- const spark_api = `syntax = "proto3";
1268
-
1269
- package tdx.volt_api.volt.v1;
1270
-
1271
- import "tdx/volt_api/volt/v1/status.proto";
1272
-
1273
- // The Spark API allows clients to start and communicate with Spark VMs.
1274
- service SparkAPI {
1275
- // Start or connect to a spark VM and establish a long-lived communication channel.
1276
- rpc Spark(stream SparkRequest) returns (stream SparkResponse);
1277
-
1278
- // Get details of running spark VMs.
1279
- rpc GetSpark(GetSparkRequest) returns (GetSparkResponse);
1280
- }
1281
-
1282
- // Start a resource-hosted spark.
1283
- // Provenance is determined from the resource owner.
1284
- message StartSparkResource {
1285
- // The id of the resource containing the VM byte code.
1286
- string resource_id = 1;
1287
-
1288
- // JSON-encoded payload to parameterise the spark.
1289
- string payload = 2;
1290
-
1291
- // Envelope signature.
1292
- string signature = 3;
1293
- }
1294
-
1295
- // Start a spark from byte code included in the payload, along with issuer/developer claims and signature.
1296
- message StartSparkAdhoc {
1297
- // Ad-hoc byte code of VM to run.
1298
- bytes byte_code = 1;
1299
-
1300
- // Verifiable credentials associated with this spark.
1301
- repeated string credential = 2;
1302
-
1303
- // Envelope signature.
1304
- string signature = 3;
1305
-
1306
- // JSON-encoded payload to parameterise the spark.
1307
- string payload = 4;
1308
- }
1309
-
1310
- // Send commands and payloads to communicate with a running spark.
1311
- message SparkCommand {
1312
- // Optional id to associate with this command.
1313
- // If this is omitted, an id will be assigned and returned in the command acknowledgement.
1314
- string command_id = 1;
1315
-
1316
- // The command to send to the spark.
1317
- string command = 2;
1318
-
1319
- // The command payload.
1320
- string payload = 3;
1321
-
1322
- // Command verifiable credential.
1323
- string credential = 4;
1324
-
1325
- // Command signature.
1326
- string signature = 5;
1327
- }
1328
-
1329
- // The request must contain one of the messages indicated below.
1330
- message SparkRequest {
1331
- oneof payload {
1332
- StartSparkResource start_resource = 1;
1333
- StartSparkAdhoc start_adhoc = 2;
1334
- SparkCommand command = 3;
1335
- }
1336
- }
1337
-
1338
- // Receive events and payload from a running spark.
1339
- message SparkData {
1340
- // The command id to which this data corresponds.
1341
- string command_id = 1;
1342
-
1343
- oneof payload {
1344
- // Acknowledges receipt of a spark command.
1345
- bool acknowledge = 2;
1346
-
1347
- // Indicates the command has completed.
1348
- bool ended = 3;
1349
-
1350
- // Will contain error details on command failure.
1351
- string error = 4;
1352
-
1353
- // Data emitted by a command, usually in stringified JSON format.
1354
- string data = 5;
1355
- }
1356
- }
1357
-
1358
- // Details of a spark instance.
1359
- message SparkInstance {
1360
- // The UUID assigned to the spark instance.
1361
- string spark_id = 1;
1362
- }
1363
-
1364
- // The response will contain one of the messages indicated below.
1365
- message SparkResponse {
1366
- oneof payload {
1367
- // Details of any error that occurred on the call.
1368
- tdx.volt_api.volt.v1.Status status = 1;
1369
-
1370
- // Details of the spark instance, sent in response to a start command.
1371
- SparkInstance spark_instance = 2;
1372
-
1373
- // Payload data emitted by the spark.
1374
- SparkData spark_data = 3;
1375
- }
1376
- }
1377
-
1378
- message GetSparkRequest {
1379
- string spark_id = 1;
1380
- }
1381
-
1382
- // One of the following fields will be present in the response.
1383
- message GetSparkResponse {
1384
- // Details of any error that occurred on the call.
1385
- tdx.volt_api.volt.v1.Status status = 1;
1386
- }
1387
-
1388
1269
  `;
1389
1270
  const ssi = `syntax = "proto3";
1390
1271
 
@@ -1460,12 +1341,11 @@ const ssi_api = `syntax = "proto3";
1460
1341
 
1461
1342
  package tdx.volt_api.volt.v1;
1462
1343
 
1463
- import "tdx/volt_api/volt/v1/status.proto";
1464
1344
  import "tdx/volt_api/volt/v1/ssi.proto";
1345
+ import "tdx/volt_api/volt/v1/status.proto";
1465
1346
 
1466
1347
  service SsiAPI {
1467
- // Get a short-lived, one-time token that can be used to authenticate with the Volt and potentially create verifiable credential(s).
1468
- rpc CreateExchangeToken(CreateExchangeTokenRequest) returns (CreateExchangeTokenResponse);
1348
+ rpc CacheEmailCredential(CacheEmailCredentialRequest) returns (CacheEmailCredentialResponse);
1469
1349
 
1470
1350
  // Delete a DID document or all DID documents originating from a given Volt.
1471
1351
  // Requires \`volt:delete-did\` API privilege.
@@ -1496,20 +1376,25 @@ service SsiAPI {
1496
1376
  rpc SearchDIDRegistry(SearchDIDRegistryRequest) returns (SearchDIDRegistryResponse);
1497
1377
  }
1498
1378
 
1499
- message CreateExchangeTokenRequest {
1500
- // The VC template to use to create a verifiable credential.
1501
- string vc_template = 1;
1379
+ message CacheEmailCredentialRequest {
1380
+ string identity_did = 1;
1381
+
1382
+ string email_address = 2;
1383
+
1384
+ string identity_provider = 3;
1385
+
1386
+ string key_passphrase = 4;
1502
1387
 
1503
1388
  // The time to live for the token, in seconds.
1504
- uint32 ttl = 2;
1389
+ uint32 ttl = 5;
1505
1390
  }
1506
1391
 
1507
- message CreateExchangeTokenResponse {
1392
+ message CacheEmailCredentialResponse {
1508
1393
  // Details of any error that occurred on the call.
1509
1394
  tdx.volt_api.volt.v1.Status status = 1;
1510
1395
 
1511
- // The one-time token.
1512
- string token = 2;
1396
+ // The verifiable credential resource id.
1397
+ string vc_id = 2;
1513
1398
  }
1514
1399
 
1515
1400
  message DeleteDIDRequest {
@@ -1726,6 +1611,7 @@ enum SyncState {
1726
1611
  SYNC_STATE_SYNCING = 1;
1727
1612
  SYNC_STATE_DONE = 2;
1728
1613
  SYNC_STATE_UPDATE = 3;
1614
+ SYNC_STATE_AWARENESS = 4;
1729
1615
  }
1730
1616
 
1731
1617
  message SyncDocumentStart {
@@ -1794,7 +1680,8 @@ message GetDocumentJSONResponse {
1794
1680
  // The current JSON snapshot of the document
1795
1681
  string json = 2;
1796
1682
  }
1797
- }`;
1683
+ }
1684
+ `;
1798
1685
  const terminal_api = `syntax = "proto3";
1799
1686
 
1800
1687
  package tdx.volt_api.volt.v1;
@@ -2709,7 +2596,7 @@ message AuthenticateRequest {
2709
2596
  // A human-readable name of the entity requesting to authenticate.
2710
2597
  string client_name = 6;
2711
2598
 
2712
- // Optional challenge code, hashed using SHA-256 and base64 encoded.
2599
+ // Optional challenge code, hashed using SHA-256 and base64 URL encoded (no padding).
2713
2600
  string challenge = 7;
2714
2601
 
2715
2602
  // The host name to add as a SAN to the issued certificate.
@@ -2737,7 +2624,7 @@ message AuthenticateResponse {
2737
2624
  // This should be persisted by the client, and submitted with all subsequent API calls as part of the call metadata.
2738
2625
  string session_id = 2;
2739
2626
 
2740
- // The identity id assigned to this authentication.
2627
+ // 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
2628
  string identity_did = 3;
2742
2629
 
2743
2630
  // A certificate issued by the volt CA, binding the request public key to the identity.
@@ -2793,6 +2680,9 @@ message CanAccessResourceResponse {
2793
2680
 
2794
2681
  // The policy decision for this access request.
2795
2682
  PolicyDecision decision = 6;
2683
+
2684
+ // The session that the access relates to.
2685
+ string session_id = 7;
2796
2686
  }
2797
2687
 
2798
2688
  message CheckCompatibilityRequest {
@@ -3138,6 +3028,9 @@ message GetIdentityResponse {
3138
3028
  message GetOneTimeTokenRequest {
3139
3029
  // Optional token TTL, in seconds. Default is 10 seconds.
3140
3030
  int32 ttl = 1;
3031
+
3032
+ // Optional token context.
3033
+ string context = 2;
3141
3034
  }
3142
3035
 
3143
3036
  message GetOneTimeTokenResponse {
@@ -3200,6 +3093,9 @@ message GetResourceResponse {
3200
3093
  message GetResourcesRequest {
3201
3094
  repeated string id = 1;
3202
3095
 
3096
+ // Wildcards permitted.
3097
+ repeated string alias = 16;
3098
+
3203
3099
  // Wildcards permitted.
3204
3100
  repeated string name = 2;
3205
3101
 
@@ -3716,7 +3612,7 @@ message SubscribeWireResponse {
3716
3612
  }
3717
3613
 
3718
3614
  `;
3719
- const voltProtos = [sqlite, sqlite_database_api, sqlite_server_api, proto_db_sync, proxy_api, relay_api, discovery_api, file, file_api, remote, spark_api, ssi, ssi_api, status, sync_api, terminal_api, volt, volt_api, wire_api];
3615
+ const voltProtos = [sqlite, sqlite_database_api, sqlite_server_api, proto_db_sync, proxy_api, relay_api, discovery_api, file, file_api, remote, ssi, ssi_api, status, sync_api, terminal_api, volt, volt_api, wire_api];
3720
3616
 
3721
3617
  debug__default["default"]("volt-client-grpc:proto-utils");
3722
3618
 
@@ -4137,11 +4033,6 @@ class GRPCCall extends EventEmitter__default["default"] {
4137
4033
  );
4138
4034
 
4139
4035
  this._call.on("data", (streamResponse) => {
4140
- if (this._ended) {
4141
- log$5("ignoring data after end on %s", this._methodName);
4142
- return;
4143
- }
4144
-
4145
4036
  try {
4146
4037
  const parsedResponse = _parseResponse.call(
4147
4038
  this,
@@ -4149,6 +4040,13 @@ class GRPCCall extends EventEmitter__default["default"] {
4149
4040
  this._initialRequest.meta,
4150
4041
  streamResponse
4151
4042
  );
4043
+
4044
+ if (this._ended && !parsedResponse.ended) {
4045
+ log$5("ignoring data after end on %s", this._methodName);
4046
+ log$5(parsedResponse);
4047
+ return;
4048
+ }
4049
+
4152
4050
  if (parsedResponse.key_exchange) {
4153
4051
  const peerKey = keyFromPem$2(
4154
4052
  parsedResponse.key_exchange.encryption_key
@@ -4180,9 +4078,6 @@ class GRPCCall extends EventEmitter__default["default"] {
4180
4078
  } else if (parsedResponse.ended) {
4181
4079
  if (parsedResponse.error) {
4182
4080
  this.emit("error", new Error(parsedResponse.error));
4183
- } else {
4184
- // Not sure this is necessary - we should receive "end" from grpc soon...
4185
- this.emit("end");
4186
4081
  }
4187
4082
  } else {
4188
4083
  log$5("method id is %s", parsedResponse.methodId);
@@ -4658,6 +4553,7 @@ function _cleanUp(immediateReconnect) {
4658
4553
  }
4659
4554
 
4660
4555
  if (this._dying) {
4556
+ log$3("dying - clearing reconnect timer");
4661
4557
  clearTimeout(this._reconnectTimer);
4662
4558
  } else if (immediateReconnect || (this._autoRetry && !this._reconnectTimer)) {
4663
4559
  this._reconnectTimer = setTimeout(
@@ -4670,6 +4566,7 @@ function _cleanUp(immediateReconnect) {
4670
4566
  }
4671
4567
 
4672
4568
  if (this.call?.writable) {
4569
+ log$3("ending Connect call");
4673
4570
  this.call.end();
4674
4571
  }
4675
4572
  }
@@ -4760,9 +4657,7 @@ function _doConnect(connectHello) {
4760
4657
  });
4761
4658
 
4762
4659
  this.call.on("end", () => {
4763
- if (this._connectionId) {
4764
- this.emit("connected", false);
4765
- }
4660
+ this.emit("connected", false);
4766
4661
  _cleanUp.call(this);
4767
4662
  });
4768
4663
 
@@ -4844,8 +4739,6 @@ class VoltConnection extends EventEmitter__default["default"] {
4844
4739
 
4845
4740
  const { publicKeyToPem: publicKeyToPem$1, removeCarriageReturn, signBase64 } = js.voltUtils;
4846
4741
 
4847
- const { filter, pick } = lodash__default["default"];
4848
-
4849
4742
  const log$2 = debug__default["default"]("volt-client-grpc:volt-client-internal");
4850
4743
 
4851
4744
  function issueAuthenticate(authenticateRequest, ttl) {
@@ -4918,15 +4811,6 @@ function issueAuthenticate(authenticateRequest, ttl) {
4918
4811
  });
4919
4812
  }
4920
4813
 
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
4814
  async function authenticateInternal(
4931
4815
  noDID = false,
4932
4816
  ownDID = false,
@@ -5103,18 +4987,18 @@ function connectInternal(helloPayload) {
5103
4987
  this._voltConnection.on("connected", (session) => {
5104
4988
  this._session = session;
5105
4989
  this._connected = !!session;
4990
+ this.emit("connected", session);
5106
4991
  if (!this._connected) {
5107
4992
  onDisconnected();
5108
4993
  }
5109
- this.emit("connected", session);
5110
4994
  });
5111
4995
 
5112
4996
  this._voltConnection.on("error", (err) => {
5113
4997
  // Should auto-reconnect.
5114
4998
  log$2("Volt connection error [%s]", err.message);
5115
4999
  if (this._connected) {
5116
- onDisconnected();
5117
5000
  this.emit("connected", false);
5001
+ onDisconnected();
5118
5002
  }
5119
5003
 
5120
5004
  if (err.message.endsWith("session invalid")) {
@@ -5189,7 +5073,11 @@ function getVoltAPIClientInternal() {
5189
5073
  const serviceAddress = this.isRelayed
5190
5074
  ? this._voltConfig.relay.address
5191
5075
  : this._voltConfig.address;
5192
- log$2("creating cached VoltAPI service client on %s", serviceAddress);
5076
+ log$2(
5077
+ "creating cached VoltAPI service client on %s for %j",
5078
+ serviceAddress,
5079
+ this._voltConfig
5080
+ );
5193
5081
 
5194
5082
  const serviceDescriptors = getBuiltInServiceDescriptors();
5195
5083
 
@@ -5198,9 +5086,7 @@ function getVoltAPIClientInternal() {
5198
5086
  serviceDescriptors,
5199
5087
  serviceAddress,
5200
5088
  this._credential,
5201
- this.isRelayed,
5202
- this._voltConfig?.relay?.cloud ? this._voltConfig.id : "",
5203
- this._voltConfig?.relay?.cloud ? this._voltConfig.id : ""
5089
+ this.isRelayed
5204
5090
  );
5205
5091
  }
5206
5092
 
@@ -5285,211 +5171,6 @@ function streamingCallInternal(methodType, method, request, service) {
5285
5171
  return call;
5286
5172
  }
5287
5173
 
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
5174
  /* eslint-disable no-underscore-dangle */
5494
5175
 
5495
5176
  const {
@@ -5746,10 +5427,19 @@ class VoltClient extends EventEmitter__default["default"] {
5746
5427
  * instead of a DID-based authentication session.
5747
5428
  * @param {string} [options.exchangeToken] - optional token to exchange in return for an authenticated session.
5748
5429
  * @param {boolean} [options.waitForAuth] - whether to block and poll on 'prompt' authenticate decisions. Default is true.
5430
+ * @param {boolean} [options.noResolve] - whether to skip resolving the Volt configuration. Default is false.
5749
5431
  */
5750
5432
  async initialise(config, options = {}) {
5751
- const { ownDID, noDID, didRegistryList, exchangeToken, extraConfig } =
5752
- options;
5433
+ log("initialise ", config, options);
5434
+
5435
+ const {
5436
+ ownDID,
5437
+ noDID,
5438
+ didRegistryList,
5439
+ exchangeToken,
5440
+ extraConfig,
5441
+ noResolve
5442
+ } = options;
5753
5443
  const waitForAuth =
5754
5444
  options.waitForAuth === undefined ? true : !!options.waitForAuth;
5755
5445
 
@@ -5799,14 +5489,17 @@ class VoltClient extends EventEmitter__default["default"] {
5799
5489
  throw new Error("client_name property required in config");
5800
5490
  }
5801
5491
 
5802
- this._config.volt = await resolveVoltConfig.call(
5803
- this,
5804
- this._config.volt,
5805
- didRegistryList
5806
- );
5492
+ if (!noResolve) {
5493
+ this._config.volt = await voltUtility.resolveVoltConfig(
5494
+ this._config.volt,
5495
+ didRegistryList
5496
+ );
5497
+ }
5807
5498
 
5808
5499
  this._voltConfig = this._config.volt;
5809
5500
 
5501
+ log("config is ", this._voltConfig);
5502
+
5810
5503
  if (!this._voltConfig.id || typeof this._voltConfig.id !== "string") {
5811
5504
  throw new Error("'id' property is missing in Volt configuration");
5812
5505
  }
@@ -5864,7 +5557,7 @@ class VoltClient extends EventEmitter__default["default"] {
5864
5557
  this._credential.saveCache();
5865
5558
  }
5866
5559
 
5867
- return Promise.resolve(this._config);
5560
+ return Promise.resolve(this.credential.config);
5868
5561
  } catch (err) {
5869
5562
  log("failure starting Volt client [%s]", err.message);
5870
5563
  throw err;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.20.8",
6
+ "version": "0.20.11",
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.8",
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-call.js CHANGED
@@ -361,11 +361,6 @@ export default class GRPCCall extends EventEmitter {
361
361
  );
362
362
 
363
363
  this._call.on("data", (streamResponse) => {
364
- if (this._ended) {
365
- log("ignoring data after end on %s", this._methodName);
366
- return;
367
- }
368
-
369
364
  try {
370
365
  const parsedResponse = _parseResponse.call(
371
366
  this,
@@ -373,6 +368,13 @@ export default class GRPCCall extends EventEmitter {
373
368
  this._initialRequest.meta,
374
369
  streamResponse
375
370
  );
371
+
372
+ if (this._ended && !parsedResponse.ended) {
373
+ log("ignoring data after end on %s", this._methodName);
374
+ log(parsedResponse);
375
+ return;
376
+ }
377
+
376
378
  if (parsedResponse.key_exchange) {
377
379
  const peerKey = keyFromPem(
378
380
  parsedResponse.key_exchange.encryption_key
@@ -404,9 +406,6 @@ export default class GRPCCall extends EventEmitter {
404
406
  } else if (parsedResponse.ended) {
405
407
  if (parsedResponse.error) {
406
408
  this.emit("error", new Error(parsedResponse.error));
407
- } else {
408
- // Not sure this is necessary - we should receive "end" from grpc soon...
409
- this.emit("end");
410
409
  }
411
410
  } else {
412
411
  log("method id is %s", parsedResponse.methodId);
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 = !!credentials.config?.volt?.relay && !Array.isArray(credentials.config?.volt?.relay);
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,
@@ -276,18 +265,18 @@ export function connectInternal(helloPayload) {
276
265
  this._voltConnection.on("connected", (session) => {
277
266
  this._session = session;
278
267
  this._connected = !!session;
268
+ this.emit("connected", session);
279
269
  if (!this._connected) {
280
270
  onDisconnected();
281
271
  }
282
- this.emit("connected", session);
283
272
  });
284
273
 
285
274
  this._voltConnection.on("error", (err) => {
286
275
  // Should auto-reconnect.
287
276
  log("Volt connection error [%s]", err.message);
288
277
  if (this._connected) {
289
- onDisconnected();
290
278
  this.emit("connected", false);
279
+ onDisconnected();
291
280
  }
292
281
 
293
282
  if (err.message.endsWith("session invalid")) {
@@ -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("creating cached VoltAPI service client on %s", serviceAddress);
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
- }
@@ -1,3 +1,4 @@
1
+ import { resolveVoltConfig } from "@tdxvolt/volt-utility";
1
2
  import debug from "debug";
2
3
  import EventEmitter from "events";
3
4
  import fs from "fs";
@@ -7,7 +8,6 @@ import {
7
8
  authenticateInternal,
8
9
  connectInternal,
9
10
  getVoltAPIClientInternal,
10
- resolveVoltConfig,
11
11
  streamingCallInternal,
12
12
  unaryCallInternal
13
13
  } from "./volt-client-internal.js";
@@ -86,10 +86,19 @@ export class VoltClient extends EventEmitter {
86
86
  * instead of a DID-based authentication session.
87
87
  * @param {string} [options.exchangeToken] - optional token to exchange in return for an authenticated session.
88
88
  * @param {boolean} [options.waitForAuth] - whether to block and poll on 'prompt' authenticate decisions. Default is true.
89
+ * @param {boolean} [options.noResolve] - whether to skip resolving the Volt configuration. Default is false.
89
90
  */
90
91
  async initialise(config, options = {}) {
91
- const { ownDID, noDID, didRegistryList, exchangeToken, extraConfig } =
92
- options;
92
+ log("initialise ", config, options);
93
+
94
+ const {
95
+ ownDID,
96
+ noDID,
97
+ didRegistryList,
98
+ exchangeToken,
99
+ extraConfig,
100
+ noResolve
101
+ } = options;
93
102
  const waitForAuth =
94
103
  options.waitForAuth === undefined ? true : !!options.waitForAuth;
95
104
 
@@ -139,14 +148,17 @@ export class VoltClient extends EventEmitter {
139
148
  throw new Error("client_name property required in config");
140
149
  }
141
150
 
142
- this._config.volt = await resolveVoltConfig.call(
143
- this,
144
- this._config.volt,
145
- didRegistryList
146
- );
151
+ if (!noResolve) {
152
+ this._config.volt = await resolveVoltConfig(
153
+ this._config.volt,
154
+ didRegistryList
155
+ );
156
+ }
147
157
 
148
158
  this._voltConfig = this._config.volt;
149
159
 
160
+ log("config is ", this._voltConfig);
161
+
150
162
  if (!this._voltConfig.id || typeof this._voltConfig.id !== "string") {
151
163
  throw new Error("'id' property is missing in Volt configuration");
152
164
  }
@@ -204,7 +216,7 @@ export class VoltClient extends EventEmitter {
204
216
  this._credential.saveCache();
205
217
  }
206
218
 
207
- return Promise.resolve(this._config);
219
+ return Promise.resolve(this.credential.config);
208
220
  } catch (err) {
209
221
  log("failure starting Volt client [%s]", err.message);
210
222
  throw err;
@@ -20,6 +20,7 @@ function _cleanUp(immediateReconnect) {
20
20
  }
21
21
 
22
22
  if (this._dying) {
23
+ log("dying - clearing reconnect timer");
23
24
  clearTimeout(this._reconnectTimer);
24
25
  } else if (immediateReconnect || (this._autoRetry && !this._reconnectTimer)) {
25
26
  this._reconnectTimer = setTimeout(
@@ -32,6 +33,7 @@ function _cleanUp(immediateReconnect) {
32
33
  }
33
34
 
34
35
  if (this.call?.writable) {
36
+ log("ending Connect call");
35
37
  this.call.end();
36
38
  }
37
39
  }
@@ -122,9 +124,7 @@ function _doConnect(connectHello) {
122
124
  });
123
125
 
124
126
  this.call.on("end", () => {
125
- if (this._connectionId) {
126
- this.emit("connected", false);
127
- }
127
+ this.emit("connected", false);
128
128
  _cleanUp.call(this);
129
129
  });
130
130
 
@@ -718,128 +718,6 @@ message RemoteResponse {
718
718
  HttpRequest http_request = 5;
719
719
  }
720
720
  }
721
- `;
722
- export const spark_api = `syntax = "proto3";
723
-
724
- package tdx.volt_api.volt.v1;
725
-
726
- import "tdx/volt_api/volt/v1/status.proto";
727
-
728
- // The Spark API allows clients to start and communicate with Spark VMs.
729
- service SparkAPI {
730
- // Start or connect to a spark VM and establish a long-lived communication channel.
731
- rpc Spark(stream SparkRequest) returns (stream SparkResponse);
732
-
733
- // Get details of running spark VMs.
734
- rpc GetSpark(GetSparkRequest) returns (GetSparkResponse);
735
- }
736
-
737
- // Start a resource-hosted spark.
738
- // Provenance is determined from the resource owner.
739
- message StartSparkResource {
740
- // The id of the resource containing the VM byte code.
741
- string resource_id = 1;
742
-
743
- // JSON-encoded payload to parameterise the spark.
744
- string payload = 2;
745
-
746
- // Envelope signature.
747
- string signature = 3;
748
- }
749
-
750
- // Start a spark from byte code included in the payload, along with issuer/developer claims and signature.
751
- message StartSparkAdhoc {
752
- // Ad-hoc byte code of VM to run.
753
- bytes byte_code = 1;
754
-
755
- // Verifiable credentials associated with this spark.
756
- repeated string credential = 2;
757
-
758
- // Envelope signature.
759
- string signature = 3;
760
-
761
- // JSON-encoded payload to parameterise the spark.
762
- string payload = 4;
763
- }
764
-
765
- // Send commands and payloads to communicate with a running spark.
766
- message SparkCommand {
767
- // Optional id to associate with this command.
768
- // If this is omitted, an id will be assigned and returned in the command acknowledgement.
769
- string command_id = 1;
770
-
771
- // The command to send to the spark.
772
- string command = 2;
773
-
774
- // The command payload.
775
- string payload = 3;
776
-
777
- // Command verifiable credential.
778
- string credential = 4;
779
-
780
- // Command signature.
781
- string signature = 5;
782
- }
783
-
784
- // The request must contain one of the messages indicated below.
785
- message SparkRequest {
786
- oneof payload {
787
- StartSparkResource start_resource = 1;
788
- StartSparkAdhoc start_adhoc = 2;
789
- SparkCommand command = 3;
790
- }
791
- }
792
-
793
- // Receive events and payload from a running spark.
794
- message SparkData {
795
- // The command id to which this data corresponds.
796
- string command_id = 1;
797
-
798
- oneof payload {
799
- // Acknowledges receipt of a spark command.
800
- bool acknowledge = 2;
801
-
802
- // Indicates the command has completed.
803
- bool ended = 3;
804
-
805
- // Will contain error details on command failure.
806
- string error = 4;
807
-
808
- // Data emitted by a command, usually in stringified JSON format.
809
- string data = 5;
810
- }
811
- }
812
-
813
- // Details of a spark instance.
814
- message SparkInstance {
815
- // The UUID assigned to the spark instance.
816
- string spark_id = 1;
817
- }
818
-
819
- // The response will contain one of the messages indicated below.
820
- message SparkResponse {
821
- oneof payload {
822
- // Details of any error that occurred on the call.
823
- tdx.volt_api.volt.v1.Status status = 1;
824
-
825
- // Details of the spark instance, sent in response to a start command.
826
- SparkInstance spark_instance = 2;
827
-
828
- // Payload data emitted by the spark.
829
- SparkData spark_data = 3;
830
- }
831
- }
832
-
833
- message GetSparkRequest {
834
- string spark_id = 1;
835
- }
836
-
837
- // One of the following fields will be present in the response.
838
- message GetSparkResponse {
839
- // Details of any error that occurred on the call.
840
- tdx.volt_api.volt.v1.Status status = 1;
841
- }
842
-
843
721
  `;
844
722
  export const ssi = `syntax = "proto3";
845
723
 
@@ -915,12 +793,11 @@ export const ssi_api = `syntax = "proto3";
915
793
 
916
794
  package tdx.volt_api.volt.v1;
917
795
 
918
- import "tdx/volt_api/volt/v1/status.proto";
919
796
  import "tdx/volt_api/volt/v1/ssi.proto";
797
+ import "tdx/volt_api/volt/v1/status.proto";
920
798
 
921
799
  service SsiAPI {
922
- // Get a short-lived, one-time token that can be used to authenticate with the Volt and potentially create verifiable credential(s).
923
- rpc CreateExchangeToken(CreateExchangeTokenRequest) returns (CreateExchangeTokenResponse);
800
+ rpc CacheEmailCredential(CacheEmailCredentialRequest) returns (CacheEmailCredentialResponse);
924
801
 
925
802
  // Delete a DID document or all DID documents originating from a given Volt.
926
803
  // Requires \`volt:delete-did\` API privilege.
@@ -951,20 +828,25 @@ service SsiAPI {
951
828
  rpc SearchDIDRegistry(SearchDIDRegistryRequest) returns (SearchDIDRegistryResponse);
952
829
  }
953
830
 
954
- message CreateExchangeTokenRequest {
955
- // The VC template to use to create a verifiable credential.
956
- string vc_template = 1;
831
+ message CacheEmailCredentialRequest {
832
+ string identity_did = 1;
833
+
834
+ string email_address = 2;
835
+
836
+ string identity_provider = 3;
837
+
838
+ string key_passphrase = 4;
957
839
 
958
840
  // The time to live for the token, in seconds.
959
- uint32 ttl = 2;
841
+ uint32 ttl = 5;
960
842
  }
961
843
 
962
- message CreateExchangeTokenResponse {
844
+ message CacheEmailCredentialResponse {
963
845
  // Details of any error that occurred on the call.
964
846
  tdx.volt_api.volt.v1.Status status = 1;
965
847
 
966
- // The one-time token.
967
- string token = 2;
848
+ // The verifiable credential resource id.
849
+ string vc_id = 2;
968
850
  }
969
851
 
970
852
  message DeleteDIDRequest {
@@ -1181,6 +1063,7 @@ enum SyncState {
1181
1063
  SYNC_STATE_SYNCING = 1;
1182
1064
  SYNC_STATE_DONE = 2;
1183
1065
  SYNC_STATE_UPDATE = 3;
1066
+ SYNC_STATE_AWARENESS = 4;
1184
1067
  }
1185
1068
 
1186
1069
  message SyncDocumentStart {
@@ -1249,7 +1132,8 @@ message GetDocumentJSONResponse {
1249
1132
  // The current JSON snapshot of the document
1250
1133
  string json = 2;
1251
1134
  }
1252
- }`;
1135
+ }
1136
+ `;
1253
1137
  export const terminal_api = `syntax = "proto3";
1254
1138
 
1255
1139
  package tdx.volt_api.volt.v1;
@@ -2164,7 +2048,7 @@ message AuthenticateRequest {
2164
2048
  // A human-readable name of the entity requesting to authenticate.
2165
2049
  string client_name = 6;
2166
2050
 
2167
- // Optional challenge code, hashed using SHA-256 and base64 encoded.
2051
+ // Optional challenge code, hashed using SHA-256 and base64 URL encoded (no padding).
2168
2052
  string challenge = 7;
2169
2053
 
2170
2054
  // The host name to add as a SAN to the issued certificate.
@@ -2192,7 +2076,7 @@ message AuthenticateResponse {
2192
2076
  // This should be persisted by the client, and submitted with all subsequent API calls as part of the call metadata.
2193
2077
  string session_id = 2;
2194
2078
 
2195
- // The identity id assigned to this authentication.
2079
+ // 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
2080
  string identity_did = 3;
2197
2081
 
2198
2082
  // A certificate issued by the volt CA, binding the request public key to the identity.
@@ -2248,6 +2132,9 @@ message CanAccessResourceResponse {
2248
2132
 
2249
2133
  // The policy decision for this access request.
2250
2134
  PolicyDecision decision = 6;
2135
+
2136
+ // The session that the access relates to.
2137
+ string session_id = 7;
2251
2138
  }
2252
2139
 
2253
2140
  message CheckCompatibilityRequest {
@@ -2593,6 +2480,9 @@ message GetIdentityResponse {
2593
2480
  message GetOneTimeTokenRequest {
2594
2481
  // Optional token TTL, in seconds. Default is 10 seconds.
2595
2482
  int32 ttl = 1;
2483
+
2484
+ // Optional token context.
2485
+ string context = 2;
2596
2486
  }
2597
2487
 
2598
2488
  message GetOneTimeTokenResponse {
@@ -2655,6 +2545,9 @@ message GetResourceResponse {
2655
2545
  message GetResourcesRequest {
2656
2546
  repeated string id = 1;
2657
2547
 
2548
+ // Wildcards permitted.
2549
+ repeated string alias = 16;
2550
+
2658
2551
  // Wildcards permitted.
2659
2552
  repeated string name = 2;
2660
2553
 
@@ -3171,4 +3064,4 @@ message SubscribeWireResponse {
3171
3064
  }
3172
3065
 
3173
3066
  `;
3174
- export const voltProtos = [sqlite, sqlite_database_api, sqlite_server_api, proto_db_sync, proxy_api, relay_api, discovery_api, file, file_api, remote, spark_api, ssi, ssi_api, status, sync_api, terminal_api, volt, volt_api, wire_api];
3067
+ export const voltProtos = [sqlite, sqlite_database_api, sqlite_server_api, proto_db_sync, proxy_api, relay_api, discovery_api, file, file_api, remote, ssi, ssi_api, status, sync_api, terminal_api, volt, volt_api, wire_api];