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