@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.js
CHANGED
|
@@ -39,10 +39,18 @@ __export(index_exports, {
|
|
|
39
39
|
RstreamTunnelsClient: () => RstreamTunnelsClient,
|
|
40
40
|
RstreamTunnelsResource: () => RstreamTunnelsResource,
|
|
41
41
|
RstreamTunnelsRessource: () => RstreamTunnelsResource,
|
|
42
|
+
RstreamWebTTYResource: () => RstreamWebTTYResource,
|
|
42
43
|
RstreamWebhookResource: () => RstreamWebhookResource,
|
|
43
44
|
RstreamWebhookRessource: () => RstreamWebhookResource,
|
|
44
45
|
Tunnels: () => RstreamTunnelsClient,
|
|
46
|
+
WEBHOOK_DELIVERY_ID_HEADER: () => WEBHOOK_DELIVERY_ID_HEADER,
|
|
47
|
+
WEBHOOK_EVENT_ID_HEADER: () => WEBHOOK_EVENT_ID_HEADER,
|
|
48
|
+
WEBHOOK_EVENT_TYPE_HEADER: () => WEBHOOK_EVENT_TYPE_HEADER,
|
|
49
|
+
WEBHOOK_ID_HEADER: () => WEBHOOK_ID_HEADER,
|
|
50
|
+
WEBHOOK_SIGNATURE_HEADER: () => WEBHOOK_SIGNATURE_HEADER,
|
|
45
51
|
Watch: () => Watch,
|
|
52
|
+
attachWebTTYParticipantParamsSchema: () => attachWebTTYParticipantParamsSchema,
|
|
53
|
+
buildWebhookHeaders: () => buildWebhookHeaders,
|
|
46
54
|
clientFilterSchema: () => clientFilterSchema,
|
|
47
55
|
clientSchema: () => clientSchema,
|
|
48
56
|
createAPITURNCredentials: () => createAPITURNCredentials,
|
|
@@ -50,28 +58,59 @@ __export(index_exports, {
|
|
|
50
58
|
createAuthTokenFromClientCredentials: () => createAuthTokenFromClientCredentials,
|
|
51
59
|
createPATTURNCredentials: () => createPATTURNCredentials,
|
|
52
60
|
createTURNCredentials: () => createTURNCredentials,
|
|
61
|
+
createWebTTYControlRequestParamsSchema: () => createWebTTYControlRequestParamsSchema,
|
|
62
|
+
detachWebTTYParticipantParamsSchema: () => detachWebTTYParticipantParamsSchema,
|
|
53
63
|
engineOpenApiDocument: () => engineOpenApiDocument,
|
|
54
64
|
engineOpenApiJson: () => engineOpenApiJson,
|
|
55
65
|
eventSchema: () => eventSchema,
|
|
66
|
+
formatStreamAccessPath: () => formatStreamAccessPath,
|
|
56
67
|
formatTunnelHost: () => formatTunnelHost,
|
|
68
|
+
generateWebhookSigningSecret: () => generateWebhookSigningSecret,
|
|
57
69
|
listClientsParamsSchema: () => listClientsParamsSchema,
|
|
58
70
|
listClientsResponseSchema: () => listClientsResponseSchema,
|
|
59
71
|
listTunnelsParamsSchema: () => listTunnelsParamsSchema,
|
|
60
72
|
listTunnelsResponseSchema: () => listTunnelsResponseSchema,
|
|
73
|
+
listWebTTYControlRequestsParamsSchema: () => listWebTTYControlRequestsParamsSchema,
|
|
74
|
+
listWebTTYKeyGrantDecryptMaterialParamsSchema: () => listWebTTYKeyGrantDecryptMaterialParamsSchema,
|
|
75
|
+
listWebTTYSessionGroupsParamsSchema: () => listWebTTYSessionGroupsParamsSchema,
|
|
76
|
+
listWebTTYSessionsParamsSchema: () => listWebTTYSessionsParamsSchema,
|
|
61
77
|
normalizeEngineAddress: () => normalizeEngineAddress,
|
|
62
78
|
parseWebTTYServers: () => parseWebTTYServers,
|
|
63
79
|
projectLogEventsSchema: () => projectLogEventsSchema,
|
|
80
|
+
readWebTTYSessionEventsParamsSchema: () => readWebTTYSessionEventsParamsSchema,
|
|
64
81
|
resolveControlPlaneCredentials: () => resolveControlPlaneCredentials,
|
|
65
82
|
resolveManagedTunnelsProject: () => resolveManagedTunnelsProject,
|
|
66
83
|
resolveTunnelsAPIURL: () => resolveTunnelsAPIURL,
|
|
67
84
|
resolveTunnelsCredentials: () => resolveTunnelsCredentials,
|
|
68
85
|
resolveTunnelsEngine: () => resolveTunnelsEngine,
|
|
86
|
+
resolveWebTTYControlRequestParamsSchema: () => resolveWebTTYControlRequestParamsSchema,
|
|
87
|
+
signWebhookPayload: () => signWebhookPayload,
|
|
69
88
|
streamEndpointSchema: () => streamEndpointSchema,
|
|
89
|
+
streamEntrySchema: () => streamEntrySchema,
|
|
70
90
|
streamSummaryEventSchema: () => streamSummaryEventSchema,
|
|
71
91
|
streamSummarySchema: () => streamSummarySchema,
|
|
72
92
|
streamTLSInfoSchema: () => streamTLSInfoSchema,
|
|
93
|
+
streamWebTTYMetadataSchema: () => streamWebTTYMetadataSchema,
|
|
73
94
|
tunnelFilterSchema: () => tunnelFilterSchema,
|
|
74
95
|
turnCredentialModeSchema: () => turnCredentialModeSchema,
|
|
96
|
+
webTTYCapabilitiesSchema: () => webTTYCapabilitiesSchema,
|
|
97
|
+
webTTYContextMetadataSchema: () => webTTYContextMetadataSchema,
|
|
98
|
+
webTTYControlRequestSchema: () => webTTYControlRequestSchema,
|
|
99
|
+
webTTYCryptoMetadataSchema: () => webTTYCryptoMetadataSchema,
|
|
100
|
+
webTTYEncryptionModeSchema: () => webTTYEncryptionModeSchema,
|
|
101
|
+
webTTYKeyGrantDecryptMaterialSchema: () => webTTYKeyGrantDecryptMaterialSchema,
|
|
102
|
+
webTTYKeyGrantSchema: () => webTTYKeyGrantSchema,
|
|
103
|
+
webTTYOriginSchema: () => webTTYOriginSchema,
|
|
104
|
+
webTTYParticipantLiveSchema: () => webTTYParticipantLiveSchema,
|
|
105
|
+
webTTYParticipantRoleSchema: () => webTTYParticipantRoleSchema,
|
|
106
|
+
webTTYParticipantSchema: () => webTTYParticipantSchema,
|
|
107
|
+
webTTYRecordingModeSchema: () => webTTYRecordingModeSchema,
|
|
108
|
+
webTTYSessionEventSchema: () => webTTYSessionEventSchema,
|
|
109
|
+
webTTYSessionGroupSchema: () => webTTYSessionGroupSchema,
|
|
110
|
+
webTTYSessionLiveSchema: () => webTTYSessionLiveSchema,
|
|
111
|
+
webTTYSessionModeSchema: () => webTTYSessionModeSchema,
|
|
112
|
+
webTTYSessionSchema: () => webTTYSessionSchema,
|
|
113
|
+
webTTYTransportSchema: () => webTTYTransportSchema,
|
|
75
114
|
webhookEventsSchema: () => webhookEventsSchema,
|
|
76
115
|
webttyServerSchema: () => webttyServerSchema,
|
|
77
116
|
wsEventsSchema: () => wsEventsSchema
|
|
@@ -294,191 +333,264 @@ var RstreamClientsResource = class {
|
|
|
294
333
|
}
|
|
295
334
|
};
|
|
296
335
|
|
|
297
|
-
// src/
|
|
336
|
+
// src/webtty-schemas.ts
|
|
298
337
|
var z2 = __toESM(require("zod"));
|
|
299
|
-
var
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
var
|
|
305
|
-
|
|
306
|
-
|
|
338
|
+
var webTTYTransportSchema = z2.enum([
|
|
339
|
+
"plain",
|
|
340
|
+
"websocket",
|
|
341
|
+
"webtransport"
|
|
342
|
+
]);
|
|
343
|
+
var webTTYRecordingModeSchema = z2.enum(["recorded", "private"]);
|
|
344
|
+
var webTTYEncryptionModeSchema = z2.enum(["managed", "e2e"]);
|
|
345
|
+
var webTTYSessionModeSchema = z2.enum([
|
|
346
|
+
"interactive",
|
|
347
|
+
"non-interactive"
|
|
348
|
+
]);
|
|
349
|
+
var webTTYOriginSchema = z2.enum([
|
|
350
|
+
"human",
|
|
351
|
+
"codex",
|
|
352
|
+
"api",
|
|
353
|
+
"automation",
|
|
354
|
+
"ci",
|
|
355
|
+
"scheduled-job"
|
|
356
|
+
]);
|
|
357
|
+
var webTTYParticipantRoleSchema = z2.enum(["controller", "spectator"]);
|
|
358
|
+
var webTTYInitiatorKindSchema = z2.enum([
|
|
359
|
+
"user",
|
|
360
|
+
"app",
|
|
361
|
+
"agent",
|
|
362
|
+
"service-account"
|
|
363
|
+
]);
|
|
364
|
+
var webTTYContextMetadataSchema = z2.object({
|
|
365
|
+
origin: webTTYOriginSchema.optional(),
|
|
366
|
+
origin_id: z2.string().optional(),
|
|
367
|
+
purpose: z2.string().optional(),
|
|
368
|
+
initiator_kind: webTTYInitiatorKindSchema.optional(),
|
|
369
|
+
agent_name: z2.string().optional(),
|
|
370
|
+
agent_version: z2.string().optional(),
|
|
371
|
+
request_id: z2.string().optional(),
|
|
372
|
+
labels: z2.record(z2.string(), z2.string()).optional()
|
|
373
|
+
}).passthrough();
|
|
374
|
+
|
|
375
|
+
// src/stream.ts
|
|
376
|
+
var z3 = __toESM(require("zod"));
|
|
377
|
+
var nonEmptyStringSchema = z3.string().min(1);
|
|
378
|
+
var isoDateTimeSchema = z3.string().datetime({ offset: true });
|
|
379
|
+
var ipAddressSchema = z3.string();
|
|
380
|
+
var intNonNegSchema = z3.number().int().nonnegative();
|
|
381
|
+
var numNonNegSchema = z3.number().nonnegative();
|
|
382
|
+
var geolocationSchema = z3.object({
|
|
383
|
+
country: z3.string().optional(),
|
|
384
|
+
region: z3.string().optional()
|
|
307
385
|
});
|
|
308
|
-
var streamTLSInfoSchema =
|
|
309
|
-
version:
|
|
310
|
-
cipher:
|
|
311
|
-
protocol:
|
|
312
|
-
curve:
|
|
313
|
-
ech:
|
|
386
|
+
var streamTLSInfoSchema = z3.object({
|
|
387
|
+
version: z3.string().min(1).optional(),
|
|
388
|
+
cipher: z3.string().min(1).optional(),
|
|
389
|
+
protocol: z3.string().min(1).optional(),
|
|
390
|
+
curve: z3.string().min(1).optional(),
|
|
391
|
+
ech: z3.boolean().optional()
|
|
314
392
|
});
|
|
315
|
-
var streamEndpointSchema =
|
|
393
|
+
var streamEndpointSchema = z3.object({
|
|
316
394
|
ip: ipAddressSchema.optional(),
|
|
317
395
|
geolocation: geolocationSchema.optional(),
|
|
318
396
|
tls: streamTLSInfoSchema.optional()
|
|
319
397
|
});
|
|
320
|
-
var httpHeadersSchema =
|
|
321
|
-
|
|
322
|
-
|
|
398
|
+
var httpHeadersSchema = z3.record(
|
|
399
|
+
z3.string(),
|
|
400
|
+
z3.union([z3.string(), z3.array(z3.string())])
|
|
323
401
|
);
|
|
324
|
-
var httpProtocolSchema =
|
|
325
|
-
var httpRequestSchema =
|
|
402
|
+
var httpProtocolSchema = z3.enum(["http/1.1", "h2", "h2c", "h3"]);
|
|
403
|
+
var httpRequestSchema = z3.object({
|
|
326
404
|
method: nonEmptyStringSchema,
|
|
327
|
-
scheme:
|
|
405
|
+
scheme: z3.string().min(1).optional(),
|
|
328
406
|
host: nonEmptyStringSchema.optional(),
|
|
329
407
|
path: nonEmptyStringSchema.optional(),
|
|
330
|
-
query:
|
|
408
|
+
query: z3.string().optional(),
|
|
331
409
|
url: nonEmptyStringSchema.optional(),
|
|
332
410
|
headers: httpHeadersSchema.optional(),
|
|
333
|
-
userAgent:
|
|
411
|
+
userAgent: z3.string().optional()
|
|
334
412
|
});
|
|
335
|
-
var httpResponseSchema =
|
|
336
|
-
status:
|
|
413
|
+
var httpResponseSchema = z3.object({
|
|
414
|
+
status: z3.number().int().min(100).max(999),
|
|
337
415
|
headers: httpHeadersSchema.optional()
|
|
338
416
|
});
|
|
339
|
-
var httpRequestStageSchema =
|
|
417
|
+
var httpRequestStageSchema = z3.object({
|
|
340
418
|
protocol: httpProtocolSchema.optional(),
|
|
341
419
|
request: httpRequestSchema
|
|
342
420
|
});
|
|
343
|
-
var httpResponseStageSchema =
|
|
421
|
+
var httpResponseStageSchema = z3.object({
|
|
344
422
|
protocol: httpProtocolSchema.optional(),
|
|
345
423
|
response: httpResponseSchema
|
|
346
424
|
});
|
|
347
|
-
var
|
|
425
|
+
var streamEntrySchema = z3.object({
|
|
426
|
+
kind: z3.enum([
|
|
427
|
+
"published_tunnel",
|
|
428
|
+
"private_rstream",
|
|
429
|
+
"proxy_egress",
|
|
430
|
+
"internal"
|
|
431
|
+
]),
|
|
432
|
+
transport: z3.enum(["rstream", "tls", "quic", "dtls", "http", "tcp"]).optional()
|
|
433
|
+
});
|
|
434
|
+
var tokenSourceSchema = z3.enum([
|
|
348
435
|
"authorization",
|
|
349
436
|
"query",
|
|
350
437
|
"client",
|
|
351
438
|
"unknown"
|
|
352
439
|
]);
|
|
353
|
-
var tokenTypeSchema =
|
|
354
|
-
var firewallRuleSchema =
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
kind:
|
|
359
|
-
source:
|
|
440
|
+
var tokenTypeSchema = z3.enum(["auth", "pat", "app", "unknown"]);
|
|
441
|
+
var firewallRuleSchema = z3.discriminatedUnion("kind", [
|
|
442
|
+
z3.object({ kind: z3.literal("none") }),
|
|
443
|
+
z3.object({ kind: z3.literal("mtls") }),
|
|
444
|
+
z3.object({
|
|
445
|
+
kind: z3.literal("rstream_auth"),
|
|
446
|
+
source: z3.literal("rstream_auth")
|
|
360
447
|
}),
|
|
361
|
-
|
|
362
|
-
kind:
|
|
448
|
+
z3.object({
|
|
449
|
+
kind: z3.literal("rstream"),
|
|
450
|
+
source: z3.literal("private_rstream").optional()
|
|
451
|
+
}),
|
|
452
|
+
z3.object({
|
|
453
|
+
kind: z3.literal("token"),
|
|
363
454
|
source: tokenSourceSchema.optional(),
|
|
364
455
|
tokenType: tokenTypeSchema.optional()
|
|
365
456
|
})
|
|
366
457
|
]);
|
|
367
|
-
var unauthorizedSourceSchema =
|
|
458
|
+
var unauthorizedSourceSchema = z3.object({
|
|
368
459
|
source: tokenSourceSchema
|
|
369
460
|
});
|
|
370
|
-
var unauthorizedReasonSchema = (shape) =>
|
|
371
|
-
var unauthorizedSchema =
|
|
461
|
+
var unauthorizedReasonSchema = (shape) => z3.object(shape).merge(unauthorizedSourceSchema);
|
|
462
|
+
var unauthorizedSchema = z3.discriminatedUnion("reason", [
|
|
372
463
|
unauthorizedReasonSchema({
|
|
373
|
-
reason:
|
|
464
|
+
reason: z3.literal("missing_token")
|
|
374
465
|
}),
|
|
375
466
|
unauthorizedReasonSchema({
|
|
376
|
-
reason:
|
|
467
|
+
reason: z3.literal("invalid_token")
|
|
377
468
|
}),
|
|
378
469
|
unauthorizedReasonSchema({
|
|
379
|
-
reason:
|
|
470
|
+
reason: z3.literal("expired_token")
|
|
380
471
|
}),
|
|
381
472
|
unauthorizedReasonSchema({
|
|
382
|
-
reason:
|
|
473
|
+
reason: z3.literal("invalid_secret")
|
|
383
474
|
}),
|
|
384
475
|
unauthorizedReasonSchema({
|
|
385
|
-
reason:
|
|
476
|
+
reason: z3.literal("user_mismatch")
|
|
386
477
|
}),
|
|
387
478
|
unauthorizedReasonSchema({
|
|
388
|
-
reason:
|
|
479
|
+
reason: z3.literal("insufficient_scope")
|
|
389
480
|
}),
|
|
390
481
|
unauthorizedReasonSchema({
|
|
391
|
-
reason:
|
|
392
|
-
policy:
|
|
393
|
-
value:
|
|
482
|
+
reason: z3.literal("policy_denied"),
|
|
483
|
+
policy: z3.enum(["ip", "geo", "mtls", "challenge", "other"]),
|
|
484
|
+
value: z3.string().optional()
|
|
394
485
|
})
|
|
395
486
|
]);
|
|
396
|
-
var failureSchema =
|
|
397
|
-
|
|
398
|
-
kind:
|
|
487
|
+
var failureSchema = z3.discriminatedUnion("kind", [
|
|
488
|
+
z3.object({
|
|
489
|
+
kind: z3.literal("timeout"),
|
|
399
490
|
timeoutMs: intNonNegSchema.optional(),
|
|
400
|
-
message:
|
|
491
|
+
message: z3.string().optional()
|
|
401
492
|
}),
|
|
402
|
-
|
|
403
|
-
kind:
|
|
493
|
+
z3.object({
|
|
494
|
+
kind: z3.literal("unauthorized"),
|
|
404
495
|
why: unauthorizedSchema,
|
|
405
|
-
message:
|
|
496
|
+
message: z3.string().optional()
|
|
406
497
|
}),
|
|
407
|
-
|
|
408
|
-
kind:
|
|
409
|
-
resource:
|
|
410
|
-
message:
|
|
498
|
+
z3.object({
|
|
499
|
+
kind: z3.literal("not_found"),
|
|
500
|
+
resource: z3.enum(["tunnel", "client", "route"]),
|
|
501
|
+
message: z3.string().optional()
|
|
411
502
|
}),
|
|
412
|
-
|
|
413
|
-
kind:
|
|
414
|
-
reason:
|
|
415
|
-
message:
|
|
503
|
+
z3.object({
|
|
504
|
+
kind: z3.literal("refused"),
|
|
505
|
+
reason: z3.enum(["capacity", "policy", "unsupported", "other"]),
|
|
506
|
+
message: z3.string().optional()
|
|
416
507
|
}),
|
|
417
|
-
|
|
418
|
-
|
|
508
|
+
z3.object({ kind: z3.literal("io"), message: z3.string().optional() }),
|
|
509
|
+
z3.object({ kind: z3.literal("internal"), message: z3.string().optional() })
|
|
419
510
|
]);
|
|
420
|
-
var firewallSchema =
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
decision:
|
|
511
|
+
var firewallSchema = z3.discriminatedUnion("decision", [
|
|
512
|
+
z3.object({ decision: z3.literal("allowed"), rule: firewallRuleSchema }),
|
|
513
|
+
z3.object({
|
|
514
|
+
decision: z3.literal("denied"),
|
|
424
515
|
rule: firewallRuleSchema,
|
|
425
516
|
failure: failureSchema
|
|
426
517
|
})
|
|
427
518
|
]);
|
|
428
|
-
var routedTunnelSchema =
|
|
519
|
+
var routedTunnelSchema = z3.object({
|
|
429
520
|
tunnelId: nonEmptyStringSchema.optional(),
|
|
430
|
-
tunnelName:
|
|
431
|
-
hostname:
|
|
432
|
-
protocol:
|
|
433
|
-
published:
|
|
434
|
-
type:
|
|
435
|
-
tlsMode:
|
|
436
|
-
httpVersion:
|
|
437
|
-
httpUseTls:
|
|
438
|
-
upstreamTls:
|
|
439
|
-
tokenAuth:
|
|
440
|
-
mtls_auth:
|
|
521
|
+
tunnelName: z3.string().optional(),
|
|
522
|
+
hostname: z3.string().optional(),
|
|
523
|
+
protocol: z3.string().optional(),
|
|
524
|
+
published: z3.boolean().optional(),
|
|
525
|
+
type: z3.string().optional(),
|
|
526
|
+
tlsMode: z3.string().optional(),
|
|
527
|
+
httpVersion: z3.string().optional(),
|
|
528
|
+
httpUseTls: z3.boolean().optional(),
|
|
529
|
+
upstreamTls: z3.boolean().optional(),
|
|
530
|
+
tokenAuth: z3.boolean().optional(),
|
|
531
|
+
mtls_auth: z3.boolean().optional()
|
|
441
532
|
});
|
|
442
|
-
var routingSchema =
|
|
443
|
-
|
|
444
|
-
|
|
533
|
+
var routingSchema = z3.discriminatedUnion("decision", [
|
|
534
|
+
z3.object({ decision: z3.literal("routed"), tunnel: routedTunnelSchema }),
|
|
535
|
+
z3.object({ decision: z3.literal("not_routed"), failure: failureSchema })
|
|
445
536
|
]);
|
|
446
|
-
var streamConnectedMetricsSchema =
|
|
537
|
+
var streamConnectedMetricsSchema = z3.object({
|
|
447
538
|
establish_ms: numNonNegSchema,
|
|
448
539
|
duration_ms: numNonNegSchema,
|
|
449
540
|
upstream_bytes: intNonNegSchema,
|
|
450
541
|
downstream_bytes: intNonNegSchema
|
|
451
542
|
});
|
|
452
|
-
var streamFailedMetricsSchema =
|
|
543
|
+
var streamFailedMetricsSchema = z3.object({
|
|
453
544
|
time_to_fail_ms: numNonNegSchema.optional(),
|
|
454
545
|
establish_ms: numNonNegSchema.optional()
|
|
455
546
|
});
|
|
456
|
-
var terminationSchema =
|
|
457
|
-
by:
|
|
458
|
-
reason:
|
|
459
|
-
message:
|
|
547
|
+
var terminationSchema = z3.object({
|
|
548
|
+
by: z3.enum(["downstream", "upstream", "server", "unknown"]),
|
|
549
|
+
reason: z3.enum(["closed", "reset", "timeout", "error", "unknown"]),
|
|
550
|
+
message: z3.string().optional()
|
|
460
551
|
});
|
|
461
|
-
var responseConnectedSchema =
|
|
462
|
-
outcome:
|
|
552
|
+
var responseConnectedSchema = z3.object({
|
|
553
|
+
outcome: z3.literal("connected"),
|
|
463
554
|
established_at: isoDateTimeSchema,
|
|
464
555
|
upstream: streamEndpointSchema.optional(),
|
|
465
556
|
metrics: streamConnectedMetricsSchema,
|
|
466
557
|
termination: terminationSchema.optional(),
|
|
467
558
|
http: httpResponseStageSchema.optional()
|
|
468
559
|
});
|
|
469
|
-
var responseFailedSchema =
|
|
470
|
-
outcome:
|
|
560
|
+
var responseFailedSchema = z3.object({
|
|
561
|
+
outcome: z3.literal("failed"),
|
|
471
562
|
failure: failureSchema,
|
|
472
563
|
upstream: streamEndpointSchema.optional(),
|
|
473
564
|
metrics: streamFailedMetricsSchema.optional(),
|
|
474
565
|
termination: terminationSchema.optional(),
|
|
475
566
|
http: httpResponseStageSchema.optional()
|
|
476
567
|
});
|
|
477
|
-
var responseSchema =
|
|
568
|
+
var responseSchema = z3.discriminatedUnion("outcome", [
|
|
478
569
|
responseConnectedSchema,
|
|
479
570
|
responseFailedSchema
|
|
480
571
|
]);
|
|
481
|
-
var
|
|
572
|
+
var streamWebTTYMetadataSchema = z3.object({
|
|
573
|
+
server_id: nonEmptyStringSchema.optional(),
|
|
574
|
+
session_id: nonEmptyStringSchema.optional(),
|
|
575
|
+
session_group_id: nonEmptyStringSchema.optional(),
|
|
576
|
+
participant_id: nonEmptyStringSchema.optional(),
|
|
577
|
+
participant_role: webTTYParticipantRoleSchema.optional(),
|
|
578
|
+
controller: z3.boolean().optional(),
|
|
579
|
+
recording_mode: webTTYRecordingModeSchema.optional(),
|
|
580
|
+
encryption_mode: webTTYEncryptionModeSchema.optional(),
|
|
581
|
+
encryption_policy: z3.enum(["disabled", "explicit_key", "workspace_managed"]).optional(),
|
|
582
|
+
e2e: z3.boolean().optional(),
|
|
583
|
+
client_proof: z3.enum(["none", "required"]).optional(),
|
|
584
|
+
session_mode: webTTYSessionModeSchema.optional(),
|
|
585
|
+
downstream_transport: webTTYTransportSchema.optional(),
|
|
586
|
+
upstream_transport: webTTYTransportSchema.optional(),
|
|
587
|
+
origin: webTTYOriginSchema.optional(),
|
|
588
|
+
origin_id: z3.string().optional(),
|
|
589
|
+
initiator_kind: webTTYInitiatorKindSchema.optional(),
|
|
590
|
+
device_id: z3.string().optional(),
|
|
591
|
+
browser_id: z3.string().optional()
|
|
592
|
+
}).passthrough();
|
|
593
|
+
var streamSummarySchema = z3.object({
|
|
482
594
|
workspace_id: nonEmptyStringSchema.optional(),
|
|
483
595
|
project_id: nonEmptyStringSchema.optional(),
|
|
484
596
|
cluster_id: nonEmptyStringSchema.optional(),
|
|
@@ -488,80 +600,561 @@ var streamSummarySchema = z2.object({
|
|
|
488
600
|
stream_id: nonEmptyStringSchema,
|
|
489
601
|
created_at: isoDateTimeSchema,
|
|
490
602
|
terminated_at: isoDateTimeSchema,
|
|
491
|
-
request:
|
|
603
|
+
request: z3.object({
|
|
492
604
|
downstream: streamEndpointSchema,
|
|
605
|
+
entry: streamEntrySchema.optional(),
|
|
493
606
|
http: httpRequestStageSchema.optional()
|
|
494
607
|
}),
|
|
495
608
|
firewall: firewallSchema,
|
|
496
609
|
routing: routingSchema,
|
|
610
|
+
webtty: streamWebTTYMetadataSchema.optional(),
|
|
497
611
|
response: responseSchema
|
|
498
612
|
});
|
|
613
|
+
function formatStreamAccessPath(entry) {
|
|
614
|
+
if (!entry) return void 0;
|
|
615
|
+
switch (entry.kind) {
|
|
616
|
+
case "published_tunnel":
|
|
617
|
+
return "Public URL";
|
|
618
|
+
case "private_rstream":
|
|
619
|
+
return "Private rstream dial";
|
|
620
|
+
case "proxy_egress":
|
|
621
|
+
return "Proxy egress";
|
|
622
|
+
case "internal":
|
|
623
|
+
return "Internal";
|
|
624
|
+
default:
|
|
625
|
+
return void 0;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// src/webtty-resource.ts
|
|
630
|
+
var z4 = __toESM(require("zod"));
|
|
631
|
+
var isoDateTimeSchema2 = z4.string().datetime({ offset: true });
|
|
632
|
+
var decimalCursorSchema = z4.string().regex(/^\d+$/);
|
|
633
|
+
var webTTYSequenceCursorInputSchema = z4.union([
|
|
634
|
+
decimalCursorSchema,
|
|
635
|
+
z4.number().int().nonnegative().safe().transform(String)
|
|
636
|
+
]);
|
|
637
|
+
var webTTYSessionStatusSchema = z4.enum([
|
|
638
|
+
"opening",
|
|
639
|
+
"active",
|
|
640
|
+
"closing",
|
|
641
|
+
"closed",
|
|
642
|
+
"errored"
|
|
643
|
+
]);
|
|
644
|
+
var webTTYControlRequestStatusSchema = z4.enum([
|
|
645
|
+
"pending",
|
|
646
|
+
"granted",
|
|
647
|
+
"refused",
|
|
648
|
+
"revoked",
|
|
649
|
+
"expired"
|
|
650
|
+
]);
|
|
651
|
+
var webTTYEventDirectionSchema = z4.enum([
|
|
652
|
+
"client_to_server",
|
|
653
|
+
"server_to_client",
|
|
654
|
+
"engine_internal"
|
|
655
|
+
]);
|
|
656
|
+
var webTTYStreamTypeSchema = z4.enum(["stdin", "stdout", "stderr"]);
|
|
657
|
+
var webTTYSessionEventTypeSchema = z4.enum([
|
|
658
|
+
"open",
|
|
659
|
+
"ack",
|
|
660
|
+
"data",
|
|
661
|
+
"resize",
|
|
662
|
+
"close",
|
|
663
|
+
"error",
|
|
664
|
+
"participant",
|
|
665
|
+
"control",
|
|
666
|
+
"recording_state"
|
|
667
|
+
]);
|
|
668
|
+
var jsonRecordSchema = z4.record(z4.string(), z4.unknown());
|
|
669
|
+
function rejectCryptoKeyEnvelopes(crypto3, ctx, path) {
|
|
670
|
+
if (crypto3 === null || typeof crypto3 !== "object") {
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
if (Object.prototype.hasOwnProperty.call(crypto3, "key_envelopes")) {
|
|
674
|
+
ctx.addIssue({
|
|
675
|
+
code: z4.ZodIssueCode.custom,
|
|
676
|
+
message: "key_envelopes are available only from the WebTTY decrypt-material endpoint.",
|
|
677
|
+
path: [...path, "key_envelopes"]
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
var webTTYCapabilitiesSchema = z4.object({
|
|
682
|
+
managed_protocol: z4.boolean(),
|
|
683
|
+
store_configured: z4.boolean(),
|
|
684
|
+
session_listing: z4.boolean(),
|
|
685
|
+
recording: z4.boolean(),
|
|
686
|
+
replay: z4.boolean(),
|
|
687
|
+
live_attach: z4.boolean(),
|
|
688
|
+
control_transfer: z4.boolean(),
|
|
689
|
+
e2e: z4.boolean(),
|
|
690
|
+
implemented_transports: z4.array(webTTYTransportSchema),
|
|
691
|
+
recording_modes: z4.array(webTTYRecordingModeSchema),
|
|
692
|
+
encryption_modes: z4.array(webTTYEncryptionModeSchema),
|
|
693
|
+
required_permissions: z4.record(z4.string(), z4.array(z4.string()))
|
|
694
|
+
});
|
|
695
|
+
var webTTYSessionLiveSchema = z4.object({
|
|
696
|
+
available: z4.boolean(),
|
|
697
|
+
attachable: z4.boolean(),
|
|
698
|
+
participant_count: z4.number().int().nonnegative(),
|
|
699
|
+
controller_participant_id: z4.string().optional(),
|
|
700
|
+
has_upstream: z4.boolean()
|
|
701
|
+
});
|
|
702
|
+
var webTTYParticipantLiveSchema = z4.object({
|
|
703
|
+
connected: z4.boolean(),
|
|
704
|
+
controller: z4.boolean()
|
|
705
|
+
});
|
|
706
|
+
var webTTYSessionSchema = z4.object({
|
|
707
|
+
id: z4.string(),
|
|
708
|
+
workspace_id: z4.string().optional(),
|
|
709
|
+
project_id: z4.string().optional(),
|
|
710
|
+
cluster_id: z4.string().optional(),
|
|
711
|
+
server_id: z4.string().optional(),
|
|
712
|
+
tunnel_id: z4.string(),
|
|
713
|
+
client_id: z4.string().optional(),
|
|
714
|
+
initiator_user_id: z4.string().optional(),
|
|
715
|
+
group_id: z4.string().optional(),
|
|
716
|
+
status: webTTYSessionStatusSchema,
|
|
717
|
+
session_mode: webTTYSessionModeSchema,
|
|
718
|
+
recording_mode: webTTYRecordingModeSchema,
|
|
719
|
+
encryption_mode: webTTYEncryptionModeSchema,
|
|
720
|
+
downstream_transport: webTTYTransportSchema.optional(),
|
|
721
|
+
upstream_transport: webTTYTransportSchema.optional(),
|
|
722
|
+
command_meta: z4.unknown().optional(),
|
|
723
|
+
context: webTTYContextMetadataSchema.optional(),
|
|
724
|
+
started_at: isoDateTimeSchema2,
|
|
725
|
+
ended_at: isoDateTimeSchema2.optional(),
|
|
726
|
+
exit_code: z4.number().int().optional(),
|
|
727
|
+
error_code: z4.string().optional(),
|
|
728
|
+
error_message: z4.string().optional(),
|
|
729
|
+
live: webTTYSessionLiveSchema.optional()
|
|
730
|
+
}).passthrough();
|
|
731
|
+
var webTTYSessionGroupSchema = z4.object({
|
|
732
|
+
id: z4.string(),
|
|
733
|
+
workspace_id: z4.string().optional(),
|
|
734
|
+
project_id: z4.string().optional(),
|
|
735
|
+
initiator_user_id: z4.string().optional(),
|
|
736
|
+
context: webTTYContextMetadataSchema.optional(),
|
|
737
|
+
created_at: isoDateTimeSchema2,
|
|
738
|
+
updated_at: isoDateTimeSchema2,
|
|
739
|
+
closed_at: isoDateTimeSchema2.optional()
|
|
740
|
+
}).passthrough();
|
|
741
|
+
var webTTYParticipantSchema = z4.object({
|
|
742
|
+
id: z4.string(),
|
|
743
|
+
session_id: z4.string(),
|
|
744
|
+
user_id: z4.string().optional(),
|
|
745
|
+
device_id: z4.string().optional(),
|
|
746
|
+
browser_id: z4.string().optional(),
|
|
747
|
+
role: webTTYParticipantRoleSchema,
|
|
748
|
+
attached_at: isoDateTimeSchema2,
|
|
749
|
+
detached_at: isoDateTimeSchema2.optional(),
|
|
750
|
+
controller: z4.boolean(),
|
|
751
|
+
grant_state: z4.string().optional(),
|
|
752
|
+
attach_grant: z4.string().optional(),
|
|
753
|
+
attach_grant_expires_at: isoDateTimeSchema2.optional(),
|
|
754
|
+
live: webTTYParticipantLiveSchema.optional()
|
|
755
|
+
}).passthrough();
|
|
756
|
+
var webTTYCryptoMetadataSchema = z4.object({
|
|
757
|
+
payload_suite: z4.string().optional(),
|
|
758
|
+
payload_key_id: z4.string().optional(),
|
|
759
|
+
nonce: z4.string().optional(),
|
|
760
|
+
key_envelope_suite: z4.string().optional(),
|
|
761
|
+
key_envelopes: z4.unknown().optional(),
|
|
762
|
+
key_context: z4.unknown().optional(),
|
|
763
|
+
key_context_raw: z4.string().optional()
|
|
764
|
+
}).passthrough();
|
|
765
|
+
var webTTYSessionEventSchema = z4.object({
|
|
766
|
+
id: z4.string(),
|
|
767
|
+
session_id: z4.string(),
|
|
768
|
+
seq: decimalCursorSchema,
|
|
769
|
+
created_at: isoDateTimeSchema2,
|
|
770
|
+
type: webTTYSessionEventTypeSchema,
|
|
771
|
+
direction: webTTYEventDirectionSchema.optional(),
|
|
772
|
+
stream_type: webTTYStreamTypeSchema.optional(),
|
|
773
|
+
participant_id: z4.string().optional(),
|
|
774
|
+
payload_length: z4.number().int().nonnegative().optional(),
|
|
775
|
+
payload_ciphertext: z4.string().optional(),
|
|
776
|
+
payload_plaintext: z4.string().optional(),
|
|
777
|
+
crypto: webTTYCryptoMetadataSchema.optional(),
|
|
778
|
+
prev_hash: z4.string().optional(),
|
|
779
|
+
hash: z4.string().optional(),
|
|
780
|
+
metadata: z4.unknown().optional()
|
|
781
|
+
}).passthrough().superRefine((value, ctx) => {
|
|
782
|
+
rejectCryptoKeyEnvelopes(value.crypto, ctx, ["crypto"]);
|
|
783
|
+
});
|
|
784
|
+
var webTTYKeyGrantBaseShape = {
|
|
785
|
+
id: z4.string(),
|
|
786
|
+
session_id: z4.string(),
|
|
787
|
+
recipient_id: z4.string(),
|
|
788
|
+
recipient_kind: z4.string(),
|
|
789
|
+
granted_by: z4.string().optional(),
|
|
790
|
+
crypto: webTTYCryptoMetadataSchema,
|
|
791
|
+
created_at: isoDateTimeSchema2,
|
|
792
|
+
revoked_at: isoDateTimeSchema2.optional()
|
|
793
|
+
};
|
|
794
|
+
var webTTYKeyGrantSchema = z4.object(webTTYKeyGrantBaseShape).passthrough().superRefine((value, ctx) => {
|
|
795
|
+
if (Object.prototype.hasOwnProperty.call(value, "wrapped_key")) {
|
|
796
|
+
ctx.addIssue({
|
|
797
|
+
code: z4.ZodIssueCode.custom,
|
|
798
|
+
message: "wrapped_key is available only from the WebTTY decrypt-material endpoint.",
|
|
799
|
+
path: ["wrapped_key"]
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
rejectCryptoKeyEnvelopes(value.crypto, ctx, ["crypto"]);
|
|
803
|
+
});
|
|
804
|
+
var webTTYKeyGrantDecryptMaterialSchema = z4.object({
|
|
805
|
+
...webTTYKeyGrantBaseShape,
|
|
806
|
+
wrapped_key: z4.string().optional()
|
|
807
|
+
}).passthrough();
|
|
808
|
+
var webTTYControlRequestSchema = z4.object({
|
|
809
|
+
id: z4.string(),
|
|
810
|
+
session_id: z4.string(),
|
|
811
|
+
requester_participant_id: z4.string(),
|
|
812
|
+
requester_user_id: z4.string().optional(),
|
|
813
|
+
approver_participant_id: z4.string().optional(),
|
|
814
|
+
approver_user_id: z4.string().optional(),
|
|
815
|
+
status: webTTYControlRequestStatusSchema,
|
|
816
|
+
reason: z4.string().optional(),
|
|
817
|
+
metadata: z4.unknown().optional(),
|
|
818
|
+
created_at: isoDateTimeSchema2,
|
|
819
|
+
updated_at: isoDateTimeSchema2,
|
|
820
|
+
resolved_at: isoDateTimeSchema2.optional(),
|
|
821
|
+
expires_at: isoDateTimeSchema2.optional()
|
|
822
|
+
}).passthrough();
|
|
823
|
+
var listWebTTYSessionsFiltersSchema = z4.object({
|
|
824
|
+
server_id: z4.string().optional(),
|
|
825
|
+
tunnel_id: z4.string().optional(),
|
|
826
|
+
user_id: z4.string().optional(),
|
|
827
|
+
group_id: z4.string().optional(),
|
|
828
|
+
origin: webTTYOriginSchema.optional(),
|
|
829
|
+
status: webTTYSessionStatusSchema.optional(),
|
|
830
|
+
started_from: isoDateTimeSchema2.optional(),
|
|
831
|
+
started_to: isoDateTimeSchema2.optional()
|
|
832
|
+
});
|
|
833
|
+
var listWebTTYSessionsParamsSchema = z4.object({
|
|
834
|
+
limit: z4.number().int().min(1).optional(),
|
|
835
|
+
filters: listWebTTYSessionsFiltersSchema.optional()
|
|
836
|
+
});
|
|
837
|
+
var listWebTTYSessionGroupsFiltersSchema = z4.object({
|
|
838
|
+
initiator_user_id: z4.string().optional(),
|
|
839
|
+
origin: webTTYOriginSchema.optional(),
|
|
840
|
+
created_from: isoDateTimeSchema2.optional(),
|
|
841
|
+
created_to: isoDateTimeSchema2.optional()
|
|
842
|
+
});
|
|
843
|
+
var listWebTTYSessionGroupsParamsSchema = z4.object({
|
|
844
|
+
limit: z4.number().int().min(1).optional(),
|
|
845
|
+
filters: listWebTTYSessionGroupsFiltersSchema.optional()
|
|
846
|
+
});
|
|
847
|
+
var readWebTTYSessionEventsParamsSchema = z4.object({
|
|
848
|
+
from_seq: webTTYSequenceCursorInputSchema.optional(),
|
|
849
|
+
limit: z4.number().int().min(1).optional()
|
|
850
|
+
});
|
|
851
|
+
var listWebTTYKeyGrantDecryptMaterialParamsSchema = z4.object({
|
|
852
|
+
recipient_id: z4.string().optional(),
|
|
853
|
+
recipient_kind: z4.string().optional()
|
|
854
|
+
});
|
|
855
|
+
var listWebTTYControlRequestsFiltersSchema = z4.object({
|
|
856
|
+
status: webTTYControlRequestStatusSchema.optional(),
|
|
857
|
+
requester_user_id: z4.string().optional()
|
|
858
|
+
});
|
|
859
|
+
var listWebTTYControlRequestsParamsSchema = z4.object({
|
|
860
|
+
limit: z4.number().int().min(1).optional(),
|
|
861
|
+
filters: listWebTTYControlRequestsFiltersSchema.optional()
|
|
862
|
+
});
|
|
863
|
+
var attachWebTTYParticipantParamsSchema = z4.object({
|
|
864
|
+
role: z4.literal("spectator").optional(),
|
|
865
|
+
device_id: z4.string().optional(),
|
|
866
|
+
browser_id: z4.string().optional(),
|
|
867
|
+
transport: webTTYTransportSchema.optional(),
|
|
868
|
+
grant_state: z4.string().optional(),
|
|
869
|
+
metadata: jsonRecordSchema.optional()
|
|
870
|
+
});
|
|
871
|
+
var detachWebTTYParticipantParamsSchema = z4.object({
|
|
872
|
+
reason: z4.string().optional(),
|
|
873
|
+
metadata: jsonRecordSchema.optional()
|
|
874
|
+
});
|
|
875
|
+
var createWebTTYControlRequestParamsSchema = z4.object({
|
|
876
|
+
participant_id: z4.string(),
|
|
877
|
+
reason: z4.string().optional(),
|
|
878
|
+
metadata: jsonRecordSchema.optional(),
|
|
879
|
+
expires_at: isoDateTimeSchema2.optional()
|
|
880
|
+
});
|
|
881
|
+
var resolveWebTTYControlRequestParamsSchema = z4.object({
|
|
882
|
+
action: z4.enum(["grant", "refuse", "revoke"]),
|
|
883
|
+
approver_participant_id: z4.string().optional(),
|
|
884
|
+
reason: z4.string().optional()
|
|
885
|
+
});
|
|
886
|
+
var webTTYSessionListSchema = z4.array(webTTYSessionSchema);
|
|
887
|
+
var webTTYSessionGroupListSchema = z4.array(webTTYSessionGroupSchema);
|
|
888
|
+
var webTTYParticipantListSchema = z4.array(webTTYParticipantSchema);
|
|
889
|
+
var webTTYSessionEventListSchema = z4.array(webTTYSessionEventSchema);
|
|
890
|
+
var webTTYKeyGrantListSchema = z4.array(webTTYKeyGrantSchema);
|
|
891
|
+
var webTTYKeyGrantDecryptMaterialListSchema = z4.array(
|
|
892
|
+
webTTYKeyGrantDecryptMaterialSchema
|
|
893
|
+
);
|
|
894
|
+
var webTTYControlRequestListSchema = z4.array(webTTYControlRequestSchema);
|
|
895
|
+
function pathId(kind, value) {
|
|
896
|
+
const normalized = value.trim();
|
|
897
|
+
if (!normalized) {
|
|
898
|
+
throw new Error(`${kind} is required.`);
|
|
899
|
+
}
|
|
900
|
+
return encodeURIComponent(normalized);
|
|
901
|
+
}
|
|
902
|
+
function pathWithParams(path, params) {
|
|
903
|
+
if (params === void 0) {
|
|
904
|
+
return path;
|
|
905
|
+
}
|
|
906
|
+
return `${path}?params=${encodeURIComponent(JSON.stringify(params))}`;
|
|
907
|
+
}
|
|
908
|
+
var RstreamWebTTYResource = class {
|
|
909
|
+
client;
|
|
910
|
+
constructor(client) {
|
|
911
|
+
this.client = client;
|
|
912
|
+
}
|
|
913
|
+
async capabilities() {
|
|
914
|
+
const response = await this.client.request(
|
|
915
|
+
"/webtty/capabilities",
|
|
916
|
+
{
|
|
917
|
+
method: "GET"
|
|
918
|
+
}
|
|
919
|
+
);
|
|
920
|
+
return webTTYCapabilitiesSchema.parse(response);
|
|
921
|
+
}
|
|
922
|
+
async listGroups(params) {
|
|
923
|
+
const parsed = params === void 0 ? void 0 : listWebTTYSessionGroupsParamsSchema.parse(params);
|
|
924
|
+
const response = await this.client.request(
|
|
925
|
+
pathWithParams("/webtty/groups", parsed),
|
|
926
|
+
{ method: "GET" }
|
|
927
|
+
);
|
|
928
|
+
return webTTYSessionGroupListSchema.parse(response);
|
|
929
|
+
}
|
|
930
|
+
async getGroup(groupId) {
|
|
931
|
+
const response = await this.client.request(
|
|
932
|
+
`/webtty/groups/${pathId("Session group ID", groupId)}`,
|
|
933
|
+
{ method: "GET" }
|
|
934
|
+
);
|
|
935
|
+
return webTTYSessionGroupSchema.parse(response);
|
|
936
|
+
}
|
|
937
|
+
async listSessions(params) {
|
|
938
|
+
const parsed = params === void 0 ? void 0 : listWebTTYSessionsParamsSchema.parse(params);
|
|
939
|
+
const response = await this.client.request(
|
|
940
|
+
pathWithParams("/webtty/sessions", parsed),
|
|
941
|
+
{ method: "GET" }
|
|
942
|
+
);
|
|
943
|
+
return webTTYSessionListSchema.parse(response);
|
|
944
|
+
}
|
|
945
|
+
async getSession(sessionId) {
|
|
946
|
+
const response = await this.client.request(
|
|
947
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}`,
|
|
948
|
+
{ method: "GET" }
|
|
949
|
+
);
|
|
950
|
+
return webTTYSessionSchema.parse(response);
|
|
951
|
+
}
|
|
952
|
+
async listParticipants(sessionId) {
|
|
953
|
+
const response = await this.client.request(
|
|
954
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/participants`,
|
|
955
|
+
{ method: "GET" }
|
|
956
|
+
);
|
|
957
|
+
return webTTYParticipantListSchema.parse(response);
|
|
958
|
+
}
|
|
959
|
+
async attachParticipant(sessionId, params = {}) {
|
|
960
|
+
const response = await this.client.request(
|
|
961
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/participants`,
|
|
962
|
+
{
|
|
963
|
+
body: JSON.stringify(attachWebTTYParticipantParamsSchema.parse(params)),
|
|
964
|
+
headers: { "Content-Type": "application/json" },
|
|
965
|
+
method: "POST"
|
|
966
|
+
}
|
|
967
|
+
);
|
|
968
|
+
return webTTYParticipantSchema.parse(response);
|
|
969
|
+
}
|
|
970
|
+
async detachParticipant(sessionId, participantId, params = {}) {
|
|
971
|
+
const response = await this.client.request(
|
|
972
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/participants/${pathId("Participant ID", participantId)}`,
|
|
973
|
+
{
|
|
974
|
+
body: JSON.stringify(detachWebTTYParticipantParamsSchema.parse(params)),
|
|
975
|
+
headers: { "Content-Type": "application/json" },
|
|
976
|
+
method: "POST"
|
|
977
|
+
}
|
|
978
|
+
);
|
|
979
|
+
return webTTYParticipantSchema.parse(response);
|
|
980
|
+
}
|
|
981
|
+
async readEvents(sessionId, params) {
|
|
982
|
+
const parsed = params === void 0 ? void 0 : readWebTTYSessionEventsParamsSchema.parse(params);
|
|
983
|
+
const response = await this.client.request(
|
|
984
|
+
pathWithParams(
|
|
985
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/events`,
|
|
986
|
+
parsed
|
|
987
|
+
),
|
|
988
|
+
{ method: "GET" }
|
|
989
|
+
);
|
|
990
|
+
return webTTYSessionEventListSchema.parse(response);
|
|
991
|
+
}
|
|
992
|
+
async listKeyGrants(sessionId) {
|
|
993
|
+
const response = await this.client.request(
|
|
994
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/key-grants`,
|
|
995
|
+
{ method: "GET" }
|
|
996
|
+
);
|
|
997
|
+
return webTTYKeyGrantListSchema.parse(response);
|
|
998
|
+
}
|
|
999
|
+
async listKeyGrantDecryptMaterial(sessionId, params) {
|
|
1000
|
+
const parsed = params === void 0 ? void 0 : listWebTTYKeyGrantDecryptMaterialParamsSchema.parse(params);
|
|
1001
|
+
const response = await this.client.request(
|
|
1002
|
+
pathWithParams(
|
|
1003
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/key-grants/decrypt-material`,
|
|
1004
|
+
parsed
|
|
1005
|
+
),
|
|
1006
|
+
{ method: "GET" }
|
|
1007
|
+
);
|
|
1008
|
+
return webTTYKeyGrantDecryptMaterialListSchema.parse(response);
|
|
1009
|
+
}
|
|
1010
|
+
async listControlRequests(sessionId, params) {
|
|
1011
|
+
const parsed = params === void 0 ? void 0 : listWebTTYControlRequestsParamsSchema.parse(params);
|
|
1012
|
+
const response = await this.client.request(
|
|
1013
|
+
pathWithParams(
|
|
1014
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/control-requests`,
|
|
1015
|
+
parsed
|
|
1016
|
+
),
|
|
1017
|
+
{ method: "GET" }
|
|
1018
|
+
);
|
|
1019
|
+
return webTTYControlRequestListSchema.parse(response);
|
|
1020
|
+
}
|
|
1021
|
+
async createControlRequest(sessionId, params) {
|
|
1022
|
+
const response = await this.client.request(
|
|
1023
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/control-requests`,
|
|
1024
|
+
{
|
|
1025
|
+
body: JSON.stringify(
|
|
1026
|
+
createWebTTYControlRequestParamsSchema.parse(params)
|
|
1027
|
+
),
|
|
1028
|
+
headers: { "Content-Type": "application/json" },
|
|
1029
|
+
method: "POST"
|
|
1030
|
+
}
|
|
1031
|
+
);
|
|
1032
|
+
return webTTYControlRequestSchema.parse(response);
|
|
1033
|
+
}
|
|
1034
|
+
async resolveControlRequest(sessionId, requestId, params) {
|
|
1035
|
+
const response = await this.client.request(
|
|
1036
|
+
`/webtty/sessions/${pathId("Session ID", sessionId)}/control-requests/${pathId("Control request ID", requestId)}`,
|
|
1037
|
+
{
|
|
1038
|
+
body: JSON.stringify(
|
|
1039
|
+
resolveWebTTYControlRequestParamsSchema.parse(params)
|
|
1040
|
+
),
|
|
1041
|
+
headers: { "Content-Type": "application/json" },
|
|
1042
|
+
method: "POST"
|
|
1043
|
+
}
|
|
1044
|
+
);
|
|
1045
|
+
return webTTYControlRequestSchema.parse(response);
|
|
1046
|
+
}
|
|
1047
|
+
};
|
|
499
1048
|
|
|
500
1049
|
// src/event.ts
|
|
501
1050
|
var import_tunnel = require("@rstreamlabs/rstream/tunnel");
|
|
502
|
-
var
|
|
503
|
-
var
|
|
504
|
-
var initialStateSchema =
|
|
505
|
-
snapshot_at:
|
|
506
|
-
clients:
|
|
507
|
-
tunnels:
|
|
1051
|
+
var z5 = __toESM(require("zod"));
|
|
1052
|
+
var isoDateTimeSchema3 = z5.string().datetime({ offset: true });
|
|
1053
|
+
var initialStateSchema = z5.object({
|
|
1054
|
+
snapshot_at: isoDateTimeSchema3,
|
|
1055
|
+
clients: z5.array(clientSchema),
|
|
1056
|
+
tunnels: z5.array(import_tunnel.tunnelSchema)
|
|
508
1057
|
});
|
|
509
|
-
var eventBaseSchema =
|
|
510
|
-
id:
|
|
511
|
-
created_at:
|
|
512
|
-
user_id:
|
|
513
|
-
workspace_id:
|
|
514
|
-
project_id:
|
|
515
|
-
cluster_id:
|
|
1058
|
+
var eventBaseSchema = z5.object({
|
|
1059
|
+
id: z5.string().optional(),
|
|
1060
|
+
created_at: isoDateTimeSchema3.optional(),
|
|
1061
|
+
user_id: z5.string().optional(),
|
|
1062
|
+
workspace_id: z5.string().optional(),
|
|
1063
|
+
project_id: z5.string().optional(),
|
|
1064
|
+
cluster_id: z5.string().optional()
|
|
516
1065
|
});
|
|
517
|
-
var withEventBase = (shape) =>
|
|
1066
|
+
var withEventBase = (shape) => z5.object(shape).merge(eventBaseSchema).passthrough();
|
|
518
1067
|
var stateInitialEventSchema = withEventBase({
|
|
519
|
-
type:
|
|
1068
|
+
type: z5.literal("state.initial"),
|
|
520
1069
|
object: initialStateSchema
|
|
521
1070
|
});
|
|
522
1071
|
var streamSummaryEventSchema = withEventBase({
|
|
523
|
-
type:
|
|
1072
|
+
type: z5.literal("stream.summary"),
|
|
524
1073
|
object: streamSummarySchema
|
|
525
1074
|
});
|
|
526
1075
|
var commonEventsSchema = [
|
|
527
1076
|
withEventBase({
|
|
528
|
-
type:
|
|
1077
|
+
type: z5.literal("client.created"),
|
|
529
1078
|
object: clientSchema
|
|
530
1079
|
}),
|
|
531
1080
|
withEventBase({
|
|
532
|
-
type:
|
|
1081
|
+
type: z5.literal("client.updated"),
|
|
533
1082
|
object: clientSchema
|
|
534
1083
|
}),
|
|
535
1084
|
withEventBase({
|
|
536
|
-
type:
|
|
1085
|
+
type: z5.literal("client.deleted"),
|
|
537
1086
|
object: clientSchema
|
|
538
1087
|
}),
|
|
539
1088
|
withEventBase({
|
|
540
|
-
type:
|
|
1089
|
+
type: z5.literal("tunnel.created"),
|
|
541
1090
|
object: import_tunnel.tunnelSchema
|
|
542
1091
|
}),
|
|
543
1092
|
withEventBase({
|
|
544
|
-
type:
|
|
1093
|
+
type: z5.literal("tunnel.updated"),
|
|
545
1094
|
object: import_tunnel.tunnelSchema
|
|
546
1095
|
}),
|
|
547
1096
|
withEventBase({
|
|
548
|
-
type:
|
|
1097
|
+
type: z5.literal("tunnel.deleted"),
|
|
549
1098
|
object: import_tunnel.tunnelSchema
|
|
550
1099
|
})
|
|
551
1100
|
];
|
|
1101
|
+
var webTTYEventsSchema = [
|
|
1102
|
+
withEventBase({
|
|
1103
|
+
type: z5.literal("webtty.session.created"),
|
|
1104
|
+
object: webTTYSessionSchema
|
|
1105
|
+
}),
|
|
1106
|
+
withEventBase({
|
|
1107
|
+
type: z5.literal("webtty.session.updated"),
|
|
1108
|
+
object: z5.union([webTTYSessionSchema, webTTYSessionGroupSchema])
|
|
1109
|
+
}),
|
|
1110
|
+
withEventBase({
|
|
1111
|
+
type: z5.literal("webtty.session.ended"),
|
|
1112
|
+
object: webTTYSessionSchema
|
|
1113
|
+
}),
|
|
1114
|
+
withEventBase({
|
|
1115
|
+
type: z5.literal("webtty.participant.joined"),
|
|
1116
|
+
object: webTTYParticipantSchema
|
|
1117
|
+
}),
|
|
1118
|
+
withEventBase({
|
|
1119
|
+
type: z5.literal("webtty.participant.updated"),
|
|
1120
|
+
object: webTTYParticipantSchema
|
|
1121
|
+
}),
|
|
1122
|
+
withEventBase({
|
|
1123
|
+
type: z5.literal("webtty.participant.left"),
|
|
1124
|
+
object: webTTYParticipantSchema
|
|
1125
|
+
}),
|
|
1126
|
+
withEventBase({
|
|
1127
|
+
type: z5.literal("webtty.control.requested"),
|
|
1128
|
+
object: webTTYControlRequestSchema
|
|
1129
|
+
}),
|
|
1130
|
+
withEventBase({
|
|
1131
|
+
type: z5.literal("webtty.control.granted"),
|
|
1132
|
+
object: webTTYControlRequestSchema
|
|
1133
|
+
}),
|
|
1134
|
+
withEventBase({
|
|
1135
|
+
type: z5.literal("webtty.control.refused"),
|
|
1136
|
+
object: webTTYControlRequestSchema
|
|
1137
|
+
}),
|
|
1138
|
+
withEventBase({
|
|
1139
|
+
type: z5.literal("webtty.control.revoked"),
|
|
1140
|
+
object: webTTYControlRequestSchema
|
|
1141
|
+
})
|
|
1142
|
+
];
|
|
552
1143
|
var webhookDeliverableEventsSchema = [
|
|
553
1144
|
commonEventsSchema[0],
|
|
554
1145
|
commonEventsSchema[2],
|
|
555
1146
|
commonEventsSchema[3],
|
|
556
|
-
commonEventsSchema[5]
|
|
1147
|
+
commonEventsSchema[5],
|
|
1148
|
+
...webTTYEventsSchema
|
|
557
1149
|
];
|
|
558
|
-
var wsEventsSchema =
|
|
1150
|
+
var wsEventsSchema = z5.union([
|
|
559
1151
|
stateInitialEventSchema,
|
|
560
|
-
...commonEventsSchema
|
|
1152
|
+
...commonEventsSchema,
|
|
1153
|
+
...webTTYEventsSchema
|
|
561
1154
|
]);
|
|
562
|
-
var webhookEventsSchema =
|
|
1155
|
+
var webhookEventsSchema = z5.union(webhookDeliverableEventsSchema);
|
|
563
1156
|
var projectLogEventsSchema = streamSummaryEventSchema;
|
|
564
|
-
var eventSchema =
|
|
1157
|
+
var eventSchema = z5.union([
|
|
565
1158
|
wsEventsSchema,
|
|
566
1159
|
webhookEventsSchema,
|
|
567
1160
|
projectLogEventsSchema
|
|
@@ -569,7 +1162,7 @@ var eventSchema = z3.union([
|
|
|
569
1162
|
|
|
570
1163
|
// src/tunnel.ts
|
|
571
1164
|
var import_tunnel2 = require("@rstreamlabs/rstream/tunnel");
|
|
572
|
-
var
|
|
1165
|
+
var z6 = __toESM(require("zod"));
|
|
573
1166
|
var DEFAULT_PUBLISHED_PORT = 443;
|
|
574
1167
|
var tunnelFilterSchema = import_tunnel2.tunnelSchema.pick({
|
|
575
1168
|
id: true,
|
|
@@ -584,11 +1177,11 @@ var tunnelFilterSchema = import_tunnel2.tunnelSchema.pick({
|
|
|
584
1177
|
http_version: true,
|
|
585
1178
|
labels: true
|
|
586
1179
|
}).partial();
|
|
587
|
-
var listTunnelsParamsSchema =
|
|
588
|
-
limit:
|
|
1180
|
+
var listTunnelsParamsSchema = z6.object({
|
|
1181
|
+
limit: z6.number().int().min(1).optional(),
|
|
589
1182
|
filters: tunnelFilterSchema.optional()
|
|
590
1183
|
});
|
|
591
|
-
var listTunnelsResponseSchema =
|
|
1184
|
+
var listTunnelsResponseSchema = z6.array(import_tunnel2.tunnelSchema);
|
|
592
1185
|
function formatTunnelHost(tunnel) {
|
|
593
1186
|
if (!tunnel.hostname) return tunnel.host;
|
|
594
1187
|
if (!tunnel.port || tunnel.port === DEFAULT_PUBLISHED_PORT) {
|
|
@@ -599,7 +1192,7 @@ function formatTunnelHost(tunnel) {
|
|
|
599
1192
|
|
|
600
1193
|
// src/openapi.ts
|
|
601
1194
|
var import_tunnel5 = require("@rstreamlabs/rstream/tunnel");
|
|
602
|
-
var
|
|
1195
|
+
var z7 = __toESM(require("zod"));
|
|
603
1196
|
var jsonContentType = "application/json";
|
|
604
1197
|
var openApiContentType = "application/vnd.oai.openapi+json;version=3.1";
|
|
605
1198
|
function isRecord(value) {
|
|
@@ -613,10 +1206,10 @@ function dropSchemaKeyword(value) {
|
|
|
613
1206
|
}
|
|
614
1207
|
function jsonSchemaFor(schema) {
|
|
615
1208
|
return dropSchemaKeyword(
|
|
616
|
-
|
|
1209
|
+
z7.toJSONSchema(schema, {
|
|
617
1210
|
unrepresentable: "any",
|
|
618
1211
|
override: (ctx) => {
|
|
619
|
-
if (ctx.zodSchema instanceof
|
|
1212
|
+
if (ctx.zodSchema instanceof z7.ZodDate) {
|
|
620
1213
|
ctx.jsonSchema.type = "string";
|
|
621
1214
|
ctx.jsonSchema.format = "date-time";
|
|
622
1215
|
}
|
|
@@ -683,7 +1276,7 @@ var readEngineStreamsRules = [
|
|
|
683
1276
|
action: "read"
|
|
684
1277
|
}
|
|
685
1278
|
];
|
|
686
|
-
var watchParamsSchema =
|
|
1279
|
+
var watchParamsSchema = z7.object({
|
|
687
1280
|
clients: clientFilterSchema.optional(),
|
|
688
1281
|
tunnels: tunnelFilterSchema.optional()
|
|
689
1282
|
});
|
|
@@ -712,6 +1305,40 @@ var enginePermissions = {
|
|
|
712
1305
|
action: ["create", "delete"]
|
|
713
1306
|
}
|
|
714
1307
|
]
|
|
1308
|
+
},
|
|
1309
|
+
"webtty.sessions.read-only": {
|
|
1310
|
+
name: "WebTTY Sessions: Read-Only",
|
|
1311
|
+
description: "List managed WebTTY sessions, participants, replay state, and join as a spectator.",
|
|
1312
|
+
rules: [
|
|
1313
|
+
{
|
|
1314
|
+
resource: "engine.webtty.sessions",
|
|
1315
|
+
action: "read"
|
|
1316
|
+
}
|
|
1317
|
+
]
|
|
1318
|
+
},
|
|
1319
|
+
"webtty.sessions.read-write": {
|
|
1320
|
+
name: "WebTTY Sessions: Read and Write",
|
|
1321
|
+
description: "Create managed WebTTY sessions and coordinate control requests for active sessions.",
|
|
1322
|
+
rules: [
|
|
1323
|
+
{
|
|
1324
|
+
resource: "engine.webtty.sessions",
|
|
1325
|
+
action: ["read", "write"]
|
|
1326
|
+
}
|
|
1327
|
+
]
|
|
1328
|
+
},
|
|
1329
|
+
"webtty.logs.read-only": {
|
|
1330
|
+
name: "WebTTY Session Logs: Read-Only",
|
|
1331
|
+
description: "Read managed WebTTY session logs. End-to-end encrypted content still requires trusted local key material.",
|
|
1332
|
+
rules: [
|
|
1333
|
+
{
|
|
1334
|
+
resource: "engine.webtty.sessions",
|
|
1335
|
+
action: "read"
|
|
1336
|
+
},
|
|
1337
|
+
{
|
|
1338
|
+
resource: "engine.webtty.logs",
|
|
1339
|
+
action: "read"
|
|
1340
|
+
}
|
|
1341
|
+
]
|
|
715
1342
|
}
|
|
716
1343
|
};
|
|
717
1344
|
var engineOpenApiDocument = {
|
|
@@ -831,11 +1458,14 @@ var engineOpenApiDocument = {
|
|
|
831
1458
|
"tunnels.resources.read-only",
|
|
832
1459
|
"tunnels.streams.create-delete"
|
|
833
1460
|
],
|
|
834
|
-
"
|
|
1461
|
+
"run-tunnel-webtty": [
|
|
835
1462
|
"tunnels.resources.read-only",
|
|
836
1463
|
"tunnels.tunnels.create-delete",
|
|
837
1464
|
"tunnels.streams.create-delete"
|
|
838
|
-
]
|
|
1465
|
+
],
|
|
1466
|
+
"join-managed-webtty": ["webtty.sessions.read-only"],
|
|
1467
|
+
"control-managed-webtty": ["webtty.sessions.read-write"],
|
|
1468
|
+
"read-managed-webtty-recordings": ["webtty.logs.read-only"]
|
|
839
1469
|
},
|
|
840
1470
|
paths: {
|
|
841
1471
|
"/api/openapi.json": {
|
|
@@ -1103,20 +1733,20 @@ var import_rstream8 = require("@rstreamlabs/rstream");
|
|
|
1103
1733
|
var import_rstream9 = require("@rstreamlabs/rstream");
|
|
1104
1734
|
var import_rstream10 = require("@rstreamlabs/rstream");
|
|
1105
1735
|
var import_turn = require("@rstreamlabs/rstream/turn");
|
|
1106
|
-
var
|
|
1736
|
+
var z8 = __toESM(require("zod"));
|
|
1107
1737
|
var import_crypto = __toESM(require("crypto"));
|
|
1108
1738
|
var defaultTURNPort = 3478;
|
|
1109
1739
|
var defaultTURNSPort = 5349;
|
|
1110
1740
|
var defaultTURNCredentialTTLSeconds = 10 * 60;
|
|
1111
1741
|
var maxTURNCredentialTTLSeconds = 60 * 60;
|
|
1112
|
-
var turnTokenClaimsSchema =
|
|
1113
|
-
exp:
|
|
1114
|
-
iat:
|
|
1115
|
-
token_endpoint:
|
|
1116
|
-
tokendpoint:
|
|
1117
|
-
type:
|
|
1742
|
+
var turnTokenClaimsSchema = z8.object({
|
|
1743
|
+
exp: z8.number().int().optional(),
|
|
1744
|
+
iat: z8.number().int().optional(),
|
|
1745
|
+
token_endpoint: z8.string().regex(/^[0-9a-f]{8}$/i).optional(),
|
|
1746
|
+
tokendpoint: z8.string().regex(/^[0-9a-f]{8}$/i).optional(),
|
|
1747
|
+
type: z8.enum(["app", "auth", "pat"])
|
|
1118
1748
|
});
|
|
1119
|
-
var turnCredentialModeSchema =
|
|
1749
|
+
var turnCredentialModeSchema = z8.enum(["api", "app", "pat"]);
|
|
1120
1750
|
function normalizeOptionalString2(value) {
|
|
1121
1751
|
const normalized = value?.trim();
|
|
1122
1752
|
return normalized ? normalized : void 0;
|
|
@@ -1477,9 +2107,18 @@ var RstreamTURNResource = class {
|
|
|
1477
2107
|
|
|
1478
2108
|
// src/webhooks-resource.ts
|
|
1479
2109
|
var import_crypto2 = __toESM(require("crypto"));
|
|
2110
|
+
var WEBHOOK_SIGNATURE_HEADER = "rstream-signature";
|
|
2111
|
+
var WEBHOOK_EVENT_ID_HEADER = "rstream-event-id";
|
|
2112
|
+
var WEBHOOK_EVENT_TYPE_HEADER = "rstream-event-type";
|
|
2113
|
+
var WEBHOOK_ID_HEADER = "rstream-webhook-id";
|
|
2114
|
+
var WEBHOOK_DELIVERY_ID_HEADER = "rstream-delivery-id";
|
|
1480
2115
|
var SIGNATURE_HEX_BYTES = 32;
|
|
2116
|
+
var webhookSecretBytes = 32;
|
|
1481
2117
|
var signatureHexSchema = /^[0-9a-fA-F]{64}$/;
|
|
1482
2118
|
var timestampSchema = /^\d+$/;
|
|
2119
|
+
function payloadBuffer(payload) {
|
|
2120
|
+
return Buffer.isBuffer(payload) ? payload : Buffer.from(payload);
|
|
2121
|
+
}
|
|
1483
2122
|
function parseSignatureTimestamp(timestamp) {
|
|
1484
2123
|
if (!timestampSchema.test(timestamp)) {
|
|
1485
2124
|
throw new Error("Invalid signature timestamp");
|
|
@@ -1496,6 +2135,19 @@ function normalizeTolerance(tolerance) {
|
|
|
1496
2135
|
}
|
|
1497
2136
|
return tolerance;
|
|
1498
2137
|
}
|
|
2138
|
+
function normalizeTimestamp(timestamp) {
|
|
2139
|
+
if (timestamp === void 0) {
|
|
2140
|
+
return Math.floor(Date.now() / 1e3);
|
|
2141
|
+
}
|
|
2142
|
+
const seconds = timestamp instanceof Date ? timestamp.getTime() / 1e3 : timestamp;
|
|
2143
|
+
if (!Number.isFinite(seconds) || seconds < 0) {
|
|
2144
|
+
throw new Error("Invalid webhook signature timestamp");
|
|
2145
|
+
}
|
|
2146
|
+
return Math.floor(seconds);
|
|
2147
|
+
}
|
|
2148
|
+
function signedPayload(timestamp, payload) {
|
|
2149
|
+
return Buffer.concat([Buffer.from(`${timestamp}.`, "utf8"), payload]);
|
|
2150
|
+
}
|
|
1499
2151
|
function readSignature(signature) {
|
|
1500
2152
|
if (!signatureHexSchema.test(signature)) {
|
|
1501
2153
|
return void 0;
|
|
@@ -1512,9 +2164,42 @@ function assertSecretConfigured(secret) {
|
|
|
1512
2164
|
throw new Error("Webhook signing secret is required");
|
|
1513
2165
|
}
|
|
1514
2166
|
}
|
|
2167
|
+
function assertNonEmpty(value, label) {
|
|
2168
|
+
const normalized = value.trim();
|
|
2169
|
+
if (normalized.length === 0) {
|
|
2170
|
+
throw new Error(`${label} is required`);
|
|
2171
|
+
}
|
|
2172
|
+
return normalized;
|
|
2173
|
+
}
|
|
2174
|
+
function generateWebhookSigningSecret() {
|
|
2175
|
+
return `whsec_${import_crypto2.default.randomBytes(webhookSecretBytes).toString("base64url")}`;
|
|
2176
|
+
}
|
|
2177
|
+
function signWebhookPayload(payload, secret, timestamp) {
|
|
2178
|
+
assertSecretConfigured(secret);
|
|
2179
|
+
const timestampSeconds = normalizeTimestamp(timestamp).toString();
|
|
2180
|
+
const signature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload(timestampSeconds, payloadBuffer(payload))).digest("hex");
|
|
2181
|
+
return `t=${timestampSeconds},v1=${signature}`;
|
|
2182
|
+
}
|
|
2183
|
+
function buildWebhookHeaders(payload, event, secret, options) {
|
|
2184
|
+
const eventId = assertNonEmpty(event.id ?? "", "Webhook event id");
|
|
2185
|
+
const eventType = assertNonEmpty(event.type, "Webhook event type");
|
|
2186
|
+
const webhookId = assertNonEmpty(options.webhookId, "Webhook id");
|
|
2187
|
+
const deliveryId = assertNonEmpty(options.deliveryId, "Webhook delivery id");
|
|
2188
|
+
return {
|
|
2189
|
+
[WEBHOOK_SIGNATURE_HEADER]: signWebhookPayload(
|
|
2190
|
+
payload,
|
|
2191
|
+
secret,
|
|
2192
|
+
options.timestamp
|
|
2193
|
+
),
|
|
2194
|
+
[WEBHOOK_EVENT_ID_HEADER]: eventId,
|
|
2195
|
+
[WEBHOOK_EVENT_TYPE_HEADER]: eventType,
|
|
2196
|
+
[WEBHOOK_ID_HEADER]: webhookId,
|
|
2197
|
+
[WEBHOOK_DELIVERY_ID_HEADER]: deliveryId
|
|
2198
|
+
};
|
|
2199
|
+
}
|
|
1515
2200
|
var RstreamWebhookResource = class {
|
|
1516
2201
|
async event(payload, header, secret, tolerance = 300, receivedAt = Date.now()) {
|
|
1517
|
-
const
|
|
2202
|
+
const rawPayload = payloadBuffer(payload);
|
|
1518
2203
|
const signatureHeader = Array.isArray(header) ? header[0] : header.toString();
|
|
1519
2204
|
if (!signatureHeader) {
|
|
1520
2205
|
throw new Error("No signature header");
|
|
@@ -1534,8 +2219,7 @@ var RstreamWebhookResource = class {
|
|
|
1534
2219
|
`Webhook signature timestamp outside tolerance: ${now}, ${timestampNum}`
|
|
1535
2220
|
);
|
|
1536
2221
|
}
|
|
1537
|
-
const
|
|
1538
|
-
const expectedSignature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload).digest();
|
|
2222
|
+
const expectedSignature = import_crypto2.default.createHmac("sha256", secret).update(signedPayload(timestamp, rawPayload)).digest();
|
|
1539
2223
|
const signatureMatched = signatures.some(
|
|
1540
2224
|
(signature) => signatureMatches(signature, expectedSignature)
|
|
1541
2225
|
);
|
|
@@ -1543,9 +2227,7 @@ var RstreamWebhookResource = class {
|
|
|
1543
2227
|
throw new Error("Signature verification failed");
|
|
1544
2228
|
}
|
|
1545
2229
|
try {
|
|
1546
|
-
return webhookEventsSchema.parse(
|
|
1547
|
-
JSON.parse(payloadBuffer.toString("utf8"))
|
|
1548
|
-
);
|
|
2230
|
+
return webhookEventsSchema.parse(JSON.parse(rawPayload.toString("utf8")));
|
|
1549
2231
|
} catch (error) {
|
|
1550
2232
|
throw new Error(
|
|
1551
2233
|
`Failed to parse webhook payload: ${error instanceof Error ? error.message : String(error)}`,
|
|
@@ -1553,6 +2235,15 @@ var RstreamWebhookResource = class {
|
|
|
1553
2235
|
);
|
|
1554
2236
|
}
|
|
1555
2237
|
}
|
|
2238
|
+
generateSigningSecret() {
|
|
2239
|
+
return generateWebhookSigningSecret();
|
|
2240
|
+
}
|
|
2241
|
+
sign(payload, secret, timestamp) {
|
|
2242
|
+
return signWebhookPayload(payload, secret, timestamp);
|
|
2243
|
+
}
|
|
2244
|
+
headers(payload, event, secret, options) {
|
|
2245
|
+
return buildWebhookHeaders(payload, event, secret, options);
|
|
2246
|
+
}
|
|
1556
2247
|
};
|
|
1557
2248
|
|
|
1558
2249
|
// src/tunnels.ts
|
|
@@ -1671,6 +2362,9 @@ var RstreamTunnelsClient = class {
|
|
|
1671
2362
|
get webhooks() {
|
|
1672
2363
|
return new RstreamWebhookResource();
|
|
1673
2364
|
}
|
|
2365
|
+
get webtty() {
|
|
2366
|
+
return new RstreamWebTTYResource(this);
|
|
2367
|
+
}
|
|
1674
2368
|
get turn() {
|
|
1675
2369
|
return new RstreamTURNResource(this);
|
|
1676
2370
|
}
|
|
@@ -1885,8 +2579,8 @@ var Watch = class {
|
|
|
1885
2579
|
};
|
|
1886
2580
|
|
|
1887
2581
|
// src/webtty.ts
|
|
1888
|
-
var
|
|
1889
|
-
var osFamilySchema =
|
|
2582
|
+
var z9 = __toESM(require("zod"));
|
|
2583
|
+
var osFamilySchema = z9.enum([
|
|
1890
2584
|
"linux",
|
|
1891
2585
|
"macos",
|
|
1892
2586
|
"windows",
|
|
@@ -1894,25 +2588,38 @@ var osFamilySchema = z7.enum([
|
|
|
1894
2588
|
"openbsd",
|
|
1895
2589
|
"freebsd"
|
|
1896
2590
|
]);
|
|
1897
|
-
var webttyCapabilitySchema =
|
|
1898
|
-
var webttyFSModeSchema =
|
|
1899
|
-
var
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
2591
|
+
var webttyCapabilitySchema = z9.enum(["exec", "fs"]);
|
|
2592
|
+
var webttyFSModeSchema = z9.enum(["read-write", "read-only"]);
|
|
2593
|
+
var webttyEncryptionPolicySchema = z9.enum([
|
|
2594
|
+
"disabled",
|
|
2595
|
+
"explicit_key",
|
|
2596
|
+
"workspace_managed"
|
|
2597
|
+
]);
|
|
2598
|
+
var webttyServerSchema = z9.object({
|
|
2599
|
+
tunnel_id: z9.string(),
|
|
2600
|
+
tunnel_protocol: z9.enum(["http", "webtty"]),
|
|
2601
|
+
managed: z9.boolean(),
|
|
2602
|
+
host: z9.string(),
|
|
2603
|
+
token_auth: z9.boolean(),
|
|
2604
|
+
server_id: z9.string().optional(),
|
|
2605
|
+
server_name: z9.string().optional(),
|
|
2606
|
+
host_key_id: z9.string().optional(),
|
|
2607
|
+
e2e: z9.enum(["disabled", "required"]).optional(),
|
|
2608
|
+
client_proof: z9.enum(["none", "required"]).optional(),
|
|
2609
|
+
encryption_policy: webttyEncryptionPolicySchema.optional(),
|
|
2610
|
+
capabilities: z9.array(webttyCapabilitySchema).optional(),
|
|
2611
|
+
exec_path: z9.string().optional(),
|
|
2612
|
+
fs_path: z9.string().optional(),
|
|
1906
2613
|
fs_mode: webttyFSModeSchema.optional(),
|
|
1907
2614
|
os_family: osFamilySchema.optional(),
|
|
1908
|
-
arch:
|
|
1909
|
-
os_id:
|
|
1910
|
-
os_version_id:
|
|
1911
|
-
os_version_codename:
|
|
1912
|
-
os_pretty_name:
|
|
1913
|
-
kernel_release:
|
|
1914
|
-
hostname:
|
|
1915
|
-
labels:
|
|
2615
|
+
arch: z9.string().optional(),
|
|
2616
|
+
os_id: z9.string().optional(),
|
|
2617
|
+
os_version_id: z9.string().optional(),
|
|
2618
|
+
os_version_codename: z9.string().optional(),
|
|
2619
|
+
os_pretty_name: z9.string().optional(),
|
|
2620
|
+
kernel_release: z9.string().optional(),
|
|
2621
|
+
hostname: z9.string().optional(),
|
|
2622
|
+
labels: z9.record(z9.string(), z9.string().optional()).optional()
|
|
1916
2623
|
});
|
|
1917
2624
|
function isWebTTYCapability(value) {
|
|
1918
2625
|
return webttyCapabilitySchema.safeParse(value).success;
|
|
@@ -1933,9 +2640,10 @@ function webTTYHasCapability(capabilities, capability) {
|
|
|
1933
2640
|
function parser(tunnel) {
|
|
1934
2641
|
if (tunnel.status !== "online") return null;
|
|
1935
2642
|
if (tunnel.publish !== true) return null;
|
|
1936
|
-
|
|
2643
|
+
const managedProtocol = tunnel.protocol === "webtty";
|
|
2644
|
+
if (tunnel.protocol !== "http" && !managedProtocol) return null;
|
|
1937
2645
|
const tunnelLabels = tunnel.labels ?? {};
|
|
1938
|
-
if (tunnelLabels["application-protocol"] !== "rstream.webtty") {
|
|
2646
|
+
if (!managedProtocol && tunnelLabels["application-protocol"] !== "rstream.webtty") {
|
|
1939
2647
|
return null;
|
|
1940
2648
|
}
|
|
1941
2649
|
const capabilities = webTTYCapabilitiesForLabels(tunnelLabels);
|
|
@@ -1948,8 +2656,16 @@ function parser(tunnel) {
|
|
|
1948
2656
|
}
|
|
1949
2657
|
const candidate = {
|
|
1950
2658
|
tunnel_id: tunnel.id,
|
|
2659
|
+
tunnel_protocol: tunnel.protocol,
|
|
2660
|
+
managed: managedProtocol,
|
|
1951
2661
|
host: formatTunnelHost(tunnel),
|
|
1952
2662
|
token_auth: tunnel.token_auth === true,
|
|
2663
|
+
server_id: tunnelLabels["rstream.webtty.server_id"],
|
|
2664
|
+
server_name: tunnelLabels["rstream.webtty.server_name"],
|
|
2665
|
+
host_key_id: tunnelLabels["rstream.webtty.host_key_id"],
|
|
2666
|
+
e2e: tunnelLabels["rstream.webtty.e2e"],
|
|
2667
|
+
client_proof: tunnelLabels["rstream.webtty.client_proof"],
|
|
2668
|
+
encryption_policy: tunnelLabels["rstream.webtty.encryption_policy"],
|
|
1953
2669
|
capabilities,
|
|
1954
2670
|
exec_path: webTTYHasCapability(capabilities, "exec") ? tunnelLabels["rstream.webtty.exec.path"] ?? "/" : void 0,
|
|
1955
2671
|
fs_path: webTTYHasCapability(capabilities, "fs") ? tunnelLabels["rstream.webtty.fs.path"] ?? "/fs" : void 0,
|
|
@@ -1982,10 +2698,18 @@ function parseWebTTYServers(tunnels) {
|
|
|
1982
2698
|
RstreamTunnelsClient,
|
|
1983
2699
|
RstreamTunnelsResource,
|
|
1984
2700
|
RstreamTunnelsRessource,
|
|
2701
|
+
RstreamWebTTYResource,
|
|
1985
2702
|
RstreamWebhookResource,
|
|
1986
2703
|
RstreamWebhookRessource,
|
|
1987
2704
|
Tunnels,
|
|
2705
|
+
WEBHOOK_DELIVERY_ID_HEADER,
|
|
2706
|
+
WEBHOOK_EVENT_ID_HEADER,
|
|
2707
|
+
WEBHOOK_EVENT_TYPE_HEADER,
|
|
2708
|
+
WEBHOOK_ID_HEADER,
|
|
2709
|
+
WEBHOOK_SIGNATURE_HEADER,
|
|
1988
2710
|
Watch,
|
|
2711
|
+
attachWebTTYParticipantParamsSchema,
|
|
2712
|
+
buildWebhookHeaders,
|
|
1989
2713
|
clientFilterSchema,
|
|
1990
2714
|
clientSchema,
|
|
1991
2715
|
createAPITURNCredentials,
|
|
@@ -1993,28 +2717,59 @@ function parseWebTTYServers(tunnels) {
|
|
|
1993
2717
|
createAuthTokenFromClientCredentials,
|
|
1994
2718
|
createPATTURNCredentials,
|
|
1995
2719
|
createTURNCredentials,
|
|
2720
|
+
createWebTTYControlRequestParamsSchema,
|
|
2721
|
+
detachWebTTYParticipantParamsSchema,
|
|
1996
2722
|
engineOpenApiDocument,
|
|
1997
2723
|
engineOpenApiJson,
|
|
1998
2724
|
eventSchema,
|
|
2725
|
+
formatStreamAccessPath,
|
|
1999
2726
|
formatTunnelHost,
|
|
2727
|
+
generateWebhookSigningSecret,
|
|
2000
2728
|
listClientsParamsSchema,
|
|
2001
2729
|
listClientsResponseSchema,
|
|
2002
2730
|
listTunnelsParamsSchema,
|
|
2003
2731
|
listTunnelsResponseSchema,
|
|
2732
|
+
listWebTTYControlRequestsParamsSchema,
|
|
2733
|
+
listWebTTYKeyGrantDecryptMaterialParamsSchema,
|
|
2734
|
+
listWebTTYSessionGroupsParamsSchema,
|
|
2735
|
+
listWebTTYSessionsParamsSchema,
|
|
2004
2736
|
normalizeEngineAddress,
|
|
2005
2737
|
parseWebTTYServers,
|
|
2006
2738
|
projectLogEventsSchema,
|
|
2739
|
+
readWebTTYSessionEventsParamsSchema,
|
|
2007
2740
|
resolveControlPlaneCredentials,
|
|
2008
2741
|
resolveManagedTunnelsProject,
|
|
2009
2742
|
resolveTunnelsAPIURL,
|
|
2010
2743
|
resolveTunnelsCredentials,
|
|
2011
2744
|
resolveTunnelsEngine,
|
|
2745
|
+
resolveWebTTYControlRequestParamsSchema,
|
|
2746
|
+
signWebhookPayload,
|
|
2012
2747
|
streamEndpointSchema,
|
|
2748
|
+
streamEntrySchema,
|
|
2013
2749
|
streamSummaryEventSchema,
|
|
2014
2750
|
streamSummarySchema,
|
|
2015
2751
|
streamTLSInfoSchema,
|
|
2752
|
+
streamWebTTYMetadataSchema,
|
|
2016
2753
|
tunnelFilterSchema,
|
|
2017
2754
|
turnCredentialModeSchema,
|
|
2755
|
+
webTTYCapabilitiesSchema,
|
|
2756
|
+
webTTYContextMetadataSchema,
|
|
2757
|
+
webTTYControlRequestSchema,
|
|
2758
|
+
webTTYCryptoMetadataSchema,
|
|
2759
|
+
webTTYEncryptionModeSchema,
|
|
2760
|
+
webTTYKeyGrantDecryptMaterialSchema,
|
|
2761
|
+
webTTYKeyGrantSchema,
|
|
2762
|
+
webTTYOriginSchema,
|
|
2763
|
+
webTTYParticipantLiveSchema,
|
|
2764
|
+
webTTYParticipantRoleSchema,
|
|
2765
|
+
webTTYParticipantSchema,
|
|
2766
|
+
webTTYRecordingModeSchema,
|
|
2767
|
+
webTTYSessionEventSchema,
|
|
2768
|
+
webTTYSessionGroupSchema,
|
|
2769
|
+
webTTYSessionLiveSchema,
|
|
2770
|
+
webTTYSessionModeSchema,
|
|
2771
|
+
webTTYSessionSchema,
|
|
2772
|
+
webTTYTransportSchema,
|
|
2018
2773
|
webhookEventsSchema,
|
|
2019
2774
|
webttyServerSchema,
|
|
2020
2775
|
wsEventsSchema
|