
























@@ -631,18 +631,21 @@ function buildInboundHistorySnapshot(params: {
631631function sanitizeForLog(value: unknown, maxLen = 200): string {
632632let cleaned = String(value).replace(/[\r\n\t\p{C}]/gu, " ");
633633// Redact common secret-bearing patterns before logging. BlueBubbles uses
634-// query-string auth (`?password=...`) by default, so attachment download
635-// failures and similar errors can carry the API password in the captured
636-// request URL; other libraries occasionally surface `Authorization: Bearer …`
637-// headers in error chains. Strip both before they reach the log sink (CWE-532).
634+// query-string auth (`?password=...`, `?guid=...`, or `?token=...`) by
635+// default, so attachment download failures and similar errors can carry the
636+// API password in the captured request URL; other libraries occasionally
637+// surface `Authorization: Bearer ...` headers in error chains. Strip both
638+// before they reach the log sink (CWE-532).
638639cleaned = cleaned.replace(
639-/([?&](?:password|token|api[_-]?key|secret)=)[^&\s"]+/gi,
640+/([?&](?:password|guid|token|api[_-]?key|secret)=)[^&\s"]+/gi,
640641"$1<redacted>",
641642);
642643cleaned = cleaned.replace(/(authorization\s*:\s*(?:bearer|basic)\s+)[^\s"]+/gi, "$1<redacted>");
643644return cleaned.length > maxLen ? cleaned.slice(0, maxLen) + "..." : cleaned;
644645}
645646647+export const _sanitizeBlueBubblesLogValueForTest = sanitizeForLog;
648+646649/**
647650 * Signal object threaded through `processMessageAfterDedupe` so the outer
648651 * wrapper can distinguish "reply delivery failed silently" from "returned
@@ -810,7 +813,7 @@ async function processMessageAfterDedupe(
810813logVerbose(
811814core,
812815runtime,
813-`attachment retry failed for msgId=${message.messageId}: ${String(err)}`,
816+`attachment retry failed for msgId=${sanitizeForLog(message.messageId)}: ${sanitizeForLog(err)}`,
814817);
815818}
816819}
@@ -904,18 +907,22 @@ async function processMessageAfterDedupe(
904907}
905908906909if (isSelfChatMessage && hasBlueBubblesSelfChatCopy(selfChatLookup)) {
907-logVerbose(core, runtime, `drop: reflected self-chat duplicate sender=${message.senderId}`);
910+logVerbose(
911+core,
912+runtime,
913+`drop: reflected self-chat duplicate sender=${sanitizeForLog(message.senderId)}`,
914+);
908915return;
909916}
910917911918if (!rawBody) {
912-logVerbose(core, runtime, `drop: empty text sender=${message.senderId}`);
919+logVerbose(core, runtime, `drop: empty text sender=${sanitizeForLog(message.senderId)}`);
913920return;
914921}
915922logVerbose(
916923core,
917924runtime,
918-`msg sender=${message.senderId} group=${isGroup} textLen=${text.length} attachments=${attachments.length} chatGuid=${message.chatGuid ?? ""} chatId=${message.chatId ?? ""}`,
925+`msg sender=${sanitizeForLog(message.senderId)} group=${isGroup} textLen=${text.length} attachments=${attachments.length} chatGuid=${sanitizeForLog(message.chatGuid ?? "")} chatId=${sanitizeForLog(message.chatId ?? "")}`,
919926);
920927921928const dmPolicy = account.config.dmPolicy ?? "pairing";
@@ -1011,8 +1018,14 @@ async function processMessageAfterDedupe(
10111018senderIdLine: `Your BlueBubbles sender id: ${message.senderId}`,
10121019meta: { name: message.senderName },
10131020onCreated: () => {
1014-runtime.log?.(`[bluebubbles] pairing request sender=${message.senderId} created=true`);
1015-logVerbose(core, runtime, `bluebubbles pairing request sender=${message.senderId}`);
1021+runtime.log?.(
1022+`[bluebubbles] pairing request sender=${sanitizeForLog(message.senderId)} created=true`,
1023+);
1024+logVerbose(
1025+core,
1026+runtime,
1027+`bluebubbles pairing request sender=${sanitizeForLog(message.senderId)}`,
1028+);
10161029},
10171030sendPairingReply: async (text) => {
10181031await sendMessageBlueBubbles(message.senderId, text, {
@@ -1025,10 +1038,10 @@ async function processMessageAfterDedupe(
10251038logVerbose(
10261039core,
10271040runtime,
1028-`bluebubbles pairing reply failed for ${message.senderId}: ${String(err)}`,
1041+`bluebubbles pairing reply failed for ${sanitizeForLog(message.senderId)}: ${sanitizeForLog(err)}`,
10291042);
10301043runtime.error?.(
1031-`[bluebubbles] pairing reply failed sender=${message.senderId}: ${String(err)}`,
1044+`[bluebubbles] pairing reply failed sender=${sanitizeForLog(message.senderId)}: ${sanitizeForLog(err)}`,
10321045);
10331046},
10341047});
@@ -1159,7 +1172,7 @@ async function processMessageAfterDedupe(
11591172logVerbose(
11601173core,
11611174runtime,
1162-`bluebubbles: participant fallback lookup failed chat=${peerId}: ${String(err)}`,
1175+`bluebubbles: participant fallback lookup failed chat=${sanitizeForLog(peerId)}: ${sanitizeForLog(err)}`,
11631176);
11641177}
11651178}
@@ -1225,7 +1238,7 @@ async function processMessageAfterDedupe(
12251238logVerbose(
12261239core,
12271240runtime,
1228-`attachment download failed guid=${attachment.guid} err=${String(err)}`,
1241+`attachment download failed guid=${sanitizeForLog(attachment.guid)} err=${sanitizeForLog(err)}`,
12291242);
12301243}
12311244}
@@ -1410,7 +1423,7 @@ async function processMessageAfterDedupe(
14101423logVerbose(
14111424core,
14121425runtime,
1413-`ack reaction failed chatGuid=${chatGuidForActions} msg=${ackMessageId}: ${String(err)}`,
1426+`ack reaction failed chatGuid=${sanitizeForLog(chatGuidForActions)} msg=${sanitizeForLog(ackMessageId)}: ${sanitizeForLog(err)}`,
14141427);
14151428return false;
14161429},
@@ -1425,9 +1438,9 @@ async function processMessageAfterDedupe(
14251438cfg: config,
14261439accountId: account.accountId,
14271440});
1428-logVerbose(core, runtime, `marked read chatGuid=${chatGuidForActions}`);
1441+logVerbose(core, runtime, `marked read chatGuid=${sanitizeForLog(chatGuidForActions)}`);
14291442} catch (err) {
1430-runtime.error?.(`[bluebubbles] mark read failed: ${String(err)}`);
1443+runtime.error?.(`[bluebubbles] mark read failed: ${sanitizeForLog(err)}`);
14311444}
14321445} else if (!sendReadReceipts) {
14331446logVerbose(core, runtime, "mark read skipped (sendReadReceipts=false)");
@@ -1569,7 +1582,7 @@ async function processMessageAfterDedupe(
15691582logVerbose(
15701583core,
15711584runtime,
1572-`history backfill failed for ${historyIdentifier}: ${String(err)} (retries left=${Math.max(remainingAttempts, 0)} next_in_ms=${nextBackoffMs})`,
1585+`history backfill failed for ${sanitizeForLog(historyIdentifier)}: ${sanitizeForLog(err)} (retries left=${Math.max(remainingAttempts, 0)} next_in_ms=${nextBackoffMs})`,
15731586);
15741587}
15751588}
@@ -1660,7 +1673,7 @@ async function processMessageAfterDedupe(
16601673cfg: config,
16611674accountId: account.accountId,
16621675}).catch((err) => {
1663-runtime.error?.(`[bluebubbles] typing restart failed: ${String(err)}`);
1676+runtime.error?.(`[bluebubbles] typing restart failed: ${sanitizeForLog(err)}`);
16641677});
16651678}, typingRestartDelayMs);
16661679};
@@ -1686,7 +1699,7 @@ async function processMessageAfterDedupe(
16861699accountId: account.accountId,
16871700});
16881701} catch (err) {
1689-runtime.error?.(`[bluebubbles] typing start failed: ${String(err)}`);
1702+runtime.error?.(`[bluebubbles] typing start failed: ${sanitizeForLog(err)}`);
16901703}
16911704},
16921705onIdle: () => {
@@ -1848,7 +1861,7 @@ async function processMessageAfterDedupe(
18481861if (info.kind === "final") {
18491862dedupeSignal.deliveryFailed = true;
18501863}
1851-runtime.error?.(`BlueBubbles ${info.kind} reply failed: ${String(err)}`);
1864+runtime.error?.(`BlueBubbles ${info.kind} reply failed: ${sanitizeForLog(err)}`);
18521865},
18531866},
18541867replyOptions: {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。