re-inject content script on 3XX redirects

This commit is contained in:
2026-07-07 18:25:48 +02:00
parent df3c66a24c
commit 3541c7d2f0
2 changed files with 45 additions and 30 deletions
+34 -24
View File
@@ -2,6 +2,30 @@ import { BackgroundMessageData, BackgroundMessageType } from '@/lib/communicatio
import { getHost } from '@/lib/host';
import { HostSettings, UrlReferer } from '@/lib/settings';
async function reInjectContentScript(domain: string) {
const contentScript: Browser.scripting.RegisteredContentScript = {
id: 'temporary-hosts',
js: ['content-scripts/content.js'],
matches: [`*://${domain}/*`],
persistAcrossSessions: false,
allFrames: true,
runAt: 'document_end'
};
const contentScripts = await browser.scripting.getRegisteredContentScripts({ ids: [contentScript.id] });
if (contentScripts.length !== 0) {
const registeredContentScript = contentScripts[0];
// do not double register for same domain
if (registeredContentScript.matches!.indexOf(contentScript.matches![0]) !== -1) return;
contentScript.matches!.push(...contentScripts[0].matches!);
await browser.scripting.updateContentScripts([contentScript]);
} else {
await browser.scripting.registerContentScripts([contentScript]);
}
}
export default defineBackground(() => {
browser.runtime.onMessage.addListener(async (message, sender) => {
const type = message.type as BackgroundMessageType;
@@ -25,28 +49,7 @@ export default defineBackground(() => {
if (import.meta.env.MANIFEST_VERSION === 3) break;
data = data as BackgroundMessageData<typeof type>;
const contentScript: Browser.scripting.RegisteredContentScript = {
id: 'temporary-hosts',
js: ['content-scripts/content.js'],
matches: [`*://${data.domain}/*`],
persistAcrossSessions: false,
allFrames: true,
runAt: 'document_end'
};
const contentScripts = await browser.scripting.getRegisteredContentScripts({ ids: [contentScript.id] });
if (contentScripts.length !== 0) {
const registeredContentScript = contentScripts[0];
// do not double register for same domain
if (registeredContentScript.matches!.indexOf(contentScript.matches![0]) !== -1) break;
contentScript.matches!.push(...contentScripts[0].matches!);
await browser.scripting.updateContentScripts([contentScript]);
} else {
await browser.scripting.registerContentScripts([contentScript]);
}
await reInjectContentScript(data.domain);
break;
}
@@ -80,10 +83,17 @@ export default defineBackground(() => {
browser.webRequest.onBeforeRedirect.addListener(
async (details) => {
const host = await getHost(new URL(details.url).hostname);
const domain = new URL(details.url).host;
const host = await getHost(domain);
if (!host) return;
await HostSettings.addTemporaryHostDomain(host.id, new URL(details.redirectUrl).hostname);
const newDomain = new URL(details.redirectUrl).host;
await Promise.all([
HostSettings.addTemporaryHostDomain(host.id, newDomain, { registerContentScript: false }),
// must be called manually, a message sent from a background script is only received on non-background pages
reInjectContentScript(newDomain)
]);
},
{ urls: ['<all_urls>'], types: ['main_frame', 'sub_frame'] }
);
+11 -6
View File
@@ -39,12 +39,17 @@ export class HostSettings {
/* tmp */
private static temporaryHostDomain = new Setting<Record<string, string>>('local:temporaryHostDomain', {});
static addTemporaryHostDomain = async (hostId: HostId, domain: string) => {
// only has an effect with mv2
const backgroundScriptInject =
import.meta.env.MANIFEST_VERSION === 2
? sendBackgroundMessage(BackgroundMessageType.RegisterContentScript, { domain: domain })
: Promise.resolve();
static addTemporaryHostDomain = async (
hostId: HostId,
domain: string,
options = {
// only has an effect with mv2
registerContentScript: import.meta.env.MANIFEST_VERSION === 2
}
) => {
const backgroundScriptInject = options.registerContentScript
? sendBackgroundMessage(BackgroundMessageType.RegisterContentScript, { domain: domain })
: Promise.resolve();
const temporaryHostDomainUpdate = this.temporaryHostDomain.update((val) => {
val[domain] = hostId;
return val;