fix: username/hostname not substituting — injector wasn't merging profiles

After the multi-profile migration, ss_identity changed from a flat
object { names, emails, ... } to { profiles: [...] }. The injector
was passing the raw profiles wrapper to the content script, which
expected the flat format.

Now the injector merges active profiles into a flat identity object
before injecting into the page world, and also merges on storage
change events. Also handles legacy format (pre-profile data) for
backward compatibility.

https://claude.ai/code/session_01Dvgwe7XMoSxnWXkih8p1Cw
This commit is contained in:
Claude
2026-03-26 04:08:02 +00:00
parent 0d9446d14e
commit 684413f5fe
+42 -8
View File
@@ -15,6 +15,38 @@
if (window.__silentSendInjected) return;
window.__silentSendInjected = true;
// Merge active profiles into flat identity object
function mergeProfiles(data) {
const profiles = data?.profiles || [];
const active = profiles.filter(p => p.active);
if (active.length === 0) {
// Legacy format: data IS the flat identity (pre-profile migration)
if (data && (data.names || data.emails || data.usernames)) return data;
return { emails: [], names: [], usernames: [], hostnames: [], phones: [],
catchAllEmail: '', emailDomains: [],
enabled: { emails: true, names: true, usernames: true, phones: true, paths: true } };
}
const merged = {
emails: [], names: [], usernames: [], hostnames: [], phones: [],
catchAllEmail: '', emailDomains: [],
enabled: { emails: true, names: true, usernames: true, phones: true, paths: true },
};
for (const p of active) {
merged.emails.push(...(p.emails || []));
merged.names.push(...(p.names || []));
merged.usernames.push(...(p.usernames || []));
merged.hostnames.push(...(p.hostnames || []));
merged.phones.push(...(p.phones || []));
if (p.catchAllEmail && !merged.catchAllEmail) merged.catchAllEmail = p.catchAllEmail;
merged.emailDomains.push(...(p.emailDomains || []));
}
return merged;
}
// Cross-browser API
const api =
typeof browser !== 'undefined' && browser.runtime
@@ -27,9 +59,12 @@
async function init() {
const result = await api.storage.local.get(['ss_mappings', 'ss_identity', 'ss_settings']);
const mappings = result.ss_mappings || [];
const identity = result.ss_identity || {};
const settings = result.ss_settings || { enabled: true };
// Merge active profiles into a flat identity object for the content script
const identityData = result.ss_identity || {};
const identity = mergeProfiles(identityData);
// Inject the main interception script into the page's world
const script = document.createElement('script');
script.setAttribute('data-ss-config', JSON.stringify({ mappings, identity, settings }));
@@ -71,15 +106,14 @@
}
});
// Forward storage changes to the page script
// Forward storage changes to the page script (merge profiles before sending)
api.storage.onChanged.addListener((changes) => {
if (changes.ss_mappings || changes.ss_identity || changes.ss_settings) {
window.postMessage({
type: 'ss:config-updated',
mappings: changes.ss_mappings?.newValue,
identity: changes.ss_identity?.newValue,
settings: changes.ss_settings?.newValue,
}, '*');
const msg = { type: 'ss:config-updated' };
if (changes.ss_mappings) msg.mappings = changes.ss_mappings.newValue;
if (changes.ss_identity) msg.identity = mergeProfiles(changes.ss_identity.newValue);
if (changes.ss_settings) msg.settings = changes.ss_settings.newValue;
window.postMessage(msg, '*');
}
});