1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-18 17:23:37 +00:00

[PM-5189] Implementing a really rough sketch of the message-connector rework based on requirements for Firefox

This commit is contained in:
Cesar Gonzalez
2024-04-09 16:35:58 -05:00
parent 27483cf486
commit 747a74c954
18 changed files with 220 additions and 138 deletions

View File

@@ -962,13 +962,19 @@ class OverlayBackground implements OverlayBackgroundInterface {
port.onDisconnect.addListener(this.handlePortOnDisconnect); port.onDisconnect.addListener(this.handlePortOnDisconnect);
port.postMessage({ port.postMessage({
command: `initAutofillOverlay${isOverlayListPort ? "List" : "Button"}`, command: `initAutofillOverlay${isOverlayListPort ? "List" : "Button"}`,
iframeUrl: chrome.runtime.getURL(`overlay/${isOverlayListPort ? "list" : "button"}.html`),
pageTitle: chrome.i18n.getMessage(
isOverlayListPort ? "bitwardenVault" : "bitwardenOverlayButton",
),
authStatus: await this.getAuthStatus(), authStatus: await this.getAuthStatus(),
styleSheetUrl: chrome.runtime.getURL(`overlay/${isOverlayListPort ? "list" : "button"}.css`), styleSheetUrl: chrome.runtime.getURL(`overlay/${isOverlayListPort ? "list" : "button"}.css`),
theme: await firstValueFrom(this.themeStateService.selectedTheme$), theme: await firstValueFrom(this.themeStateService.selectedTheme$),
translations: this.getTranslations(), translations: this.getTranslations(),
ciphers: isOverlayListPort ? await this.getOverlayCipherData() : null, ciphers: isOverlayListPort ? await this.getOverlayCipherData() : null,
messageConnectorUrl: chrome.runtime.getURL("overlay/message-connector.html"),
portKey: this.portKeyForTab[port.sender.tab.id], portKey: this.portKeyForTab[port.sender.tab.id],
portName: isOverlayListPort
? AutofillOverlayPort.ListMessageConnector
: AutofillOverlayPort.ButtonMessageConnector,
}); });
void this.updateOverlayPosition( void this.updateOverlayPosition(
{ {

View File

@@ -7,7 +7,6 @@ type UpdateAuthStatusMessage = OverlayButtonMessage & { authStatus: Authenticati
type InitAutofillOverlayButtonMessage = UpdateAuthStatusMessage & { type InitAutofillOverlayButtonMessage = UpdateAuthStatusMessage & {
styleSheetUrl: string; styleSheetUrl: string;
translations: Record<string, string>; translations: Record<string, string>;
messageConnectorUrl: string;
portKey: string; portKey: string;
}; };

View File

@@ -2,6 +2,7 @@ type AutofillOverlayIframeExtensionMessage = {
command: string; command: string;
styles?: Partial<CSSStyleDeclaration>; styles?: Partial<CSSStyleDeclaration>;
theme?: string; theme?: string;
portKey?: string;
}; };
type AutofillOverlayIframeWindowMessageHandlers = { type AutofillOverlayIframeWindowMessageHandlers = {
@@ -15,6 +16,7 @@ type AutofillOverlayIframeExtensionMessageParam = {
type BackgroundPortMessageHandlers = { type BackgroundPortMessageHandlers = {
[key: string]: CallableFunction; [key: string]: CallableFunction;
initAutofillOverlayButton: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
initAutofillOverlayList: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void; initAutofillOverlayList: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
updateIframePosition: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void; updateIframePosition: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
updateOverlayHidden: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void; updateOverlayHidden: ({ message }: AutofillOverlayIframeExtensionMessageParam) => void;
@@ -22,7 +24,7 @@ type BackgroundPortMessageHandlers = {
}; };
interface AutofillOverlayIframeService { interface AutofillOverlayIframeService {
initOverlayIframe(initStyles: Partial<CSSStyleDeclaration>, ariaAlert?: string): void; initMenuIframe(): void;
} }
export { export {

View File

@@ -6,7 +6,6 @@ class AutofillOverlayButtonIframe extends AutofillOverlayIframeElement {
constructor(element: HTMLElement) { constructor(element: HTMLElement) {
super( super(
element, element,
"overlay/button.html",
AutofillOverlayPort.Button, AutofillOverlayPort.Button,
{ {
background: "transparent", background: "transparent",

View File

@@ -3,7 +3,6 @@ import AutofillOverlayIframeService from "./autofill-overlay-iframe.service";
class AutofillOverlayIframeElement { class AutofillOverlayIframeElement {
constructor( constructor(
element: HTMLElement, element: HTMLElement,
iframePath: string,
portName: string, portName: string,
initStyles: Partial<CSSStyleDeclaration>, initStyles: Partial<CSSStyleDeclaration>,
iframeTitle: string, iframeTitle: string,
@@ -11,11 +10,13 @@ class AutofillOverlayIframeElement {
) { ) {
const shadow: ShadowRoot = element.attachShadow({ mode: "closed" }); const shadow: ShadowRoot = element.attachShadow({ mode: "closed" });
const autofillOverlayIframeService = new AutofillOverlayIframeService( const autofillOverlayIframeService = new AutofillOverlayIframeService(
iframePath,
portName,
shadow, shadow,
portName,
initStyles,
iframeTitle,
ariaAlert,
); );
autofillOverlayIframeService.initOverlayIframe(initStyles, iframeTitle, ariaAlert); autofillOverlayIframeService.initMenuIframe();
} }
} }

View File

@@ -11,6 +11,7 @@ import {
class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterface { class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterface {
private sendExtensionMessage = sendExtensionMessage; private sendExtensionMessage = sendExtensionMessage;
private port: chrome.runtime.Port | null = null; private port: chrome.runtime.Port | null = null;
private portKey: string;
private iframeMutationObserver: MutationObserver; private iframeMutationObserver: MutationObserver;
private iframe: HTMLIFrameElement; private iframe: HTMLIFrameElement;
private ariaAlertElement: HTMLDivElement; private ariaAlertElement: HTMLDivElement;
@@ -34,7 +35,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
private defaultIframeAttributes: Record<string, string> = { private defaultIframeAttributes: Record<string, string> = {
src: "", src: "",
title: "", title: "",
sandbox: "allow-scripts", // sandbox: "allow-scripts",
allowtransparency: "true", allowtransparency: "true",
tabIndex: "-1", tabIndex: "-1",
}; };
@@ -42,6 +43,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
private mutationObserverIterations = 0; private mutationObserverIterations = 0;
private mutationObserverIterationsResetTimeout: number | NodeJS.Timeout; private mutationObserverIterationsResetTimeout: number | NodeJS.Timeout;
private readonly backgroundPortMessageHandlers: BackgroundPortMessageHandlers = { private readonly backgroundPortMessageHandlers: BackgroundPortMessageHandlers = {
initAutofillOverlayButton: ({ message }) => this.initAutofillOverlay(message),
initAutofillOverlayList: ({ message }) => this.initAutofillOverlayList(message), initAutofillOverlayList: ({ message }) => this.initAutofillOverlayList(message),
updateIframePosition: ({ message }) => this.updateIframePosition(message.styles), updateIframePosition: ({ message }) => this.updateIframePosition(message.styles),
updateOverlayHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles), updateOverlayHidden: ({ message }) => this.updateElementStyles(this.iframe, message.styles),
@@ -49,9 +51,11 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
}; };
constructor( constructor(
private iframePath: string,
private portName: string,
private shadow: ShadowRoot, private shadow: ShadowRoot,
private portName: string,
private initStyles: Partial<CSSStyleDeclaration>,
private iframeTitle: string,
private ariaAlert?: string,
) { ) {
this.iframeMutationObserver = new MutationObserver(this.handleMutations); this.iframeMutationObserver = new MutationObserver(this.handleMutations);
} }
@@ -63,29 +67,20 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
* create an aria alert element to announce to screen readers when the iframe * create an aria alert element to announce to screen readers when the iframe
* is loaded. The end result is append to the shadowDOM of the custom element * is loaded. The end result is append to the shadowDOM of the custom element
* that is declared. * that is declared.
*
*
* @param initStyles - Initial styles to apply to the iframe
* @param iframeTitle - Title to apply to the iframe
* @param ariaAlert - Text to announce to screen readers when the iframe is loaded
*/ */
initOverlayIframe( initMenuIframe() {
initStyles: Partial<CSSStyleDeclaration>, this.defaultIframeAttributes.src = chrome.runtime.getURL("overlay/menu.html");
iframeTitle: string, this.defaultIframeAttributes.title = this.iframeTitle;
ariaAlert?: string,
) {
this.defaultIframeAttributes.src = chrome.runtime.getURL(this.iframePath);
this.defaultIframeAttributes.title = iframeTitle;
this.iframe = globalThis.document.createElement("iframe"); this.iframe = globalThis.document.createElement("iframe");
this.updateElementStyles(this.iframe, { ...this.iframeStyles, ...initStyles }); this.updateElementStyles(this.iframe, { ...this.iframeStyles, ...this.initStyles });
for (const [attribute, value] of Object.entries(this.defaultIframeAttributes)) { for (const [attribute, value] of Object.entries(this.defaultIframeAttributes)) {
this.iframe.setAttribute(attribute, value); this.iframe.setAttribute(attribute, value);
} }
this.iframe.addEventListener(EVENTS.LOAD, this.setupPortMessageListener); this.iframe.addEventListener(EVENTS.LOAD, this.setupPortMessageListener);
if (ariaAlert) { if (this.ariaAlert) {
this.createAriaAlertElement(ariaAlert); this.createAriaAlertElement(this.ariaAlert);
} }
this.shadow.appendChild(this.iframe); this.shadow.appendChild(this.iframe);
@@ -185,9 +180,14 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
return; return;
} }
this.iframe.contentWindow?.postMessage(message, "*"); this.postMessageToIFrame(message);
}; };
private initAutofillOverlay(message: AutofillOverlayIframeExtensionMessage) {
this.portKey = message.portKey;
this.postMessageToIFrame(message);
}
/** /**
* Handles messages sent from the iframe to the extension background script. * Handles messages sent from the iframe to the extension background script.
* Will adjust the border element to fit the user's set theme. * Will adjust the border element to fit the user's set theme.
@@ -196,6 +196,7 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
*/ */
private initAutofillOverlayList(message: AutofillOverlayIframeExtensionMessage) { private initAutofillOverlayList(message: AutofillOverlayIframeExtensionMessage) {
const { theme } = message; const { theme } = message;
this.portKey = message.portKey;
let borderColor: string; let borderColor: string;
let verifiedTheme = theme; let verifiedTheme = theme;
if (verifiedTheme === ThemeType.System) { if (verifiedTheme === ThemeType.System) {
@@ -218,7 +219,11 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
} }
message.theme = verifiedTheme; message.theme = verifiedTheme;
this.iframe.contentWindow?.postMessage(message, "*"); this.postMessageToIFrame(message);
}
private postMessageToIFrame(message: any) {
this.iframe.contentWindow?.postMessage({ portKey: this.portKey, ...message }, "*");
} }
/** /**
@@ -247,10 +252,10 @@ class AutofillOverlayIframeService implements AutofillOverlayIframeServiceInterf
.querySelector("meta[name='color-scheme']") .querySelector("meta[name='color-scheme']")
?.getAttribute("content"); ?.getAttribute("content");
this.iframe.contentWindow?.postMessage( this.postMessageToIFrame({
{ command: "updateOverlayPageColorScheme", colorScheme: colorSchemeValue || "normal" }, command: "updateOverlayPageColorScheme",
"*", colorScheme: colorSchemeValue || "normal",
); });
} }
/** /**

View File

@@ -6,7 +6,6 @@ class AutofillOverlayListIframe extends AutofillOverlayIframeElement {
constructor(element: HTMLElement) { constructor(element: HTMLElement) {
super( super(
element, element,
"overlay/list.html",
AutofillOverlayPort.List, AutofillOverlayPort.List,
{ {
height: "0px", height: "0px",

View File

@@ -53,16 +53,9 @@ class AutofillOverlayButton extends AutofillOverlayPageElement {
authStatus, authStatus,
styleSheetUrl, styleSheetUrl,
translations, translations,
messageConnectorUrl,
portKey, portKey,
}: InitAutofillOverlayButtonMessage) { }: InitAutofillOverlayButtonMessage) {
const linkElement = await this.initOverlayPage( const linkElement = await this.initOverlayPage("button", styleSheetUrl, translations, portKey);
"button",
styleSheetUrl,
translations,
messageConnectorUrl,
portKey,
);
this.buttonElement.tabIndex = -1; this.buttonElement.tabIndex = -1;
this.buttonElement.type = "button"; this.buttonElement.type = "button";
this.buttonElement.classList.add("overlay-button"); this.buttonElement.classList.add("overlay-button");

View File

@@ -44,7 +44,6 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
* @param theme - The theme to use for the overlay list. * @param theme - The theme to use for the overlay list.
* @param authStatus - The current authentication status. * @param authStatus - The current authentication status.
* @param ciphers - The ciphers to display in the overlay list. * @param ciphers - The ciphers to display in the overlay list.
* @param messageConnectorUrl - The URL of the message connector to use.
* @param portKey - Background generated key that allows the port to communicate with the background. * @param portKey - Background generated key that allows the port to communicate with the background.
*/ */
private async initAutofillOverlayList({ private async initAutofillOverlayList({
@@ -53,16 +52,9 @@ class AutofillOverlayList extends AutofillOverlayPageElement {
theme, theme,
authStatus, authStatus,
ciphers, ciphers,
messageConnectorUrl,
portKey, portKey,
}: InitAutofillOverlayListMessage) { }: InitAutofillOverlayListMessage) {
const linkElement = await this.initOverlayPage( const linkElement = await this.initOverlayPage("list", styleSheetUrl, translations, portKey);
"list",
styleSheetUrl,
translations,
messageConnectorUrl,
portKey,
);
const themeClass = `theme_${theme}`; const themeClass = `theme_${theme}`;
globalThis.document.documentElement.classList.add(themeClass); globalThis.document.documentElement.classList.add(themeClass);

View File

@@ -0,0 +1,132 @@
import { EVENTS } from "@bitwarden/common/autofill/constants";
import { setElementStyles } from "../../../utils";
export class AutofillOverlayMenuContainer {
private initMessage: any;
private extensionOriginsSet: Set<string>;
private port: chrome.runtime.Port | null = null;
private portName: string;
private iframe: HTMLIFrameElement;
private iframeStyles: Partial<CSSStyleDeclaration> = {
all: "initial",
position: "fixed",
top: "0",
left: "0",
width: "100%",
height: "100%",
display: "block",
zIndex: "2147483647",
lineHeight: "0",
overflow: "hidden",
visibility: "visible",
clipPath: "none",
pointerEvents: "auto",
margin: "0",
padding: "0",
colorScheme: "normal",
};
private defaultIframeAttributes: Record<string, string> = {
src: "",
title: "",
// sandbox: "allow-scripts",
allowtransparency: "true",
tabIndex: "-1",
};
private windowMessageHandlers: Record<string, (message: any) => void> = {
initAutofillOverlayList: (message: any) => this.handleInitOverlayIframe(message),
initAutofillOverlayButton: (message: any) => this.handleInitOverlayIframe(message),
};
private backgroundPortMessageHandlers: Record<string, (message: any) => void> = {};
constructor() {
this.extensionOriginsSet = new Set([
chrome.runtime.getURL("").slice(0, -1).toLowerCase(), // Remove the trailing slash and normalize the extension url to lowercase
"null",
]);
globalThis.addEventListener("message", this.handleWindowMessage);
}
private handleInitOverlayIframe(message: any) {
this.initMessage = message;
this.defaultIframeAttributes.src = message.iframeUrl;
this.defaultIframeAttributes.title = message.pageTitle;
this.portName = message.portName;
this.iframe = globalThis.document.createElement("iframe");
setElementStyles(this.iframe, this.iframeStyles, true);
for (const [attribute, value] of Object.entries(this.defaultIframeAttributes)) {
this.iframe.setAttribute(attribute, value);
}
this.iframe.addEventListener(EVENTS.LOAD, this.setupPortMessageListener);
globalThis.document.body.appendChild(this.iframe);
}
private setupPortMessageListener = () => {
this.port = chrome.runtime.connect({ name: this.portName });
this.port.onMessage.addListener(this.handlePortMessage);
this.iframe.contentWindow?.postMessage(this.initMessage, "*");
};
private handlePortMessage = (message: any, port: chrome.runtime.Port) => {
if (port.name !== this.portName) {
return;
}
if (this.backgroundPortMessageHandlers[message.command]) {
this.backgroundPortMessageHandlers[message.command]({ message, port });
return;
}
this.iframe.contentWindow?.postMessage(message, "*");
};
private handleWindowMessage = (event: MessageEvent) => {
const message = event.data;
if (this.isForeignWindowMessage(event)) {
return;
}
if (this.windowMessageHandlers[message.command]) {
this.windowMessageHandlers[message.command](message);
return;
}
if (event.source === globalThis.parent) {
this.iframe?.contentWindow?.postMessage(message, "*");
return;
}
this.port?.postMessage(message);
};
private isForeignWindowMessage(event: MessageEvent) {
if (!event.data.portKey) {
return true;
}
if (globalThis.parent === event.source) {
return false;
}
return (
this.iframe?.contentWindow !== event.source ||
!this.isFromExtensionOrigin(event.origin.toLowerCase())
);
}
/**
* Chrome returns null for any sandboxed iframe sources.
* Firefox references the extension URI as its origin.
* Any other origin value is a security risk.
*
* @param messageOrigin - The origin of the window message
*/
private isFromExtensionOrigin(messageOrigin: string): boolean {
return this.extensionOriginsSet.has(messageOrigin);
}
}

View File

@@ -0,0 +1,3 @@
import { AutofillOverlayMenuContainer } from "./autofill-overlay-menu-container";
(() => new AutofillOverlayMenuContainer())();

View File

@@ -1,7 +1,7 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<title>Autofill overlay message connector</title> <title>Bitwarden inline menu</title>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" /> <meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="color-scheme" content="normal" /> <meta name="color-scheme" content="normal" />

View File

@@ -1,3 +0,0 @@
import { AutofillOverlayMessageConnector } from "./message-connector";
(() => new AutofillOverlayMessageConnector())();

View File

@@ -1,44 +0,0 @@
export class AutofillOverlayMessageConnector {
private extensionOriginsSet: Set<string>;
private port: chrome.runtime.Port | null = null;
constructor() {
globalThis.addEventListener("message", this.handleWindowMessage);
this.extensionOriginsSet = new Set([
chrome.runtime.getURL("").slice(0, -1).toLowerCase(), // Remove the trailing slash and normalize the extension url to lowercase
"null",
]);
}
private handleWindowMessage = (event: MessageEvent) => {
const message = event.data;
if (
event.source !== globalThis.parent ||
!this.isFromExtensionOrigin(event.origin.toLowerCase()) ||
!message.portKey
) {
return;
}
if (this.port) {
this.port.postMessage(message);
return;
}
if (message.command === "initAutofillOverlayPort") {
this.port = chrome.runtime.connect({ name: message.portName });
}
};
/**
* Chrome returns null for any sandboxed iframe sources.
* Firefox references the extension URI as its origin.
* Any other origin value is a security risk.
*
* @param messageOrigin - The origin of the window message
*/
private isFromExtensionOrigin(messageOrigin: string): boolean {
return this.extensionOriginsSet.has(messageOrigin);
}
}

View File

@@ -1,6 +1,6 @@
import { EVENTS } from "@bitwarden/common/autofill/constants"; import { EVENTS } from "@bitwarden/common/autofill/constants";
import { AutofillOverlayPort, RedirectFocusDirection } from "../../../utils/autofill-overlay.enum"; import { RedirectFocusDirection } from "../../../utils/autofill-overlay.enum";
import { import {
AutofillOverlayPageElementWindowMessage, AutofillOverlayPageElementWindowMessage,
WindowMessageHandlers, WindowMessageHandlers,
@@ -27,14 +27,12 @@ class AutofillOverlayPageElement extends HTMLElement {
* @param elementName - The name of the element, e.g. "button" or "list" * @param elementName - The name of the element, e.g. "button" or "list"
* @param styleSheetUrl - The URL of the stylesheet to apply to the page * @param styleSheetUrl - The URL of the stylesheet to apply to the page
* @param translations - The translations to apply to the page * @param translations - The translations to apply to the page
* @param messageConnectorUrl - The URL of the message connector to use
* @param portKey - Background generated key that allows the port to communicate with the background * @param portKey - Background generated key that allows the port to communicate with the background
*/ */
protected async initOverlayPage( protected async initOverlayPage(
elementName: "button" | "list", elementName: "button" | "list",
styleSheetUrl: string, styleSheetUrl: string,
translations: Record<string, string>, translations: Record<string, string>,
messageConnectorUrl: string,
portKey: string, portKey: string,
): Promise<HTMLLinkElement> { ): Promise<HTMLLinkElement> {
this.portKey = portKey; this.portKey = portKey;
@@ -43,8 +41,6 @@ class AutofillOverlayPageElement extends HTMLElement {
globalThis.document.documentElement.setAttribute("lang", this.getTranslation("locale")); globalThis.document.documentElement.setAttribute("lang", this.getTranslation("locale"));
globalThis.document.head.title = this.getTranslation(`${elementName}PageTitle`); globalThis.document.head.title = this.getTranslation(`${elementName}PageTitle`);
await this.initMessageConnector(messageConnectorUrl, elementName);
this.shadowDom.innerHTML = ""; this.shadowDom.innerHTML = "";
const linkElement = globalThis.document.createElement("link"); const linkElement = globalThis.document.createElement("link");
linkElement.setAttribute("rel", "stylesheet"); linkElement.setAttribute("rel", "stylesheet");
@@ -62,30 +58,30 @@ class AutofillOverlayPageElement extends HTMLElement {
* @param messageConnectorUrl - The URL of the message connector to use * @param messageConnectorUrl - The URL of the message connector to use
* @param elementName - The name of the element, e.g. "button" or "list" * @param elementName - The name of the element, e.g. "button" or "list"
*/ */
private initMessageConnector(messageConnectorUrl: string, elementName: "button" | "list") { // private initMessageConnector(messageConnectorUrl: string, elementName: "button" | "list") {
this.messageConnectorIframe = globalThis.document.createElement("iframe"); // this.messageConnectorIframe = globalThis.document.createElement("iframe");
this.messageConnectorIframe.src = messageConnectorUrl; // this.messageConnectorIframe.src = messageConnectorUrl;
this.messageConnectorIframe.style.opacity = "0"; // this.messageConnectorIframe.style.opacity = "0";
this.messageConnectorIframe.style.position = "absolute"; // this.messageConnectorIframe.style.position = "absolute";
this.messageConnectorIframe.style.width = "0"; // this.messageConnectorIframe.style.width = "0";
this.messageConnectorIframe.style.height = "0"; // this.messageConnectorIframe.style.height = "0";
this.messageConnectorIframe.style.border = "none"; // this.messageConnectorIframe.style.border = "none";
this.messageConnectorIframe.style.pointerEvents = "none"; // this.messageConnectorIframe.style.pointerEvents = "none";
globalThis.document.body.appendChild(this.messageConnectorIframe); // globalThis.document.body.appendChild(this.messageConnectorIframe);
//
return new Promise<void>((resolve) => { // return new Promise<void>((resolve) => {
this.messageConnectorIframe.addEventListener(EVENTS.LOAD, () => { // this.messageConnectorIframe.addEventListener(EVENTS.LOAD, () => {
this.postMessageToConnector({ // this.postMessageToConnector({
command: `initAutofillOverlayPort`, // command: `initAutofillOverlayPort`,
portName: // portName:
elementName === "list" // elementName === "list"
? AutofillOverlayPort.ListMessageConnector // ? AutofillOverlayPort.ListMessageConnector
: AutofillOverlayPort.ButtonMessageConnector, // : AutofillOverlayPort.ButtonMessageConnector,
}); // });
resolve(); // resolve();
}); // });
}); // });
} // }
/** /**
* Posts a window message to the parent window. * Posts a window message to the parent window.
@@ -93,10 +89,12 @@ class AutofillOverlayPageElement extends HTMLElement {
* @param message - The message to post * @param message - The message to post
*/ */
protected postMessageToConnector(message: AutofillOverlayPageElementWindowMessage) { protected postMessageToConnector(message: AutofillOverlayPageElementWindowMessage) {
this.messageConnectorIframe.contentWindow.postMessage( globalThis.parent.postMessage({ portKey: this.portKey, ...message }, "*");
{ portKey: this.portKey, ...message },
"*", // this.messageConnectorIframe.contentWindow.postMessage(
); // { portKey: this.portKey, ...message },
// "*",
// );
} }
/** /**

View File

@@ -115,7 +115,7 @@
"images/icon38_locked.png", "images/icon38_locked.png",
"overlay/button.html", "overlay/button.html",
"overlay/list.html", "overlay/list.html",
"overlay/message-connector.html", "overlay/menu.html",
"popup/fonts/*" "popup/fonts/*"
], ],
"applications": { "applications": {

View File

@@ -119,7 +119,7 @@
"images/icon38_locked.png", "images/icon38_locked.png",
"overlay/button.html", "overlay/button.html",
"overlay/list.html", "overlay/list.html",
"overlay/message-connector.html", "overlay/menu.html",
"popup/fonts/*" "popup/fonts/*"
], ],
"matches": ["<all_urls>"] "matches": ["<all_urls>"]

View File

@@ -117,9 +117,9 @@ const plugins = [
chunks: ["overlay/list"], chunks: ["overlay/list"],
}), }),
new HtmlWebpackPlugin({ new HtmlWebpackPlugin({
template: "./src/autofill/overlay/pages/message-connector/message-connector.html", template: "./src/autofill/overlay/pages/menu/menu.html",
filename: "overlay/message-connector.html", filename: "overlay/menu.html",
chunks: ["overlay/message-connector"], chunks: ["overlay/menu"],
}), }),
new CopyWebpackPlugin({ new CopyWebpackPlugin({
patterns: [ patterns: [
@@ -178,8 +178,8 @@ const mainConfig = {
"notification/bar": "./src/autofill/notification/bar.ts", "notification/bar": "./src/autofill/notification/bar.ts",
"overlay/button": "./src/autofill/overlay/pages/button/bootstrap-autofill-overlay-button.ts", "overlay/button": "./src/autofill/overlay/pages/button/bootstrap-autofill-overlay-button.ts",
"overlay/list": "./src/autofill/overlay/pages/list/bootstrap-autofill-overlay-list.ts", "overlay/list": "./src/autofill/overlay/pages/list/bootstrap-autofill-overlay-list.ts",
"overlay/message-connector": "overlay/menu":
"./src/autofill/overlay/pages/message-connector/bootstrap-autofill-overlay-message-connector.ts", "./src/autofill/overlay/pages/menu/bootstrap-autofill-overlay-menu-container.ts",
"encrypt-worker": "../../libs/common/src/platform/services/cryptography/encrypt.worker.ts", "encrypt-worker": "../../libs/common/src/platform/services/cryptography/encrypt.worker.ts",
"content/lp-fileless-importer": "./src/tools/content/lp-fileless-importer.ts", "content/lp-fileless-importer": "./src/tools/content/lp-fileless-importer.ts",
"content/send-on-installed-message": "./src/vault/content/send-on-installed-message.ts", "content/send-on-installed-message": "./src/vault/content/send-on-installed-message.ts",