@tdxvolt/volt-client-grpc 0.20.32 → 0.20.34

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
@@ -1043,9 +1043,12 @@ import "tdx/volt_api/volt/v1/volt.proto";
1043
1043
 
1044
1044
  // The Drive API allows clients to create and manage Volt Drive resources.
1045
1045
  service DriveAPI {
1046
- // Create or update a drive connection resource.
1047
- // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
1048
- rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
1046
+ // Create or update a drive connection resource.
1047
+ // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
1048
+ rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
1049
+
1050
+ // Stream the FolderSync status of the drive instances on this Volt that host \`synapse_id\`. Busy means the local ingest/materialise queue is working. If there is no instance on this Volt, the stream reports absent.
1051
+ rpc WatchDriveInstanceStatus(stream WatchDriveInstanceStatusRequest) returns (stream WatchDriveInstanceStatusResponse);
1049
1052
  }
1050
1053
 
1051
1054
  message SaveDriveInstanceRequest {
@@ -1106,6 +1109,47 @@ message SaveDriveInstanceResponse {
1106
1109
  Resource resource = 2;
1107
1110
  }
1108
1111
 
1112
+ enum DriveInstanceState {
1113
+ // No drive instance for this synapse is running on this Volt, so this Volt has nothing to say about its sync progress.
1114
+ DRIVE_INSTANCE_STATE_ABSENT = 0;
1115
+
1116
+ // An instance is running with nothing queued.
1117
+ DRIVE_INSTANCE_STATE_IDLE = 1;
1118
+
1119
+ // Files are queued, in flight, or the initial scan is running.
1120
+ DRIVE_INSTANCE_STATE_BUSY = 2;
1121
+ }
1122
+
1123
+ // FolderSync work on this Volt for a drive synapse.
1124
+ message DriveInstanceStatus {
1125
+ DriveInstanceState state = 1;
1126
+
1127
+ // Distinct files admitted to the operation currently underway, summed over every instance on this Volt that hosts the synapse. Grows as more work is discovered and never shrinks mid-operation. Zero once the drive settles.
1128
+ uint32 total_count = 2;
1129
+
1130
+ // How many of \`total_count\` have reached a terminal state.
1131
+ uint32 completed_count = 3;
1132
+ }
1133
+
1134
+ message WatchDriveInstanceStatusStart {
1135
+ // The id of the drive synapse (drive database) to watch.
1136
+ string synapse_id = 1;
1137
+ }
1138
+
1139
+ message WatchDriveInstanceStatusRequest {
1140
+ oneof payload {
1141
+ WatchDriveInstanceStatusStart start = 1;
1142
+ bool stop = 2;
1143
+ }
1144
+ }
1145
+
1146
+ message WatchDriveInstanceStatusResponse {
1147
+ oneof result {
1148
+ tdx.volt_api.volt.v1.Status status = 1;
1149
+ DriveInstanceStatus update = 2;
1150
+ }
1151
+ }
1152
+
1109
1153
  `;
1110
1154
  const file = `syntax = "proto3";
1111
1155
 
@@ -3282,6 +3326,14 @@ service VoltAPI {
3282
3326
  // This is a privileged API call and requires volt:api-call / volt:save-http-file-server permission.
3283
3327
  rpc SaveHttpFileServer(SaveHttpFileServerRequest) returns (SaveHttpFileServerResponse);
3284
3328
 
3329
+ // Publish a local filesystem folder over HTTP, optionally via a connected relay.
3330
+ // This is a privileged API call and requires volt:api-call / volt:publish-folder permission. Updating an existing publication additionally requires volt:resource-write on the published-folder resource.
3331
+ // On failure any resource this call created is removed, so a publication is never left half-built. Updates to an existing publication are idempotent: retry the same request to recover from a partial failure.
3332
+ rpc PublishFolder(PublishFolderRequest) returns (PublishFolderResponse);
3333
+
3334
+ // Remove a folder published by PublishFolder. Remote forwarder and OIDC resources are deleted first; the local file-server record is kept if remote cleanup fails so the operation can be retried. DeleteResource on a volt:published-folder resource performs the same remote cleanup.
3335
+ rpc UnpublishFolder(UnpublishFolderRequest) returns (UnpublishFolderResponse);
3336
+
3285
3337
  // Create or update an HTTP forwarder resource.
3286
3338
  // This is a privileged API call and requires volt:api-call / volt:save-http-forwarder permission.
3287
3339
  rpc SaveHttpForwarder(SaveHttpForwarderRequest) returns (SaveHttpForwarderResponse);
@@ -4286,7 +4338,7 @@ message SaveHttpForwarderRequest {
4286
4338
  // Set to indicate the resource attributes should be purged before saving the resource.
4287
4339
  bool purge_attributes = 4;
4288
4340
 
4289
- // The domain to forward requests to.
4341
+ // FQDN of the public Host this forwarder matches (e.g. wiki.tdxid.com). Do not include a scheme or port. Must not be this Volt's own hostname (use \`path\` for own-host forwarding). Optional when \`path\` is set.
4290
4342
  string domain = 5;
4291
4343
 
4292
4344
  // The host to forward requests to.
@@ -4298,7 +4350,7 @@ message SaveHttpForwarderRequest {
4298
4350
  // Set to indicate that the host header should reflect the proxy domain rather than the target host.
4299
4351
  bool forward_host = 8;
4300
4352
 
4301
- // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (sub-domain + path, e.g. sub.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
4353
+ // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (host + path, e.g. app.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
4302
4354
  string path = 9;
4303
4355
 
4304
4356
  // When a \`path\` prefix is configured, keep that prefix on the request path when forwarding. The default (false) is standard reverse-proxy behaviour: the prefix is stripped so the target receives the request at its own root (e.g. "/drive/assets/x.js" -> "/assets/x.js"), which suits plain static file servers and root-mounted backends. Set to true for targets that are themselves configured under the same sub-path and expect to receive the prefix. The \`X-Forwarded-Prefix\` header is always sent.
@@ -4307,7 +4359,7 @@ message SaveHttpForwarderRequest {
4307
4359
  // When true, incoming HTTP requests to this forwarder must carry a valid authenticated session (established via the OIDC sign-in flow) and pass the policy check before being proxied, except for the public-path and manifest exceptions on \`auth_public_paths\`. Unauthenticated top-level document navigations are redirected to the configured OpenID Provider; other unauthenticated requests receive 401. An authenticated session that fails the policy check receives 403. The Volt session cookie is stripped from the HTTP hop to the target. WebSocket and SSE upgrades are not gated.
4308
4360
  bool auth_enabled = 11;
4309
4361
 
4310
- // OpenID Provider issuer URL used for discovery (\`<issuer>/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
4362
+ // OpenID Provider issuer URL used for discovery (\`[issuer]/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
4311
4363
  string oidc_issuer = 12;
4312
4364
 
4313
4365
  // OAuth 2.0 client identifier registered with the OpenID Provider.
@@ -4327,6 +4379,10 @@ message SaveHttpForwarderRequest {
4327
4379
 
4328
4380
  // Effective-path patterns that may be fetched without a session (GET/HEAD). A trailing \`/*\` matches descendants on segment boundaries (e.g. \`/icon/*\`). Used for PWA icons and similar public chrome; the manifest itself is allowed via \`Sec-Fetch-Dest: manifest\` and does not need to be listed.
4329
4381
  repeated string auth_public_paths = 18;
4382
+
4383
+ // The identity whose Volt hosts the target \`host\`/\`port\`, i.e. where requests matching this forwarder are tunnelled to. This allows a forwarder to be created on a public Volt (for a named host) while the target server runs on a different Volt that is relay-connected to it. When omitted, the creating identity is used.
4384
+ // The caller must be entitled to target the identity: it must either be the caller's own identity, the Volt handling this request, or an identity that has granted the caller \`volt:resource-write\`.
4385
+ string target_identity = 19;
4330
4386
  }
4331
4387
 
4332
4388
  message SaveHttpForwarderResponse {
@@ -4419,6 +4475,60 @@ message SaveHttpFileServerResponse {
4419
4475
  Resource resource = 2;
4420
4476
  }
4421
4477
 
4478
+ message PublishFolderRequest {
4479
+ // Optional name, extra user kinds, and attributes copied onto the local static file server (for example drive:publication-drive).
4480
+ // If \`id\` is set, this call updates the existing published-folder resource with that id; otherwise it creates a new published-folder resource. Updating keeps the loopback port the file server already listens on, and rotates the OIDC client id and secret when \`auth_enabled\` is set, which ends any sign-in sessions established against the previous pair.
4481
+ Resource resource = 1;
4482
+
4483
+ // Local filesystem path to publish. \`~\` is expanded. Must exist and be a directory.
4484
+ string path = 2;
4485
+
4486
+ // FQDN of the public Host to publish on (e.g. wiki.tdxid.com). This is also the HTTP forwarder's \`domain\`. Do not include a scheme or port. Must not be the publish Volt's own hostname. May be changed when updating, in which case the previous address is released.
4487
+ string domain = 3;
4488
+
4489
+ // DID of the relay Volt that owns the public domain. When omitted, the single connected \`volt:volt-link\` with \`volt:relay-exposed\` is used. If several such relays are connected, this field is required. If none are connected, the path is published on this Volt when HTTP forwarding is enabled.
4490
+ string relay_id = 4;
4491
+
4492
+ // When true, visitors must sign in via OIDC on the publish Volt and match an invitee access rule.
4493
+ bool auth_enabled = 5;
4494
+
4495
+ // Emails, email wildcards (e.g. "*@example.com"), or DIDs permitted through the published host when \`auth_enabled\` is set. At least one is required in that case.
4496
+ repeated string invitee = 6;
4497
+
4498
+ // When true, missing paths are rewritten to \`catch_all\` (SPA-style fallback). An empty \`catch_all\` responds with 404.
4499
+ bool catch_all_enabled = 7;
4500
+
4501
+ // Catch-all path, e.g. \`/index.html\` or \`/\`. Used when \`catch_all_enabled\` is set.
4502
+ string catch_all = 8;
4503
+ }
4504
+
4505
+ message PublishFolderResponse {
4506
+ // Details of any error that occurred on the call.
4507
+ tdx.volt_api.volt.v1.Status status = 1;
4508
+
4509
+ // The local static file server that represents the publication.
4510
+ Resource resource = 2;
4511
+
4512
+ // Public URL of the published folder.
4513
+ string url = 3;
4514
+
4515
+ // Resource id of the HTTP forwarder on the publish Volt.
4516
+ string forwarder_id = 4;
4517
+
4518
+ // Resource id of the OIDC client, when access is restricted.
4519
+ string oidc_client_id = 5;
4520
+ }
4521
+
4522
+ message UnpublishFolderRequest {
4523
+ // Resource id of the local file server created by PublishFolder. The resource must have kind \`volt:published-folder\`.
4524
+ string resource_id = 1;
4525
+ }
4526
+
4527
+ message UnpublishFolderResponse {
4528
+ // Details of any error that occurred on the call.
4529
+ tdx.volt_api.volt.v1.Status status = 1;
4530
+ }
4531
+
4422
4532
  message SaveHttpRestApiServerRequest {
4423
4533
  // Details of the resource to save.
4424
4534
  Resource resource = 1;
@@ -6895,6 +7005,10 @@ class VoltClient extends EventEmitter__default["default"] {
6895
7005
  return unaryCallInternal.call(this, "GetSessions", request);
6896
7006
  }
6897
7007
 
7008
+ PublishFolder(request) {
7009
+ return unaryCallInternal.call(this, "PublishFolder", request);
7010
+ }
7011
+
6898
7012
  SaveAccess(request) {
6899
7013
  return unaryCallInternal.call(this, "SaveAccess", request);
6900
7014
  }
@@ -6931,6 +7045,10 @@ class VoltClient extends EventEmitter__default["default"] {
6931
7045
  return unaryCallInternal.call(this, "SignVerify", request);
6932
7046
  }
6933
7047
 
7048
+ UnpublishFolder(request) {
7049
+ return unaryCallInternal.call(this, "UnpublishFolder", request);
7050
+ }
7051
+
6934
7052
  /**
6935
7053
  * VoltAPI - streaming (bidi). Use connect() for Connect stream.
6936
7054
  * Invoke is for relay proxying; returns a duplex stream of InvokeRequest/InvokeResponse.
@@ -7170,6 +7288,16 @@ class VoltClient extends EventEmitter__default["default"] {
7170
7288
  return unaryCallInternal.call(this, "SaveDriveInstance", request);
7171
7289
  }
7172
7290
 
7291
+ WatchDriveInstanceStatus(request) {
7292
+ const grpcClient = this.getVoltAPIClient();
7293
+ const watchDriveInstanceStatusCall = new GRPCCall(
7294
+ this,
7295
+ "WatchDriveInstanceStatus",
7296
+ "METHOD_TYPE_BIDI"
7297
+ );
7298
+ return watchDriveInstanceStatusCall.start(grpcClient, request);
7299
+ }
7300
+
7173
7301
  /**
7174
7302
  * SyncAPI
7175
7303
  */
@@ -7177,6 +7305,10 @@ class VoltClient extends EventEmitter__default["default"] {
7177
7305
  return unaryCallInternal.call(this, "CreateSynapseConnection", request);
7178
7306
  }
7179
7307
 
7308
+ CreateSyncDocumentVersion(request) {
7309
+ return unaryCallInternal.call(this, "CreateSyncDocumentVersion", request);
7310
+ }
7311
+
7180
7312
  DeleteSynapseConnection(request) {
7181
7313
  return unaryCallInternal.call(this, "DeleteSynapseConnection", request);
7182
7314
  }
@@ -7193,6 +7325,18 @@ class VoltClient extends EventEmitter__default["default"] {
7193
7325
  return unaryCallInternal.call(this, "GetSynapseDocumentState", request);
7194
7326
  }
7195
7327
 
7328
+ GetSyncDocumentVersion(request) {
7329
+ return unaryCallInternal.call(this, "GetSyncDocumentVersion", request);
7330
+ }
7331
+
7332
+ ListSyncDocumentVersions(request) {
7333
+ return unaryCallInternal.call(this, "ListSyncDocumentVersions", request);
7334
+ }
7335
+
7336
+ RevertSyncDocumentVersion(request) {
7337
+ return unaryCallInternal.call(this, "RevertSyncDocumentVersion", request);
7338
+ }
7339
+
7196
7340
  SaveSynapse(request) {
7197
7341
  return unaryCallInternal.call(this, "SaveSynapse", request);
7198
7342
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.20.32",
6
+ "version": "0.20.34",
7
7
  "description": "tdx Volt library for nodejs clients",
8
8
  "type": "module",
9
9
  "exports": {
@@ -33,8 +33,8 @@
33
33
  "author": "toby.ealden@gmail.com",
34
34
  "license": "ISC",
35
35
  "dependencies": {
36
- "@tdxvolt/volt-client-web": "^0.20.32",
37
- "@tdxvolt/volt-utility": "^0.20.32",
36
+ "@tdxvolt/volt-client-web": "^0.20.34",
37
+ "@tdxvolt/volt-utility": "^0.20.34",
38
38
  "debug": "^4.1.1",
39
39
  "ip": "^1.1.5",
40
40
  "jsonwebtoken": "^8.5.1",
@@ -455,6 +455,10 @@ export class VoltClient extends EventEmitter {
455
455
  return unaryCallInternal.call(this, "GetSessions", request);
456
456
  }
457
457
 
458
+ PublishFolder(request) {
459
+ return unaryCallInternal.call(this, "PublishFolder", request);
460
+ }
461
+
458
462
  SaveAccess(request) {
459
463
  return unaryCallInternal.call(this, "SaveAccess", request);
460
464
  }
@@ -491,6 +495,10 @@ export class VoltClient extends EventEmitter {
491
495
  return unaryCallInternal.call(this, "SignVerify", request);
492
496
  }
493
497
 
498
+ UnpublishFolder(request) {
499
+ return unaryCallInternal.call(this, "UnpublishFolder", request);
500
+ }
501
+
494
502
  /**
495
503
  * VoltAPI - streaming (bidi). Use connect() for Connect stream.
496
504
  * Invoke is for relay proxying; returns a duplex stream of InvokeRequest/InvokeResponse.
@@ -732,6 +740,16 @@ export class VoltClient extends EventEmitter {
732
740
  return unaryCallInternal.call(this, "SaveDriveInstance", request);
733
741
  }
734
742
 
743
+ WatchDriveInstanceStatus(request) {
744
+ const grpcClient = this.getVoltAPIClient();
745
+ const watchDriveInstanceStatusCall = new GRPCCall(
746
+ this,
747
+ "WatchDriveInstanceStatus",
748
+ "METHOD_TYPE_BIDI"
749
+ );
750
+ return watchDriveInstanceStatusCall.start(grpcClient, request);
751
+ }
752
+
735
753
  /**
736
754
  * SyncAPI
737
755
  */
@@ -739,6 +757,10 @@ export class VoltClient extends EventEmitter {
739
757
  return unaryCallInternal.call(this, "CreateSynapseConnection", request);
740
758
  }
741
759
 
760
+ CreateSyncDocumentVersion(request) {
761
+ return unaryCallInternal.call(this, "CreateSyncDocumentVersion", request);
762
+ }
763
+
742
764
  DeleteSynapseConnection(request) {
743
765
  return unaryCallInternal.call(this, "DeleteSynapseConnection", request);
744
766
  }
@@ -755,6 +777,18 @@ export class VoltClient extends EventEmitter {
755
777
  return unaryCallInternal.call(this, "GetSynapseDocumentState", request);
756
778
  }
757
779
 
780
+ GetSyncDocumentVersion(request) {
781
+ return unaryCallInternal.call(this, "GetSyncDocumentVersion", request);
782
+ }
783
+
784
+ ListSyncDocumentVersions(request) {
785
+ return unaryCallInternal.call(this, "ListSyncDocumentVersions", request);
786
+ }
787
+
788
+ RevertSyncDocumentVersion(request) {
789
+ return unaryCallInternal.call(this, "RevertSyncDocumentVersion", request);
790
+ }
791
+
758
792
  SaveSynapse(request) {
759
793
  return unaryCallInternal.call(this, "SaveSynapse", request);
760
794
  }
@@ -495,9 +495,12 @@ import "tdx/volt_api/volt/v1/volt.proto";
495
495
 
496
496
  // The Drive API allows clients to create and manage Volt Drive resources.
497
497
  service DriveAPI {
498
- // Create or update a drive connection resource.
499
- // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
500
- rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
498
+ // Create or update a drive connection resource.
499
+ // This is a privileged API call and requires volt:api-call / volt:save-drive-instance permission.
500
+ rpc SaveDriveInstance(SaveDriveInstanceRequest) returns (SaveDriveInstanceResponse);
501
+
502
+ // Stream the FolderSync status of the drive instances on this Volt that host \`synapse_id\`. Busy means the local ingest/materialise queue is working. If there is no instance on this Volt, the stream reports absent.
503
+ rpc WatchDriveInstanceStatus(stream WatchDriveInstanceStatusRequest) returns (stream WatchDriveInstanceStatusResponse);
501
504
  }
502
505
 
503
506
  message SaveDriveInstanceRequest {
@@ -558,6 +561,47 @@ message SaveDriveInstanceResponse {
558
561
  Resource resource = 2;
559
562
  }
560
563
 
564
+ enum DriveInstanceState {
565
+ // No drive instance for this synapse is running on this Volt, so this Volt has nothing to say about its sync progress.
566
+ DRIVE_INSTANCE_STATE_ABSENT = 0;
567
+
568
+ // An instance is running with nothing queued.
569
+ DRIVE_INSTANCE_STATE_IDLE = 1;
570
+
571
+ // Files are queued, in flight, or the initial scan is running.
572
+ DRIVE_INSTANCE_STATE_BUSY = 2;
573
+ }
574
+
575
+ // FolderSync work on this Volt for a drive synapse.
576
+ message DriveInstanceStatus {
577
+ DriveInstanceState state = 1;
578
+
579
+ // Distinct files admitted to the operation currently underway, summed over every instance on this Volt that hosts the synapse. Grows as more work is discovered and never shrinks mid-operation. Zero once the drive settles.
580
+ uint32 total_count = 2;
581
+
582
+ // How many of \`total_count\` have reached a terminal state.
583
+ uint32 completed_count = 3;
584
+ }
585
+
586
+ message WatchDriveInstanceStatusStart {
587
+ // The id of the drive synapse (drive database) to watch.
588
+ string synapse_id = 1;
589
+ }
590
+
591
+ message WatchDriveInstanceStatusRequest {
592
+ oneof payload {
593
+ WatchDriveInstanceStatusStart start = 1;
594
+ bool stop = 2;
595
+ }
596
+ }
597
+
598
+ message WatchDriveInstanceStatusResponse {
599
+ oneof result {
600
+ tdx.volt_api.volt.v1.Status status = 1;
601
+ DriveInstanceStatus update = 2;
602
+ }
603
+ }
604
+
561
605
  `;
562
606
  export const file = `syntax = "proto3";
563
607
 
@@ -2734,6 +2778,14 @@ service VoltAPI {
2734
2778
  // This is a privileged API call and requires volt:api-call / volt:save-http-file-server permission.
2735
2779
  rpc SaveHttpFileServer(SaveHttpFileServerRequest) returns (SaveHttpFileServerResponse);
2736
2780
 
2781
+ // Publish a local filesystem folder over HTTP, optionally via a connected relay.
2782
+ // This is a privileged API call and requires volt:api-call / volt:publish-folder permission. Updating an existing publication additionally requires volt:resource-write on the published-folder resource.
2783
+ // On failure any resource this call created is removed, so a publication is never left half-built. Updates to an existing publication are idempotent: retry the same request to recover from a partial failure.
2784
+ rpc PublishFolder(PublishFolderRequest) returns (PublishFolderResponse);
2785
+
2786
+ // Remove a folder published by PublishFolder. Remote forwarder and OIDC resources are deleted first; the local file-server record is kept if remote cleanup fails so the operation can be retried. DeleteResource on a volt:published-folder resource performs the same remote cleanup.
2787
+ rpc UnpublishFolder(UnpublishFolderRequest) returns (UnpublishFolderResponse);
2788
+
2737
2789
  // Create or update an HTTP forwarder resource.
2738
2790
  // This is a privileged API call and requires volt:api-call / volt:save-http-forwarder permission.
2739
2791
  rpc SaveHttpForwarder(SaveHttpForwarderRequest) returns (SaveHttpForwarderResponse);
@@ -3738,7 +3790,7 @@ message SaveHttpForwarderRequest {
3738
3790
  // Set to indicate the resource attributes should be purged before saving the resource.
3739
3791
  bool purge_attributes = 4;
3740
3792
 
3741
- // The domain to forward requests to.
3793
+ // FQDN of the public Host this forwarder matches (e.g. wiki.tdxid.com). Do not include a scheme or port. Must not be this Volt's own hostname (use \`path\` for own-host forwarding). Optional when \`path\` is set.
3742
3794
  string domain = 5;
3743
3795
 
3744
3796
  // The host to forward requests to.
@@ -3750,7 +3802,7 @@ message SaveHttpForwarderRequest {
3750
3802
  // Set to indicate that the host header should reflect the proxy domain rather than the target host.
3751
3803
  bool forward_host = 8;
3752
3804
 
3753
- // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (sub-domain + path, e.g. sub.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
3805
+ // Optional path prefix (e.g. "/myapp") for path-based forwarding. May be used on its own (path forwarding on the Volt's own host) or together with \`domain\` (host + path, e.g. app.acme.com/myapp). At least one of \`domain\` or \`path\` must be set.
3754
3806
  string path = 9;
3755
3807
 
3756
3808
  // When a \`path\` prefix is configured, keep that prefix on the request path when forwarding. The default (false) is standard reverse-proxy behaviour: the prefix is stripped so the target receives the request at its own root (e.g. "/drive/assets/x.js" -> "/assets/x.js"), which suits plain static file servers and root-mounted backends. Set to true for targets that are themselves configured under the same sub-path and expect to receive the prefix. The \`X-Forwarded-Prefix\` header is always sent.
@@ -3759,7 +3811,7 @@ message SaveHttpForwarderRequest {
3759
3811
  // When true, incoming HTTP requests to this forwarder must carry a valid authenticated session (established via the OIDC sign-in flow) and pass the policy check before being proxied, except for the public-path and manifest exceptions on \`auth_public_paths\`. Unauthenticated top-level document navigations are redirected to the configured OpenID Provider; other unauthenticated requests receive 401. An authenticated session that fails the policy check receives 403. The Volt session cookie is stripped from the HTTP hop to the target. WebSocket and SSE upgrades are not gated.
3760
3812
  bool auth_enabled = 11;
3761
3813
 
3762
- // OpenID Provider issuer URL used for discovery (\`<issuer>/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
3814
+ // OpenID Provider issuer URL used for discovery (\`[issuer]/.well-known/openid-configuration\`). May be a Volt acting as an OpenID Provider, or any external OIDC provider. Required when \`auth_enabled\` is set.
3763
3815
  string oidc_issuer = 12;
3764
3816
 
3765
3817
  // OAuth 2.0 client identifier registered with the OpenID Provider.
@@ -3779,6 +3831,10 @@ message SaveHttpForwarderRequest {
3779
3831
 
3780
3832
  // Effective-path patterns that may be fetched without a session (GET/HEAD). A trailing \`/*\` matches descendants on segment boundaries (e.g. \`/icon/*\`). Used for PWA icons and similar public chrome; the manifest itself is allowed via \`Sec-Fetch-Dest: manifest\` and does not need to be listed.
3781
3833
  repeated string auth_public_paths = 18;
3834
+
3835
+ // The identity whose Volt hosts the target \`host\`/\`port\`, i.e. where requests matching this forwarder are tunnelled to. This allows a forwarder to be created on a public Volt (for a named host) while the target server runs on a different Volt that is relay-connected to it. When omitted, the creating identity is used.
3836
+ // The caller must be entitled to target the identity: it must either be the caller's own identity, the Volt handling this request, or an identity that has granted the caller \`volt:resource-write\`.
3837
+ string target_identity = 19;
3782
3838
  }
3783
3839
 
3784
3840
  message SaveHttpForwarderResponse {
@@ -3871,6 +3927,60 @@ message SaveHttpFileServerResponse {
3871
3927
  Resource resource = 2;
3872
3928
  }
3873
3929
 
3930
+ message PublishFolderRequest {
3931
+ // Optional name, extra user kinds, and attributes copied onto the local static file server (for example drive:publication-drive).
3932
+ // If \`id\` is set, this call updates the existing published-folder resource with that id; otherwise it creates a new published-folder resource. Updating keeps the loopback port the file server already listens on, and rotates the OIDC client id and secret when \`auth_enabled\` is set, which ends any sign-in sessions established against the previous pair.
3933
+ Resource resource = 1;
3934
+
3935
+ // Local filesystem path to publish. \`~\` is expanded. Must exist and be a directory.
3936
+ string path = 2;
3937
+
3938
+ // FQDN of the public Host to publish on (e.g. wiki.tdxid.com). This is also the HTTP forwarder's \`domain\`. Do not include a scheme or port. Must not be the publish Volt's own hostname. May be changed when updating, in which case the previous address is released.
3939
+ string domain = 3;
3940
+
3941
+ // DID of the relay Volt that owns the public domain. When omitted, the single connected \`volt:volt-link\` with \`volt:relay-exposed\` is used. If several such relays are connected, this field is required. If none are connected, the path is published on this Volt when HTTP forwarding is enabled.
3942
+ string relay_id = 4;
3943
+
3944
+ // When true, visitors must sign in via OIDC on the publish Volt and match an invitee access rule.
3945
+ bool auth_enabled = 5;
3946
+
3947
+ // Emails, email wildcards (e.g. "*@example.com"), or DIDs permitted through the published host when \`auth_enabled\` is set. At least one is required in that case.
3948
+ repeated string invitee = 6;
3949
+
3950
+ // When true, missing paths are rewritten to \`catch_all\` (SPA-style fallback). An empty \`catch_all\` responds with 404.
3951
+ bool catch_all_enabled = 7;
3952
+
3953
+ // Catch-all path, e.g. \`/index.html\` or \`/\`. Used when \`catch_all_enabled\` is set.
3954
+ string catch_all = 8;
3955
+ }
3956
+
3957
+ message PublishFolderResponse {
3958
+ // Details of any error that occurred on the call.
3959
+ tdx.volt_api.volt.v1.Status status = 1;
3960
+
3961
+ // The local static file server that represents the publication.
3962
+ Resource resource = 2;
3963
+
3964
+ // Public URL of the published folder.
3965
+ string url = 3;
3966
+
3967
+ // Resource id of the HTTP forwarder on the publish Volt.
3968
+ string forwarder_id = 4;
3969
+
3970
+ // Resource id of the OIDC client, when access is restricted.
3971
+ string oidc_client_id = 5;
3972
+ }
3973
+
3974
+ message UnpublishFolderRequest {
3975
+ // Resource id of the local file server created by PublishFolder. The resource must have kind \`volt:published-folder\`.
3976
+ string resource_id = 1;
3977
+ }
3978
+
3979
+ message UnpublishFolderResponse {
3980
+ // Details of any error that occurred on the call.
3981
+ tdx.volt_api.volt.v1.Status status = 1;
3982
+ }
3983
+
3874
3984
  message SaveHttpRestApiServerRequest {
3875
3985
  // Details of the resource to save.
3876
3986
  Resource resource = 1;