@rstreamlabs/tunnels 3.2.0 → 3.4.0
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/README.md +58 -4
- package/dist/chunk-6OUCIT5G.mjs +1330 -0
- package/dist/index.d.mts +2977 -131
- package/dist/index.d.ts +2977 -131
- package/dist/index.js +926 -171
- package/dist/index.mjs +165 -9
- package/dist/openapi.d.mts +4 -1
- package/dist/openapi.d.ts +4 -1
- package/dist/openapi.js +479 -58
- package/dist/openapi.mjs +1 -1
- package/package.json +2 -2
- package/dist/chunk-VUAM3LRU.mjs +0 -710
package/dist/index.mjs
CHANGED
|
@@ -1,23 +1,54 @@
|
|
|
1
1
|
import {
|
|
2
|
+
RstreamWebTTYResource,
|
|
3
|
+
attachWebTTYParticipantParamsSchema,
|
|
2
4
|
clientFilterSchema,
|
|
3
5
|
clientSchema,
|
|
6
|
+
createWebTTYControlRequestParamsSchema,
|
|
7
|
+
detachWebTTYParticipantParamsSchema,
|
|
4
8
|
engineOpenApiDocument,
|
|
5
9
|
engineOpenApiJson,
|
|
6
10
|
eventSchema,
|
|
11
|
+
formatStreamAccessPath,
|
|
7
12
|
formatTunnelHost,
|
|
8
13
|
listClientsParamsSchema,
|
|
9
14
|
listClientsResponseSchema,
|
|
10
15
|
listTunnelsParamsSchema,
|
|
11
16
|
listTunnelsResponseSchema,
|
|
17
|
+
listWebTTYControlRequestsParamsSchema,
|
|
18
|
+
listWebTTYKeyGrantDecryptMaterialParamsSchema,
|
|
19
|
+
listWebTTYSessionGroupsParamsSchema,
|
|
20
|
+
listWebTTYSessionsParamsSchema,
|
|
12
21
|
projectLogEventsSchema,
|
|
22
|
+
readWebTTYSessionEventsParamsSchema,
|
|
23
|
+
resolveWebTTYControlRequestParamsSchema,
|
|
13
24
|
streamEndpointSchema,
|
|
25
|
+
streamEntrySchema,
|
|
14
26
|
streamSummaryEventSchema,
|
|
15
27
|
streamSummarySchema,
|
|
16
28
|
streamTLSInfoSchema,
|
|
29
|
+
streamWebTTYMetadataSchema,
|
|
17
30
|
tunnelFilterSchema,
|
|
31
|
+
webTTYCapabilitiesSchema,
|
|
32
|
+
webTTYContextMetadataSchema,
|
|
33
|
+
webTTYControlRequestSchema,
|
|
34
|
+
webTTYCryptoMetadataSchema,
|
|
35
|
+
webTTYEncryptionModeSchema,
|
|
36
|
+
webTTYKeyGrantDecryptMaterialSchema,
|
|
37
|
+
webTTYKeyGrantSchema,
|
|
38
|
+
webTTYOriginSchema,
|
|
39
|
+
webTTYParticipantLiveSchema,
|
|
40
|
+
webTTYParticipantRoleSchema,
|
|
41
|
+
webTTYParticipantSchema,
|
|
42
|
+
webTTYRecordingModeSchema,
|
|
43
|
+
webTTYSessionEventSchema,
|
|
44
|
+
webTTYSessionGroupSchema,
|
|
45
|
+
webTTYSessionLiveSchema,
|
|
46
|
+
webTTYSessionModeSchema,
|
|
47
|
+
webTTYSessionSchema,
|
|
48
|
+
webTTYTransportSchema,
|
|
18
49
|
webhookEventsSchema,
|
|
19
50
|
wsEventsSchema
|
|
20
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-6OUCIT5G.mjs";
|
|
21
52
|
|
|
22
53
|
// src/auth-resource.ts
|
|
23
54
|
import { createAuthTokenParamsSchema } from "@rstreamlabs/rstream/auth-token";
|
|
@@ -730,9 +761,18 @@ var RstreamTURNResource = class {
|
|
|
730
761
|
|
|
731
762
|
// src/webhooks-resource.ts
|
|
732
763
|
import crypto2 from "crypto";
|
|
764
|
+
var WEBHOOK_SIGNATURE_HEADER = "rstream-signature";
|
|
765
|
+
var WEBHOOK_EVENT_ID_HEADER = "rstream-event-id";
|
|
766
|
+
var WEBHOOK_EVENT_TYPE_HEADER = "rstream-event-type";
|
|
767
|
+
var WEBHOOK_ID_HEADER = "rstream-webhook-id";
|
|
768
|
+
var WEBHOOK_DELIVERY_ID_HEADER = "rstream-delivery-id";
|
|
733
769
|
var SIGNATURE_HEX_BYTES = 32;
|
|
770
|
+
var webhookSecretBytes = 32;
|
|
734
771
|
var signatureHexSchema = /^[0-9a-fA-F]{64}$/;
|
|
735
772
|
var timestampSchema = /^\d+$/;
|
|
773
|
+
function payloadBuffer(payload) {
|
|
774
|
+
return Buffer.isBuffer(payload) ? payload : Buffer.from(payload);
|
|
775
|
+
}
|
|
736
776
|
function parseSignatureTimestamp(timestamp) {
|
|
737
777
|
if (!timestampSchema.test(timestamp)) {
|
|
738
778
|
throw new Error("Invalid signature timestamp");
|
|
@@ -749,6 +789,19 @@ function normalizeTolerance(tolerance) {
|
|
|
749
789
|
}
|
|
750
790
|
return tolerance;
|
|
751
791
|
}
|
|
792
|
+
function normalizeTimestamp(timestamp) {
|
|
793
|
+
if (timestamp === void 0) {
|
|
794
|
+
return Math.floor(Date.now() / 1e3);
|
|
795
|
+
}
|
|
796
|
+
const seconds = timestamp instanceof Date ? timestamp.getTime() / 1e3 : timestamp;
|
|
797
|
+
if (!Number.isFinite(seconds) || seconds < 0) {
|
|
798
|
+
throw new Error("Invalid webhook signature timestamp");
|
|
799
|
+
}
|
|
800
|
+
return Math.floor(seconds);
|
|
801
|
+
}
|
|
802
|
+
function signedPayload(timestamp, payload) {
|
|
803
|
+
return Buffer.concat([Buffer.from(`${timestamp}.`, "utf8"), payload]);
|
|
804
|
+
}
|
|
752
805
|
function readSignature(signature) {
|
|
753
806
|
if (!signatureHexSchema.test(signature)) {
|
|
754
807
|
return void 0;
|
|
@@ -765,9 +818,42 @@ function assertSecretConfigured(secret) {
|
|
|
765
818
|
throw new Error("Webhook signing secret is required");
|
|
766
819
|
}
|
|
767
820
|
}
|
|
821
|
+
function assertNonEmpty(value, label) {
|
|
822
|
+
const normalized = value.trim();
|
|
823
|
+
if (normalized.length === 0) {
|
|
824
|
+
throw new Error(`${label} is required`);
|
|
825
|
+
}
|
|
826
|
+
return normalized;
|
|
827
|
+
}
|
|
828
|
+
function generateWebhookSigningSecret() {
|
|
829
|
+
return `whsec_${crypto2.randomBytes(webhookSecretBytes).toString("base64url")}`;
|
|
830
|
+
}
|
|
831
|
+
function signWebhookPayload(payload, secret, timestamp) {
|
|
832
|
+
assertSecretConfigured(secret);
|
|
833
|
+
const timestampSeconds = normalizeTimestamp(timestamp).toString();
|
|
834
|
+
const signature = crypto2.createHmac("sha256", secret).update(signedPayload(timestampSeconds, payloadBuffer(payload))).digest("hex");
|
|
835
|
+
return `t=${timestampSeconds},v1=${signature}`;
|
|
836
|
+
}
|
|
837
|
+
function buildWebhookHeaders(payload, event, secret, options) {
|
|
838
|
+
const eventId = assertNonEmpty(event.id ?? "", "Webhook event id");
|
|
839
|
+
const eventType = assertNonEmpty(event.type, "Webhook event type");
|
|
840
|
+
const webhookId = assertNonEmpty(options.webhookId, "Webhook id");
|
|
841
|
+
const deliveryId = assertNonEmpty(options.deliveryId, "Webhook delivery id");
|
|
842
|
+
return {
|
|
843
|
+
[WEBHOOK_SIGNATURE_HEADER]: signWebhookPayload(
|
|
844
|
+
payload,
|
|
845
|
+
secret,
|
|
846
|
+
options.timestamp
|
|
847
|
+
),
|
|
848
|
+
[WEBHOOK_EVENT_ID_HEADER]: eventId,
|
|
849
|
+
[WEBHOOK_EVENT_TYPE_HEADER]: eventType,
|
|
850
|
+
[WEBHOOK_ID_HEADER]: webhookId,
|
|
851
|
+
[WEBHOOK_DELIVERY_ID_HEADER]: deliveryId
|
|
852
|
+
};
|
|
853
|
+
}
|
|
768
854
|
var RstreamWebhookResource = class {
|
|
769
855
|
async event(payload, header, secret, tolerance = 300, receivedAt = Date.now()) {
|
|
770
|
-
const
|
|
856
|
+
const rawPayload = payloadBuffer(payload);
|
|
771
857
|
const signatureHeader = Array.isArray(header) ? header[0] : header.toString();
|
|
772
858
|
if (!signatureHeader) {
|
|
773
859
|
throw new Error("No signature header");
|
|
@@ -787,8 +873,7 @@ var RstreamWebhookResource = class {
|
|
|
787
873
|
`Webhook signature timestamp outside tolerance: ${now}, ${timestampNum}`
|
|
788
874
|
);
|
|
789
875
|
}
|
|
790
|
-
const
|
|
791
|
-
const expectedSignature = crypto2.createHmac("sha256", secret).update(signedPayload).digest();
|
|
876
|
+
const expectedSignature = crypto2.createHmac("sha256", secret).update(signedPayload(timestamp, rawPayload)).digest();
|
|
792
877
|
const signatureMatched = signatures.some(
|
|
793
878
|
(signature) => signatureMatches(signature, expectedSignature)
|
|
794
879
|
);
|
|
@@ -796,9 +881,7 @@ var RstreamWebhookResource = class {
|
|
|
796
881
|
throw new Error("Signature verification failed");
|
|
797
882
|
}
|
|
798
883
|
try {
|
|
799
|
-
return webhookEventsSchema.parse(
|
|
800
|
-
JSON.parse(payloadBuffer.toString("utf8"))
|
|
801
|
-
);
|
|
884
|
+
return webhookEventsSchema.parse(JSON.parse(rawPayload.toString("utf8")));
|
|
802
885
|
} catch (error) {
|
|
803
886
|
throw new Error(
|
|
804
887
|
`Failed to parse webhook payload: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -806,6 +889,15 @@ var RstreamWebhookResource = class {
|
|
|
806
889
|
);
|
|
807
890
|
}
|
|
808
891
|
}
|
|
892
|
+
generateSigningSecret() {
|
|
893
|
+
return generateWebhookSigningSecret();
|
|
894
|
+
}
|
|
895
|
+
sign(payload, secret, timestamp) {
|
|
896
|
+
return signWebhookPayload(payload, secret, timestamp);
|
|
897
|
+
}
|
|
898
|
+
headers(payload, event, secret, options) {
|
|
899
|
+
return buildWebhookHeaders(payload, event, secret, options);
|
|
900
|
+
}
|
|
809
901
|
};
|
|
810
902
|
|
|
811
903
|
// src/tunnels.ts
|
|
@@ -924,6 +1016,9 @@ var RstreamTunnelsClient = class {
|
|
|
924
1016
|
get webhooks() {
|
|
925
1017
|
return new RstreamWebhookResource();
|
|
926
1018
|
}
|
|
1019
|
+
get webtty() {
|
|
1020
|
+
return new RstreamWebTTYResource(this);
|
|
1021
|
+
}
|
|
927
1022
|
get turn() {
|
|
928
1023
|
return new RstreamTURNResource(this);
|
|
929
1024
|
}
|
|
@@ -1149,10 +1244,23 @@ var osFamilySchema = z2.enum([
|
|
|
1149
1244
|
]);
|
|
1150
1245
|
var webttyCapabilitySchema = z2.enum(["exec", "fs"]);
|
|
1151
1246
|
var webttyFSModeSchema = z2.enum(["read-write", "read-only"]);
|
|
1247
|
+
var webttyEncryptionPolicySchema = z2.enum([
|
|
1248
|
+
"disabled",
|
|
1249
|
+
"explicit_key",
|
|
1250
|
+
"workspace_managed"
|
|
1251
|
+
]);
|
|
1152
1252
|
var webttyServerSchema = z2.object({
|
|
1153
1253
|
tunnel_id: z2.string(),
|
|
1254
|
+
tunnel_protocol: z2.enum(["http", "webtty"]),
|
|
1255
|
+
managed: z2.boolean(),
|
|
1154
1256
|
host: z2.string(),
|
|
1155
1257
|
token_auth: z2.boolean(),
|
|
1258
|
+
server_id: z2.string().optional(),
|
|
1259
|
+
server_name: z2.string().optional(),
|
|
1260
|
+
host_key_id: z2.string().optional(),
|
|
1261
|
+
e2e: z2.enum(["disabled", "required"]).optional(),
|
|
1262
|
+
client_proof: z2.enum(["none", "required"]).optional(),
|
|
1263
|
+
encryption_policy: webttyEncryptionPolicySchema.optional(),
|
|
1156
1264
|
capabilities: z2.array(webttyCapabilitySchema).optional(),
|
|
1157
1265
|
exec_path: z2.string().optional(),
|
|
1158
1266
|
fs_path: z2.string().optional(),
|
|
@@ -1186,9 +1294,10 @@ function webTTYHasCapability(capabilities, capability) {
|
|
|
1186
1294
|
function parser(tunnel) {
|
|
1187
1295
|
if (tunnel.status !== "online") return null;
|
|
1188
1296
|
if (tunnel.publish !== true) return null;
|
|
1189
|
-
|
|
1297
|
+
const managedProtocol = tunnel.protocol === "webtty";
|
|
1298
|
+
if (tunnel.protocol !== "http" && !managedProtocol) return null;
|
|
1190
1299
|
const tunnelLabels = tunnel.labels ?? {};
|
|
1191
|
-
if (tunnelLabels["application-protocol"] !== "rstream.webtty") {
|
|
1300
|
+
if (!managedProtocol && tunnelLabels["application-protocol"] !== "rstream.webtty") {
|
|
1192
1301
|
return null;
|
|
1193
1302
|
}
|
|
1194
1303
|
const capabilities = webTTYCapabilitiesForLabels(tunnelLabels);
|
|
@@ -1201,8 +1310,16 @@ function parser(tunnel) {
|
|
|
1201
1310
|
}
|
|
1202
1311
|
const candidate = {
|
|
1203
1312
|
tunnel_id: tunnel.id,
|
|
1313
|
+
tunnel_protocol: tunnel.protocol,
|
|
1314
|
+
managed: managedProtocol,
|
|
1204
1315
|
host: formatTunnelHost(tunnel),
|
|
1205
1316
|
token_auth: tunnel.token_auth === true,
|
|
1317
|
+
server_id: tunnelLabels["rstream.webtty.server_id"],
|
|
1318
|
+
server_name: tunnelLabels["rstream.webtty.server_name"],
|
|
1319
|
+
host_key_id: tunnelLabels["rstream.webtty.host_key_id"],
|
|
1320
|
+
e2e: tunnelLabels["rstream.webtty.e2e"],
|
|
1321
|
+
client_proof: tunnelLabels["rstream.webtty.client_proof"],
|
|
1322
|
+
encryption_policy: tunnelLabels["rstream.webtty.encryption_policy"],
|
|
1206
1323
|
capabilities,
|
|
1207
1324
|
exec_path: webTTYHasCapability(capabilities, "exec") ? tunnelLabels["rstream.webtty.exec.path"] ?? "/" : void 0,
|
|
1208
1325
|
fs_path: webTTYHasCapability(capabilities, "fs") ? tunnelLabels["rstream.webtty.fs.path"] ?? "/fs" : void 0,
|
|
@@ -1234,10 +1351,18 @@ export {
|
|
|
1234
1351
|
RstreamTunnelsClient,
|
|
1235
1352
|
RstreamTunnelsResource,
|
|
1236
1353
|
RstreamTunnelsResource as RstreamTunnelsRessource,
|
|
1354
|
+
RstreamWebTTYResource,
|
|
1237
1355
|
RstreamWebhookResource,
|
|
1238
1356
|
RstreamWebhookResource as RstreamWebhookRessource,
|
|
1239
1357
|
RstreamTunnelsClient as Tunnels,
|
|
1358
|
+
WEBHOOK_DELIVERY_ID_HEADER,
|
|
1359
|
+
WEBHOOK_EVENT_ID_HEADER,
|
|
1360
|
+
WEBHOOK_EVENT_TYPE_HEADER,
|
|
1361
|
+
WEBHOOK_ID_HEADER,
|
|
1362
|
+
WEBHOOK_SIGNATURE_HEADER,
|
|
1240
1363
|
Watch,
|
|
1364
|
+
attachWebTTYParticipantParamsSchema,
|
|
1365
|
+
buildWebhookHeaders,
|
|
1241
1366
|
clientFilterSchema,
|
|
1242
1367
|
clientSchema,
|
|
1243
1368
|
createAPITURNCredentials,
|
|
@@ -1245,28 +1370,59 @@ export {
|
|
|
1245
1370
|
createAuthTokenFromClientCredentials,
|
|
1246
1371
|
createPATTURNCredentials,
|
|
1247
1372
|
createTURNCredentials,
|
|
1373
|
+
createWebTTYControlRequestParamsSchema,
|
|
1374
|
+
detachWebTTYParticipantParamsSchema,
|
|
1248
1375
|
engineOpenApiDocument,
|
|
1249
1376
|
engineOpenApiJson,
|
|
1250
1377
|
eventSchema,
|
|
1378
|
+
formatStreamAccessPath,
|
|
1251
1379
|
formatTunnelHost,
|
|
1380
|
+
generateWebhookSigningSecret,
|
|
1252
1381
|
listClientsParamsSchema,
|
|
1253
1382
|
listClientsResponseSchema,
|
|
1254
1383
|
listTunnelsParamsSchema,
|
|
1255
1384
|
listTunnelsResponseSchema,
|
|
1385
|
+
listWebTTYControlRequestsParamsSchema,
|
|
1386
|
+
listWebTTYKeyGrantDecryptMaterialParamsSchema,
|
|
1387
|
+
listWebTTYSessionGroupsParamsSchema,
|
|
1388
|
+
listWebTTYSessionsParamsSchema,
|
|
1256
1389
|
normalizeEngineAddress,
|
|
1257
1390
|
parseWebTTYServers,
|
|
1258
1391
|
projectLogEventsSchema,
|
|
1392
|
+
readWebTTYSessionEventsParamsSchema,
|
|
1259
1393
|
resolveControlPlaneCredentials,
|
|
1260
1394
|
resolveManagedTunnelsProject,
|
|
1261
1395
|
resolveTunnelsAPIURL,
|
|
1262
1396
|
resolveTunnelsCredentials,
|
|
1263
1397
|
resolveTunnelsEngine,
|
|
1398
|
+
resolveWebTTYControlRequestParamsSchema,
|
|
1399
|
+
signWebhookPayload,
|
|
1264
1400
|
streamEndpointSchema,
|
|
1401
|
+
streamEntrySchema,
|
|
1265
1402
|
streamSummaryEventSchema,
|
|
1266
1403
|
streamSummarySchema,
|
|
1267
1404
|
streamTLSInfoSchema,
|
|
1405
|
+
streamWebTTYMetadataSchema,
|
|
1268
1406
|
tunnelFilterSchema,
|
|
1269
1407
|
turnCredentialModeSchema,
|
|
1408
|
+
webTTYCapabilitiesSchema,
|
|
1409
|
+
webTTYContextMetadataSchema,
|
|
1410
|
+
webTTYControlRequestSchema,
|
|
1411
|
+
webTTYCryptoMetadataSchema,
|
|
1412
|
+
webTTYEncryptionModeSchema,
|
|
1413
|
+
webTTYKeyGrantDecryptMaterialSchema,
|
|
1414
|
+
webTTYKeyGrantSchema,
|
|
1415
|
+
webTTYOriginSchema,
|
|
1416
|
+
webTTYParticipantLiveSchema,
|
|
1417
|
+
webTTYParticipantRoleSchema,
|
|
1418
|
+
webTTYParticipantSchema,
|
|
1419
|
+
webTTYRecordingModeSchema,
|
|
1420
|
+
webTTYSessionEventSchema,
|
|
1421
|
+
webTTYSessionGroupSchema,
|
|
1422
|
+
webTTYSessionLiveSchema,
|
|
1423
|
+
webTTYSessionModeSchema,
|
|
1424
|
+
webTTYSessionSchema,
|
|
1425
|
+
webTTYTransportSchema,
|
|
1270
1426
|
webhookEventsSchema,
|
|
1271
1427
|
webttyServerSchema,
|
|
1272
1428
|
wsEventsSchema
|
package/dist/openapi.d.mts
CHANGED
|
@@ -116,7 +116,10 @@ declare const engineOpenApiDocument: {
|
|
|
116
116
|
"inspect-engine-state": string[];
|
|
117
117
|
"expose-service-from-cli": string[];
|
|
118
118
|
"connect-private-tunnel": string[];
|
|
119
|
-
"
|
|
119
|
+
"run-tunnel-webtty": string[];
|
|
120
|
+
"join-managed-webtty": string[];
|
|
121
|
+
"control-managed-webtty": string[];
|
|
122
|
+
"read-managed-webtty-recordings": string[];
|
|
120
123
|
};
|
|
121
124
|
paths: {
|
|
122
125
|
"/api/openapi.json": {
|
package/dist/openapi.d.ts
CHANGED
|
@@ -116,7 +116,10 @@ declare const engineOpenApiDocument: {
|
|
|
116
116
|
"inspect-engine-state": string[];
|
|
117
117
|
"expose-service-from-cli": string[];
|
|
118
118
|
"connect-private-tunnel": string[];
|
|
119
|
-
"
|
|
119
|
+
"run-tunnel-webtty": string[];
|
|
120
|
+
"join-managed-webtty": string[];
|
|
121
|
+
"control-managed-webtty": string[];
|
|
122
|
+
"read-managed-webtty-recordings": string[];
|
|
120
123
|
};
|
|
121
124
|
paths: {
|
|
122
125
|
"/api/openapi.json": {
|