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
This commit is contained in:
Claude
2026-04-04 15:18:51 +00:00
parent d8a4e3a668
commit fb237c91a8
+23 -3
View File
@@ -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);