diff --git a/src/content/content.js b/src/content/content.js index b843d72..0d907e4 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -287,7 +287,7 @@ } // ============================================================ - // Combined substitution: smart patterns + explicit + secret scan + // Combined substitution: smart patterns + explicit + auto-redact // + auto-detect warning for unconfigured PPI // ============================================================ function substituteAll(text) { @@ -303,10 +303,10 @@ // 3. Auto Redact (API keys, tokens, SSNs, credit cards, custom patterns, etc.) let finalText = explicit.text; - if (settings.secretScanning !== false) { - const secrets = scanAndRedactSecrets(finalText); - allReplacements.push(...secrets.redactions); - finalText = secrets.text; + if (settings.autoRedact !== false) { + const redacted = runAutoRedact(finalText); + allReplacements.push(...redacted.redactions); + finalText = redacted.text; } // 4. Auto-detect: scan the FINAL text for unconfigured PPI @@ -665,11 +665,11 @@ } // ============================================================ - // Auto Redact — Secret Scanner (inline for page world) + // Auto Redact (inline for page world) // Detects API keys, tokens, passwords, SSNs, credit cards, // plus user-defined custom patterns from settings. // ============================================================ - const SECRET_PATTERNS = [ + const REDACT_PATTERNS = [ // OpenAI { name: 'OpenAI Key', re: /\bsk-[A-Za-z0-9]{20,}\b/g, to: '[REDACTED-OPENAI-KEY]' }, { name: 'OpenAI Project Key', re: /\bsk-proj-[A-Za-z0-9_-]{20,}\b/g, to: '[REDACTED-OPENAI-KEY]' }, @@ -707,13 +707,13 @@ { name: 'Credit Card', re: /\b(?:4\d{3}|5[1-5]\d{2}|3[47]\d{2}|6(?:011|5\d{2}))[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g, to: '[REDACTED-CARD]' }, ]; - function scanAndRedactSecrets(text) { + function runAutoRedact(text) { const redactions = []; let result = text; // Combine built-in + custom patterns - const allPatterns = [...SECRET_PATTERNS]; - const custom = settings.customSecretPatterns || []; + const allPatterns = [...REDACT_PATTERNS]; + const custom = settings.customRedactPatterns || []; for (const cp of custom) { if (!cp.enabled || !cp.pattern) continue; try { @@ -739,7 +739,7 @@ redactions.push({ original: match.value.slice(0, 8) + '...', // Don't log the full secret replaced: replacement, - category: 'secret', + category: 'redact', pattern: pat.name, }); result = @@ -1437,7 +1437,7 @@ } } - // Also add auto-detect and secret scanner substitutions from this session + // Also add auto-detect and auto-redact substitutions from this session for (const [key, entry] of sessionSubstitutions) { if (!pairs.some(p => p.from.toLowerCase() === key)) { pairs.push({ from: entry.replaced, to: entry.original }); diff --git a/src/lib/secret-scanner.js b/src/lib/auto-redact.js similarity index 94% rename from src/lib/secret-scanner.js rename to src/lib/auto-redact.js index 4679d08..125c703 100644 --- a/src/lib/secret-scanner.js +++ b/src/lib/auto-redact.js @@ -1,5 +1,5 @@ /** - * Silent Send - Auto Redact (Secret Scanner) + * Silent Send - Auto Redact * * Detects common secret/credential patterns in text and either * warns or auto-redacts them. This catches things the identity-based @@ -15,7 +15,7 @@ * - severity: 'critical' (always redact) or 'warning' (flag but allow) */ -const SECRET_PATTERNS = [ +const REDACT_PATTERNS = [ // --- API Keys --- { name: 'OpenAI API Key', @@ -163,13 +163,13 @@ const SECRET_PATTERNS = [ }, ]; -const SecretScanner = { +const AutoRedact = { /** * Build the full pattern list (built-in + custom). - * Custom patterns come from settings.customSecretPatterns. + * Custom patterns come from settings.customRedactPatterns. */ _buildPatterns(customPatterns) { - const all = [...SECRET_PATTERNS]; + const all = [...REDACT_PATTERNS]; if (Array.isArray(customPatterns)) { for (const cp of customPatterns) { if (!cp.enabled || !cp.pattern) continue; @@ -189,7 +189,7 @@ const SecretScanner = { /** * Scan text for secrets. Returns list of findings. * @param {string} text - * @param {Array} [customPatterns] — from settings.customSecretPatterns + * @param {Array} [customPatterns] — from settings.customRedactPatterns */ scan(text, customPatterns) { const findings = []; @@ -232,7 +232,7 @@ const SecretScanner = { * Redact all critical secrets in text. Warnings are not auto-redacted. * Returns { text, redactions[] } * @param {string} text - * @param {Array} [customPatterns] — from settings.customSecretPatterns + * @param {Array} [customPatterns] — from settings.customRedactPatterns */ redact(text, customPatterns) { const findings = this.scan(text, customPatterns); @@ -249,7 +249,7 @@ const SecretScanner = { redactions.push({ original: f.value, replaced: f.redactTo, - category: 'secret', + category: 'redact', pattern: f.name, }); } @@ -266,7 +266,7 @@ const SecretScanner = { }; if (typeof globalThis !== 'undefined') { - globalThis.SecretScanner = SecretScanner; + globalThis.AutoRedact = AutoRedact; } -export default SecretScanner; +export default AutoRedact; diff --git a/src/lib/org-policy.js b/src/lib/org-policy.js index 4e53470..8a6808f 100644 --- a/src/lib/org-policy.js +++ b/src/lib/org-policy.js @@ -202,7 +202,7 @@ const OrgPolicy = { * * @returns {Array} additional patterns to add to auto-redact */ - async getOrgSecretPatterns() { + async getOrgRedactPatterns() { const policy = await this.getPolicy(); if (!policy?.requiredSecretPatterns?.length) return []; diff --git a/src/lib/storage.js b/src/lib/storage.js index dea8bfa..3927ccc 100644 --- a/src/lib/storage.js +++ b/src/lib/storage.js @@ -34,13 +34,13 @@ const DEFAULT_SETTINGS = { enabled: true, showHighlights: false, revealMode: false, - secretScanning: true, + autoRedact: true, autoDetect: true, autoRedactDetected: true, autoAddDetected: true, maxLogEntries: 100, customDomains: [], - customSecretPatterns: [], + customRedactPatterns: [], categories: ['name', 'email', 'phone', 'address', 'ssn', 'dob', 'domain', 'password', 'general'], browserSync: false, }; diff --git a/src/options/options.html b/src/options/options.html index 504f2e4..c306c66 100644 --- a/src/options/options.html +++ b/src/options/options.html @@ -53,26 +53,26 @@

