diff --git a/apps/browser/src/autofill/background/abstractions/overlay.background.ts b/apps/browser/src/autofill/background/abstractions/overlay.background.ts index 27b7ff1163b..f461de48f4e 100644 --- a/apps/browser/src/autofill/background/abstractions/overlay.background.ts +++ b/apps/browser/src/autofill/background/abstractions/overlay.background.ts @@ -39,8 +39,14 @@ type OverlayAddNewItemMessage = { }; }; +type FocusedFieldData = { + focusedFieldStyles: Partial; + focusedFieldRects: Partial; + tabId?: number; + frameId?: number; +}; + type OverlayBackgroundExtensionMessage = { - [key: string]: any; command: string; tab?: chrome.tabs.Tab; sender?: string; @@ -50,8 +56,11 @@ type OverlayBackgroundExtensionMessage = { isOverlayHidden?: boolean; setTransparentOverlay?: boolean; isFieldCurrentlyFocused?: boolean; - isCurrentlyFilling?: boolean; + isFieldCurrentlyFilling?: boolean; + subFrameData?: SubFrameOffsetData; + focusedFieldData?: FocusedFieldData; data?: LockedVaultPendingNotificationsData; + styles?: Partial; } & OverlayAddNewItemMessage; type OverlayPortMessage = { @@ -61,20 +70,13 @@ type OverlayPortMessage = { overlayCipherId?: string; }; -type FocusedFieldData = { - focusedFieldStyles: Partial; - focusedFieldRects: Partial; - tabId?: number; - frameId?: number; -}; - type OverlayCipherData = { id: string; name: string; type: CipherType; reprompt: CipherRepromptType; favorite: boolean; - icon: { imageEnabled: boolean; image: string; fallbackImage: string; icon: string }; + icon: WebsiteIconData; login?: { username: string }; card?: string; }; diff --git a/apps/browser/src/autofill/background/overlay.background.spec.ts b/apps/browser/src/autofill/background/overlay.background.spec.ts index f17097986fb..95cdd5063c8 100644 --- a/apps/browser/src/autofill/background/overlay.background.spec.ts +++ b/apps/browser/src/autofill/background/overlay.background.spec.ts @@ -1,4 +1,4 @@ -import { mock, mockReset } from "jest-mock-extended"; +import { mock, MockProxy, mockReset } from "jest-mock-extended"; import { BehaviorSubject, of } from "rxjs"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; @@ -16,6 +16,7 @@ import { EnvironmentService, Region, } from "@bitwarden/common/platform/abstractions/environment.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CloudEnvironment } from "@bitwarden/common/platform/services/default-environment.service"; @@ -60,6 +61,7 @@ describe("OverlayBackground", () => { let buttonPortSpy: chrome.runtime.Port; let listPortSpy: chrome.runtime.Port; let overlayBackground: OverlayBackground; + let logService: MockProxy; const cipherService = mock(); const autofillService = mock(); const authService = mock(); @@ -93,8 +95,10 @@ describe("OverlayBackground", () => { }; beforeEach(() => { + logService = mock(); domainSettingsService = new DefaultDomainSettingsService(fakeStateProvider); overlayBackground = new OverlayBackground( + logService, cipherService, autofillService, authService, diff --git a/apps/browser/src/autofill/background/overlay.background.ts b/apps/browser/src/autofill/background/overlay.background.ts index 7b7359b80ed..24ad70ac54f 100644 --- a/apps/browser/src/autofill/background/overlay.background.ts +++ b/apps/browser/src/autofill/background/overlay.background.ts @@ -8,6 +8,7 @@ import { DomainSettingsService } from "@bitwarden/common/autofill/services/domai import { InlineMenuVisibilitySetting } from "@bitwarden/common/autofill/types"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -42,7 +43,6 @@ import { PageDetailsForTab, SubFrameOffsetData, SubFrameOffsetsForTab, - WebsiteIconData, } from "./abstractions/overlay.background"; class OverlayBackground implements OverlayBackgroundInterface { @@ -58,7 +58,7 @@ class OverlayBackground implements OverlayBackgroundInterface { private overlayListPort: chrome.runtime.Port; private focusedFieldData: FocusedFieldData; private isFieldCurrentlyFocused: boolean = false; - private isCurrentlyFilling: boolean = false; + private isFieldCurrentlyFilling: boolean = false; private overlayPageTranslations: Record; private iconsServerUrl: string; private readonly extensionMessageHandlers: OverlayBackgroundExtensionMessageHandlers = { @@ -95,11 +95,7 @@ class OverlayBackground implements OverlayBackgroundInterface { this.closeOverlay(port.sender, { forceCloseOverlay: true }), overlayPageBlurred: () => this.checkOverlayListFocused(), redirectOverlayFocusOut: ({ message, port }) => this.redirectOverlayFocusOut(message, port), - getPageColorScheme: () => { - this.overlayButtonPort?.postMessage({ - command: "getPageColorScheme", - }); - }, + getPageColorScheme: () => this.updateButtonPageColorScheme(), }; private readonly overlayListPortMessageHandlers: OverlayListPortMessageHandlers = { checkAutofillOverlayButtonFocused: () => this.checkOverlayButtonFocused(), @@ -111,15 +107,11 @@ class OverlayBackground implements OverlayBackgroundInterface { addNewVaultItem: ({ port }) => this.getNewVaultItemDetails(port), viewSelectedCipher: ({ message, port }) => this.viewSelectedCipher(message, port), redirectOverlayFocusOut: ({ message, port }) => this.redirectOverlayFocusOut(message, port), - updateAutofillOverlayListHeight: ({ message }) => { - this.overlayListPort?.postMessage({ - command: "updateIframePosition", - styles: message.styles, - }); - }, + updateAutofillOverlayListHeight: ({ message }) => this.updateOverlayListHeight(message), }; constructor( + private logService: LogService, private cipherService: CipherService, private autofillService: AutofillService, private authService: AuthService, @@ -197,13 +189,9 @@ class OverlayBackground implements OverlayBackgroundInterface { const showFavicons = await firstValueFrom(this.domainSettingsService.showFavicons$); const overlayCiphersArray = Array.from(this.overlayLoginCiphers); const overlayCipherData = []; - let loginCipherIcon: WebsiteIconData; for (let cipherIndex = 0; cipherIndex < overlayCiphersArray.length; cipherIndex++) { const [overlayCipherId, cipher] = overlayCiphersArray[cipherIndex]; - if (!loginCipherIcon && cipher.type === CipherType.Login) { - loginCipherIcon = buildCipherIcon(this.iconsServerUrl, cipher, showFavicons); - } overlayCipherData.push({ id: overlayCipherId, @@ -211,10 +199,7 @@ class OverlayBackground implements OverlayBackgroundInterface { type: cipher.type, reprompt: cipher.reprompt, favorite: cipher.favorite, - icon: - cipher.type === CipherType.Login - ? loginCipherIcon - : buildCipherIcon(this.iconsServerUrl, cipher, showFavicons), + icon: buildCipherIcon(this.iconsServerUrl, cipher, showFavicons), login: cipher.type === CipherType.Login ? { username: cipher.login.username } : null, card: cipher.type === CipherType.Card ? cipher.card.subTitle : null, }); @@ -253,7 +238,10 @@ class OverlayBackground implements OverlayBackgroundInterface { pageDetailsMap.set(sender.frameId, pageDetails); } - private updateSubFrameData(message: any, sender: chrome.runtime.MessageSender) { + private updateSubFrameData( + message: OverlayBackgroundExtensionMessage, + sender: chrome.runtime.MessageSender, + ) { const subFrameOffsetsForTab = this.subFrameOffsetsForTab[sender.tab.id]; if (subFrameOffsetsForTab) { subFrameOffsetsForTab.set(message.subFrameData.frameId, message.subFrameData); @@ -431,7 +419,7 @@ class OverlayBackground implements OverlayBackgroundInterface { return; } - if (this.isCurrentlyFilling) { + if (this.isFieldCurrentlyFilling) { void BrowserApi.tabSendMessage( sender.tab, { @@ -852,11 +840,11 @@ class OverlayBackground implements OverlayBackgroundInterface { } private updateIsFieldCurrentlyFilling(message: OverlayBackgroundExtensionMessage) { - this.isCurrentlyFilling = message.isFieldCurrentlyFilling; + this.isFieldCurrentlyFilling = message.isFieldCurrentlyFilling; } private checkIsFieldCurrentlyFilling() { - return this.isCurrentlyFilling; + return this.isFieldCurrentlyFilling; } private async checkIsInlineMenuButtonVisible(sender: chrome.runtime.MessageSender) { @@ -879,6 +867,19 @@ class OverlayBackground implements OverlayBackgroundInterface { return sender.tab.id === this.focusedFieldData.tabId && this.overlayLoginCiphers.size > 0; } + private updateButtonPageColorScheme() { + this.overlayButtonPort?.postMessage({ + command: "getPageColorScheme", + }); + } + + private updateOverlayListHeight(message: OverlayBackgroundExtensionMessage) { + this.overlayListPort?.postMessage({ + command: "updateIframePosition", + styles: message.styles, + }); + } + /** * Sets up the extension message listeners for the overlay. */ @@ -909,9 +910,9 @@ class OverlayBackground implements OverlayBackgroundInterface { return; } - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - Promise.resolve(messageResponse).then((response) => sendResponse(response)); + Promise.resolve(messageResponse) + .then((response) => sendResponse(response)) + .catch(this.logService.error); return true; }; diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index f8a8e4fdb9a..cb3a7011c11 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -911,6 +911,7 @@ export default class MainBackground { this.configService, ); this.overlayBackground = new OverlayBackground( + this.logService, this.cipherService, this.autofillService, this.authService,