@crouton-kit/capture 1.3.17 → 1.3.19
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/bin/capture +4184 -3258
- package/package.json +1 -1
- package/src/capture.ts +4 -1
- package/src/cdp/args.ts +14 -2
- package/src/cdp/browser-process.ts +510 -0
- package/src/cdp/client.ts +10 -1
- package/src/cdp/commands/cdp.ts +5 -5
- package/src/cdp/commands/measure/snap.ts +37 -2
- package/src/cdp/commands/motion/mask.ts +8 -2
- package/src/cdp/commands/page/click.ts +14 -0
- package/src/cdp/commands/page/elements.ts +2 -2
- package/src/cdp/commands/page/shot.ts +26 -5
- package/src/cdp/commands/tab/index.ts +19 -8
- package/src/cdp/commands/tab/launch.ts +73 -0
- package/src/cdp/commands/tab/list.ts +14 -2
- package/src/cdp/commands/tab/quit.ts +78 -0
- package/src/cdp/har-recorder.ts +14 -20
- package/src/cdp/measure/collectors/ax.ts +3 -4
- package/src/cdp/measure/collectors/forms.ts +4 -6
- package/src/cdp/measure/collectors/media.ts +1 -2
- package/src/cdp/measure/collectors/states.ts +1 -6
- package/src/cdp/measure/collectors/style-provenance.ts +4 -16
- package/src/cdp/measure/collectors/styles.ts +21 -10
- package/src/cdp/measure/collectors/text.ts +3 -5
- package/src/cdp/measure/snapshot.ts +195 -29
- package/src/cdp/measure/types.ts +32 -2
- package/src/cdp/motion/jank.ts +8 -1
- package/src/cdp/record.ts +37 -5
- package/src/cdp/screenshot.ts +83 -8
- package/src/cdp/targets.ts +5 -0
- package/src/cdp/types.ts +4 -0
- package/src/har-manager.ts +16 -15
- package/src/interact.ts +20 -4
- package/src/output/render.ts +2 -0
- package/src/registry.ts +1 -1
- package/src/session/commands.ts +287 -70
- package/src/session/har-redact.ts +125 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render-time credential redaction for HAR request URLs — the ONE narrow
|
|
3
|
+
* carve-out in Capture's otherwise no-redaction posture.
|
|
4
|
+
*
|
|
5
|
+
* Capture preserves browser evidence rather than redacting it, and the HAR
|
|
6
|
+
* artifact on disk remains full fidelity: this module is applied only where a
|
|
7
|
+
* URL is rendered into a `session har` block, never on collection, never on
|
|
8
|
+
* the stored `har.json`/live NDJSON, and never on the value a `--filter-url`
|
|
9
|
+
* pattern is matched against. Its whole job is to keep a dashboard/API session
|
|
10
|
+
* token out of an agent's transcript and terminal scrollback while leaving the
|
|
11
|
+
* request itself identifiable — the parameter name, ordering, and every
|
|
12
|
+
* non-credential value survive untouched, so the row still joins to the
|
|
13
|
+
* artifact record it came from.
|
|
14
|
+
*
|
|
15
|
+
* Matching is on the parameter NAME only; no value is ever inspected, so this
|
|
16
|
+
* cannot depend on the shape of any observed secret.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** Replacement text for a credential-like parameter value in rendered output. */
|
|
20
|
+
export const REDACTED_VALUE = 'REDACTED';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Parameter names that are credential-bearing on their own. Compared after
|
|
24
|
+
* normalization (lowercased, every non-alphanumeric character dropped), so
|
|
25
|
+
* `api_key`, `API-Key`, and `apiKey` all reduce to `apikey`.
|
|
26
|
+
*/
|
|
27
|
+
const CREDENTIAL_PARAM_NAMES: ReadonlySet<string> = new Set([
|
|
28
|
+
'key',
|
|
29
|
+
'apikey',
|
|
30
|
+
'accesskey',
|
|
31
|
+
'secretkey',
|
|
32
|
+
'privatekey',
|
|
33
|
+
'sig',
|
|
34
|
+
'signature',
|
|
35
|
+
'auth',
|
|
36
|
+
'authorization',
|
|
37
|
+
'credential',
|
|
38
|
+
'credentials',
|
|
39
|
+
'password',
|
|
40
|
+
'passwd',
|
|
41
|
+
'pwd',
|
|
42
|
+
'token',
|
|
43
|
+
'secret',
|
|
44
|
+
'code',
|
|
45
|
+
'authcode',
|
|
46
|
+
'authorizationcode',
|
|
47
|
+
'sessionid',
|
|
48
|
+
'sessionkey',
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Fragments that make ANY containing parameter name credential-bearing —
|
|
53
|
+
* `access_token`, `refresh-token`, `clientSecret`, `x-amz-signature`, and the
|
|
54
|
+
* rest of the long tail no exact list keeps up with.
|
|
55
|
+
*/
|
|
56
|
+
const CREDENTIAL_PARAM_FRAGMENTS: readonly string[] = [
|
|
57
|
+
'token',
|
|
58
|
+
'secret',
|
|
59
|
+
'password',
|
|
60
|
+
'passwd',
|
|
61
|
+
'credential',
|
|
62
|
+
'apikey',
|
|
63
|
+
'accesskey',
|
|
64
|
+
'privatekey',
|
|
65
|
+
'signature',
|
|
66
|
+
'authorization',
|
|
67
|
+
'sessionid',
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
function normalizeParamName(raw: string): string {
|
|
71
|
+
let decoded = raw;
|
|
72
|
+
try {
|
|
73
|
+
decoded = decodeURIComponent(raw.replace(/\+/g, ' '));
|
|
74
|
+
} catch {
|
|
75
|
+
decoded = raw;
|
|
76
|
+
}
|
|
77
|
+
return decoded.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** Whether a query/fragment parameter name names a credential. */
|
|
81
|
+
export function isCredentialParamName(raw: string): boolean {
|
|
82
|
+
const name = normalizeParamName(raw);
|
|
83
|
+
if (name === '') return false;
|
|
84
|
+
if (CREDENTIAL_PARAM_NAMES.has(name)) return true;
|
|
85
|
+
return CREDENTIAL_PARAM_FRAGMENTS.some((fragment) => name.includes(fragment));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Redacts credential values in one `a=1&b=2` parameter section. */
|
|
89
|
+
function redactParamSection(section: string): string {
|
|
90
|
+
return section
|
|
91
|
+
.split('&')
|
|
92
|
+
.map((pair) => {
|
|
93
|
+
const eq = pair.indexOf('=');
|
|
94
|
+
if (eq < 0) return pair;
|
|
95
|
+
const name = pair.slice(0, eq);
|
|
96
|
+
return isCredentialParamName(name) ? `${name}=${REDACTED_VALUE}` : pair;
|
|
97
|
+
})
|
|
98
|
+
.join('&');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Returns the URL with credential-like query (and parameter-shaped fragment)
|
|
103
|
+
* values replaced by `REDACTED`. Everything else — scheme, host, path, other
|
|
104
|
+
* parameters, ordering — is returned verbatim; a URL carrying no credential
|
|
105
|
+
* parameter comes back byte-identical. Operates on the raw string rather than
|
|
106
|
+
* `new URL()` so a relative or malformed URL is never re-encoded or dropped.
|
|
107
|
+
*/
|
|
108
|
+
export function redactUrlCredentials(url: string): string {
|
|
109
|
+
const hashIndex = url.indexOf('#');
|
|
110
|
+
const base = hashIndex < 0 ? url : url.slice(0, hashIndex);
|
|
111
|
+
const fragment = hashIndex < 0 ? null : url.slice(hashIndex + 1);
|
|
112
|
+
|
|
113
|
+
const queryIndex = base.indexOf('?');
|
|
114
|
+
const head = queryIndex < 0 ? base : base.slice(0, queryIndex);
|
|
115
|
+
const query = queryIndex < 0 ? null : base.slice(queryIndex + 1);
|
|
116
|
+
|
|
117
|
+
const renderedQuery = query === null ? '' : `?${redactParamSection(query)}`;
|
|
118
|
+
// A fragment is only treated as parameters when it actually looks like them;
|
|
119
|
+
// an ordinary `#section-2` anchor is left exactly as captured.
|
|
120
|
+
const renderedFragment = fragment === null
|
|
121
|
+
? ''
|
|
122
|
+
: `#${fragment.includes('=') ? redactParamSection(fragment) : fragment}`;
|
|
123
|
+
|
|
124
|
+
return `${head}${renderedQuery}${renderedFragment}`;
|
|
125
|
+
}
|