Automatically detect and redact API keys, tokens, passwords, SSNs, credit card numbers, and custom patterns

-

Custom Secret Patterns

+

Custom Redact Patterns

Define your own patterns to catch proprietary tokens, internal URLs with keys, or any format the built-in scanner doesn't cover.

-
+
- - + +
- - + +

diff --git a/src/options/options.js b/src/options/options.js index 67f3749..3cd0da2 100644 --- a/src/options/options.js +++ b/src/options/options.js @@ -26,7 +26,7 @@ document.addEventListener('DOMContentLoaded', async () => { // Apply settings to UI $('#showHighlights').checked = settings.showHighlights || false; - $('#secretScanning').checked = settings.secretScanning !== false; + $('#autoRedactToggle').checked = settings.autoRedact !== false; $('#autoDetect').checked = settings.autoDetect !== false; $('#autoRedactDetected').checked = settings.autoRedactDetected !== false; $('#autoAddDetected').checked = settings.autoAddDetected !== false; @@ -293,15 +293,15 @@ document.addEventListener('DOMContentLoaded', async () => { await Storage.saveSettings({ showHighlights: e.target.checked }); }); - $('#secretScanning').addEventListener('change', async (e) => { - await Storage.saveSettings({ secretScanning: e.target.checked }); + $('#autoRedactToggle').addEventListener('change', async (e) => { + await Storage.saveSettings({ autoRedact: e.target.checked }); }); - // Custom secret patterns - renderCustomSecrets(); - $('#btnAddSecretPattern').addEventListener('click', addCustomSecret); - $('#newSecretPattern').addEventListener('keydown', (e) => { - if (e.key === 'Enter') addCustomSecret(); + // Custom redact patterns + renderCustomRedactPatterns(); + $('#btnAddRedactPattern').addEventListener('click', addCustomRedactPattern); + $('#newRedactPattern').addEventListener('keydown', (e) => { + if (e.key === 'Enter') addCustomRedactPattern(); }); $('#autoDetect').addEventListener('change', async (e) => { @@ -805,12 +805,12 @@ function renderDomains() { }); } -// --- Custom Secret Patterns --- +// --- Custom Redact Patterns --- -function addCustomSecret() { - const name = $('#newSecretName').value.trim(); - const pattern = $('#newSecretPattern').value.trim(); - const redact = $('#newSecretRedact').value.trim(); +function addCustomRedactPattern() { + const name = $('#newRedactName').value.trim(); + const pattern = $('#newRedactPattern').value.trim(); + const redact = $('#newRedactReplacement').value.trim(); if (!pattern) { alert('Pattern is required.'); return; } @@ -825,7 +825,7 @@ function addCustomSecret() { const label = name || 'Custom Pattern'; const replacement = redact || `[REDACTED-${label.toUpperCase().replace(/\s+/g, '-')}]`; - const patterns = settings.customSecretPatterns || []; + const patterns = settings.customRedactPatterns || []; patterns.push({ id: crypto.randomUUID(), name: label, @@ -834,19 +834,19 @@ function addCustomSecret() { enabled: true, }); - settings.customSecretPatterns = patterns; - Storage.saveSettings({ customSecretPatterns: patterns }); - renderCustomSecrets(); + settings.customRedactPatterns = patterns; + Storage.saveSettings({ customRedactPatterns: patterns }); + renderCustomRedactPatterns(); - $('#newSecretName').value = ''; - $('#newSecretPattern').value = ''; - $('#newSecretRedact').value = ''; + $('#newRedactName').value = ''; + $('#newRedactPattern').value = ''; + $('#newRedactReplacement').value = ''; } -function renderCustomSecrets() { - const list = $('#customSecretList'); +function renderCustomRedactPatterns() { + const list = $('#customRedactList'); if (!list) return; - const patterns = settings.customSecretPatterns || []; + const patterns = settings.customRedactPatterns || []; if (patterns.length === 0) { safeHTML(list, '

No custom patterns defined. Built-in patterns cover common API keys, tokens, and credentials.
'); @@ -856,35 +856,35 @@ function renderCustomSecrets() { safeHTML(list, patterns.map((p, i) => `
${escapeHtml(p.name)} ${escapeHtml(p.pattern)} → ${escapeHtml(p.redact)} - +
`).join('')); // Toggle handlers - list.querySelectorAll('.secret-toggle').forEach(toggle => { + list.querySelectorAll('.redact-toggle').forEach(toggle => { toggle.addEventListener('change', async () => { const idx = parseInt(toggle.dataset.index, 10); - const patterns = settings.customSecretPatterns || []; + const patterns = settings.customRedactPatterns || []; patterns[idx].enabled = toggle.checked; - settings.customSecretPatterns = patterns; - await Storage.saveSettings({ customSecretPatterns: patterns }); + settings.customRedactPatterns = patterns; + await Storage.saveSettings({ customRedactPatterns: patterns }); }); }); // Remove handlers - list.querySelectorAll('.btn-remove-secret').forEach(btn => { + list.querySelectorAll('.btn-remove-redact').forEach(btn => { btn.addEventListener('click', async () => { const idx = parseInt(btn.dataset.index, 10); - const patterns = settings.customSecretPatterns || []; + const patterns = settings.customRedactPatterns || []; patterns.splice(idx, 1); - settings.customSecretPatterns = patterns; - await Storage.saveSettings({ customSecretPatterns: patterns }); - renderCustomSecrets(); + settings.customRedactPatterns = patterns; + await Storage.saveSettings({ customRedactPatterns: patterns }); + renderCustomRedactPatterns(); }); }); } diff --git a/src/popup/popup.html b/src/popup/popup.html index f9a1076..deeaae6 100644 --- a/src/popup/popup.html +++ b/src/popup/popup.html @@ -201,7 +201,7 @@ Auto Redact Automatically redact API keys, tokens, passwords, SSNs, credit cards, and custom patterns
- +
diff --git a/src/popup/popup.js b/src/popup/popup.js index 1f9303e..f22223c 100644 --- a/src/popup/popup.js +++ b/src/popup/popup.js @@ -1,6 +1,6 @@ import SubstitutionEngine from '../lib/substitution-engine.js'; import SmartPatterns from '../lib/smart-patterns.js'; -import SecretScanner from '../lib/secret-scanner.js'; +import AutoRedact from '../lib/auto-redact.js'; import AutoDetect from '../lib/auto-detect.js'; import Storage from '../lib/storage.js'; import SilentSendSync from '../lib/sync.js'; @@ -220,7 +220,7 @@ async function initUnlockedUI() { }); // Load options tab settings - $('#optSecretScanning').checked = settings.secretScanning !== false; + $('#optAutoRedact').checked = settings.autoRedact !== false; $('#optAutoDetect').checked = settings.autoDetect !== false; $('#optAutoRedact').checked = settings.autoRedactDetected !== false; $('#optHighlights').checked = settings.showHighlights || false; @@ -228,7 +228,7 @@ async function initUnlockedUI() { // Options tab change handlers const optHandlers = [ - ['optSecretScanning', 'secretScanning'], + ['optAutoRedact', 'autoRedact'], ['optAutoDetect', 'autoDetect'], ['optAutoRedact', 'autoRedactDetected'], ['optHighlights', 'showHighlights'], @@ -713,16 +713,16 @@ function renderTestDiff() { const smartResult = SmartPatterns.substitute(input, identity); const explicitResult = SubstitutionEngine.substitute(smartResult.text, mappings); - const secretResult = SecretScanner.redact(explicitResult.text, settings.customSecretPatterns); + const redactResult = AutoRedact.redact(explicitResult.text, settings.customRedactPatterns); const allReplacements = [ ...smartResult.replacements, ...explicitResult.replacements, - ...secretResult.redactions, + ...redactResult.redactions, ]; - const finalText = secretResult.text; + const finalText = redactResult.text; - if (finalText === input && secretResult.warnings.length === 0) { + if (finalText === input && redactResult.warnings.length === 0) { output.textContent = input; stats.textContent = 'No substitutions detected'; return; @@ -738,8 +738,8 @@ function renderTestDiff() { `${escapedReplaced}` ); } - // Highlight secret redactions in red - for (const r of secretResult.redactions) { + // Highlight auto-redactions in red + for (const r of redactResult.redactions) { const escapedReplaced = escapeHtml(r.replaced); html = html.replace( escapedReplaced, @@ -750,12 +750,12 @@ function renderTestDiff() { const smartCount = smartResult.replacements.length; const explicitCount = explicitResult.replacements.length; - const secretCount = secretResult.redactions.length; - const warnCount = secretResult.warnings.length; + const redactCount = redactResult.redactions.length; + const warnCount = redactResult.warnings.length; const parts = []; if (smartCount > 0) parts.push(`${smartCount} smart`); if (explicitCount > 0) parts.push(`${explicitCount} explicit`); - if (secretCount > 0) parts.push(`${secretCount} secrets redacted`); + if (redactCount > 0) parts.push(`${redactCount} auto-redacted`); if (warnCount > 0) parts.push(`${warnCount} warnings`); // Auto-detect unconfigured PPI in the final text