yunti-browser-runtime 0.1.2 → 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/mcp/redaction.js CHANGED
@@ -1,5 +1,14 @@
1
1
  const SENSITIVE_KEY_RE =
2
2
  /cookie|authorization|token|secret|password|passwd|pwd|sid|session|ticket|tgc|captcha|验证码|密码/i
3
+ const JWT_RE = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g
4
+ const BEARER_RE = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}\b/gi
5
+ const PRIVATE_KEY_RE = /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g
6
+ const LONG_RANDOM_RE = /\b[A-Za-z0-9_-]{32,}\b/g
7
+ const EMAIL_RE = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi
8
+ const PHONE_RE = /(?:\+?\d[\d\s().-]{7,}\d)/g
9
+ const PAYMENT_CARD_RE = /(?:^|[^\d])((?:\d[ -]?){13,19})(?=$|[^\d])/g
10
+ const ADDRESS_RE =
11
+ /\b\d{1,6}\s+[\p{L}0-9 .'-]{2,}\s+(street|st|road|rd|avenue|ave|lane|ln|boulevard|blvd|drive|dr|way|court|ct)\b|[\p{Script=Han}]{1,20}(省|市|区|县|路|街|号楼|单元|室)/giu
3
12
 
4
13
  export function clampNumber(value, min, max, fallback = min) {
5
14
  const number = Number(value)
@@ -17,12 +26,52 @@ export function redactValue(key, value) {
17
26
  }
18
27
 
19
28
  export function redactLikelySecrets(text) {
20
- return truncateText(text, 1500).replace(
21
- /(cookie|authorization|token|secret|password|passwd|pwd|sid|session|ticket|tgc|captcha)(["'\s:=]+)([^"',\s}&]+)/gi,
29
+ return redactLikelySensitiveText(text, 1500)
30
+ }
31
+
32
+ export function redactLikelySensitiveText(text, max = 1500) {
33
+ const redacted = truncateText(text, max)
34
+ .replace(PRIVATE_KEY_RE, "[REDACTED_PRIVATE_KEY]")
35
+ .replace(JWT_RE, "[REDACTED_JWT]")
36
+ .replace(BEARER_RE, "Bearer [REDACTED]")
37
+ .replace(
38
+ /(cookie|authorization|token|secret|password|passwd|pwd|sid|session|ticket|tgc|captcha|api[-_]?key)(["'\s:=]+)([^"',\s}&]+)/gi,
39
+ "$1$2[REDACTED]"
40
+ )
41
+ .replace(LONG_RANDOM_RE, "[REDACTED_TOKEN]")
42
+ .replace(EMAIL_RE, "[REDACTED_EMAIL]")
43
+ .replace(PAYMENT_CARD_RE, (match, digitsPart) => {
44
+ const digits = String(digitsPart || "").replace(/\D/g, "")
45
+ if (!isPaymentCardLike(digits)) return match
46
+ return match.replace(digitsPart, "[REDACTED_PAYMENT_CARD]")
47
+ })
48
+ .replace(PHONE_RE, "[REDACTED_PHONE]")
49
+ .replace(ADDRESS_RE, "[REDACTED_ADDRESS]")
50
+ return redacted.replace(
51
+ /\b(authorization|cookie|token|secret|password|passwd|pwd|sid|session|ticket|tgc|captcha|api[-_]?key)(["'\s:=]+)\[REDACTED\](?:\s+\[REDACTED(?:_[A-Z]+)?\])+/gi,
22
52
  "$1$2[REDACTED]"
23
53
  )
24
54
  }
25
55
 
56
+ function isPaymentCardLike(digits) {
57
+ return digits.length >= 13 && digits.length <= 19 && passesLuhn(digits)
58
+ }
59
+
60
+ function passesLuhn(digits) {
61
+ let sum = 0
62
+ let shouldDouble = false
63
+ for (let index = digits.length - 1; index >= 0; index -= 1) {
64
+ let digit = Number(digits[index])
65
+ if (shouldDouble) {
66
+ digit *= 2
67
+ if (digit > 9) digit -= 9
68
+ }
69
+ sum += digit
70
+ shouldDouble = !shouldDouble
71
+ }
72
+ return sum % 10 === 0
73
+ }
74
+
26
75
  export function sanitizeUrl(rawUrl) {
27
76
  try {
28
77
  const url = new URL(String(rawUrl || ""))
@@ -51,7 +100,7 @@ export function sanitizeRequestBody(body) {
51
100
  }
52
101
  }
53
102
  if (Number.isFinite(Number(body.rawBytes))) out.rawBytes = Number(body.rawBytes)
54
- if (typeof body.preview === "string") out.preview = redactLikelySecrets(body.preview)
103
+ if (typeof body.preview === "string") out.preview = redactLikelySensitiveText(body.preview)
55
104
  return Object.keys(out).length ? out : null
56
105
  }
57
106
 
package/mcp/server.js CHANGED
@@ -214,6 +214,7 @@ export async function runStdio() {
214
214
  console.error(
215
215
  `[yunti-browser-runtime] bridge ${bridge.mode} on http://${bridge.host}:${bridge.port}`
216
216
  )
217
+ console.error(`[yunti-browser-runtime] console http://${bridge.host}:${bridge.port}/console`)
217
218
  if (bridge.mode === "owner") {
218
219
  if (bridge.authRequired) {
219
220
  console.error(
@@ -253,6 +254,7 @@ export async function runBridgeOnly() {
253
254
  console.error(
254
255
  `[yunti-browser-runtime] bridge ${bridge.mode} on http://${bridge.host}:${bridge.port}`
255
256
  )
257
+ console.error(`[yunti-browser-runtime] console http://${bridge.host}:${bridge.port}/console`)
256
258
  if (bridge.mode === "owner") {
257
259
  if (bridge.authRequired) {
258
260
  console.error(