|
| 1 | +//#region src/error-format.ts |
| 2 | +const SECRET_PATTERNS = [ |
| 3 | + /\b[A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CARD[_-]?NUMBER|CARD[_-]?CVC|CARD[_-]?CVV|CVC|CVV|SECURITY[_-]?CODE|PAYMENT[_-]?CREDENTIAL|SHARED[_-]?PAYMENT[_-]?TOKEN)\b\s*[=:]\s*(["']?)([^\s"'\\]+)\1/g, |
| 4 | + /\b[A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|CARD[_-]?NUMBER|CARD[_-]?CVC|CARD[_-]?CVV|CVC|CVV|SECURITY[_-]?CODE|PAYMENT[_-]?CREDENTIAL|SHARED[_-]?PAYMENT[_-]?TOKEN)\b\s*[=:]\s*\\+(["'])([^\s"'\\]+)\\+\1/g, |
| 5 | + /[?&](?:access[-_]?token|auth[-_]?token|hook[-_]?token|refresh[-_]?token|api[-_]?key|client[-_]?secret|token|key|secret|password|pass|passwd|auth|signature|card[-_]?number|card[-_]?cvc|card[-_]?cvv|cvc|cvv|security[-_]?code|payment[-_]?credential|shared[-_]?payment[-_]?token)=([^&\s"'<>]+)/gi, |
| 6 | + /"(?:apiKey|token|secret|password|passwd|accessToken|refreshToken|cardNumber|card_number|cardCvc|card_cvc|cardCvv|card_cvv|cvc|cvv|securityCode|security_code|paymentCredential|payment_credential|sharedPaymentToken|shared_payment_token)"\s*:\s*"([^"]+)"/g, |
| 7 | + /(^|[\s,{])["']?(?:api[-_]key|access[-_]token|refresh[-_]token|authToken|auth[-_]token|clientSecret|client[-_]secret|appSecret|app[-_]secret)["']?\s*[:=]\s*(["'])([^"'\r\n]+)\2/gi, |
| 8 | + /(^|[\s,{])["']?(?:authorization|proxy-authorization|cookie|set-cookie|x-api-key|x-auth-token)["']?\s*[:=]\s*(["'])([^"'\r\n]+)\2/gi, |
| 9 | + /--(?:api[-_]?key|hook[-_]?token|token|secret|password|passwd|card[-_]?number|card[-_]?cvc|card[-_]?cvv|cvc|cvv|security[-_]?code|payment[-_]?credential|shared[-_]?payment[-_]?token)\s+(["']?)([^\s"']+)\1/gi, |
| 10 | + /Authorization\s*[:=]\s*Bearer\s+([A-Za-z0-9._\-+=]+)/gi, |
| 11 | + /Authorization\s*[:=]\s*Basic\s+([A-Za-z0-9+/=]+)/gi, |
| 12 | + /(?:X-OpenClaw-Token|x-pomerium-jwt-assertion|X-Api-Key|X-Auth-Token)\s*[:=]\s*([^\s"',;]+)/gi, |
| 13 | + /\bBearer\s+([A-Za-z0-9._\-+=]{18,})\b/g, |
| 14 | + /(^|[\s,;])(?:access_token|refresh_token|auth[-_]?token|api[-_]?key|client[-_]?secret|app[-_]?secret|token|secret|password|passwd|card[-_]?number|card[-_]?cvc|card[-_]?cvv|cvc|cvv|security[-_]?code|payment[-_]?credential|shared[-_]?payment[-_]?token)=([^\s&#]+)/gi, |
| 15 | + /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]+?-----END [A-Z ]*PRIVATE KEY-----/g, |
| 16 | + /\b(sk-[A-Za-z0-9_-]{8,})\b/g, |
| 17 | + /(ghp_[A-Za-z0-9]{20,})/g, |
| 18 | + /(github_pat_[A-Za-z0-9_]{20,})/g, |
| 19 | + /(xox[baprs]-[A-Za-z0-9-]{10,})/g, |
| 20 | + /(xapp-[A-Za-z0-9-]{10,})/g, |
| 21 | + /(gsk_[A-Za-z0-9_-]{10,})/g, |
| 22 | + /(AIza[0-9A-Za-z\-_]{20,})/g, |
| 23 | + /(ya29\.[0-9A-Za-z_\-./+=]{10,})/g, |
| 24 | + /(1\/\/0[0-9A-Za-z_\-./+=]{10,})/g, |
| 25 | + /(eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,})/g, |
| 26 | + /(pplx-[A-Za-z0-9_-]{10,})/g, |
| 27 | + /(npm_[A-Za-z0-9]{10,})/g, |
| 28 | + /(AKID[A-Za-z0-9]{10,})/g, |
| 29 | + /(LTAI[A-Za-z0-9]{10,})/g, |
| 30 | + /(hf_[A-Za-z0-9]{10,})/g, |
| 31 | + /(r8_[A-Za-z0-9]{10,})/g, |
| 32 | + /\bbot(\d{6,}:[A-Za-z0-9_-]{20,})\b/g, |
| 33 | + /\b(\d{6,}:[A-Za-z0-9_-]{20,})\b/g |
| 34 | +]; |
| 35 | +let configuredRedactor; |
| 36 | +function configureAcpErrorRedactor(redactor) { |
| 37 | + configuredRedactor = redactor; |
| 38 | +} |
| 39 | +function redactSensitiveText(value) { |
| 40 | + if (configuredRedactor) return configuredRedactor(value); |
| 41 | + let redacted = value; |
| 42 | + for (const pattern of SECRET_PATTERNS) redacted = redacted.replace(pattern, (match, ...args) => { |
| 43 | + if (match.includes("PRIVATE KEY-----")) return "[REDACTED_PRIVATE_KEY]"; |
| 44 | + const token = args.slice(0, -2).findLast((group) => typeof group === "string" && group.length > 0); |
| 45 | + return token ? match.replace(token, "[REDACTED]") : "[REDACTED]"; |
| 46 | + }); |
| 47 | + return redacted; |
| 48 | +} |
| 49 | +/** |
| 50 | +* Render a non-Error `cause` value without leaking `[object Object]` or throwing |
| 51 | +* while formatting nested ACP runtime failures. |
| 52 | +*/ |
| 53 | +function stringifyNonErrorCause(value) { |
| 54 | + if (value === null) return "null"; |
| 55 | + if (typeof value === "string") return value; |
| 56 | + if (typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") return String(value); |
| 57 | + try { |
| 58 | + return JSON.stringify(value); |
| 59 | + } catch { |
| 60 | + return Object.prototype.toString.call(value); |
| 61 | + } |
| 62 | +} |
| 63 | +//#endregion |
| 64 | +export { configureAcpErrorRedactor, redactSensitiveText, stringifyNonErrorCause }; |
0 commit comments