mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-25 12:15:18 +01:00
[PM-6921] Optimize methodology for storing page details within inline menu background processes (#8385)
* [PM-6921] Optimize methodology for storing page details within inline menu background processes * [PM-6921] Incorporating method for ensuring that we clear the Map datastructure when the page details are being removed * [PM-6921] Adjusting method to ensure that page details always remain up to date for when processed
This commit is contained in:
parent
600cc080b8
commit
b9f9ad029f
@ -125,7 +125,8 @@ describe("OverlayBackground", () => {
|
||||
describe("removePageDetails", () => {
|
||||
it("removes the page details for a specific tab from the pageDetailsForTab object", () => {
|
||||
const tabId = 1;
|
||||
overlayBackground["pageDetailsForTab"][tabId] = [createPageDetailMock()];
|
||||
const frameId = 2;
|
||||
overlayBackground["pageDetailsForTab"][tabId] = new Map([[frameId, createPageDetailMock()]]);
|
||||
overlayBackground.removePageDetails(tabId);
|
||||
|
||||
expect(overlayBackground["pageDetailsForTab"][tabId]).toBeUndefined();
|
||||
@ -864,29 +865,40 @@ describe("OverlayBackground", () => {
|
||||
sender,
|
||||
);
|
||||
|
||||
expect(overlayBackground["pageDetailsForTab"][sender.tab.id]).toStrictEqual([
|
||||
{ frameId: sender.frameId, tab: sender.tab, details: pageDetails1 },
|
||||
]);
|
||||
expect(overlayBackground["pageDetailsForTab"][sender.tab.id]).toStrictEqual(
|
||||
new Map([
|
||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails1 }],
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("updates the page details for a tab that already has a set of page details stored ", () => {
|
||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = [
|
||||
{
|
||||
frameId: sender.frameId,
|
||||
tab: sender.tab,
|
||||
details: pageDetails1,
|
||||
},
|
||||
];
|
||||
const secondFrameSender = mock<chrome.runtime.MessageSender>({
|
||||
tab: { id: 1 },
|
||||
frameId: 3,
|
||||
});
|
||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails1 }],
|
||||
]);
|
||||
|
||||
sendExtensionRuntimeMessage(
|
||||
{ command: "collectPageDetailsResponse", details: pageDetails2 },
|
||||
sender,
|
||||
secondFrameSender,
|
||||
);
|
||||
|
||||
expect(overlayBackground["pageDetailsForTab"][sender.tab.id]).toStrictEqual([
|
||||
{ frameId: sender.frameId, tab: sender.tab, details: pageDetails1 },
|
||||
{ frameId: sender.frameId, tab: sender.tab, details: pageDetails2 },
|
||||
]);
|
||||
expect(overlayBackground["pageDetailsForTab"][sender.tab.id]).toStrictEqual(
|
||||
new Map([
|
||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails1 }],
|
||||
[
|
||||
secondFrameSender.frameId,
|
||||
{
|
||||
frameId: secondFrameSender.frameId,
|
||||
tab: secondFrameSender.tab,
|
||||
details: pageDetails2,
|
||||
},
|
||||
],
|
||||
]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1196,6 +1208,10 @@ describe("OverlayBackground", () => {
|
||||
let getLoginCiphersSpy: jest.SpyInstance;
|
||||
let isPasswordRepromptRequiredSpy: jest.SpyInstance;
|
||||
let doAutoFillSpy: jest.SpyInstance;
|
||||
let sender: chrome.runtime.MessageSender;
|
||||
const pageDetails = createAutofillPageDetailsMock({
|
||||
login: { username: "username1", password: "password1" },
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
getLoginCiphersSpy = jest.spyOn(overlayBackground["overlayLoginCiphers"], "get");
|
||||
@ -1204,6 +1220,7 @@ describe("OverlayBackground", () => {
|
||||
"isPasswordRepromptRequired",
|
||||
);
|
||||
doAutoFillSpy = jest.spyOn(overlayBackground["autofillService"], "doAutoFill");
|
||||
sender = mock<chrome.runtime.MessageSender>({ tab: { id: 1 } });
|
||||
});
|
||||
|
||||
it("ignores the fill request if the overlay cipher id is not provided", async () => {
|
||||
@ -1215,12 +1232,27 @@ describe("OverlayBackground", () => {
|
||||
expect(doAutoFillSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("ignores the fill request if the tab does not contain any identified page details", async () => {
|
||||
sendPortMessage(listPortSpy, {
|
||||
command: "fillSelectedListItem",
|
||||
overlayCipherId: "overlay-cipher-1",
|
||||
});
|
||||
await flushPromises();
|
||||
|
||||
expect(getLoginCiphersSpy).not.toHaveBeenCalled();
|
||||
expect(isPasswordRepromptRequiredSpy).not.toHaveBeenCalled();
|
||||
expect(doAutoFillSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("ignores the fill request if a master password reprompt is required", async () => {
|
||||
const cipher = mock<CipherView>({
|
||||
reprompt: CipherRepromptType.Password,
|
||||
type: CipherType.Login,
|
||||
});
|
||||
overlayBackground["overlayLoginCiphers"] = new Map([["overlay-cipher-1", cipher]]);
|
||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails }],
|
||||
]);
|
||||
getLoginCiphersSpy = jest.spyOn(overlayBackground["overlayLoginCiphers"], "get");
|
||||
isPasswordRepromptRequiredSpy.mockResolvedValue(true);
|
||||
|
||||
@ -1247,6 +1279,14 @@ describe("OverlayBackground", () => {
|
||||
["overlay-cipher-2", cipher2],
|
||||
["overlay-cipher-3", cipher3],
|
||||
]);
|
||||
const pageDetailsForTab = {
|
||||
frameId: sender.frameId,
|
||||
tab: sender.tab,
|
||||
details: pageDetails,
|
||||
};
|
||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
||||
[sender.frameId, pageDetailsForTab],
|
||||
]);
|
||||
isPasswordRepromptRequiredSpy.mockResolvedValue(false);
|
||||
|
||||
sendPortMessage(listPortSpy, {
|
||||
@ -1262,7 +1302,7 @@ describe("OverlayBackground", () => {
|
||||
expect(doAutoFillSpy).toHaveBeenCalledWith({
|
||||
tab: listPortSpy.sender.tab,
|
||||
cipher: cipher2,
|
||||
pageDetails: undefined,
|
||||
pageDetails: [pageDetailsForTab],
|
||||
fillNewPassword: true,
|
||||
allowTotpAutofill: true,
|
||||
});
|
||||
@ -1278,6 +1318,9 @@ describe("OverlayBackground", () => {
|
||||
it("copies the cipher's totp code to the clipboard after filling", async () => {
|
||||
const cipher1 = mock<CipherView>({ id: "overlay-cipher-1" });
|
||||
overlayBackground["overlayLoginCiphers"] = new Map([["overlay-cipher-1", cipher1]]);
|
||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails }],
|
||||
]);
|
||||
isPasswordRepromptRequiredSpy.mockResolvedValue(false);
|
||||
const copyToClipboardSpy = jest
|
||||
.spyOn(overlayBackground["platformUtilsService"], "copyToClipboard")
|
||||
|
@ -47,7 +47,10 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
private readonly openViewVaultItemPopout = openViewVaultItemPopout;
|
||||
private readonly openAddEditVaultItemPopout = openAddEditVaultItemPopout;
|
||||
private overlayLoginCiphers: Map<string, CipherView> = new Map();
|
||||
private pageDetailsForTab: Record<number, PageDetail[]> = {};
|
||||
private pageDetailsForTab: Record<
|
||||
chrome.runtime.MessageSender["tab"]["id"],
|
||||
Map<chrome.runtime.MessageSender["frameId"], PageDetail>
|
||||
> = {};
|
||||
private userAuthStatus: AuthenticationStatus = AuthenticationStatus.LoggedOut;
|
||||
private overlayButtonPort: chrome.runtime.Port;
|
||||
private overlayListPort: chrome.runtime.Port;
|
||||
@ -107,6 +110,11 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
* @param tabId - Used to reference the page details of a specific tab
|
||||
*/
|
||||
removePageDetails(tabId: number) {
|
||||
if (!this.pageDetailsForTab[tabId]) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.pageDetailsForTab[tabId].clear();
|
||||
delete this.pageDetailsForTab[tabId];
|
||||
}
|
||||
|
||||
@ -203,12 +211,13 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
details: message.details,
|
||||
};
|
||||
|
||||
if (this.pageDetailsForTab[sender.tab.id]?.length) {
|
||||
this.pageDetailsForTab[sender.tab.id].push(pageDetails);
|
||||
const pageDetailsMap = this.pageDetailsForTab[sender.tab.id];
|
||||
if (!pageDetailsMap) {
|
||||
this.pageDetailsForTab[sender.tab.id] = new Map([[sender.frameId, pageDetails]]);
|
||||
return;
|
||||
}
|
||||
|
||||
this.pageDetailsForTab[sender.tab.id] = [pageDetails];
|
||||
pageDetailsMap.set(sender.frameId, pageDetails);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,7 +231,8 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
{ overlayCipherId }: OverlayPortMessage,
|
||||
{ sender }: chrome.runtime.Port,
|
||||
) {
|
||||
if (!overlayCipherId) {
|
||||
const pageDetails = this.pageDetailsForTab[sender.tab.id];
|
||||
if (!overlayCipherId || !pageDetails?.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -234,7 +244,7 @@ class OverlayBackground implements OverlayBackgroundInterface {
|
||||
const totpCode = await this.autofillService.doAutoFill({
|
||||
tab: sender.tab,
|
||||
cipher: cipher,
|
||||
pageDetails: this.pageDetailsForTab[sender.tab.id],
|
||||
pageDetails: Array.from(pageDetails.values()),
|
||||
fillNewPassword: true,
|
||||
allowTotpAutofill: true,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user