@switchbot/openapi-cli 2.3.0 → 2.5.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.
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Header/value redaction utilities for verbose traces.
3
+ *
4
+ * C6 contract: any header whose name matches a sensitive pattern is mid-masked
5
+ * (first 2 chars + `*` run + last 2 chars) before it is written to stderr. The
6
+ * `--trace-unsafe` flag turns masking off — with a prominent one-time warning.
7
+ */
8
+ import { isTraceUnsafe } from './flags.js';
9
+ const SENSITIVE_HEADER_PATTERNS = [
10
+ /^authorization$/i,
11
+ /^token$/i,
12
+ /^sign$/i,
13
+ /^nonce$/i,
14
+ /^x-api-key$/i,
15
+ /^cookie$/i,
16
+ /^set-cookie$/i,
17
+ /^x-auth-token$/i,
18
+ ];
19
+ // The `t` header (timestamp) is treated as sensitive alongside sign because
20
+ // together they reconstruct the HMAC signature — anyone watching the logs
21
+ // shouldn't be able to replay the exact timestamp that was used.
22
+ const SENSITIVE_EXACT_KEYS = new Set(['t']);
23
+ export function isSensitiveHeader(name) {
24
+ if (SENSITIVE_EXACT_KEYS.has(name))
25
+ return true;
26
+ return SENSITIVE_HEADER_PATTERNS.some((re) => re.test(name));
27
+ }
28
+ export function maskValue(value) {
29
+ if (value.length <= 4)
30
+ return '****';
31
+ return `${value.slice(0, 2)}${'*'.repeat(Math.max(4, value.length - 4))}${value.slice(-2)}`;
32
+ }
33
+ /**
34
+ * Redact the sensitive entries of a headers object. Returns a new object
35
+ * alongside the count of entries that were masked.
36
+ */
37
+ export function redactHeaders(headers) {
38
+ const safe = {};
39
+ let redactedCount = 0;
40
+ if (!headers)
41
+ return { safe, redactedCount };
42
+ const unsafe = isTraceUnsafe();
43
+ for (const [k, v] of Object.entries(headers)) {
44
+ const strVal = typeof v === 'string' ? v : v == null ? '' : String(v);
45
+ if (!unsafe && isSensitiveHeader(k)) {
46
+ safe[k] = maskValue(strVal);
47
+ redactedCount++;
48
+ }
49
+ else {
50
+ safe[k] = strVal;
51
+ }
52
+ }
53
+ return { safe, redactedCount };
54
+ }
55
+ let unsafeBannerShown = false;
56
+ /**
57
+ * Print the big "REDACTION DISABLED" banner once per process when
58
+ * --trace-unsafe is on. Callers should invoke this once before any
59
+ * header-spilling output.
60
+ */
61
+ export function warnOnceIfUnsafe() {
62
+ if (unsafeBannerShown)
63
+ return;
64
+ if (!isTraceUnsafe())
65
+ return;
66
+ unsafeBannerShown = true;
67
+ process.stderr.write('⚠️ --trace-unsafe: sensitive headers will be printed UNMASKED. Do not share this output.\n');
68
+ }
@@ -0,0 +1,4 @@
1
+ import { createRequire } from 'module';
2
+ const require = createRequire(import.meta.url);
3
+ const { version: VERSION } = require('../package.json');
4
+ export { VERSION };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@switchbot/openapi-cli",
3
- "version": "2.3.0",
3
+ "version": "2.5.0",
4
4
  "description": "SwitchBot smart home CLI — control devices, run scenes, stream real-time events, and integrate AI agents via MCP. Full API v1.1 coverage.",
5
5
  "keywords": [
6
6
  "switchbot",