@tdxvolt/volt-client-grpc 0.11.8 → 0.14.60

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
@@ -603,6 +603,7 @@ class VoltCredential {
603
603
  aud: audience,
604
604
  iat: Math.floor(Date.now() / 1000) - ttl,
605
605
  exp: Math.floor(Date.now() / 1000) + ttl,
606
+ sub: this._cryptoCache.client_id,
606
607
  };
607
608
 
608
609
  let sharedKey;
@@ -1082,50 +1083,55 @@ class GRPCCall extends EventEmitter__default["default"] {
1082
1083
  const log$2 = debug__default["default"]("volt-client-grpc:volt-connection");
1083
1084
 
1084
1085
  function _cleanUp(immediateReconnect) {
1085
- this._session = false;
1086
-
1087
- if (this._pingTimer) {
1088
- clearTimeout(this._pingTimer);
1089
- this._pingTimer = 0;
1090
- }
1091
-
1092
- if (this._pingTimeoutTimer) {
1093
- clearTimeout(this._pingTimeoutTimer);
1094
- this._pingTimeoutTimer = 0;
1095
- }
1096
-
1097
- if (
1098
- !this._dying &&
1099
- (immediateReconnect || (this._autoRetry && !this._reconnectTimer))
1100
- ) {
1101
- this._reconnectTimer = setTimeout(
1102
- () => {
1103
- this._reconnectTimer = 0;
1104
- _doConnect.call(this);
1105
- },
1106
- immediateReconnect ? 0 : this._reconnectInterval,
1107
- );
1108
- }
1109
-
1110
- if (this.call?.writable) {
1111
- this.call.end();
1112
- }
1086
+ this._connectionId = "";
1087
+
1088
+ if (this._pingTimer) {
1089
+ clearTimeout(this._pingTimer);
1090
+ this._pingTimer = 0;
1091
+ }
1092
+
1093
+ if (this._pingTimeoutTimer) {
1094
+ clearTimeout(this._pingTimeoutTimer);
1095
+ this._pingTimeoutTimer = 0;
1096
+ }
1097
+
1098
+ if (
1099
+ !this._dying &&
1100
+ (immediateReconnect || (this._autoRetry && !this._reconnectTimer))
1101
+ ) {
1102
+ this._reconnectTimer = setTimeout(
1103
+ () => {
1104
+ this._reconnectTimer = 0;
1105
+ _doConnect.call(this, this._helloPayload);
1106
+ },
1107
+ immediateReconnect ? 0 : this._reconnectInterval,
1108
+ );
1109
+ }
1110
+
1111
+ if (this.call?.writable) {
1112
+ this.call.end();
1113
+ }
1113
1114
  }
1114
1115
 
1115
1116
  function _connectionTimeoutHandler() {
1116
- log$2("server timed out");
1117
- this.emit("connected", false);
1118
- _cleanUp.call(this);
1117
+ log$2("server timed out");
1118
+ this.emit("connected", false);
1119
+ _cleanUp.call(this);
1119
1120
  }
1120
1121
 
1121
- function _doConnect() {
1122
- this.call = new GRPCCall(this._voltClient, "Connect", "METHOD_TYPE_BIDI");
1122
+ function _doConnect(connectHello) {
1123
+ this.call = new GRPCCall(this._voltClient, "Connect", "METHOD_TYPE_BIDI");
1124
+
1125
+ const grpcClient = this._voltClient.getVoltAPIClient();
1126
+
1127
+ let helloPayload = connectHello;
1128
+ if (!connectHello) {
1129
+ log$2("defaulting hello payload");
1130
+ helloPayload = {
1131
+ hello: {},
1132
+ };
1133
+ }
1123
1134
 
1124
- const grpcClient = this._voltClient.getVoltAPIClient();
1125
- const helloPayload = {
1126
- hello: {},
1127
- };
1128
-
1129
1135
  this.call.on("error", (err) => {
1130
1136
  log$2("error on connection stream [%s]", err.message);
1131
1137
  _cleanUp.call(this);
@@ -1146,10 +1152,11 @@ function _doConnect() {
1146
1152
  _startPingTimer.call(this);
1147
1153
  break;
1148
1154
  }
1149
- case "hello": {
1150
- if (!this._session) {
1151
- this._session = true;
1152
- this.emit("connected", this._session);
1155
+ case "acknowledge": {
1156
+ if (!this._connectionId) {
1157
+ this._connectionId = response.acknowledge.connection_id;
1158
+ log$2("connection id is %s", this._connectionId);
1159
+ this.emit("connected", this._connectionId);
1153
1160
  }
1154
1161
  break;
1155
1162
  }
@@ -1165,74 +1172,76 @@ function _doConnect() {
1165
1172
  });
1166
1173
 
1167
1174
  this.call.on("end", () => {
1168
- if (this._session) {
1175
+ if (this._connectionId) {
1169
1176
  this.emit("connected", false);
1170
1177
  }
1171
1178
  _cleanUp.call(this);
1172
1179
  });
1173
1180
 
1174
- this.call.start(grpcClient, helloPayload);
1181
+ this.call.start(grpcClient, helloPayload);
1175
1182
 
1176
- _startPingTimer.call(this);
1183
+ _startPingTimer.call(this);
1177
1184
  }
1178
1185
 
1179
1186
  function _startPingTimer() {
1180
- if (this._pingTimer) {
1181
- log$2("ping timer running");
1182
- return;
1183
- }
1184
-
1185
- this._pingTimer = setTimeout(() => {
1186
- // Send next ping to server.
1187
- const request = { ping: { timestamp: Date.now() } };
1188
-
1189
- log$2("pinging Volt");
1190
- this.call.write(request);
1191
-
1192
- this._pingTimer = 0;
1193
-
1194
- // Schedule a timeout if we don't hear back from the server.
1195
- if (this._pingTimeoutTimer) {
1196
- clearTimeout(this._pingTimeoutTimer);
1197
- }
1198
-
1199
- this._pingTimeoutTimer = setTimeout(
1200
- _connectionTimeoutHandler.bind(this),
1201
- this._timeoutInterval,
1202
- );
1203
- }, this._pingInterval);
1187
+ if (this._pingTimer) {
1188
+ log$2("ping timer running");
1189
+ return;
1190
+ }
1191
+
1192
+ this._pingTimer = setTimeout(() => {
1193
+ // Send next ping to server.
1194
+ const request = { ping: { timestamp: Date.now() } };
1195
+
1196
+ log$2("pinging Volt");
1197
+ this.call.write(request);
1198
+
1199
+ this._pingTimer = 0;
1200
+
1201
+ // Schedule a timeout if we don't hear back from the server.
1202
+ if (this._pingTimeoutTimer) {
1203
+ clearTimeout(this._pingTimeoutTimer);
1204
+ }
1205
+
1206
+ this._pingTimeoutTimer = setTimeout(
1207
+ _connectionTimeoutHandler.bind(this),
1208
+ this._timeoutInterval,
1209
+ );
1210
+ }, this._pingInterval);
1204
1211
  }
1205
1212
 
1206
1213
  class VoltConnection extends EventEmitter__default["default"] {
1207
- constructor(voltClient, grpc) {
1208
- super();
1209
-
1210
- const config = voltClient.config;
1211
- this._grpc = grpc;
1212
- this._autoRetry =
1213
- config.autoReconnect === undefined ? true : !!config.autoReconnect;
1214
- this._dying = false;
1215
- this._voltClient = voltClient;
1216
- this._pingTimer = 0;
1217
- this._pingTimeoutTimer = 0;
1218
- this._session = false;
1219
- this._pingInterval = config.pingInterval || 10000;
1220
- this._reconnectInterval = config.reconnectInterval || 5000;
1221
- this._timeoutInterval = config.timeoutInterval || 60000;
1222
- }
1223
-
1224
- connect(throwOnFail) {
1225
- if (throwOnFail) {
1226
- return _doConnect.call(this);
1227
- } else {
1228
- return Promise.resolve(_cleanUp.call(this, true));
1229
- }
1230
- }
1231
-
1232
- disconnect() {
1233
- this._dying = true;
1234
- _cleanUp.call(this);
1235
- }
1214
+ constructor(voltClient, grpc) {
1215
+ super();
1216
+
1217
+ const config = voltClient.config;
1218
+ this._grpc = grpc;
1219
+ this._autoRetry =
1220
+ config.autoReconnect === undefined ? true : !!config.autoReconnect;
1221
+ this._dying = false;
1222
+ this._voltClient = voltClient;
1223
+ this._pingTimer = 0;
1224
+ this._pingTimeoutTimer = 0;
1225
+ this._connectionId = "";
1226
+ this._pingInterval = config.pingInterval || 10000;
1227
+ this._reconnectInterval = config.reconnectInterval || 5000;
1228
+ this._timeoutInterval = config.timeoutInterval || 60000;
1229
+ this._helloPayload = undefined;
1230
+ }
1231
+
1232
+ connect(helloPayload, throwOnFail) {
1233
+ this._helloPayload = helloPayload;
1234
+ if (throwOnFail) {
1235
+ return _doConnect.call(this, this._helloPayload);
1236
+ } else {
1237
+ return Promise.resolve(_cleanUp.call(this, true));
1238
+ }
1239
+ }
1240
+
1241
+ disconnect() {
1242
+ this._dying = true;
1243
+ _cleanUp.call(this);
1244
+ }
1236
1245
  }
1237
1246
 
1238
1247
  /* eslint-disable no-underscore-dangle */
@@ -1268,10 +1277,10 @@ function issueBind(bindRequest, ttl) {
1268
1277
  // This is the certificate assigned to us by the volt.
1269
1278
  this._credential.cache.cert = bindResponse.cert;
1270
1279
 
1271
- // This is the signing CA used by the volt (don't ov)
1280
+ // This is the signing CA used by the volt.
1272
1281
  this._credential.cache.ca = bindResponse.chain;
1273
1282
 
1274
- // Resource id is assigned by the volt.
1283
+ // Identity resource id is assigned by the volt.
1275
1284
  this._credential.cache.client_id = bindResponse.identity_id;
1276
1285
  this._credential.saveCache();
1277
1286
  break;
@@ -1413,7 +1422,7 @@ async function bindInternal() {
1413
1422
  }
1414
1423
  }
1415
1424
 
1416
- function connectInternal() {
1425
+ function connectInternal(helloPayload) {
1417
1426
  try {
1418
1427
  if (this._voltConnection) {
1419
1428
  log$1("connectInternal - Volt connection already exists");
@@ -1443,7 +1452,7 @@ function connectInternal() {
1443
1452
  if (!this._connected) {
1444
1453
  onDisconnected();
1445
1454
  }
1446
- this.emit("connected", !!session);
1455
+ this.emit("connected", session);
1447
1456
  });
1448
1457
 
1449
1458
  this._voltConnection.on("error", (err) => {
@@ -1459,7 +1468,7 @@ function connectInternal() {
1459
1468
  this.emit("evt", evt);
1460
1469
  });
1461
1470
 
1462
- return this._voltConnection.connect();
1471
+ return this._voltConnection.connect(helloPayload);
1463
1472
  } catch (err) {
1464
1473
  log$1("connect - error [%s]", err.message);
1465
1474
  throw err;
@@ -1758,10 +1767,10 @@ class VoltClient extends EventEmitter__default["default"] {
1758
1767
  }
1759
1768
  }
1760
1769
 
1761
- initialiseAndConnect(configPath, extras = {}) {
1770
+ initialiseAndConnect(configPath, helloPayload = undefined, extras = {}) {
1762
1771
  return this.initialise(configPath, extras)
1763
1772
  .then(() => {
1764
- return connectInternal.call(this);
1773
+ return connectInternal.call(this, helloPayload);
1765
1774
  })
1766
1775
  .catch((err) => {
1767
1776
  log("initialiseAndConnect failure: %s", err.message);
@@ -1834,8 +1843,8 @@ class VoltClient extends EventEmitter__default["default"] {
1834
1843
  return this.isRemote && !this._voltConfig?.relay.cloud;
1835
1844
  }
1836
1845
 
1837
- connect() {
1838
- return connectInternal.call(this);
1846
+ connect(helloPayload) {
1847
+ return connectInternal.call(this, helloPayload);
1839
1848
  }
1840
1849
 
1841
1850
  disconnect() {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.11.8",
6
+ "version": "0.14.60",
7
7
  "description": "tdx Volt library for nodejs clients",
8
8
  "type": "module",
9
9
  "exports": {
@@ -16,6 +16,9 @@ service SqliteDatabaseAPI {
16
16
  rpc Execute(stream SqlExecuteRequest) returns (stream SqlExecuteResponse);
17
17
 
18
18
  // Import CSV data into a table.
19
+ // The import handler will inspect the incoming CSV data, infer the columns and data types required, and create and populate the SQL table.
20
+ // The CSV must contain a header row containing the column names and at least one row of data so that the types can be inferred.
21
+ // The importer assumes all data in any given CSV file relates to a single table.
19
22
  // The data can either be streamed in chunks or retrieved from an existing resource.
20
23
  // If the data is streamed in chunks, the client must call the Close() method on the stream to indicate that it has finished.
21
24
  rpc ImportCSV(stream SqlImportCSVRequest) returns (stream SqlImportCSVResponse);
@@ -51,7 +54,7 @@ message SqlExecuteRequest {
51
54
  // This field is only relevant to 'query' databases, i.e. those with kind `tdx:sqlite-query`.
52
55
  // The values in the list should be in the same order as the parameters defined by the query attributes.
53
56
  // A query may have no parameters defined, in which case leave this field empty.
54
- repeated tdx.volt_api.volt.v1.AttributeValue parameter = 4;
57
+ map<string, tdx.volt_api.volt.v1.AttributeValue> parameter = 4;
55
58
  }
56
59
 
57
60
  // One of the following fields will be present in any given message.
@@ -88,6 +91,7 @@ message SqlImportCSVConfiguration {
88
91
  uint32 progress_interval = 5;
89
92
  }
90
93
 
94
+ // Each message must contain one and only one of the following fields.
91
95
  message SqlImportCSVRequest {
92
96
  oneof payload {
93
97
  // The initial request must contain the configuration parameters for the import.
@@ -7,7 +7,7 @@ import "tdx/volt_api/volt/v1/remote.proto";
7
7
  import "tdx/volt_api/volt/v1/volt.proto";
8
8
 
9
9
  service RelayAPI {
10
- // Retrieve the list of Volts available on the Relay Volt or cloud-based tunnel.
10
+ // Retrieve the list of Volts available on the Relay Volt.
11
11
  rpc GetVoltEndpoint(GetVoltEndpointRequest) returns (GetVoltEndpointResponse);
12
12
 
13
13
  // This is the actual tunnel stream.
@@ -8,7 +8,7 @@ import "tdx/volt_api/volt/v1/file.proto";
8
8
  // The File API exposes basic file management functions.
9
9
  service FileAPI {
10
10
 
11
- // Download from file resource.
11
+ // A server-stream to download contents from a file resource.
12
12
  rpc DownloadFile(DownloadFileRequest) returns (stream DownloadFileResponse);
13
13
 
14
14
  // Get file resource metadata.
@@ -48,7 +48,6 @@ message MethodInvoke {
48
48
  string service_id = 2;
49
49
  string method_name = 3;
50
50
  MethodType method_type = 4;
51
- string token = 5;
52
51
  oneof invoke_request {
53
52
  bytes request = 6;
54
53
  string json_request = 7;
@@ -53,8 +53,7 @@ enum ShareMode {
53
53
 
54
54
  // Represents an outbound connection from a Volt to a remote service that will act as a proxy for that Volt.
55
55
  // This enables Volts to bypass firewall and NATs.
56
- // Example 1 - connection from a Volt to the cloud-based Volt tunnel at cloud.tdxvolt.com
57
- // Example 2 - connection from a Volt to Relay Volt running on the public internet, such as tdxvolt.com
56
+ // Example - connection from a Volt to a Relay Volt running on the public internet, such as tdxvolt.com
58
57
  message ProxyConnection {
59
58
  // Unique connection id.
60
59
  string id = 1;
@@ -74,9 +73,6 @@ message ProxyConnection {
74
73
  // Indicates this connection is currently in use.
75
74
  bool connected = 6;
76
75
 
77
- // Indicates this is a connection to a cloud-based tunnel, rather than to a Relay Volt.
78
- bool is_cloud_connection = 7;
79
-
80
76
  // Indicates that this connection will handle HTTP proxying as well as GRPC.
81
77
  bool enable_http_proxy = 8;
82
78
 
@@ -196,12 +192,15 @@ message VoltParameters {
196
192
  // The certificate authority of the Relay if this is a remote connection via a Relay.
197
193
  string relay_ca_pem = 33;
198
194
 
199
- // Set to indicate this is a remote connection to a Volt via a cloud tunnel.
200
- bool is_cloud_relay = 34;
201
-
202
195
  // An optional alias that can be used to refer to the Volt rather than the `id` field.
203
196
  // This alias must be unique within the scope of the Battery in which the Volt is stored.
204
197
  string alias = 35;
198
+
199
+ // The runtime version this Volt is running.
200
+ Version version = 36;
201
+
202
+ // If set, indicates that any client that provides the correct challenge in the bind phase will automatically be approved to access the Volt.
203
+ bool approve_on_challenge = 37;
205
204
  }
206
205
 
207
206
  message VoltEndpoint {
@@ -260,28 +259,54 @@ message ProtoFile {
260
259
  repeated string service_name = 3;
261
260
  }
262
261
 
262
+ enum ServiceHostType {
263
+ SERVICE_HOST_TYPE_UNKNOWN = 0;
264
+ SERVICE_HOST_TYPE_BUILTIN = 1;
265
+ SERVICE_HOST_TYPE_SERVER = 2;
266
+ SERVICE_HOST_TYPE_RELAYED = 3;
267
+ }
268
+
263
269
  // Describes a Volt service.
264
270
  message ServiceDescription {
271
+ ServiceHostType host_type = 1;
272
+
265
273
  // The id of the server resource that is hosting this service.
266
- string server_id = 1;
274
+ // For built-in services, i.e. those hosted by the Volt, this will set to the Volt id.
275
+ string host_service_id = 2;
276
+
277
+ // The identity of the client that is exposing the service via a relay connection.
278
+ // This will be empty if the service is exposed via a grpc server.
279
+ string host_client_id = 3;
267
280
 
268
281
  // The address of the grpc server hosting this service.
269
- string address = 2;
282
+ // This will be empty if the service is hosted by a relay client (see `relay_public_key` below).
283
+ string host_address = 4;
284
+
285
+ // The certificate authority (chain) that signed the service server certificate.
286
+ // This is only relevant to grpc-hosted services.
287
+ string host_ca_pem = 5;
288
+
289
+ // The public key of the service host, which is used to encrypt payloads.
290
+ // This may change as the service comes and goes online.
291
+ string host_public_key = 6;
292
+
293
+ // The fingerprint derived from `host_public_key`, included for convenience.
294
+ string host_fingerprint = 7;
295
+
296
+ // The connection id currently used to host this service.
297
+ string host_connection_id = 8;
270
298
 
271
299
  // The discovery mode.
272
- DiscoveryMode discoverable = 4;
300
+ DiscoveryMode discoverable = 10;
273
301
 
274
302
  // The ping timestamp of the server hosting this service.
275
- int64 ping_timestamp = 5;
303
+ int64 ping_timestamp = 11;
276
304
 
277
305
  // The protobuf definitions of the APIs exposed by this service.
278
- repeated ProtoFile proto_file = 6;
306
+ repeated ProtoFile proto_file = 12;
279
307
 
280
308
  // The fully qualified names of the protobuf services, for example tdx.volt_api.webcam.v1.WebcamControlAPI.
281
- repeated string service_api = 7;
282
-
283
- // The certificate authority (chain) that signed the service server certificate.
284
- string ca_pem = 8;
309
+ repeated string service_api = 13;
285
310
 
286
311
  // Internal use only.
287
312
  repeated MethodDescription method = 100;
@@ -376,7 +401,7 @@ message Resource {
376
401
  repeated string kind = 110;
377
402
 
378
403
  // The online status.
379
- // For most kinds of resource this indicates that the server hosting the resource is online, the exception being identity resources, in which case the status reflects whether or not the identity has a live session.
404
+ // For most kinds of resource this indicates that the server hosting the resource is online, the exception being identity resources, in which case the status reflects whether or not the identity has a live connection.
380
405
  // All built-in resources are hosted by the Volt itself and are therefore always online when the Volt is running.
381
406
  // Resources hosted by external servers are online if the server itself is online and has registered the resource as online using `setServiceStatus`.
382
407
  OnlineStatus online_status = 111;
@@ -403,28 +428,6 @@ enum IdentityType {
403
428
  IDENTITY_TYPE_GROUP = 3;
404
429
  }
405
430
 
406
- enum IdentityAliasType {
407
- IDENTITY_ALIAS_TYPE_UNKNOWN = 0;
408
- IDENTITY_ALIAS_TYPE_PUBLIC_KEY = 1;
409
- IDENTITY_ALIAS_TYPE_COMMON_NAME = 2;
410
- }
411
-
412
- enum IdentityAliasSubType {
413
- IDENTITY_ALIAS_SUB_TYPE_UNKNOWN = 0;
414
-
415
- // Identifies email common name aliases.
416
- IDENTITY_ALIAS_SUB_TYPE_EMAIL = 1;
417
-
418
- // Identifies phone number common name aliases.
419
- IDENTITY_ALIAS_SUB_TYPE_PHONE = 2;
420
-
421
- // Identifies DNS common name aliases.
422
- IDENTITY_ALIAS_SUB_TYPE_DNS = 3;
423
-
424
- // Identifies public key aliases that originate from owner credentials rather than the identity itself.
425
- IDENTITY_ALIAS_SUB_TYPE_OWNER = 4;
426
- }
427
-
428
431
  message IdentityAlias {
429
432
  // The corresponding identity id.
430
433
  string identity_id = 1;
@@ -432,15 +435,15 @@ message IdentityAlias {
432
435
  // The actual alias, e.g. a common name or key fingerprint.
433
436
  string alias = 2;
434
437
 
435
- // This will only be populated if alias_type == PUBLIC_KEY
438
+ // This will only be populated if alias_type == tdx:public-key
436
439
  string public_key = 3;
437
440
 
438
- // This will only be populated if alias_type == PUBLIC_KEY
441
+ // This will only be populated if alias_type == tdx:public-key
439
442
  string private_key = 4;
440
443
 
441
- IdentityAliasType alias_type = 5;
444
+ string alias_type = 5;
442
445
 
443
- IdentityAliasSubType alias_sub_type = 6;
446
+ string issuer_id = 6;
444
447
 
445
448
  // Indicates if this alias has an 'authenticate' policy decision assigned.
446
449
  PolicyDecision authenticate = 7;
@@ -561,6 +564,29 @@ message Access {
561
564
  uint32 request_count = 17;
562
565
  }
563
566
 
567
+ enum SessionStatus {
568
+ SESSION_STATUS_UNKNOWN = 0;
569
+ SESSION_STATUS_PENDING = 1;
570
+ SESSION_STATUS_ESTABLISHED = 2;
571
+ SESSION_STATUS_REJECTED = 3;
572
+ }
573
+
574
+ message Session {
575
+ string id = 1;
576
+
577
+ string identity_id = 2;
578
+
579
+ string identity_name = 3;
580
+
581
+ string ip = 4;
582
+
583
+ uint64 created = 5;
584
+
585
+ uint64 modified = 6;
586
+
587
+ SessionStatus status = 7;
588
+ }
589
+
564
590
  message VerifiableCredential {
565
591
  string encoded = 1;
566
592
  }