Merge pull request #27 from outis1one/claude/read-repo-wA3y1

fix: reveal mode broken + missing await + select rendering — v2.0.10
This commit is contained in:
Outis
2026-03-27 08:45:43 -04:00
committed by GitHub
7 changed files with 33 additions and 13 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Silent Send",
"version": "2.0.9",
"version": "2.0.10",
"description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.",
"browser_specific_settings": {
"gecko": {
+1 -1
View File
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Silent Send",
"version": "2.0.9",
"version": "2.0.10",
"description": "Intercepts personal info and substitutes it with user-defined replacements before sending to AI services.",
"permissions": [
"storage",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "silent-send",
"version": "2.0.9",
"version": "2.0.10",
"private": true,
"license": "BSL-1.1",
"description": "Browser extension that substitutes personal data before sending to AI services",
+16 -2
View File
@@ -784,11 +784,25 @@
// Record what was actually substituted so reveal knows
for (const r of replacements) {
if (r.replaced && r.original) {
// Store with lowercase key for lookup, but preserve original case
// Store full replacement with lowercase key for lookup
sessionSubstitutions.set(r.replaced.toLowerCase(), {
original: r.original,
replaced: r.replaced, // preserve original case
replaced: r.replaced,
});
// Also store individual words so reveal pairs match identity entries
// e.g. "Ademo Demo" → store "ademo" and "demo" separately
const replacedWords = r.replaced.split(/\s+/);
const originalWords = r.original.split(/\s+/);
if (replacedWords.length > 1) {
for (let i = 0; i < replacedWords.length; i++) {
if (replacedWords[i] && originalWords[i]) {
sessionSubstitutions.set(replacedWords[i].toLowerCase(), {
original: originalWords[i],
replaced: replacedWords[i],
});
}
}
}
}
}
+2 -2
View File
@@ -476,7 +476,7 @@ const SilentSendSync = {
if (!keyInfo) return { data: null, decrypted: false, needsAuth: true };
try {
const decrypted = await SilentSendCrypto.decryptWithKey(data.payload, keyInfo.key);
return this._handleDecryptedMeta(decrypted);
return await this._handleDecryptedMeta(decrypted);
} catch {
return { data: null, decrypted: false, needsAuth: true };
}
@@ -488,7 +488,7 @@ const SilentSendSync = {
if (tempKeyStore) {
try {
const decrypted = await SilentSendCrypto.decryptWithKey(data.payload, tempKeyStore.key);
return this._handleDecryptedMeta(decrypted);
return await this._handleDecryptedMeta(decrypted);
} catch { /* wrong key, fall through to prompt */ }
}
+1 -1
View File
@@ -591,7 +591,7 @@
</section>
<footer>
<p>Silent Send v2.0.9</p>
<p>Silent Send v2.0.10</p>
</footer>
</div>
+11 -5
View File
@@ -338,11 +338,17 @@ async function showLockedUI() {
// --- Profiles ---
function renderProfileSelector() {
const select = $('#profileSelect');
safeHTML(select, profiles.map(p =>
`<option value="${p.id}" ${p.id === currentProfileId ? 'selected' : ''}>` +
`${escapeHtml(p.name)}${p.active ? '' : ' (off)'}` +
`</option>`
).join(''));
// Build options via DOM API — safeHTML + DOMParser mangles <option> elements
select.replaceChildren();
for (const p of profiles) {
const opt = new Option(
`${p.name}${p.active ? '' : ' (off)'}`,
p.id,
false,
p.id === currentProfileId
);
select.appendChild(opt);
}
const profile = profiles.find(p => p.id === currentProfileId);
$('#profileActive').checked = profile?.active ?? true;