From fb237c91a80ce53c05717b27cd685191f1b61588 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 4 Apr 2026 15:18:51 +0000 Subject: [PATCH] Fix substitute values being re-detected as PII after adding mapping Two issues fixed: 1. autoDetectPII only skipped identity values (names, emails, etc.) but not mapping values. After clicking "+" to map e.g. an IP address, the fake substitute IP was immediately re-detected as PII, causing the notification to reappear. Now autoDetectPII accepts opts.mappings and adds both real and substitute values to the skip set. 2. The local mappings array was only updated after the async background round-trip completed. The 150ms re-scan could fire before that, missing the new mapping. Now an optimistic temp mapping is added to the local array immediately so the re-scan already knows to skip both values. https://claude.ai/code/session_01RfzvB5sHah326acr8Xa7Jn --- src/content/content.js | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/content/content.js b/src/content/content.js index 0fae146..2626424 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -280,7 +280,7 @@ // 4. Auto-detect: scan the FINAL text for unconfigured PII // Auto-redact if enabled, otherwise just warn if (settings.autoDetect !== false) { - const warnings = autoDetectPII(finalText, identity, { detectProperNouns: settings.detectProperNouns === true }) + const warnings = autoDetectPII(finalText, identity, { detectProperNouns: settings.detectProperNouns === true, mappings }) .filter(w => !ignoredDetections.has(w.value)); if (warnings.length > 0) { // Auto-redact detected PII in the outbound text @@ -471,6 +471,14 @@ addAll(ident.names); addAll(ident.emails); addAll(ident.usernames); addAll(ident.hostnames); addAll(ident.phones); } + // Also skip values covered by mappings (both real and substitute) + if (opts?.mappings) { + for (const m of opts.mappings) { + if (!m.enabled) continue; + if (m.real) configured.add(m.real.toLowerCase()); + if (m.substitute) configured.add(m.substitute.toLowerCase()); + } + } const findings = []; for (const pat of PII_PATTERNS) { @@ -1412,7 +1420,19 @@ preSendWarningEl.classList.remove('visible'); } - // Add to mappings via background script (handles encryption) + // Optimistically add to local mappings so re-scan skips this value + const tempMapping = { + id: crypto.randomUUID(), + real, substitute: fake, + category: cat, + caseSensitive: false, + enabled: true, + createdAt: Date.now(), + }; + mappings = [...mappings, tempMapping]; + + // Persist via background script (handles encryption); + // update local mappings with the authoritative list on success addMappingViaBackground({ real, substitute: fake, category: cat }) .then(updatedMappings => { if (updatedMappings.length) mappings = updatedMappings; @@ -1509,7 +1529,7 @@ return; } - const warnings = autoDetectPII(text, identity, { detectProperNouns: settings.detectProperNouns === true }) + const warnings = autoDetectPII(text, identity, { detectProperNouns: settings.detectProperNouns === true, mappings }) .filter(w => !ignoredDetections.has(w.value)); if (warnings.length > 0) { showPreSendWarning(warnings, target);