Files
paseo/packages/desktop/src/features/browser-webviews/window-open.ts
T
Mohamed BoudraandGitHub 328361667f Keep browser sign-ins across tabs and restarts (#2089)
* feat(desktop): share persistent browser data across tabs

Keep browser sign-ins and site storage across tabs and app restarts, with a Settings action to clear the shared profile.

* fix(settings): prevent duplicate browser data clears

* fix(desktop): complete browser data cleanup

Clear legacy per-tab profiles after upgrades and localize the browser data settings in every supported language.

* fix(desktop): close browser profile cleanup races
2026-07-16 00:40:24 +08:00

65 lines
1.7 KiB
TypeScript

export const BROWSER_NEW_TAB_REQUEST_EVENT = "paseo:event:browser-new-tab-request";
export interface BrowserNewTabRequestPayload {
sourceBrowserId: string;
url: string;
}
const MAX_PENDING_WINDOW_OPEN_REQUESTS_PER_GUEST = 20;
export class PendingBrowserWindowOpenRequests {
private readonly urlsByWebContentsId = new Map<number, string[]>();
public add(webContentsId: number, url: string): void {
if (!isAllowedBrowserWebviewUrl(url)) {
return;
}
const urls = this.urlsByWebContentsId.get(webContentsId) ?? [];
if (urls.length >= MAX_PENDING_WINDOW_OPEN_REQUESTS_PER_GUEST) {
return;
}
urls.push(url);
this.urlsByWebContentsId.set(webContentsId, urls);
}
public take(webContentsId: number): string[] {
const urls = this.urlsByWebContentsId.get(webContentsId) ?? [];
this.urlsByWebContentsId.delete(webContentsId);
return urls;
}
public delete(webContentsId: number): void {
this.urlsByWebContentsId.delete(webContentsId);
}
}
export function isAllowedBrowserWebviewUrl(value: string | undefined): boolean {
if (!value) {
return true;
}
try {
const parsed = new URL(value);
return (
parsed.protocol === "http:" || parsed.protocol === "https:" || parsed.href === "about:blank"
);
} catch {
return false;
}
}
export function handleBrowserWindowOpenRequest(input: {
url: string;
sourceBrowserId: string | null;
requestNewTab: (payload: BrowserNewTabRequestPayload) => void;
}): { action: "deny" } {
if (!isAllowedBrowserWebviewUrl(input.url) || !input.sourceBrowserId) {
return { action: "deny" };
}
input.requestNewTab({
sourceBrowserId: input.sourceBrowserId,
url: input.url,
});
return { action: "deny" };
}