@moqtap/codec 0.9.0 → 0.11.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/CHANGELOG.md +173 -0
- package/dist/auth-redaction-DsdLq4Qs.d.cts +102 -0
- package/dist/auth-redaction-DsdLq4Qs.d.ts +102 -0
- package/dist/{chunk-PU2KV7VP.cjs → chunk-27K5BUAG.cjs} +485 -515
- package/dist/{chunk-BV6MITLO.js → chunk-3RNQMGKA.js} +365 -390
- package/dist/{chunk-2XH6PHXR.js → chunk-5AWIXOLB.js} +442 -467
- package/dist/{chunk-4XLYCT5Q.cjs → chunk-5IMHJIAZ.cjs} +52 -2
- package/dist/{chunk-TVSFDQYE.cjs → chunk-5JGZCKJO.cjs} +513 -531
- package/dist/{chunk-IADVBKEJ.cjs → chunk-73K4OSAN.cjs} +407 -432
- package/dist/{chunk-N2V7Z37J.js → chunk-7VQKRGRD.js} +19 -3
- package/dist/{chunk-UZO5Z2XT.cjs → chunk-A3UCQOIB.cjs} +490 -515
- package/dist/{chunk-JKMYAUGY.js → chunk-A7PDMVXM.js} +35 -11
- package/dist/{chunk-VZHL2U2N.cjs → chunk-A7VQO6YC.cjs} +54 -38
- package/dist/{chunk-KCH4BQXK.cjs → chunk-ACQHZLRZ.cjs} +73 -47
- package/dist/{chunk-H6DTAIWM.js → chunk-BBICOMW6.js} +47 -19
- package/dist/{chunk-MAXEHYVB.cjs → chunk-BNIUVOCJ.cjs} +554 -612
- package/dist/{chunk-QGIHC6BA.cjs → chunk-CNC6ANS4.cjs} +70 -46
- package/dist/{chunk-NH4L6NIY.js → chunk-FDLQSWHK.js} +437 -467
- package/dist/{chunk-IJAF6PAY.js → chunk-FFNOE4UR.js} +19 -3
- package/dist/{chunk-CZNW3R5E.cjs → chunk-GMENT63T.cjs} +54 -38
- package/dist/{chunk-7ENEWAMZ.cjs → chunk-HM7BLRVP.cjs} +305 -305
- package/dist/{chunk-XHAP2YST.js → chunk-HZONHFNO.js} +19 -3
- package/dist/{chunk-EVCPBFSR.cjs → chunk-ILYABWDK.cjs} +83 -55
- package/dist/{chunk-IDV2JYJ6.cjs → chunk-KRSFTZVO.cjs} +56 -40
- package/dist/{chunk-RIIA4ALQ.cjs → chunk-KSPH6KMH.cjs} +54 -38
- package/dist/{chunk-UA5XFP4O.cjs → chunk-KTY4LAUV.cjs} +485 -494
- package/dist/{chunk-RZTLQAKF.js → chunk-OJNLJT5D.js} +0 -1
- package/dist/{chunk-YJGOD3Y4.js → chunk-PJK2ZS3I.js} +492 -550
- package/dist/{chunk-TMXRYOBS.js → chunk-PSMZKHOC.js} +444 -453
- package/dist/{chunk-7RE6KSIY.cjs → chunk-Q5JQGHWY.cjs} +0 -1
- package/dist/{chunk-23KRITJ6.js → chunk-SQTUQY5E.js} +37 -11
- package/dist/{chunk-XQGEOFGE.js → chunk-WCRLAKDW.js} +253 -253
- package/dist/{chunk-KYVTM5VI.js → chunk-WL2YUEXH.js} +19 -3
- package/dist/{chunk-Q7NSUXXB.js → chunk-YCNIVZS7.js} +464 -482
- package/dist/{chunk-KLPWJU6W.js → chunk-YRZQVNZO.js} +50 -0
- package/dist/{codec-Bym-K2q2.d.cts → codec-76xzrLTL.d.cts} +21 -2
- package/dist/{codec-BKsVu3Fr.d.ts → codec-8p40WdLg.d.ts} +21 -2
- package/dist/{codec-Dl_QIXMz.d.ts → codec-BN2Bu0KI.d.ts} +20 -1
- package/dist/{codec-D4RvFQmu.d.ts → codec-Bb6GKTrv.d.ts} +21 -2
- package/dist/{codec-DAyiF5sq.d.cts → codec-BgpfHoAd.d.cts} +21 -2
- package/dist/{codec-CA6nbbEk.d.ts → codec-BkheTXO7.d.ts} +21 -2
- package/dist/{codec-DchsPfr3.d.cts → codec-BwVDkokh.d.cts} +21 -2
- package/dist/{codec-CgZdadPt.d.cts → codec-C5s1eBJX.d.cts} +21 -2
- package/dist/codec-CM5yd6n3.d.ts +38 -0
- package/dist/{codec-DJmqoIsp.d.cts → codec-Cb8HC3XV.d.cts} +21 -2
- package/dist/codec-Clu_skx8.d.cts +38 -0
- package/dist/{codec-DzkdW4kO.d.cts → codec-CpOpemR8.d.cts} +20 -1
- package/dist/{codec-CXCjya_G.d.cts → codec-Cshdl9Tt.d.cts} +20 -1
- package/dist/{codec-CSBFdPgP.d.cts → codec-DELe00w_.d.cts} +21 -2
- package/dist/{codec-C_xxsbKy.d.cts → codec-DHzKAUCa.d.cts} +21 -2
- package/dist/{codec--CVeqGQv.d.ts → codec-DdVBtvx7.d.ts} +20 -1
- package/dist/{codec-CviAa4lp.d.ts → codec-DlxGuYMv.d.ts} +21 -2
- package/dist/{codec-BNy5syCU.d.ts → codec-DxtgPxJS.d.ts} +20 -1
- package/dist/{codec-CtvFK4aV.d.cts → codec-GAY4lybi.d.cts} +21 -2
- package/dist/{codec-Cfo_z5ET.d.cts → codec-I8u2pfS4.d.cts} +20 -1
- package/dist/{codec-vddqy0KY.d.cts → codec-XLrnreeu.d.cts} +21 -2
- package/dist/{codec-O-1Js7h4.d.ts → codec-c0YEwwWn.d.ts} +21 -2
- package/dist/{codec-Cl73EfRW.d.ts → codec-ejDu-va6.d.ts} +21 -2
- package/dist/{codec-C006F75E.d.ts → codec-kaBUzdpV.d.ts} +21 -2
- package/dist/{codec-C5evFHL-.d.ts → codec-mVYqkIUF.d.ts} +21 -2
- package/dist/{codec-BMwgZIgG.d.ts → codec-qSbO5nOa.d.ts} +21 -2
- package/dist/{codec-BQa6Qsav.d.ts → codec-yYKGOipj.d.ts} +21 -2
- package/dist/{codec-DzLvG8Wb.d.cts → codec-zfzg9uiy.d.cts} +21 -2
- package/dist/draft07.cjs +48 -4
- package/dist/draft07.d.cts +42 -2
- package/dist/draft07.d.ts +42 -2
- package/dist/draft07.js +49 -5
- package/dist/draft08.cjs +76 -3
- package/dist/draft08.d.cts +70 -2
- package/dist/draft08.d.ts +70 -2
- package/dist/draft08.js +77 -4
- package/dist/draft09.cjs +76 -3
- package/dist/draft09.d.cts +70 -2
- package/dist/draft09.d.ts +70 -2
- package/dist/draft09.js +77 -4
- package/dist/draft10.cjs +76 -3
- package/dist/draft10.d.cts +70 -2
- package/dist/draft10.d.ts +70 -2
- package/dist/draft10.js +77 -4
- package/dist/draft11-session.d.cts +1 -1
- package/dist/draft11-session.d.ts +1 -1
- package/dist/draft11.cjs +104 -3
- package/dist/draft11.d.cts +100 -4
- package/dist/draft11.d.ts +100 -4
- package/dist/draft11.js +105 -4
- package/dist/draft12-session.d.cts +1 -1
- package/dist/draft12-session.d.ts +1 -1
- package/dist/draft12.cjs +113 -3
- package/dist/draft12.d.cts +109 -4
- package/dist/draft12.d.ts +109 -4
- package/dist/draft12.js +114 -4
- package/dist/draft13-session.d.cts +1 -1
- package/dist/draft13-session.d.ts +1 -1
- package/dist/draft13.cjs +105 -3
- package/dist/draft13.d.cts +101 -4
- package/dist/draft13.d.ts +101 -4
- package/dist/draft13.js +106 -4
- package/dist/draft14-session.d.cts +1 -1
- package/dist/draft14-session.d.ts +1 -1
- package/dist/draft14.cjs +107 -3
- package/dist/draft14.d.cts +103 -30
- package/dist/draft14.d.ts +103 -30
- package/dist/draft14.js +108 -4
- package/dist/draft15-session.d.cts +1 -1
- package/dist/draft15-session.d.ts +1 -1
- package/dist/draft15.cjs +69 -3
- package/dist/draft15.d.cts +65 -22
- package/dist/draft15.d.ts +65 -22
- package/dist/draft15.js +70 -4
- package/dist/draft16-session.cjs +2 -2
- package/dist/draft16-session.d.cts +1 -1
- package/dist/draft16-session.d.ts +1 -1
- package/dist/draft16-session.js +1 -1
- package/dist/draft16.cjs +76 -8
- package/dist/draft16.d.cts +67 -13
- package/dist/draft16.d.ts +67 -13
- package/dist/draft16.js +73 -5
- package/dist/draft17-session.d.cts +1 -1
- package/dist/draft17-session.d.ts +1 -1
- package/dist/draft17.cjs +77 -3
- package/dist/draft17.d.cts +73 -4
- package/dist/draft17.d.ts +73 -4
- package/dist/draft17.js +78 -4
- package/dist/draft18-session.d.cts +1 -1
- package/dist/draft18-session.d.ts +1 -1
- package/dist/draft18.cjs +8 -3
- package/dist/draft18.d.cts +4 -3
- package/dist/draft18.d.ts +4 -3
- package/dist/draft18.js +9 -4
- package/dist/draft19-session.d.cts +1 -1
- package/dist/draft19-session.d.ts +1 -1
- package/dist/draft19.cjs +11 -4
- package/dist/draft19.d.cts +4 -3
- package/dist/draft19.d.ts +4 -3
- package/dist/draft19.js +12 -5
- package/dist/draft20-session.d.cts +1 -1
- package/dist/draft20-session.d.ts +1 -1
- package/dist/draft20.cjs +8 -3
- package/dist/draft20.d.cts +4 -3
- package/dist/draft20.d.ts +4 -3
- package/dist/draft20.js +9 -4
- package/dist/index.cjs +30 -30
- package/dist/index.d.cts +25 -24
- package/dist/index.d.ts +25 -24
- package/dist/index.js +15 -15
- package/dist/session.cjs +2 -2
- package/dist/session.d.cts +10 -10
- package/dist/session.d.ts +10 -10
- package/dist/session.js +1 -1
- package/dist/{types-zHgCS6o5.d.cts → types-Btp416jt.d.cts} +15 -7
- package/dist/{types-zHgCS6o5.d.ts → types-Btp416jt.d.ts} +15 -7
- package/dist/{types-Cm9fjeYC.d.cts → types-BxTL1NXw.d.cts} +9 -2
- package/dist/{types-Cm9fjeYC.d.ts → types-BxTL1NXw.d.ts} +9 -2
- package/dist/{types-Bio-91Rt.d.cts → types-CI_SX4Xe.d.cts} +2 -2
- package/dist/{types-Bio-91Rt.d.ts → types-CI_SX4Xe.d.ts} +2 -2
- package/dist/{types-HI_bbXka.d.cts → types-CmqT0jUf.d.cts} +1 -1
- package/dist/{types-HI_bbXka.d.ts → types-CmqT0jUf.d.ts} +1 -1
- package/dist/{types-CPaYBsMG.d.cts → types-CuibHYcf.d.cts} +9 -2
- package/dist/{types-CPaYBsMG.d.ts → types-CuibHYcf.d.ts} +9 -2
- package/dist/{types-CWCQwuvy.d.cts → types-CwN7AEoL.d.cts} +24 -12
- package/dist/{types-CWCQwuvy.d.ts → types-CwN7AEoL.d.ts} +24 -12
- package/dist/{types-Ck45Ex5S.d.cts → types-D0kTgUuL.d.cts} +1 -1
- package/dist/{types-Ck45Ex5S.d.ts → types-D0kTgUuL.d.ts} +1 -1
- package/dist/{types-D9eiB_9A.d.cts → types-DAnalt5K.d.cts} +9 -2
- package/dist/{types-D9eiB_9A.d.ts → types-DAnalt5K.d.ts} +9 -2
- package/dist/{types-CXlSn0I9.d.cts → types-DjxexghA.d.cts} +2 -2
- package/dist/{types-CXlSn0I9.d.ts → types-DjxexghA.d.ts} +2 -2
- package/dist/{types-Cqp10JtB.d.cts → types-DxXNP32l.d.cts} +10 -2
- package/dist/{types-Cqp10JtB.d.ts → types-DxXNP32l.d.ts} +10 -2
- package/package.json +3 -3
- package/src/core/auth-redaction.ts +192 -0
- package/src/drafts/draft07/codec.ts +40 -0
- package/src/drafts/draft07/error-codes.ts +44 -0
- package/src/drafts/draft07/index.ts +15 -0
- package/src/drafts/draft08/codec.ts +40 -0
- package/src/drafts/draft08/error-codes.ts +76 -0
- package/src/drafts/draft08/index.ts +21 -0
- package/src/drafts/draft09/codec.ts +40 -0
- package/src/drafts/draft09/error-codes.ts +76 -0
- package/src/drafts/draft09/index.ts +21 -0
- package/src/drafts/draft10/codec.ts +40 -0
- package/src/drafts/draft10/error-codes.ts +76 -0
- package/src/drafts/draft10/index.ts +21 -0
- package/src/drafts/draft11/codec.ts +71 -8
- package/src/drafts/draft11/error-codes.ts +106 -0
- package/src/drafts/draft11/index.ts +23 -0
- package/src/drafts/draft11/types.ts +1 -1
- package/src/drafts/draft12/codec.ts +83 -16
- package/src/drafts/draft12/error-codes.ts +116 -0
- package/src/drafts/draft12/index.ts +25 -0
- package/src/drafts/draft12/types.ts +2 -2
- package/src/drafts/draft13/codec.ts +75 -11
- package/src/drafts/draft13/error-codes.ts +107 -0
- package/src/drafts/draft13/index.ts +23 -0
- package/src/drafts/draft13/types.ts +3 -3
- package/src/drafts/draft14/codec.ts +79 -12
- package/src/drafts/draft14/data-streams.ts +331 -259
- package/src/drafts/draft14/error-codes.ts +109 -0
- package/src/drafts/draft14/index.ts +23 -0
- package/src/drafts/draft14/types.ts +1 -1
- package/src/drafts/draft15/codec.ts +71 -8
- package/src/drafts/draft15/data-streams.ts +489 -444
- package/src/drafts/draft15/error-codes.ts +66 -0
- package/src/drafts/draft15/index.ts +15 -0
- package/src/drafts/draft15/types.ts +9 -2
- package/src/drafts/draft16/codec.ts +149 -49
- package/src/drafts/draft16/data-streams.ts +513 -442
- package/src/drafts/draft16/error-codes.ts +68 -0
- package/src/drafts/draft16/index.ts +15 -0
- package/src/drafts/draft16/messages.ts +4 -4
- package/src/drafts/draft16/session-fsm.ts +0 -1
- package/src/drafts/draft16/types.ts +24 -10
- package/src/drafts/draft17/codec.ts +77 -10
- package/src/drafts/draft17/data-streams.ts +567 -488
- package/src/drafts/draft17/index.ts +15 -0
- package/src/drafts/draft17/types.ts +9 -2
- package/src/drafts/draft18/codec.ts +70 -7
- package/src/drafts/draft18/data-streams.ts +570 -482
- package/src/drafts/draft18/index.ts +3 -0
- package/src/drafts/draft18/types.ts +18 -10
- package/src/drafts/draft19/codec.ts +95 -23
- package/src/drafts/draft19/data-streams.ts +570 -482
- package/src/drafts/draft19/error-codes.ts +3 -1
- package/src/drafts/draft19/index.ts +3 -0
- package/src/drafts/draft19/messages.ts +3 -1
- package/src/drafts/draft19/types.ts +32 -18
- package/src/drafts/draft20/codec.ts +115 -36
- package/src/drafts/draft20/data-streams.ts +610 -563
- package/src/drafts/draft20/index.ts +3 -0
- package/src/drafts/draft20/types.ts +31 -13
- package/dist/codec-BJ7BHuiZ.d.ts +0 -18
- package/dist/codec-C6Mx4bwz.d.cts +0 -18
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AuthRedaction, recordAuthValueSpan, redactWith } from '../../core/auth-redaction.js'
|
|
1
2
|
import { BufferReader } from '../../core/buffer-reader.js'
|
|
2
3
|
import { BufferWriter } from '../../core/buffer-writer.js'
|
|
3
4
|
import { bytesToHex, hexToBytes } from '../../core/hex.js'
|
|
@@ -115,7 +116,7 @@ function encodeSetupParams(params: Draft13SetupParams, w: BufferWriter): void {
|
|
|
115
116
|
let count = 0
|
|
116
117
|
if (params.path !== undefined) count++
|
|
117
118
|
if (params.max_request_id !== undefined) count++
|
|
118
|
-
|
|
119
|
+
count += params.authorization_token?.length ?? 0
|
|
119
120
|
if (params.max_auth_token_cache_size !== undefined) count++
|
|
120
121
|
if (params.unknown) count += params.unknown.length
|
|
121
122
|
|
|
@@ -131,9 +132,9 @@ function encodeSetupParams(params: Draft13SetupParams, w: BufferWriter): void {
|
|
|
131
132
|
w.writeVarInt(SETUP_PARAM_MAX_REQUEST_ID)
|
|
132
133
|
w.writeVarInt(params.max_request_id)
|
|
133
134
|
}
|
|
134
|
-
|
|
135
|
+
for (const token of params.authorization_token ?? []) {
|
|
135
136
|
w.writeVarInt(SETUP_PARAM_AUTHORIZATION_TOKEN)
|
|
136
|
-
encodeAuthorizationToken(
|
|
137
|
+
encodeAuthorizationToken(token, w)
|
|
137
138
|
}
|
|
138
139
|
if (params.max_auth_token_cache_size !== undefined) {
|
|
139
140
|
w.writeVarInt(SETUP_PARAM_MAX_AUTH_TOKEN_CACHE_SIZE)
|
|
@@ -185,7 +186,10 @@ function decodeSetupParams(r: BufferReader): Draft13SetupParams {
|
|
|
185
186
|
const bytes = r.readBytes(length)
|
|
186
187
|
result.path = textDecoder.decode(bytes)
|
|
187
188
|
} else if (paramType === SETUP_PARAM_AUTHORIZATION_TOKEN) {
|
|
188
|
-
|
|
189
|
+
const valueStart = r.offset
|
|
190
|
+
const token = decodeAuthorizationToken(r, length)
|
|
191
|
+
noteAuthTokenValue(valueStart, length, token.token_value)
|
|
192
|
+
result.authorization_token = [...(result.authorization_token ?? []), token]
|
|
189
193
|
} else {
|
|
190
194
|
const bytes = r.readBytes(length)
|
|
191
195
|
unknown.push({
|
|
@@ -207,7 +211,7 @@ function decodeSetupParams(r: BufferReader): Draft13SetupParams {
|
|
|
207
211
|
function encodeParams(params: Draft13Params, w: BufferWriter): void {
|
|
208
212
|
let count = params.unknown ? params.unknown.length : 0
|
|
209
213
|
if (params.delivery_timeout !== undefined) count++
|
|
210
|
-
|
|
214
|
+
count += params.authorization_token?.length ?? 0
|
|
211
215
|
if (params.max_cache_duration !== undefined) count++
|
|
212
216
|
w.writeVarInt(count)
|
|
213
217
|
|
|
@@ -216,10 +220,10 @@ function encodeParams(params: Draft13Params, w: BufferWriter): void {
|
|
|
216
220
|
w.writeVarInt(PARAM_DELIVERY_TIMEOUT)
|
|
217
221
|
w.writeVarInt(params.delivery_timeout)
|
|
218
222
|
}
|
|
219
|
-
|
|
223
|
+
for (const token of params.authorization_token ?? []) {
|
|
220
224
|
// AUTHORIZATION_TOKEN = 0x03 (odd → length-prefixed)
|
|
221
225
|
w.writeVarInt(PARAM_AUTHORIZATION_TOKEN)
|
|
222
|
-
encodeAuthorizationToken(
|
|
226
|
+
encodeAuthorizationToken(token, w)
|
|
223
227
|
}
|
|
224
228
|
if (params.max_cache_duration !== undefined) {
|
|
225
229
|
// MAX_CACHE_DURATION = 0x04 (even → bare varint)
|
|
@@ -275,7 +279,10 @@ function decodeParams(r: BufferReader): Draft13Params {
|
|
|
275
279
|
const length = Number(r.readVarInt())
|
|
276
280
|
|
|
277
281
|
if (paramType === PARAM_AUTHORIZATION_TOKEN) {
|
|
278
|
-
|
|
282
|
+
const valueStart = r.offset
|
|
283
|
+
const token = decodeAuthorizationToken(r, length)
|
|
284
|
+
noteAuthTokenValue(valueStart, length, token.token_value)
|
|
285
|
+
result.authorization_token = [...(result.authorization_token ?? []), token]
|
|
279
286
|
} else {
|
|
280
287
|
const bytes = r.readBytes(length)
|
|
281
288
|
unknown.push({
|
|
@@ -425,7 +432,7 @@ function encodeAnnounceCancelPayload(
|
|
|
425
432
|
w.writeString(msg.reason_phrase)
|
|
426
433
|
}
|
|
427
434
|
|
|
428
|
-
// Draft-13
|
|
435
|
+
// Draft-13 subscribe_namespace (0x11) — byte-identical to the payload draft-12 spells subscribe_announces.
|
|
429
436
|
function encodeSubscribeNamespacePayload(
|
|
430
437
|
msg: Draft13Message & { type: 'subscribe_namespace' },
|
|
431
438
|
w: BufferWriter,
|
|
@@ -547,7 +554,7 @@ function encodeFetchCancelPayload(
|
|
|
547
554
|
w.writeVarInt(msg.request_id)
|
|
548
555
|
}
|
|
549
556
|
|
|
550
|
-
// Draft-13:
|
|
557
|
+
// Draft-13 Section 8.20: the TRACK_STATUS message format is identical to SUBSCRIBE.
|
|
551
558
|
function encodeTrackStatusPayload(
|
|
552
559
|
msg: Draft13Message & { type: 'track_status' },
|
|
553
560
|
w: BufferWriter,
|
|
@@ -777,7 +784,6 @@ function decodeAnnounceCancelPayload(r: BufferReader): Draft13Message {
|
|
|
777
784
|
return { type: 'announce_cancel', track_namespace, error_code, reason_phrase }
|
|
778
785
|
}
|
|
779
786
|
|
|
780
|
-
// Draft-13: subscribe_namespace (renamed from subscribe_announces)
|
|
781
787
|
function decodeSubscribeNamespacePayload(r: BufferReader): Draft13Message {
|
|
782
788
|
const request_id = r.readVarInt()
|
|
783
789
|
const track_namespace_prefix = r.readTuple()
|
|
@@ -1293,3 +1299,61 @@ export function createDraft13Codec(): Draft13Codec {
|
|
|
1293
1299
|
createStreamDecoder,
|
|
1294
1300
|
}
|
|
1295
1301
|
}
|
|
1302
|
+
|
|
1303
|
+
/**
|
|
1304
|
+
* Record where a Token Value sits, so it can be overwritten before the frame
|
|
1305
|
+
* reaches anything that keeps it.
|
|
1306
|
+
*
|
|
1307
|
+
* The span falls out of the decode with no second walk. The Token Value is the
|
|
1308
|
+
* last field of the Token structure, so its start is the parameter value's end
|
|
1309
|
+
* minus the value's own length. The fields before it are left alone
|
|
1310
|
+
* deliberately: Alias Type, Token Alias and Token Type are structure rather
|
|
1311
|
+
* than secret, and they are what distinguishes a session that failed to
|
|
1312
|
+
* authenticate from one that never tried.
|
|
1313
|
+
*
|
|
1314
|
+
* A token carrying no value at all -- DELETE and USE_ALIAS -- records nothing,
|
|
1315
|
+
* and its frame passes through untouched.
|
|
1316
|
+
*/
|
|
1317
|
+
function noteAuthTokenValue(
|
|
1318
|
+
valueStart: number,
|
|
1319
|
+
valueLength: number,
|
|
1320
|
+
value: Uint8Array | undefined,
|
|
1321
|
+
): void {
|
|
1322
|
+
if (value === undefined || value.byteLength === 0) return
|
|
1323
|
+
recordAuthValueSpan(valueStart + valueLength - value.byteLength, value.byteLength)
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
/**
|
|
1327
|
+
* Overwrite every Authorization Token value in a draft-13 control frame.
|
|
1328
|
+
*
|
|
1329
|
+
* One decode, whose *output is discarded*: the point is not to read the
|
|
1330
|
+
* message, it is to learn where the credentials were so the caller never has to
|
|
1331
|
+
* hold a frame that contains one. A caller that also wants the message should
|
|
1332
|
+
* decode the **redacted** frame with {@link decodeMessage}, which then cannot
|
|
1333
|
+
* produce a value because there is no longer one in the bytes.
|
|
1334
|
+
*
|
|
1335
|
+
* A frame that fails to decode is still redacted as far as the decode got. That
|
|
1336
|
+
* is the useful direction to fail in: a value that was read is a value that was
|
|
1337
|
+
* exposed, whatever went wrong after it.
|
|
1338
|
+
*
|
|
1339
|
+
* See {@link AuthRedaction.incomplete} for the one result a caller must not
|
|
1340
|
+
* treat as clean, and {@link AuthRedaction.decoded} for the residual it cannot
|
|
1341
|
+
* close.
|
|
1342
|
+
*/
|
|
1343
|
+
export function redactAuthTokens(bytes: Uint8Array): AuthRedaction {
|
|
1344
|
+
let payloadStart: number
|
|
1345
|
+
try {
|
|
1346
|
+
const probe = new BufferReader(bytes)
|
|
1347
|
+
probe.readVarInt()
|
|
1348
|
+
probe.readUint8()
|
|
1349
|
+
probe.readUint8()
|
|
1350
|
+
payloadStart = probe.offset
|
|
1351
|
+
} catch {
|
|
1352
|
+
// Too short to carry a message header, and so too short for the parameters
|
|
1353
|
+
// that carry a credential. Reported as not decoded rather than as clean: a
|
|
1354
|
+
// framer only ever emits complete frames, so a caller that gets here is
|
|
1355
|
+
// holding something this function did not check.
|
|
1356
|
+
return { bytes, redacted: 0, incomplete: false, decoded: false }
|
|
1357
|
+
}
|
|
1358
|
+
return redactWith(bytes, payloadStart, () => decodeMessage(bytes).ok)
|
|
1359
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Draft-13 error, status and termination code registries.
|
|
2
|
+
|
|
3
|
+
export const SessionErrorCode = {
|
|
4
|
+
NoError: 0x0n,
|
|
5
|
+
InternalError: 0x1n,
|
|
6
|
+
Unauthorized: 0x2n,
|
|
7
|
+
ProtocolViolation: 0x3n,
|
|
8
|
+
InvalidRequestId: 0x4n,
|
|
9
|
+
DuplicateTrackAlias: 0x5n,
|
|
10
|
+
KeyValueFormattingError: 0x6n,
|
|
11
|
+
TooManyRequests: 0x7n,
|
|
12
|
+
InvalidPath: 0x8n,
|
|
13
|
+
MalformedPath: 0x9n,
|
|
14
|
+
GoawayTimeout: 0x10n,
|
|
15
|
+
ControlMessageTimeout: 0x11n,
|
|
16
|
+
DataStreamTimeout: 0x12n,
|
|
17
|
+
AuthTokenCacheOverflow: 0x13n,
|
|
18
|
+
DuplicateAuthTokenAlias: 0x14n,
|
|
19
|
+
VersionNegotiationFailed: 0x15n,
|
|
20
|
+
MalformedAuthToken: 0x16n,
|
|
21
|
+
UnknownAuthTokenAlias: 0x17n,
|
|
22
|
+
ExpiredAuthToken: 0x18n,
|
|
23
|
+
} as const
|
|
24
|
+
export type SessionErrorCodeValue = (typeof SessionErrorCode)[keyof typeof SessionErrorCode]
|
|
25
|
+
|
|
26
|
+
export const SubscribeErrorCode = {
|
|
27
|
+
InternalError: 0x0n,
|
|
28
|
+
Unauthorized: 0x1n,
|
|
29
|
+
Timeout: 0x2n,
|
|
30
|
+
NotSupported: 0x3n,
|
|
31
|
+
TrackDoesNotExist: 0x4n,
|
|
32
|
+
InvalidRange: 0x5n,
|
|
33
|
+
MalformedAuthToken: 0x10n,
|
|
34
|
+
ExpiredAuthToken: 0x12n,
|
|
35
|
+
} as const
|
|
36
|
+
export type SubscribeErrorCodeValue = (typeof SubscribeErrorCode)[keyof typeof SubscribeErrorCode]
|
|
37
|
+
|
|
38
|
+
export const SubscribeDoneStatusCode = {
|
|
39
|
+
InternalError: 0x0n,
|
|
40
|
+
Unauthorized: 0x1n,
|
|
41
|
+
TrackEnded: 0x2n,
|
|
42
|
+
SubscriptionEnded: 0x3n,
|
|
43
|
+
GoingAway: 0x4n,
|
|
44
|
+
Expired: 0x5n,
|
|
45
|
+
TooFarBehind: 0x6n,
|
|
46
|
+
MalformedTrack: 0x7n,
|
|
47
|
+
} as const
|
|
48
|
+
export type SubscribeDoneStatusCodeValue =
|
|
49
|
+
(typeof SubscribeDoneStatusCode)[keyof typeof SubscribeDoneStatusCode]
|
|
50
|
+
|
|
51
|
+
export const PublishErrorCode = {
|
|
52
|
+
InternalError: 0x0n,
|
|
53
|
+
Unauthorized: 0x1n,
|
|
54
|
+
Timeout: 0x2n,
|
|
55
|
+
NotSupported: 0x3n,
|
|
56
|
+
Uninterested: 0x4n,
|
|
57
|
+
} as const
|
|
58
|
+
export type PublishErrorCodeValue = (typeof PublishErrorCode)[keyof typeof PublishErrorCode]
|
|
59
|
+
|
|
60
|
+
export const FetchErrorCode = {
|
|
61
|
+
InternalError: 0x0n,
|
|
62
|
+
Unauthorized: 0x1n,
|
|
63
|
+
Timeout: 0x2n,
|
|
64
|
+
NotSupported: 0x3n,
|
|
65
|
+
TrackDoesNotExist: 0x4n,
|
|
66
|
+
InvalidRange: 0x5n,
|
|
67
|
+
NoObjects: 0x6n,
|
|
68
|
+
InvalidJoiningRequestId: 0x7n,
|
|
69
|
+
UnknownStatusInRange: 0x8n,
|
|
70
|
+
MalformedTrack: 0x9n,
|
|
71
|
+
MalformedAuthToken: 0x10n,
|
|
72
|
+
ExpiredAuthToken: 0x12n,
|
|
73
|
+
} as const
|
|
74
|
+
export type FetchErrorCodeValue = (typeof FetchErrorCode)[keyof typeof FetchErrorCode]
|
|
75
|
+
|
|
76
|
+
export const AnnounceErrorCode = {
|
|
77
|
+
InternalError: 0x0n,
|
|
78
|
+
Unauthorized: 0x1n,
|
|
79
|
+
Timeout: 0x2n,
|
|
80
|
+
NotSupported: 0x3n,
|
|
81
|
+
Uninterested: 0x4n,
|
|
82
|
+
MalformedAuthToken: 0x10n,
|
|
83
|
+
ExpiredAuthToken: 0x12n,
|
|
84
|
+
} as const
|
|
85
|
+
export type AnnounceErrorCodeValue = (typeof AnnounceErrorCode)[keyof typeof AnnounceErrorCode]
|
|
86
|
+
|
|
87
|
+
export const SubscribeNamespaceErrorCode = {
|
|
88
|
+
InternalError: 0x0n,
|
|
89
|
+
Unauthorized: 0x1n,
|
|
90
|
+
Timeout: 0x2n,
|
|
91
|
+
NotSupported: 0x3n,
|
|
92
|
+
NamespacePrefixUnknown: 0x4n,
|
|
93
|
+
NamespacePrefixOverlap: 0x5n,
|
|
94
|
+
MalformedAuthToken: 0x10n,
|
|
95
|
+
ExpiredAuthToken: 0x12n,
|
|
96
|
+
} as const
|
|
97
|
+
export type SubscribeNamespaceErrorCodeValue =
|
|
98
|
+
(typeof SubscribeNamespaceErrorCode)[keyof typeof SubscribeNamespaceErrorCode]
|
|
99
|
+
|
|
100
|
+
export const StreamResetErrorCode = {
|
|
101
|
+
InternalError: 0x0n,
|
|
102
|
+
Cancelled: 0x1n,
|
|
103
|
+
DeliveryTimeout: 0x2n,
|
|
104
|
+
SessionClosed: 0x3n,
|
|
105
|
+
} as const
|
|
106
|
+
export type StreamResetErrorCodeValue =
|
|
107
|
+
(typeof StreamResetErrorCode)[keyof typeof StreamResetErrorCode]
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export const DRAFT_VERSION = 0xff00000dn
|
|
2
2
|
|
|
3
|
+
export type { AuthRedaction } from '../../core/auth-redaction.js'
|
|
4
|
+
export { REDACTION_FILL } from '../../core/auth-redaction.js'
|
|
3
5
|
export type { Draft13Codec } from './codec.js'
|
|
4
6
|
export {
|
|
5
7
|
createDraft13Codec,
|
|
@@ -13,7 +15,28 @@ export {
|
|
|
13
15
|
encodeFetchStream,
|
|
14
16
|
encodeMessage,
|
|
15
17
|
encodeSubgroupStream,
|
|
18
|
+
redactAuthTokens,
|
|
16
19
|
} from './codec.js'
|
|
20
|
+
export type {
|
|
21
|
+
AnnounceErrorCodeValue,
|
|
22
|
+
FetchErrorCodeValue,
|
|
23
|
+
PublishErrorCodeValue,
|
|
24
|
+
SessionErrorCodeValue,
|
|
25
|
+
StreamResetErrorCodeValue,
|
|
26
|
+
SubscribeDoneStatusCodeValue,
|
|
27
|
+
SubscribeErrorCodeValue,
|
|
28
|
+
SubscribeNamespaceErrorCodeValue,
|
|
29
|
+
} from './error-codes.js'
|
|
30
|
+
export {
|
|
31
|
+
AnnounceErrorCode,
|
|
32
|
+
FetchErrorCode,
|
|
33
|
+
PublishErrorCode,
|
|
34
|
+
SessionErrorCode,
|
|
35
|
+
StreamResetErrorCode,
|
|
36
|
+
SubscribeDoneStatusCode,
|
|
37
|
+
SubscribeErrorCode,
|
|
38
|
+
SubscribeNamespaceErrorCode,
|
|
39
|
+
} from './error-codes.js'
|
|
17
40
|
export {
|
|
18
41
|
MESSAGE_ID_MAP,
|
|
19
42
|
MESSAGE_TYPE_MAP,
|
|
@@ -21,7 +21,7 @@ export interface AuthorizationToken {
|
|
|
21
21
|
export interface Draft13SetupParams {
|
|
22
22
|
path?: string // 0x01 odd
|
|
23
23
|
max_request_id?: bigint // 0x02 even
|
|
24
|
-
authorization_token?: AuthorizationToken // 0x03 odd
|
|
24
|
+
authorization_token?: readonly AuthorizationToken[] // 0x03 odd
|
|
25
25
|
max_auth_token_cache_size?: bigint // 0x04 even
|
|
26
26
|
unknown?: UnknownParam[]
|
|
27
27
|
}
|
|
@@ -29,7 +29,7 @@ export interface Draft13SetupParams {
|
|
|
29
29
|
// Version-specific parameters — even/odd convention
|
|
30
30
|
export interface Draft13Params {
|
|
31
31
|
delivery_timeout?: bigint // 0x02 even
|
|
32
|
-
authorization_token?: AuthorizationToken // 0x03 odd
|
|
32
|
+
authorization_token?: readonly AuthorizationToken[] // 0x03 odd
|
|
33
33
|
max_cache_duration?: bigint // 0x04 even
|
|
34
34
|
unknown?: UnknownParam[]
|
|
35
35
|
}
|
|
@@ -181,7 +181,7 @@ export interface Draft13AnnounceCancel extends Draft13BaseMessage {
|
|
|
181
181
|
readonly reason_phrase: string
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
// Subscribe Namespace
|
|
184
|
+
// Subscribe Namespace — type 0x11; drafts 07-12 name the same codepoint SUBSCRIBE_ANNOUNCES
|
|
185
185
|
export interface Draft13SubscribeNamespace extends Draft13BaseMessage {
|
|
186
186
|
readonly type: 'subscribe_namespace'
|
|
187
187
|
readonly request_id: bigint
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AuthRedaction, recordAuthValueSpan, redactWith } from '../../core/auth-redaction.js'
|
|
1
2
|
import { BufferReader } from '../../core/buffer-reader.js'
|
|
2
3
|
import { BufferWriter } from '../../core/buffer-writer.js'
|
|
3
4
|
import { bytesToHex, hexToBytes } from '../../core/hex.js'
|
|
@@ -78,7 +79,7 @@ function encodeSetupParams(params: Draft14Params, writer: BufferWriter): void {
|
|
|
78
79
|
if (params.role !== undefined) count++
|
|
79
80
|
if (params.path !== undefined) count++
|
|
80
81
|
if (params.max_request_id !== undefined) count++
|
|
81
|
-
|
|
82
|
+
count += params.authorization_token?.length ?? 0
|
|
82
83
|
if (params.authority !== undefined) count++
|
|
83
84
|
if (params.max_auth_token_cache_size !== undefined) count++
|
|
84
85
|
if (params.moqt_implementation !== undefined) count++
|
|
@@ -100,9 +101,9 @@ function encodeSetupParams(params: Draft14Params, writer: BufferWriter): void {
|
|
|
100
101
|
writer.writeVarInt(PARAM_MAX_REQUEST_ID)
|
|
101
102
|
writer.writeVarInt(params.max_request_id)
|
|
102
103
|
}
|
|
103
|
-
|
|
104
|
+
for (const token of params.authorization_token ?? []) {
|
|
104
105
|
writer.writeVarInt(PARAM_AUTHORIZATION_TOKEN)
|
|
105
|
-
const tok =
|
|
106
|
+
const tok = token
|
|
106
107
|
const tmpWriter = new BufferWriter(64)
|
|
107
108
|
tmpWriter.writeVarInt(tok.alias_type)
|
|
108
109
|
if (tok.token_type !== undefined) {
|
|
@@ -183,11 +184,15 @@ function decodeSetupParams(reader: BufferReader): Draft14Params {
|
|
|
183
184
|
if (tokenReader.remaining > 0) {
|
|
184
185
|
tok.token_type = tokenReader.readVarInt()
|
|
185
186
|
if (tokenReader.remaining > 0) {
|
|
186
|
-
const
|
|
187
|
-
tok.token_value =
|
|
187
|
+
const value = new Uint8Array(tokenReader.readBytesView(tokenReader.remaining))
|
|
188
|
+
tok.token_value = value
|
|
189
|
+
noteAuthTokenValue(reader.offset - length, length, value)
|
|
188
190
|
}
|
|
189
191
|
}
|
|
190
|
-
result.authorization_token =
|
|
192
|
+
result.authorization_token = [
|
|
193
|
+
...(result.authorization_token ?? []),
|
|
194
|
+
tok as unknown as AuthorizationToken,
|
|
195
|
+
]
|
|
191
196
|
} else if (paramType === PARAM_AUTHORITY) {
|
|
192
197
|
result.authority = textDecoder.decode(bytes)
|
|
193
198
|
} else if (paramType === PARAM_MOQT_IMPLEMENTATION) {
|
|
@@ -209,7 +214,7 @@ function decodeSetupParams(reader: BufferReader): Draft14Params {
|
|
|
209
214
|
function encodeMessageParams(params: Draft14Params, writer: BufferWriter): void {
|
|
210
215
|
let count = 0
|
|
211
216
|
if (params.delivery_timeout !== undefined) count++
|
|
212
|
-
|
|
217
|
+
count += params.authorization_token?.length ?? 0
|
|
213
218
|
if (params.max_cache_duration !== undefined) count++
|
|
214
219
|
if (params.unknown) count += params.unknown.length
|
|
215
220
|
|
|
@@ -219,9 +224,9 @@ function encodeMessageParams(params: Draft14Params, writer: BufferWriter): void
|
|
|
219
224
|
writer.writeVarInt(PARAM_DELIVERY_TIMEOUT)
|
|
220
225
|
writer.writeVarInt(params.delivery_timeout)
|
|
221
226
|
}
|
|
222
|
-
|
|
227
|
+
for (const token of params.authorization_token ?? []) {
|
|
223
228
|
writer.writeVarInt(PARAM_AUTHORIZATION_TOKEN)
|
|
224
|
-
const tok =
|
|
229
|
+
const tok = token
|
|
225
230
|
const tmpWriter = new BufferWriter(64)
|
|
226
231
|
tmpWriter.writeVarInt(tok.alias_type)
|
|
227
232
|
if (tok.token_type !== undefined) {
|
|
@@ -286,11 +291,15 @@ function decodeMessageParams(reader: BufferReader): Draft14Params {
|
|
|
286
291
|
if (tokenReader.remaining > 0) {
|
|
287
292
|
tok.token_type = tokenReader.readVarInt()
|
|
288
293
|
if (tokenReader.remaining > 0) {
|
|
289
|
-
const
|
|
290
|
-
tok.token_value =
|
|
294
|
+
const value = new Uint8Array(tokenReader.readBytesView(tokenReader.remaining))
|
|
295
|
+
tok.token_value = value
|
|
296
|
+
noteAuthTokenValue(reader.offset - length, length, value)
|
|
291
297
|
}
|
|
292
298
|
}
|
|
293
|
-
result.authorization_token =
|
|
299
|
+
result.authorization_token = [
|
|
300
|
+
...(result.authorization_token ?? []),
|
|
301
|
+
tok as unknown as AuthorizationToken,
|
|
302
|
+
]
|
|
294
303
|
} else {
|
|
295
304
|
unknown.push({
|
|
296
305
|
id: `0x${paramType.toString(16)}`,
|
|
@@ -1380,3 +1389,61 @@ export function createDraft14Codec(): Draft14Codec {
|
|
|
1380
1389
|
createDataStreamDecoder,
|
|
1381
1390
|
}
|
|
1382
1391
|
}
|
|
1392
|
+
|
|
1393
|
+
/**
|
|
1394
|
+
* Record where a Token Value sits, so it can be overwritten before the frame
|
|
1395
|
+
* reaches anything that keeps it.
|
|
1396
|
+
*
|
|
1397
|
+
* The span falls out of the decode with no second walk. The Token Value is the
|
|
1398
|
+
* last field of the Token structure, so its start is the parameter value's end
|
|
1399
|
+
* minus the value's own length. The fields before it are left alone
|
|
1400
|
+
* deliberately: Alias Type, Token Alias and Token Type are structure rather
|
|
1401
|
+
* than secret, and they are what distinguishes a session that failed to
|
|
1402
|
+
* authenticate from one that never tried.
|
|
1403
|
+
*
|
|
1404
|
+
* A token carrying no value at all -- DELETE and USE_ALIAS -- records nothing,
|
|
1405
|
+
* and its frame passes through untouched.
|
|
1406
|
+
*/
|
|
1407
|
+
function noteAuthTokenValue(
|
|
1408
|
+
valueStart: number,
|
|
1409
|
+
valueLength: number,
|
|
1410
|
+
value: Uint8Array | undefined,
|
|
1411
|
+
): void {
|
|
1412
|
+
if (value === undefined || value.byteLength === 0) return
|
|
1413
|
+
recordAuthValueSpan(valueStart + valueLength - value.byteLength, value.byteLength)
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
/**
|
|
1417
|
+
* Overwrite every Authorization Token value in a draft-14 control frame.
|
|
1418
|
+
*
|
|
1419
|
+
* One decode, whose *output is discarded*: the point is not to read the
|
|
1420
|
+
* message, it is to learn where the credentials were so the caller never has to
|
|
1421
|
+
* hold a frame that contains one. A caller that also wants the message should
|
|
1422
|
+
* decode the **redacted** frame with {@link decodeMessage}, which then cannot
|
|
1423
|
+
* produce a value because there is no longer one in the bytes.
|
|
1424
|
+
*
|
|
1425
|
+
* A frame that fails to decode is still redacted as far as the decode got. That
|
|
1426
|
+
* is the useful direction to fail in: a value that was read is a value that was
|
|
1427
|
+
* exposed, whatever went wrong after it.
|
|
1428
|
+
*
|
|
1429
|
+
* See {@link AuthRedaction.incomplete} for the one result a caller must not
|
|
1430
|
+
* treat as clean, and {@link AuthRedaction.decoded} for the residual it cannot
|
|
1431
|
+
* close.
|
|
1432
|
+
*/
|
|
1433
|
+
export function redactAuthTokens(bytes: Uint8Array): AuthRedaction {
|
|
1434
|
+
let payloadStart: number
|
|
1435
|
+
try {
|
|
1436
|
+
const probe = new BufferReader(bytes)
|
|
1437
|
+
probe.readVarInt()
|
|
1438
|
+
probe.readUint8()
|
|
1439
|
+
probe.readUint8()
|
|
1440
|
+
payloadStart = probe.offset
|
|
1441
|
+
} catch {
|
|
1442
|
+
// Too short to carry a message header, and so too short for the parameters
|
|
1443
|
+
// that carry a credential. Reported as not decoded rather than as clean: a
|
|
1444
|
+
// framer only ever emits complete frames, so a caller that gets here is
|
|
1445
|
+
// holding something this function did not check.
|
|
1446
|
+
return { bytes, redacted: 0, incomplete: false, decoded: false }
|
|
1447
|
+
}
|
|
1448
|
+
return redactWith(bytes, payloadStart, () => decodeMessage(bytes).ok)
|
|
1449
|
+
}
|