@browsercore/testing 0.1.3 → 0.2.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 +5 -0
- package/captures/DIVERGENCE_REPORT.md +325 -0
- package/captures/IMPERSIONATION_GAPS_REPORT.md +367 -0
- package/captures/README.md +56 -0
- package/captures/REVIEW_FINDINGS.md +71 -0
- package/captures/_probe/analyze.py +67 -0
- package/captures/_probe/capture_bytes.py +127 -0
- package/captures/_probe/chrome131_determinism.py +32 -0
- package/captures/_probe/diagnose_capture.py +59 -0
- package/captures/_probe/golden_analysis.py +91 -0
- package/captures/_probe/inspect_golden.py +55 -0
- package/captures/_probe/inspect_sv.py +16 -0
- package/captures/_probe/make_golden.py +170 -0
- package/captures/_probe/output/chrome100.json +219 -0
- package/captures/_probe/output/chrome101.json +219 -0
- package/captures/_probe/output/chrome104.json +219 -0
- package/captures/_probe/output/chrome107.json +220 -0
- package/captures/_probe/output/chrome110.json +220 -0
- package/captures/_probe/output/chrome116.json +220 -0
- package/captures/_probe/output/chrome119.json +219 -0
- package/captures/_probe/output/chrome120.json +219 -0
- package/captures/_probe/output/chrome123.json +223 -0
- package/captures/_probe/output/chrome124.json +224 -0
- package/captures/_probe/output/chrome131.json +224 -0
- package/captures/_probe/output/chrome131_fresh.json +224 -0
- package/captures/_probe/output/chrome133a.json +224 -0
- package/captures/_probe/output/chrome136.json +224 -0
- package/captures/_probe/output/chrome99.json +219 -0
- package/captures/_probe/output/edge101.json +219 -0
- package/captures/_probe/output/edge99.json +219 -0
- package/captures/_probe/output/firefox133.json +227 -0
- package/captures/_probe/output/firefox135.json +230 -0
- package/captures/_probe/output/safari155.json +210 -0
- package/captures/_probe/output/safari170.json +214 -0
- package/captures/_probe/output/safari170_fresh.json +214 -0
- package/captures/_probe/output/safari180.json +216 -0
- package/captures/_probe/output/safari180_ios.json +216 -0
- package/captures/_probe/output/safari184.json +215 -0
- package/captures/_probe/output/safari260.json +211 -0
- package/captures/_probe/output/summary.json +2520 -0
- package/captures/_probe/parse_existing_settings.py +15 -0
- package/captures/_probe/peetprint.py +39 -0
- package/captures/_probe/probe.py +137 -0
- package/captures/_probe/raw_bytes/chrome-131_client_hello.bin +0 -0
- package/captures/_probe/raw_bytes/chrome-131_client_hello.hex +32 -0
- package/captures/_probe/raw_bytes/firefox-133_client_hello.bin +0 -0
- package/captures/_probe/raw_bytes/firefox-133_client_hello.hex +32 -0
- package/captures/_probe/raw_bytes/safari-17_client_hello.bin +0 -0
- package/captures/_probe/raw_bytes/safari-17_client_hello.hex +32 -0
- package/captures/_probe/relay_capture.py +137 -0
- package/captures/_probe/socks_capture.py +138 -0
- package/captures/_probe/validate_fresh.py +66 -0
- package/captures/_probe/validate_golden.py +97 -0
- package/captures/_probe/verify_capture.py +68 -0
- package/captures/chrome-131/http2/settings.bin +0 -0
- package/captures/chrome-131/http2/settings.meta.json +9 -0
- package/captures/chrome-131/oracle_capture.reference.json +224 -0
- package/captures/chrome-131/tls/client_hello.bin +0 -0
- package/captures/chrome-131/tls/client_hello.meta.json +20 -0
- package/captures/chrome-140/http2/settings.bin +0 -0
- package/captures/chrome-140/http2/settings.meta.json +9 -0
- package/captures/chrome-140/tls/client_hello.bin +0 -0
- package/captures/chrome-140/tls/client_hello.meta.json +12 -0
- package/captures/firefox-128/tls/client_hello.bin +0 -0
- package/captures/firefox-128/tls/client_hello.meta.json +12 -0
- package/captures/firefox-133/http2/settings.bin +0 -0
- package/captures/firefox-133/http2/settings.meta.json +9 -0
- package/captures/firefox-133/oracle_capture.reference.json +227 -0
- package/captures/firefox-133/tls/client_hello.bin +0 -0
- package/captures/firefox-133/tls/client_hello.meta.json +20 -0
- package/captures/safari-17/http2/settings.bin +0 -0
- package/captures/safari-17/http2/settings.meta.json +9 -0
- package/captures/safari-17/oracle_capture.reference.json +214 -0
- package/captures/safari-17/tls/client_hello.bin +0 -0
- package/captures/safari-17/tls/client_hello.meta.json +20 -0
- package/dist/bench/bench.d.ts +22 -6
- package/dist/bench/bench.d.ts.map +1 -1
- package/dist/bench/bench.js +105 -10
- package/dist/bench/bench.js.map +1 -1
- package/dist/captures/manifest.d.ts.map +1 -1
- package/dist/captures/manifest.js +2 -3
- package/dist/captures/manifest.js.map +1 -1
- package/dist/categories/cookies.d.ts +3 -2
- package/dist/categories/cookies.d.ts.map +1 -1
- package/dist/categories/cookies.js +228 -11
- package/dist/categories/cookies.js.map +1 -1
- package/dist/categories/redirects.d.ts +8 -2
- package/dist/categories/redirects.d.ts.map +1 -1
- package/dist/categories/redirects.js +97 -12
- package/dist/categories/redirects.js.map +1 -1
- package/dist/e2e/cert-gen.d.ts +30 -0
- package/dist/e2e/cert-gen.d.ts.map +1 -0
- package/dist/e2e/cert-gen.js +158 -0
- package/dist/e2e/cert-gen.js.map +1 -0
- package/dist/e2e/parse-clienthello.d.ts +177 -0
- package/dist/e2e/parse-clienthello.d.ts.map +1 -0
- package/dist/e2e/parse-clienthello.js +343 -0
- package/dist/e2e/parse-clienthello.js.map +1 -0
- package/dist/e2e/sink-server.d.ts +109 -0
- package/dist/e2e/sink-server.d.ts.map +1 -0
- package/dist/e2e/sink-server.js +292 -0
- package/dist/e2e/sink-server.js.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/fingerprint/index.d.ts +5 -2
- package/dist/fingerprint/index.d.ts.map +1 -1
- package/dist/fingerprint/index.js +3 -2
- package/dist/fingerprint/index.js.map +1 -1
- package/dist/fingerprint/ja3.d.ts.map +1 -1
- package/dist/fingerprint/ja3.js +33 -4
- package/dist/fingerprint/ja3.js.map +1 -1
- package/dist/fingerprint/ja4-errors.d.ts +17 -0
- package/dist/fingerprint/ja4-errors.d.ts.map +1 -0
- package/dist/fingerprint/ja4-errors.js +20 -0
- package/dist/fingerprint/ja4-errors.js.map +1 -0
- package/dist/fingerprint/ja4-reader.d.ts +44 -0
- package/dist/fingerprint/ja4-reader.d.ts.map +1 -0
- package/dist/fingerprint/ja4-reader.js +112 -0
- package/dist/fingerprint/ja4-reader.js.map +1 -0
- package/dist/fingerprint/ja4.d.ts +11 -43
- package/dist/fingerprint/ja4.d.ts.map +1 -1
- package/dist/fingerprint/ja4.js +54 -141
- package/dist/fingerprint/ja4.js.map +1 -1
- package/dist/fingerprint/ja4h.d.ts +46 -0
- package/dist/fingerprint/ja4h.d.ts.map +1 -0
- package/dist/fingerprint/ja4h.js +50 -0
- package/dist/fingerprint/ja4h.js.map +1 -0
- package/dist/golden/golden.d.ts +15 -1
- package/dist/golden/golden.d.ts.map +1 -1
- package/dist/golden/golden.js +35 -22
- package/dist/golden/golden.js.map +1 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/dist/reference/browser-provider.d.ts +33 -0
- package/dist/reference/browser-provider.d.ts.map +1 -0
- package/dist/reference/browser-provider.js +60 -0
- package/dist/reference/browser-provider.js.map +1 -0
- package/dist/reference/curl-provider.d.ts +40 -0
- package/dist/reference/curl-provider.d.ts.map +1 -0
- package/dist/reference/curl-provider.js +96 -0
- package/dist/reference/curl-provider.js.map +1 -0
- package/dist/reference/dump.d.ts +42 -0
- package/dist/reference/dump.d.ts.map +1 -0
- package/dist/reference/dump.js +102 -0
- package/dist/reference/dump.js.map +1 -0
- package/dist/reference/node-reference.d.ts.map +1 -1
- package/dist/reference/node-reference.js +2 -5
- package/dist/reference/node-reference.js.map +1 -1
- package/dist/reference/reference-errors.d.ts +36 -0
- package/dist/reference/reference-errors.d.ts.map +1 -0
- package/dist/reference/reference-errors.js +43 -0
- package/dist/reference/reference-errors.js.map +1 -0
- package/dist/reference/reference-types.d.ts +33 -0
- package/dist/reference/reference-types.d.ts.map +1 -0
- package/dist/reference/reference-types.js +9 -0
- package/dist/reference/reference-types.js.map +1 -0
- package/dist/reference/reference.d.ts +14 -77
- package/dist/reference/reference.d.ts.map +1 -1
- package/dist/reference/reference.js +43 -207
- package/dist/reference/reference.js.map +1 -1
- package/dist/rfc/rfcTests.d.ts +46 -8
- package/dist/rfc/rfcTests.d.ts.map +1 -1
- package/dist/rfc/rfcTests.js +203 -16
- package/dist/rfc/rfcTests.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +11 -5
- package/dist/utils.js.map +1 -1
- package/package.json +61 -55
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* curl-impersonate dump parsing + TLS fingerprint derivation.
|
|
3
|
+
*
|
|
4
|
+
* Split out of `reference.ts` so the providers and facade stay focused on
|
|
5
|
+
* dispatch while this file owns the curl-impersonate `--dump-traffic` byte
|
|
6
|
+
* format and the JA3/JA4 derivation from a captured ClientHello.
|
|
7
|
+
*/
|
|
8
|
+
import { computeJa3, computeJa4Fingerprint } from "../fingerprint/index.js";
|
|
9
|
+
import { loadCaptureMeta } from "../golden/golden.js";
|
|
10
|
+
import { DumpParseError } from "./reference-errors.js";
|
|
11
|
+
/** Map a {@link ProfileId} to its {@link CaptureSource} tag. */
|
|
12
|
+
export function profileToSource(profile) {
|
|
13
|
+
const p = String(profile);
|
|
14
|
+
if (p.startsWith("firefox")) {
|
|
15
|
+
return "firefox-135";
|
|
16
|
+
}
|
|
17
|
+
if (p.startsWith("safari")) {
|
|
18
|
+
return "safari-18";
|
|
19
|
+
}
|
|
20
|
+
if (p.startsWith("edge")) {
|
|
21
|
+
return "edge-140";
|
|
22
|
+
}
|
|
23
|
+
return "chrome-140";
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse curl-impersonate `--dump-traffic` output into raw bytes.
|
|
27
|
+
*
|
|
28
|
+
* The dump format is a hex dump with one line per record; we extract the hex
|
|
29
|
+
* payload after the `>>> traffic <<<` marker. Throws {@link DumpParseError}
|
|
30
|
+
* when no hex bytes follow the marker or the hex has odd length.
|
|
31
|
+
*/
|
|
32
|
+
export function parseDumpOutput(stdout) {
|
|
33
|
+
// Find the hex body — everything after the ">>> traffic <<<" marker.
|
|
34
|
+
const marker = ">>> traffic <<<";
|
|
35
|
+
const idx = stdout.indexOf(marker);
|
|
36
|
+
const body = idx === -1 ? stdout : stdout.slice(idx + marker.length);
|
|
37
|
+
const hex = body.replaceAll(/[^0-9a-fA-F]/gu, "");
|
|
38
|
+
if (hex.length === 0) {
|
|
39
|
+
throw new DumpParseError("no_hex", 0);
|
|
40
|
+
}
|
|
41
|
+
if (hex.length % 2 !== 0) {
|
|
42
|
+
throw new DumpParseError("odd_length", hex.length);
|
|
43
|
+
}
|
|
44
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
45
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
46
|
+
bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
47
|
+
}
|
|
48
|
+
return bytes;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Derive a {@link Fingerprint} from a TLS ClientHello capture.
|
|
52
|
+
*
|
|
53
|
+
* Computes JA3 + JA4 from the raw bytes and reads the per-extension metadata
|
|
54
|
+
* (supported groups, signature algorithms, ALPN) from the sidecar
|
|
55
|
+
* `.meta.json` when available.
|
|
56
|
+
*
|
|
57
|
+
* Exported for unit testing the try/catch branches: the happy path reads the
|
|
58
|
+
* sidecar meta, while the fallback path is taken when the sidecar is missing.
|
|
59
|
+
*/
|
|
60
|
+
export function fingerprintFromTlsCapture(capture) {
|
|
61
|
+
const ja3 = computeJa3(capture.bytes);
|
|
62
|
+
const ja4 = computeJa4Fingerprint(capture.bytes);
|
|
63
|
+
// Read the sidecar meta for richer fields (signature algorithms, ALPN,
|
|
64
|
+
// supported curves). Fall back to empty arrays if missing.
|
|
65
|
+
const alpn = [];
|
|
66
|
+
const signatureAlgorithms = [];
|
|
67
|
+
const ellipticCurves = [];
|
|
68
|
+
try {
|
|
69
|
+
const meta = loadCaptureMeta(capture.id);
|
|
70
|
+
if (meta.protocol === "tls") {
|
|
71
|
+
// CaptureMeta doesn't carry ALPN/sigAlgs/curves yet; this is a
|
|
72
|
+
// placeholder for when the sidecar schema is extended.
|
|
73
|
+
void meta;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Sidecar missing or unparseable — leave richer fields empty.
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
ja3,
|
|
81
|
+
ja4: ja4.tag,
|
|
82
|
+
alpn,
|
|
83
|
+
cipherSuite: cipherSuiteName(ja4.tag),
|
|
84
|
+
protocolVersion: ja4.tag.slice(5, 7) || "unknown",
|
|
85
|
+
signatureAlgorithms,
|
|
86
|
+
ellipticCurves,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Extract a human-readable cipher-suite name from a JA4 tag.
|
|
91
|
+
*
|
|
92
|
+
* JA4 doesn't directly encode the negotiated cipher; this is a placeholder
|
|
93
|
+
* that returns the JA4_a segment for inspection. Real cipher-suite resolution
|
|
94
|
+
* requires parsing the ServerHello, which is out of scope for the capture.
|
|
95
|
+
*
|
|
96
|
+
* Exported for unit testing the empty-tag fallback branch.
|
|
97
|
+
*/
|
|
98
|
+
export function cipherSuiteName(ja4Tag) {
|
|
99
|
+
const a = ja4Tag.split("_")[0] ?? "";
|
|
100
|
+
return a.length > 0 ? a : "unknown";
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=dump.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump.js","sourceRoot":"","sources":["../../src/reference/dump.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-reference.d.ts","sourceRoot":"","sources":["../../src/reference/node-reference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"node-reference.d.ts","sourceRoot":"","sources":["../../src/reference/node-reference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAOH,SAAS,IAAI,aAAa,EAC7B,MAAM,WAAW,CAAC;AAqBnB,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAGhD,iFAAiF;AACjF,eAAO,MAAM,UAAU;IACnB,iEAAiE;aACjE,MAAM,SAAO,UAAU,KAAG,UAAU;IAIpC,iEAAiE;aACjE,MAAM,SAAO,UAAU,KAAG,UAAU;IAIpC;;;OAGG;aACH,IAAI,cACW,aAAa,QAClB,UAAU,OACX,UAAU,QACT,UAAU,UACR,MAAM,KACf,UAAU;IAOb,qDAAqD;aACrD,IAAI,cAAY,aAAa,OAAO,UAAU,QAAQ,UAAU,KAAG,UAAU;IAK7E,6DAA6D;aAC7D,WAAW,WAAS,MAAM,KAAG,UAAU;IAIvC,yDAAyD;aACzD,YAAY,cAAY,aAAa,KAAG,MAAM;CAGxC,CAAC;AAEX,yDAAyD;AACzD,eAAO,MAAM,OAAO;IAChB,0EAA0E;aAC1E,MAAM,SACI,MAAM,QACN,OAAO,KACd,OAAO,CAAC;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC;CAY1D,CAAC;AAEX,kFAAkF;AAClF,eAAO,MAAM,QAAQ;aACjB,IAAI,SAAO,UAAU,KAAG,UAAU;aAGlC,MAAM,SAAO,UAAU,KAAG,UAAU;aAGpC,OAAO,SAAO,UAAU,KAAG,UAAU;aAGrC,OAAO,SAAO,UAAU,KAAG,UAAU;aAGrC,cAAc,SAAO,UAAU,KAAG,UAAU;aAG5C,gBAAgB,SAAO,UAAU,KAAG,UAAU;IAG9C,8EAA8E;aAC1E,aAAa,EAAI,OAAO,aAAa;CAGnC,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,QAAQ;IACjB;;;;OAIG;aACH,8BAA8B,WAClB,MAAM,OACT,MAAM,WACF,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KACrC,UAAU;CAQP,CAAC;AAEX,8EAA8E;AAC9E,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAKzC;AAED,sDAAsD;AACtD,MAAM,MAAM,cAAc,GACpB;IAAE,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GACxB;IAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,cAAc,CAUhF"}
|
|
@@ -16,10 +16,8 @@
|
|
|
16
16
|
* for comparison with our packages' Uint8Array-centric APIs.
|
|
17
17
|
*/
|
|
18
18
|
import { createHash, createHmac, hkdfSync, randomBytes } from "node:crypto";
|
|
19
|
-
import { gunzipSync, gzipSync, brotliCompressSync, brotliDecompressSync } from "node:zlib";
|
|
19
|
+
import { deflateSync, inflateSync, gunzipSync, gzipSync, brotliCompressSync, brotliDecompressSync, constants as zlibConstants, } from "node:zlib";
|
|
20
20
|
import { lookup as dnsLookup } from "node:dns";
|
|
21
|
-
import { deflateSync, inflateSync, constants as zlibConstants } from "node:zlib";
|
|
22
|
-
import { assertNever } from "../utils.js";
|
|
23
21
|
/** Normalize a Node Buffer / Uint8Array / readonly Uint8Array to a fresh Uint8Array. */
|
|
24
22
|
function toBytes(data) {
|
|
25
23
|
return new Uint8Array(data);
|
|
@@ -72,7 +70,7 @@ export const nodeCrypto = {
|
|
|
72
70
|
/** DNS resolution oracle (mirrors our `resolveHost`). */
|
|
73
71
|
export const nodeDns = {
|
|
74
72
|
/** Resolve a host to an address, matching our `resolveHost` semantics. */
|
|
75
|
-
|
|
73
|
+
lookup(host, ipv6) {
|
|
76
74
|
return new Promise((resolve, reject) => {
|
|
77
75
|
const options = { family: ipv6 ? 6 : 4 };
|
|
78
76
|
dnsLookup(host, options, (err, address, family) => {
|
|
@@ -157,5 +155,4 @@ function firstDiff(a, b) {
|
|
|
157
155
|
}
|
|
158
156
|
return len;
|
|
159
157
|
}
|
|
160
|
-
void assertNever;
|
|
161
158
|
//# sourceMappingURL=node-reference.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-reference.js","sourceRoot":"","sources":["../../src/reference/node-reference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,
|
|
1
|
+
{"version":3,"file":"node-reference.js","sourceRoot":"","sources":["../../src/reference/node-reference.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors for the reference provider (docs/TEST-SUITE.md, Cat 3/4/14).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the transport pattern: errors carry a `kind` discriminator so callers
|
|
5
|
+
* can match on type instead of parsing message text. `ReferenceError` is the
|
|
6
|
+
* base failure for capture / fingerprint; `DumpParseError` covers the
|
|
7
|
+
* curl-impersonate dump-format failures specifically.
|
|
8
|
+
*/
|
|
9
|
+
import { TestingError } from "../errors.js";
|
|
10
|
+
/**
|
|
11
|
+
* Raised when a reference provider cannot capture or fingerprint a profile.
|
|
12
|
+
*
|
|
13
|
+
* Extends {@link TestingError} (the package-wide base) so it inherits the
|
|
14
|
+
* `"TestingError"` discriminator; callers can `instanceof ReferenceError` for
|
|
15
|
+
* the narrower match.
|
|
16
|
+
*/
|
|
17
|
+
export declare class ReferenceError extends TestingError {
|
|
18
|
+
constructor(message: string, options?: {
|
|
19
|
+
cause?: Error;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Raised when curl-impersonate `--dump-traffic` output cannot be parsed.
|
|
24
|
+
*
|
|
25
|
+
* Discriminated by {@link dumpKind}: `"no_hex"` (no hex bytes after the
|
|
26
|
+
* marker) or `"odd_length"` (an odd number of hex digits cannot form whole
|
|
27
|
+
* bytes).
|
|
28
|
+
*/
|
|
29
|
+
export declare class DumpParseError extends ReferenceError {
|
|
30
|
+
readonly dumpKind: DumpParseKind;
|
|
31
|
+
readonly hexLength: number;
|
|
32
|
+
constructor(dumpKind: DumpParseKind, hexLength: number);
|
|
33
|
+
}
|
|
34
|
+
/** Why a dump could not be parsed. */
|
|
35
|
+
export type DumpParseKind = "no_hex" | "odd_length";
|
|
36
|
+
//# sourceMappingURL=reference-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-errors.d.ts","sourceRoot":"","sources":["../../src/reference/reference-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC5C,YAAY,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,KAAK,CAAA;KAAE,EAGvD;CACJ;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,cAAc;IAC9C,SAAgB,QAAQ,EAAE,aAAa,CAAC;IACxC,SAAgB,SAAS,EAAE,MAAM,CAAC;IAElC,YAAY,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EASrD;CACJ;AAED,sCAAsC;AACtC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed errors for the reference provider (docs/TEST-SUITE.md, Cat 3/4/14).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors the transport pattern: errors carry a `kind` discriminator so callers
|
|
5
|
+
* can match on type instead of parsing message text. `ReferenceError` is the
|
|
6
|
+
* base failure for capture / fingerprint; `DumpParseError` covers the
|
|
7
|
+
* curl-impersonate dump-format failures specifically.
|
|
8
|
+
*/
|
|
9
|
+
import { TestingError } from "../errors.js";
|
|
10
|
+
/**
|
|
11
|
+
* Raised when a reference provider cannot capture or fingerprint a profile.
|
|
12
|
+
*
|
|
13
|
+
* Extends {@link TestingError} (the package-wide base) so it inherits the
|
|
14
|
+
* `"TestingError"` discriminator; callers can `instanceof ReferenceError` for
|
|
15
|
+
* the narrower match.
|
|
16
|
+
*/
|
|
17
|
+
export class ReferenceError extends TestingError {
|
|
18
|
+
constructor(message, options) {
|
|
19
|
+
super(message, options);
|
|
20
|
+
this.name = "ReferenceError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Raised when curl-impersonate `--dump-traffic` output cannot be parsed.
|
|
25
|
+
*
|
|
26
|
+
* Discriminated by {@link dumpKind}: `"no_hex"` (no hex bytes after the
|
|
27
|
+
* marker) or `"odd_length"` (an odd number of hex digits cannot form whole
|
|
28
|
+
* bytes).
|
|
29
|
+
*/
|
|
30
|
+
export class DumpParseError extends ReferenceError {
|
|
31
|
+
dumpKind;
|
|
32
|
+
hexLength;
|
|
33
|
+
constructor(dumpKind, hexLength) {
|
|
34
|
+
const message = dumpKind === "no_hex"
|
|
35
|
+
? "curl-impersonate dump produced no hex bytes"
|
|
36
|
+
: `curl-impersonate dump produced odd-length hex (${hexLength})`;
|
|
37
|
+
super(message);
|
|
38
|
+
this.name = "DumpParseError";
|
|
39
|
+
this.dumpKind = dumpKind;
|
|
40
|
+
this.hexLength = hexLength;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=reference-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-errors.js","sourceRoot":"","sources":["../../src/reference/reference-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,YAAY;IAC5C,YAAY,OAAe,EAAE,OAA2B;QACpD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IACjC,CAAC;CACJ;AAED;;;;;;GAMG;AACH,MAAM,OAAO,cAAe,SAAQ,cAAc;IAC9B,QAAQ,CAAgB;IACxB,SAAS,CAAS;IAElC,YAAY,QAAuB,EAAE,SAAiB;QAClD,MAAM,OAAO,GACT,QAAQ,KAAK,QAAQ;YACjB,CAAC,CAAC,6CAA6C;YAC/C,CAAC,CAAC,kDAAkD,SAAS,GAAG,CAAC;QACzE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC/B,CAAC;CACJ"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the reference provider layer.
|
|
3
|
+
*
|
|
4
|
+
* Lives in its own module so the providers (`curl-provider.ts`,
|
|
5
|
+
* `browser-provider.ts`), the dump helpers (`dump.ts`), and the facade
|
|
6
|
+
* (`reference.ts`) all import from one place without forming an import cycle.
|
|
7
|
+
*/
|
|
8
|
+
import type { ProfileId } from "@browsercore/profiles";
|
|
9
|
+
import type { GoldenCapture } from "../types.js";
|
|
10
|
+
/** Which reference backend to use. Discriminated union — no bare string. */
|
|
11
|
+
export type ReferenceProviderKind = {
|
|
12
|
+
readonly kind: "curl-impersonate";
|
|
13
|
+
} | {
|
|
14
|
+
readonly kind: "real-browser";
|
|
15
|
+
};
|
|
16
|
+
/** Observable TLS/HTTP fingerprint of a captured reference exchange. */
|
|
17
|
+
export interface Fingerprint {
|
|
18
|
+
readonly ja3: string;
|
|
19
|
+
readonly ja4: string;
|
|
20
|
+
readonly alpn: readonly string[];
|
|
21
|
+
readonly cipherSuite: string;
|
|
22
|
+
readonly protocolVersion: string;
|
|
23
|
+
readonly signatureAlgorithms: readonly string[];
|
|
24
|
+
readonly ellipticCurves: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/** A source of truth for a browser profile's wire behavior. */
|
|
27
|
+
export interface ReferenceProvider {
|
|
28
|
+
readonly kind: ReferenceProviderKind;
|
|
29
|
+
capture(profile: ProfileId, url: string): Promise<GoldenCapture>;
|
|
30
|
+
fingerprint(profile: ProfileId): Promise<Fingerprint>;
|
|
31
|
+
availableProfiles(): ProfileId[];
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=reference-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-types.d.ts","sourceRoot":"","sources":["../../src/reference/reference-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,4EAA4E;AAC5E,MAAM,MAAM,qBAAqB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAA;CAAE,GACrC;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAExC,wEAAwE;AACxE,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAC9B,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACjE,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,iBAAiB,IAAI,SAAS,EAAE,CAAC;CACpC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for the reference provider layer.
|
|
3
|
+
*
|
|
4
|
+
* Lives in its own module so the providers (`curl-provider.ts`,
|
|
5
|
+
* `browser-provider.ts`), the dump helpers (`dump.ts`), and the facade
|
|
6
|
+
* (`reference.ts`) all import from one place without forming an import cycle.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=reference-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-types.js","sourceRoot":"","sources":["../../src/reference/reference-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pluggable layered reference provider.
|
|
2
|
+
* Pluggable layered reference provider — facade + factory.
|
|
3
3
|
*
|
|
4
4
|
* The reference implementation is the source of truth for what a given browser
|
|
5
5
|
* profile SHOULD produce on the wire. Three backends are wrapped behind one
|
|
@@ -17,90 +17,27 @@
|
|
|
17
17
|
* primary then secondary; fingerprint is derived from the captured bytes; the
|
|
18
18
|
* node-reference oracle is exposed for primitive-layer comparisons.
|
|
19
19
|
*
|
|
20
|
-
*
|
|
20
|
+
* The providers and dump helpers live in their own modules; this file owns the
|
|
21
|
+
* facade + factory dispatch. See docs/TEST-SUITE.md (Cat 3, 4, 14).
|
|
21
22
|
*/
|
|
22
23
|
import type { ProfileId } from "@browsercore/profiles";
|
|
23
24
|
import type { GoldenCapture } from "../types.js";
|
|
24
|
-
import {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
readonly alpn: readonly string[];
|
|
36
|
-
readonly cipherSuite: string;
|
|
37
|
-
readonly protocolVersion: string;
|
|
38
|
-
readonly signatureAlgorithms: readonly string[];
|
|
39
|
-
readonly ellipticCurves: readonly string[];
|
|
40
|
-
}
|
|
41
|
-
/** Options for the curl-impersonate provider. */
|
|
42
|
-
export interface CurlImpersonateOptions {
|
|
43
|
-
/** Path / name of the curl-impersonate binary. Default "curl-impersonate". */
|
|
44
|
-
readonly command: string;
|
|
45
|
-
/** Extra argv passed to the binary. */
|
|
46
|
-
readonly extraArgs?: readonly string[];
|
|
47
|
-
}
|
|
48
|
-
/** Options for the real-browser (pre-recorded capture) provider. */
|
|
49
|
-
export interface RealBrowserOptions {
|
|
50
|
-
readonly command?: undefined;
|
|
51
|
-
/** Override captures directory. Defaults to the in-repo `captures/` dir. */
|
|
52
|
-
readonly capturesDir?: string;
|
|
53
|
-
}
|
|
25
|
+
import type { Fingerprint, ReferenceProvider, ReferenceProviderKind } from "./reference-types.js";
|
|
26
|
+
import { type CurlImpersonateOptions } from "./curl-provider.js";
|
|
27
|
+
import { type RealBrowserOptions } from "./browser-provider.js";
|
|
28
|
+
export { CurlImpersonateProvider } from "./curl-provider.js";
|
|
29
|
+
export type { CurlImpersonateOptions } from "./curl-provider.js";
|
|
30
|
+
export { RealBrowserCaptureProvider } from "./browser-provider.js";
|
|
31
|
+
export type { RealBrowserOptions } from "./browser-provider.js";
|
|
32
|
+
export { ReferenceError, DumpParseError } from "./reference-errors.js";
|
|
33
|
+
export type { DumpParseKind } from "./reference-errors.js";
|
|
34
|
+
export { parseDumpOutput, fingerprintFromTlsCapture, cipherSuiteName } from "./dump.js";
|
|
35
|
+
export type { Fingerprint, ReferenceProvider, ReferenceProviderKind, } from "./reference-types.js";
|
|
54
36
|
/** Options for the {@link ReferenceProviderFacade}. */
|
|
55
37
|
export interface ReferenceFacadeOptions {
|
|
56
38
|
readonly curl?: CurlImpersonateOptions;
|
|
57
39
|
readonly browser?: RealBrowserOptions;
|
|
58
40
|
}
|
|
59
|
-
/** A source of truth for a browser profile's wire behavior. */
|
|
60
|
-
export interface ReferenceProvider {
|
|
61
|
-
readonly kind: ReferenceProviderKind;
|
|
62
|
-
capture(profile: ProfileId, url: string): Promise<GoldenCapture>;
|
|
63
|
-
fingerprint(profile: ProfileId): Promise<Fingerprint>;
|
|
64
|
-
availableProfiles(): ProfileId[];
|
|
65
|
-
}
|
|
66
|
-
/** Raised when a reference provider cannot capture or fingerprint a profile. */
|
|
67
|
-
export declare class ReferenceError extends TestingError {
|
|
68
|
-
constructor(message: string, options?: {
|
|
69
|
-
cause?: Error;
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* PRIMARY provider — shells out to curl-impersonate.
|
|
74
|
-
*
|
|
75
|
-
* `capture()` invokes the curl-impersonate binary against `url`, impersonating
|
|
76
|
-
* `profile`, and returns the raw bytes it observed on the wire. The binary
|
|
77
|
-
* must be on PATH (or in `command`); if it is missing, the call throws
|
|
78
|
-
* {@link ReferenceError} so the facade can fall back to the secondary.
|
|
79
|
-
*/
|
|
80
|
-
export declare class CurlImpersonateProvider implements ReferenceProvider {
|
|
81
|
-
readonly kind: ReferenceProviderKind;
|
|
82
|
-
readonly command: string;
|
|
83
|
-
readonly extraArgs: readonly string[];
|
|
84
|
-
constructor(options?: CurlImpersonateOptions);
|
|
85
|
-
availableProfiles(): ProfileId[];
|
|
86
|
-
capture(profile: ProfileId, url: string): Promise<GoldenCapture>;
|
|
87
|
-
fingerprint(profile: ProfileId): Promise<Fingerprint>;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* SECONDARY provider — loads pre-recorded captures from the `captures/` dir.
|
|
91
|
-
*
|
|
92
|
-
* `capture()` resolves a stored capture for the profile; `fingerprint()`
|
|
93
|
-
* derives a {@link Fingerprint} from the captured bytes (only TLS
|
|
94
|
-
* ClientHellos are fingerprinted — other protocols return a stub).
|
|
95
|
-
*/
|
|
96
|
-
export declare class RealBrowserCaptureProvider implements ReferenceProvider {
|
|
97
|
-
readonly kind: ReferenceProviderKind;
|
|
98
|
-
readonly capturesDir: string;
|
|
99
|
-
constructor(options?: RealBrowserOptions);
|
|
100
|
-
availableProfiles(): ProfileId[];
|
|
101
|
-
capture(profile: ProfileId, _url: string): Promise<GoldenCapture>;
|
|
102
|
-
fingerprint(profile: ProfileId): Promise<Fingerprint>;
|
|
103
|
-
}
|
|
104
41
|
/**
|
|
105
42
|
* Facade wrapping the node-reference oracle + primary (curl-impersonate) and
|
|
106
43
|
* secondary (real-browser) providers behind a single {@link ReferenceProvider}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/reference/reference.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reference.d.ts","sourceRoot":"","sources":["../../src/reference/reference.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EACR,WAAW,EACX,iBAAiB,EACjB,qBAAqB,EACxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAA2B,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAA8B,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAM5F,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,YAAY,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvE,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACxF,YAAY,EACR,WAAW,EACX,iBAAiB,EACjB,qBAAqB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,uDAAuD;AACvD,MAAM,WAAW,sBAAsB;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,sBAAsB,CAAC;IACvC,QAAQ,CAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED;;;;;;;;;GASG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC7D,SAAgB,IAAI,EAAE,qBAAqB,CAAyC;IACpF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA6B;IAEvD,YAAY,OAAO,CAAC,EAAE,sBAAsB,EAG3C;IAED;;;;OAIG;IACH,IAAI,UAAU,IAAI,OAAO,UAAU,CAElC;IAED,iBAAiB,IAAI,SAAS,EAAE,CAa/B;IAEK,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAiBrE;IAEK,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAgB1D;CACJ;AAED;;;;GAIG;AACH,OAAO,KAAK,UAAU,MAAM,qBAAqB,CAAC;AAElD,sFAAsF;AACtF,wBAAgB,uBAAuB,CACnC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,CAAC,EAAE,sBAAsB,GAAG,kBAAkB,GACtD,iBAAiB,CAWnB;AAmCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,uBAAuB,CAE/F"}
|