mirror of
https://github.com/bitwarden/browser
synced 2025-12-18 01:03:35 +00:00
[PM-5189] Refactoring implementation
This commit is contained in:
@@ -73,10 +73,10 @@ export type OverlayPortMessage = {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
command: string;
|
command: string;
|
||||||
direction?: string;
|
direction?: string;
|
||||||
overlayCipherId?: string;
|
inlineMenuCipherId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OverlayCipherData = {
|
export type InlineMenuCipherData = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: CipherType;
|
type: CipherType;
|
||||||
@@ -139,8 +139,8 @@ export type PortOnMessageHandlerParams = PortMessageParam & PortConnectionParam;
|
|||||||
|
|
||||||
export type InlineMenuButtonPortMessageHandlers = {
|
export type InlineMenuButtonPortMessageHandlers = {
|
||||||
[key: string]: CallableFunction;
|
[key: string]: CallableFunction;
|
||||||
autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void;
|
|
||||||
triggerDelayedAutofillInlineMenuClosure: ({ port }: PortConnectionParam) => void;
|
triggerDelayedAutofillInlineMenuClosure: ({ port }: PortConnectionParam) => void;
|
||||||
|
autofillInlineMenuButtonClicked: ({ port }: PortConnectionParam) => void;
|
||||||
autofillInlineMenuBlurred: () => void;
|
autofillInlineMenuBlurred: () => void;
|
||||||
redirectAutofillInlineMenuFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void;
|
redirectAutofillInlineMenuFocusOut: ({ message, port }: PortOnMessageHandlerParams) => void;
|
||||||
updateAutofillInlineMenuColorScheme: () => void;
|
updateAutofillInlineMenuColorScheme: () => void;
|
||||||
@@ -161,5 +161,5 @@ export type InlineMenuListPortMessageHandlers = {
|
|||||||
export interface OverlayBackground {
|
export interface OverlayBackground {
|
||||||
init(): Promise<void>;
|
init(): Promise<void>;
|
||||||
removePageDetails(tabId: number): void;
|
removePageDetails(tabId: number): void;
|
||||||
updateOverlayCiphers(): void;
|
updateInlineMenuCiphers(): void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -512,7 +512,7 @@ describe("OverlayBackground", () => {
|
|||||||
it("skips updating the overlay ciphers if the user's auth status is not unlocked", async () => {
|
it("skips updating the overlay ciphers if the user's auth status is not unlocked", async () => {
|
||||||
activeAccountStatusMock$.next(AuthenticationStatus.Locked);
|
activeAccountStatusMock$.next(AuthenticationStatus.Locked);
|
||||||
|
|
||||||
await overlayBackground.updateOverlayCiphers();
|
await overlayBackground.updateInlineMenuCiphers();
|
||||||
|
|
||||||
expect(getTabFromCurrentWindowIdSpy).not.toHaveBeenCalled();
|
expect(getTabFromCurrentWindowIdSpy).not.toHaveBeenCalled();
|
||||||
expect(cipherService.getAllDecryptedForUrl).not.toHaveBeenCalled();
|
expect(cipherService.getAllDecryptedForUrl).not.toHaveBeenCalled();
|
||||||
@@ -521,7 +521,7 @@ describe("OverlayBackground", () => {
|
|||||||
it("ignores updating the overlay ciphers if the tab is undefined", async () => {
|
it("ignores updating the overlay ciphers if the tab is undefined", async () => {
|
||||||
getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(undefined);
|
getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(undefined);
|
||||||
|
|
||||||
await overlayBackground.updateOverlayCiphers();
|
await overlayBackground.updateInlineMenuCiphers();
|
||||||
|
|
||||||
expect(getTabFromCurrentWindowIdSpy).toHaveBeenCalled();
|
expect(getTabFromCurrentWindowIdSpy).toHaveBeenCalled();
|
||||||
expect(cipherService.getAllDecryptedForUrl).not.toHaveBeenCalled();
|
expect(cipherService.getAllDecryptedForUrl).not.toHaveBeenCalled();
|
||||||
@@ -532,26 +532,26 @@ describe("OverlayBackground", () => {
|
|||||||
cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher2]);
|
cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher2]);
|
||||||
cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1);
|
cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1);
|
||||||
|
|
||||||
await overlayBackground.updateOverlayCiphers();
|
await overlayBackground.updateInlineMenuCiphers();
|
||||||
|
|
||||||
expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled();
|
expect(BrowserApi.getTabFromCurrentWindowId).toHaveBeenCalled();
|
||||||
expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url);
|
expect(cipherService.getAllDecryptedForUrl).toHaveBeenCalledWith(url);
|
||||||
expect(cipherService.sortCiphersByLastUsedThenName).toHaveBeenCalled();
|
expect(cipherService.sortCiphersByLastUsedThenName).toHaveBeenCalled();
|
||||||
expect(overlayBackground["inlineMenuCiphers"]).toStrictEqual(
|
expect(overlayBackground["inlineMenuCiphers"]).toStrictEqual(
|
||||||
new Map([
|
new Map([
|
||||||
["overlay-cipher-0", cipher2],
|
["inline-menu-cipher-0", cipher2],
|
||||||
["overlay-cipher-1", cipher1],
|
["inline-menu-cipher-1", cipher1],
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("posts an `updateOverlayListCiphers` message to the overlay list port, and send a `updateIsOverlayCiphersPopulated` message to the tab indicating that the list of ciphers is populated", async () => {
|
it("posts an `updateOverlayListCiphers` message to the overlay list port, and send a `updateAutofillInlineMenuListCiphers` message to the tab indicating that the list of ciphers is populated", async () => {
|
||||||
overlayBackground["inlineMenuListPort"] = mock<chrome.runtime.Port>();
|
overlayBackground["inlineMenuListPort"] = mock<chrome.runtime.Port>();
|
||||||
cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher2]);
|
cipherService.getAllDecryptedForUrl.mockResolvedValue([cipher1, cipher2]);
|
||||||
cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1);
|
cipherService.sortCiphersByLastUsedThenName.mockReturnValue(-1);
|
||||||
getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab);
|
getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(tab);
|
||||||
|
|
||||||
await overlayBackground.updateOverlayCiphers();
|
await overlayBackground.updateInlineMenuCiphers();
|
||||||
|
|
||||||
expect(overlayBackground["inlineMenuListPort"].postMessage).toHaveBeenCalledWith({
|
expect(overlayBackground["inlineMenuListPort"].postMessage).toHaveBeenCalledWith({
|
||||||
command: "updateAutofillInlineMenuListCiphers",
|
command: "updateAutofillInlineMenuListCiphers",
|
||||||
@@ -565,7 +565,7 @@ describe("OverlayBackground", () => {
|
|||||||
image: undefined,
|
image: undefined,
|
||||||
imageEnabled: true,
|
imageEnabled: true,
|
||||||
},
|
},
|
||||||
id: "overlay-cipher-0",
|
id: "inline-menu-cipher-0",
|
||||||
login: null,
|
login: null,
|
||||||
name: "name-2",
|
name: "name-2",
|
||||||
reprompt: cipher2.reprompt,
|
reprompt: cipher2.reprompt,
|
||||||
@@ -580,7 +580,7 @@ describe("OverlayBackground", () => {
|
|||||||
image: "https://icons.bitwarden.com//jest-testing-website.com/icon.png",
|
image: "https://icons.bitwarden.com//jest-testing-website.com/icon.png",
|
||||||
imageEnabled: true,
|
imageEnabled: true,
|
||||||
},
|
},
|
||||||
id: "overlay-cipher-1",
|
id: "inline-menu-cipher-1",
|
||||||
login: {
|
login: {
|
||||||
username: "username-1",
|
username: "username-1",
|
||||||
},
|
},
|
||||||
@@ -705,7 +705,7 @@ describe("OverlayBackground", () => {
|
|||||||
|
|
||||||
it("returns true if the overlay login ciphers are populated", async () => {
|
it("returns true if the overlay login ciphers are populated", async () => {
|
||||||
overlayBackground["inlineMenuCiphers"] = new Map([
|
overlayBackground["inlineMenuCiphers"] = new Map([
|
||||||
["overlay-cipher-0", mock<CipherView>()],
|
["inline-menu-cipher-0", mock<CipherView>()],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
sendMockExtensionMessage(
|
sendMockExtensionMessage(
|
||||||
@@ -1334,10 +1334,10 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("unlockCompleted", () => {
|
describe("unlockCompleted", () => {
|
||||||
let updateOverlayCiphersSpy: jest.SpyInstance;
|
let updateInlineMenuCiphersSpy: jest.SpyInstance;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
updateOverlayCiphersSpy = jest.spyOn(overlayBackground, "updateOverlayCiphers");
|
updateInlineMenuCiphersSpy = jest.spyOn(overlayBackground, "updateInlineMenuCiphers");
|
||||||
await initOverlayElementPorts();
|
await initOverlayElementPorts();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1352,15 +1352,15 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("updates the overlay ciphers", async () => {
|
it("updates the overlay ciphers", async () => {
|
||||||
const updateOverlayCiphersSpy = jest.spyOn(overlayBackground, "updateOverlayCiphers");
|
const updateInlineMenuCiphersSpy = jest.spyOn(overlayBackground, "updateInlineMenuCiphers");
|
||||||
sendMockExtensionMessage({ command: "unlockCompleted" });
|
sendMockExtensionMessage({ command: "unlockCompleted" });
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|
||||||
expect(updateOverlayCiphersSpy).toHaveBeenCalled();
|
expect(updateInlineMenuCiphersSpy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("opens the inline menu if a retry command is present in the message", async () => {
|
it("opens the inline menu if a retry command is present in the message", async () => {
|
||||||
updateOverlayCiphersSpy.mockImplementation();
|
updateInlineMenuCiphersSpy.mockImplementation();
|
||||||
getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(createChromeTabMock({ id: 1 }));
|
getTabFromCurrentWindowIdSpy.mockResolvedValueOnce(createChromeTabMock({ id: 1 }));
|
||||||
sendMockExtensionMessage({
|
sendMockExtensionMessage({
|
||||||
command: "unlockCompleted",
|
command: "unlockCompleted",
|
||||||
@@ -1392,13 +1392,13 @@ describe("OverlayBackground", () => {
|
|||||||
];
|
];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.spyOn(overlayBackground, "updateOverlayCiphers").mockImplementation();
|
jest.spyOn(overlayBackground, "updateInlineMenuCiphers").mockImplementation();
|
||||||
});
|
});
|
||||||
|
|
||||||
extensionMessages.forEach((message) => {
|
extensionMessages.forEach((message) => {
|
||||||
it(`triggers an update of the overlay ciphers when the ${message} message is received`, () => {
|
it(`triggers an update of the overlay ciphers when the ${message} message is received`, () => {
|
||||||
sendMockExtensionMessage({ command: message });
|
sendMockExtensionMessage({ command: message });
|
||||||
expect(overlayBackground.updateOverlayCiphers).toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1640,7 +1640,7 @@ describe("OverlayBackground", () => {
|
|||||||
it("ignores the fill request if the tab does not contain any identified page details", async () => {
|
it("ignores the fill request if the tab does not contain any identified page details", async () => {
|
||||||
sendPortMessage(listMessageConnectorSpy, {
|
sendPortMessage(listMessageConnectorSpy, {
|
||||||
command: "fillSelectedAutofillInlineMenuListItem",
|
command: "fillSelectedAutofillInlineMenuListItem",
|
||||||
overlayCipherId: "overlay-cipher-1",
|
inlineMenuCipherId: "inline-menu-cipher-1",
|
||||||
portKey,
|
portKey,
|
||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@@ -1654,7 +1654,7 @@ describe("OverlayBackground", () => {
|
|||||||
reprompt: CipherRepromptType.Password,
|
reprompt: CipherRepromptType.Password,
|
||||||
type: CipherType.Login,
|
type: CipherType.Login,
|
||||||
});
|
});
|
||||||
overlayBackground["inlineMenuCiphers"] = new Map([["overlay-cipher-1", cipher]]);
|
overlayBackground["inlineMenuCiphers"] = new Map([["inline-menu-cipher-1", cipher]]);
|
||||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
||||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails }],
|
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails }],
|
||||||
]);
|
]);
|
||||||
@@ -1662,7 +1662,7 @@ describe("OverlayBackground", () => {
|
|||||||
|
|
||||||
sendPortMessage(listMessageConnectorSpy, {
|
sendPortMessage(listMessageConnectorSpy, {
|
||||||
command: "fillSelectedAutofillInlineMenuListItem",
|
command: "fillSelectedAutofillInlineMenuListItem",
|
||||||
overlayCipherId: "overlay-cipher-1",
|
inlineMenuCipherId: "inline-menu-cipher-1",
|
||||||
portKey,
|
portKey,
|
||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@@ -1672,13 +1672,13 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("auto-fills the selected cipher and move it to the top of the front of the ciphers map", async () => {
|
it("auto-fills the selected cipher and move it to the top of the front of the ciphers map", async () => {
|
||||||
const cipher1 = mock<CipherView>({ id: "overlay-cipher-1" });
|
const cipher1 = mock<CipherView>({ id: "inline-menu-cipher-1" });
|
||||||
const cipher2 = mock<CipherView>({ id: "overlay-cipher-2" });
|
const cipher2 = mock<CipherView>({ id: "inline-menu-cipher-2" });
|
||||||
const cipher3 = mock<CipherView>({ id: "overlay-cipher-3" });
|
const cipher3 = mock<CipherView>({ id: "inline-menu-cipher-3" });
|
||||||
overlayBackground["inlineMenuCiphers"] = new Map([
|
overlayBackground["inlineMenuCiphers"] = new Map([
|
||||||
["overlay-cipher-1", cipher1],
|
["inline-menu-cipher-1", cipher1],
|
||||||
["overlay-cipher-2", cipher2],
|
["inline-menu-cipher-2", cipher2],
|
||||||
["overlay-cipher-3", cipher3],
|
["inline-menu-cipher-3", cipher3],
|
||||||
]);
|
]);
|
||||||
const pageDetailsForTab = {
|
const pageDetailsForTab = {
|
||||||
frameId: sender.frameId,
|
frameId: sender.frameId,
|
||||||
@@ -1692,7 +1692,7 @@ describe("OverlayBackground", () => {
|
|||||||
|
|
||||||
sendPortMessage(listMessageConnectorSpy, {
|
sendPortMessage(listMessageConnectorSpy, {
|
||||||
command: "fillSelectedAutofillInlineMenuListItem",
|
command: "fillSelectedAutofillInlineMenuListItem",
|
||||||
overlayCipherId: "overlay-cipher-2",
|
inlineMenuCipherId: "inline-menu-cipher-2",
|
||||||
portKey,
|
portKey,
|
||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@@ -1710,16 +1710,16 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
expect(overlayBackground["inlineMenuCiphers"].entries()).toStrictEqual(
|
expect(overlayBackground["inlineMenuCiphers"].entries()).toStrictEqual(
|
||||||
new Map([
|
new Map([
|
||||||
["overlay-cipher-2", cipher2],
|
["inline-menu-cipher-2", cipher2],
|
||||||
["overlay-cipher-1", cipher1],
|
["inline-menu-cipher-1", cipher1],
|
||||||
["overlay-cipher-3", cipher3],
|
["inline-menu-cipher-3", cipher3],
|
||||||
]).entries(),
|
]).entries(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("copies the cipher's totp code to the clipboard after filling", async () => {
|
it("copies the cipher's totp code to the clipboard after filling", async () => {
|
||||||
const cipher1 = mock<CipherView>({ id: "overlay-cipher-1" });
|
const cipher1 = mock<CipherView>({ id: "inline-menu-cipher-1" });
|
||||||
overlayBackground["inlineMenuCiphers"] = new Map([["overlay-cipher-1", cipher1]]);
|
overlayBackground["inlineMenuCiphers"] = new Map([["inline-menu-cipher-1", cipher1]]);
|
||||||
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
overlayBackground["pageDetailsForTab"][sender.tab.id] = new Map([
|
||||||
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails }],
|
[sender.frameId, { frameId: sender.frameId, tab: sender.tab, details: pageDetails }],
|
||||||
]);
|
]);
|
||||||
@@ -1731,7 +1731,7 @@ describe("OverlayBackground", () => {
|
|||||||
|
|
||||||
sendPortMessage(listMessageConnectorSpy, {
|
sendPortMessage(listMessageConnectorSpy, {
|
||||||
command: "fillSelectedAutofillInlineMenuListItem",
|
command: "fillSelectedAutofillInlineMenuListItem",
|
||||||
overlayCipherId: "overlay-cipher-2",
|
inlineMenuCipherId: "inline-menu-cipher-2",
|
||||||
portKey,
|
portKey,
|
||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@@ -1779,12 +1779,12 @@ describe("OverlayBackground", () => {
|
|||||||
|
|
||||||
it("returns early if the passed cipher ID does not match one of the inline menu ciphers", async () => {
|
it("returns early if the passed cipher ID does not match one of the inline menu ciphers", async () => {
|
||||||
overlayBackground["inlineMenuCiphers"] = new Map([
|
overlayBackground["inlineMenuCiphers"] = new Map([
|
||||||
["overlay-cipher-0", mock<CipherView>({ id: "overlay-cipher-0" })],
|
["inline-menu-cipher-0", mock<CipherView>({ id: "inline-menu-cipher-0" })],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
sendPortMessage(listMessageConnectorSpy, {
|
sendPortMessage(listMessageConnectorSpy, {
|
||||||
command: "viewSelectedCipher",
|
command: "viewSelectedCipher",
|
||||||
overlayCipherId: "overlay-cipher-1",
|
inlineMenuCipherId: "inline-menu-cipher-1",
|
||||||
portKey,
|
portKey,
|
||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
@@ -1793,15 +1793,15 @@ describe("OverlayBackground", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("will open the view vault item popout with the selected cipher", async () => {
|
it("will open the view vault item popout with the selected cipher", async () => {
|
||||||
const cipher = mock<CipherView>({ id: "overlay-cipher-1" });
|
const cipher = mock<CipherView>({ id: "inline-menu-cipher-1" });
|
||||||
overlayBackground["inlineMenuCiphers"] = new Map([
|
overlayBackground["inlineMenuCiphers"] = new Map([
|
||||||
["overlay-cipher-0", mock<CipherView>({ id: "overlay-cipher-0" })],
|
["inline-menu-cipher-0", mock<CipherView>({ id: "inline-menu-cipher-0" })],
|
||||||
["overlay-cipher-1", cipher],
|
["inline-menu-cipher-1", cipher],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
sendPortMessage(listMessageConnectorSpy, {
|
sendPortMessage(listMessageConnectorSpy, {
|
||||||
command: "viewSelectedCipher",
|
command: "viewSelectedCipher",
|
||||||
overlayCipherId: "overlay-cipher-1",
|
inlineMenuCipherId: "inline-menu-cipher-1",
|
||||||
portKey,
|
portKey,
|
||||||
});
|
});
|
||||||
await flushPromises();
|
await flushPromises();
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import {
|
|||||||
OverlayBackgroundExtensionMessage,
|
OverlayBackgroundExtensionMessage,
|
||||||
OverlayBackgroundExtensionMessageHandlers,
|
OverlayBackgroundExtensionMessageHandlers,
|
||||||
InlineMenuButtonPortMessageHandlers,
|
InlineMenuButtonPortMessageHandlers,
|
||||||
OverlayCipherData,
|
InlineMenuCipherData,
|
||||||
InlineMenuListPortMessageHandlers,
|
InlineMenuListPortMessageHandlers,
|
||||||
OverlayPortMessage,
|
OverlayPortMessage,
|
||||||
PageDetailsForTab,
|
PageDetailsForTab,
|
||||||
@@ -94,15 +94,15 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
rebuildSubFrameOffsets: ({ sender }) => this.rebuildSubFrameOffsets(sender),
|
rebuildSubFrameOffsets: ({ sender }) => this.rebuildSubFrameOffsets(sender),
|
||||||
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
|
collectPageDetailsResponse: ({ message, sender }) => this.storePageDetails(message, sender),
|
||||||
unlockCompleted: ({ message }) => this.unlockCompleted(message),
|
unlockCompleted: ({ message }) => this.unlockCompleted(message),
|
||||||
addedCipher: () => this.updateOverlayCiphers(),
|
addedCipher: () => this.updateInlineMenuCiphers(),
|
||||||
addEditCipherSubmitted: () => this.updateOverlayCiphers(),
|
addEditCipherSubmitted: () => this.updateInlineMenuCiphers(),
|
||||||
editedCipher: () => this.updateOverlayCiphers(),
|
editedCipher: () => this.updateInlineMenuCiphers(),
|
||||||
deletedCipher: () => this.updateOverlayCiphers(),
|
deletedCipher: () => this.updateInlineMenuCiphers(),
|
||||||
};
|
};
|
||||||
private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = {
|
private readonly inlineMenuButtonPortMessageHandlers: InlineMenuButtonPortMessageHandlers = {
|
||||||
autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port),
|
|
||||||
triggerDelayedAutofillInlineMenuClosure: ({ port }) =>
|
triggerDelayedAutofillInlineMenuClosure: ({ port }) =>
|
||||||
this.triggerDelayedInlineMenuClosure(port.sender),
|
this.triggerDelayedInlineMenuClosure(port.sender),
|
||||||
|
autofillInlineMenuButtonClicked: ({ port }) => this.handleInlineMenuButtonClicked(port),
|
||||||
autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(),
|
autofillInlineMenuBlurred: () => this.checkInlineMenuListFocused(),
|
||||||
redirectAutofillInlineMenuFocusOut: ({ message, port }) =>
|
redirectAutofillInlineMenuFocusOut: ({ message, port }) =>
|
||||||
this.redirectInlineMenuFocusOut(message, port),
|
this.redirectInlineMenuFocusOut(message, port),
|
||||||
@@ -171,7 +171,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
* Queries all ciphers for the given url, and sorts them by last used. Will not update the
|
* Queries all ciphers for the given url, and sorts them by last used. Will not update the
|
||||||
* list of ciphers if the extension is not unlocked.
|
* list of ciphers if the extension is not unlocked.
|
||||||
*/
|
*/
|
||||||
async updateOverlayCiphers() {
|
async updateInlineMenuCiphers() {
|
||||||
const authStatus = await firstValueFrom(this.authService.activeAccountStatus$);
|
const authStatus = await firstValueFrom(this.authService.activeAccountStatus$);
|
||||||
if (authStatus !== AuthenticationStatus.Unlocked) {
|
if (authStatus !== AuthenticationStatus.Unlocked) {
|
||||||
return;
|
return;
|
||||||
@@ -187,10 +187,10 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
(a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b),
|
(a, b) => this.cipherService.sortCiphersByLastUsedThenName(a, b),
|
||||||
);
|
);
|
||||||
for (let cipherIndex = 0; cipherIndex < ciphersViews.length; cipherIndex++) {
|
for (let cipherIndex = 0; cipherIndex < ciphersViews.length; cipherIndex++) {
|
||||||
this.inlineMenuCiphers.set(`overlay-cipher-${cipherIndex}`, ciphersViews[cipherIndex]);
|
this.inlineMenuCiphers.set(`inline-menu-cipher-${cipherIndex}`, ciphersViews[cipherIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ciphers = await this.getOverlayCipherData();
|
const ciphers = await this.getInlineMenuCipherData();
|
||||||
this.inlineMenuListPort?.postMessage({
|
this.inlineMenuListPort?.postMessage({
|
||||||
command: "updateAutofillInlineMenuListCiphers",
|
command: "updateAutofillInlineMenuListCiphers",
|
||||||
ciphers,
|
ciphers,
|
||||||
@@ -201,16 +201,16 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
* Strips out unnecessary data from the ciphers and returns an array of
|
* Strips out unnecessary data from the ciphers and returns an array of
|
||||||
* objects that contain the cipher data needed for the inline menu list.
|
* objects that contain the cipher data needed for the inline menu list.
|
||||||
*/
|
*/
|
||||||
private async getOverlayCipherData(): Promise<OverlayCipherData[]> {
|
private async getInlineMenuCipherData(): Promise<InlineMenuCipherData[]> {
|
||||||
const showFavicons = await firstValueFrom(this.domainSettingsService.showFavicons$);
|
const showFavicons = await firstValueFrom(this.domainSettingsService.showFavicons$);
|
||||||
const overlayCiphersArray = Array.from(this.inlineMenuCiphers);
|
const inlineMenuCiphersArray = Array.from(this.inlineMenuCiphers);
|
||||||
const overlayCipherData: OverlayCipherData[] = [];
|
const inlineMenuCipherData: InlineMenuCipherData[] = [];
|
||||||
|
|
||||||
for (let cipherIndex = 0; cipherIndex < overlayCiphersArray.length; cipherIndex++) {
|
for (let cipherIndex = 0; cipherIndex < inlineMenuCiphersArray.length; cipherIndex++) {
|
||||||
const [overlayCipherId, cipher] = overlayCiphersArray[cipherIndex];
|
const [inlineMenuCipherId, cipher] = inlineMenuCiphersArray[cipherIndex];
|
||||||
|
|
||||||
overlayCipherData.push({
|
inlineMenuCipherData.push({
|
||||||
id: overlayCipherId,
|
id: inlineMenuCipherId,
|
||||||
name: cipher.name,
|
name: cipher.name,
|
||||||
type: cipher.type,
|
type: cipher.type,
|
||||||
reprompt: cipher.reprompt,
|
reprompt: cipher.reprompt,
|
||||||
@@ -221,7 +221,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return overlayCipherData;
|
return inlineMenuCipherData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -414,19 +414,19 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
* Triggers autofill for the selected cipher in the inline menu list. Also places
|
* Triggers autofill for the selected cipher in the inline menu list. Also places
|
||||||
* the selected cipher at the top of the list of ciphers.
|
* the selected cipher at the top of the list of ciphers.
|
||||||
*
|
*
|
||||||
* @param overlayCipherId - Cipher ID corresponding to the inlineMenuCiphers map. Does not correspond to the actual cipher's ID.
|
* @param inlineMenuCipherId - Cipher ID corresponding to the inlineMenuCiphers map. Does not correspond to the actual cipher's ID.
|
||||||
* @param sender - The sender of the port message
|
* @param sender - The sender of the port message
|
||||||
*/
|
*/
|
||||||
private async fillSelectedInlineMenuListItem(
|
private async fillSelectedInlineMenuListItem(
|
||||||
{ overlayCipherId }: OverlayPortMessage,
|
{ inlineMenuCipherId }: OverlayPortMessage,
|
||||||
{ sender }: chrome.runtime.Port,
|
{ sender }: chrome.runtime.Port,
|
||||||
) {
|
) {
|
||||||
const pageDetails = this.pageDetailsForTab[sender.tab.id];
|
const pageDetails = this.pageDetailsForTab[sender.tab.id];
|
||||||
if (!overlayCipherId || !pageDetails?.size) {
|
if (!inlineMenuCipherId || !pageDetails?.size) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cipher = this.inlineMenuCiphers.get(overlayCipherId);
|
const cipher = this.inlineMenuCiphers.get(inlineMenuCipherId);
|
||||||
|
|
||||||
if (await this.autofillService.isPasswordRepromptRequired(cipher, sender.tab)) {
|
if (await this.autofillService.isPasswordRepromptRequired(cipher, sender.tab)) {
|
||||||
return;
|
return;
|
||||||
@@ -443,7 +443,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
this.platformUtilsService.copyToClipboard(totpCode);
|
this.platformUtilsService.copyToClipboard(totpCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.inlineMenuCiphers = new Map([[overlayCipherId, cipher], ...this.inlineMenuCiphers]);
|
this.inlineMenuCiphers = new Map([[inlineMenuCipherId, cipher], ...this.inlineMenuCiphers]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -814,14 +814,14 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
/**
|
/**
|
||||||
* Triggers the opening of a vault item popout window associated
|
* Triggers the opening of a vault item popout window associated
|
||||||
* with the passed cipher ID.
|
* with the passed cipher ID.
|
||||||
* @param overlayCipherId - Cipher ID corresponding to the inlineMenuCiphers map. Does not correspond to the actual cipher's ID.
|
* @param inlineMenuCipherId - Cipher ID corresponding to the inlineMenuCiphers map. Does not correspond to the actual cipher's ID.
|
||||||
* @param sender - The sender of the port message
|
* @param sender - The sender of the port message
|
||||||
*/
|
*/
|
||||||
private async viewSelectedCipher(
|
private async viewSelectedCipher(
|
||||||
{ overlayCipherId }: OverlayPortMessage,
|
{ inlineMenuCipherId }: OverlayPortMessage,
|
||||||
{ sender }: chrome.runtime.Port,
|
{ sender }: chrome.runtime.Port,
|
||||||
) {
|
) {
|
||||||
const cipher = this.inlineMenuCiphers.get(overlayCipherId);
|
const cipher = this.inlineMenuCiphers.get(inlineMenuCipherId);
|
||||||
if (!cipher) {
|
if (!cipher) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -847,7 +847,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
*/
|
*/
|
||||||
private async unlockCompleted(message: OverlayBackgroundExtensionMessage) {
|
private async unlockCompleted(message: OverlayBackgroundExtensionMessage) {
|
||||||
await this.updateInlineMenuButtonAuthStatus();
|
await this.updateInlineMenuButtonAuthStatus();
|
||||||
await this.updateOverlayCiphers();
|
await this.updateInlineMenuCiphers();
|
||||||
|
|
||||||
if (message.data?.commandToRetry?.message?.command === "openAutofillInlineMenu") {
|
if (message.data?.commandToRetry?.message?.command === "openAutofillInlineMenu") {
|
||||||
await this.openInlineMenu(true);
|
await this.openInlineMenu(true);
|
||||||
@@ -1159,7 +1159,7 @@ export class OverlayBackground implements OverlayBackgroundInterface {
|
|||||||
),
|
),
|
||||||
theme: await firstValueFrom(this.themeStateService.selectedTheme$),
|
theme: await firstValueFrom(this.themeStateService.selectedTheme$),
|
||||||
translations: this.getInlineMenuTranslations(),
|
translations: this.getInlineMenuTranslations(),
|
||||||
ciphers: isInlineMenuListPort ? await this.getOverlayCipherData() : null,
|
ciphers: isInlineMenuListPort ? await this.getInlineMenuCipherData() : null,
|
||||||
portKey: this.portKeyForTab[port.sender.tab.id],
|
portKey: this.portKeyForTab[port.sender.tab.id],
|
||||||
portName: isInlineMenuListPort
|
portName: isInlineMenuListPort
|
||||||
? AutofillOverlayPort.ListMessageConnector
|
? AutofillOverlayPort.ListMessageConnector
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a `windowChanged` message", async () => {
|
it("sends a `windowChanged` message", async () => {
|
||||||
@@ -93,7 +93,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a `tabChanged` message to the messaging service", async () => {
|
it("sends a `tabChanged` message to the messaging service", async () => {
|
||||||
@@ -129,7 +129,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a `tabChanged` message to the messaging service", async () => {
|
it("sends a `tabChanged` message to the messaging service", async () => {
|
||||||
@@ -173,7 +173,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).not.toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).not.toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).not.toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).not.toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).not.toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("skips updating the current tab data if the updated tab is not for the focusedWindowId", async () => {
|
it("skips updating the current tab data if the updated tab is not for the focusedWindowId", async () => {
|
||||||
@@ -183,7 +183,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).not.toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).not.toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).not.toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).not.toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).not.toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("skips updating the current tab data if the updated tab is not active", async () => {
|
it("skips updating the current tab data if the updated tab is not active", async () => {
|
||||||
@@ -193,7 +193,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).not.toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).not.toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).not.toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).not.toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).not.toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("skips updating the badge, context menu and notification bar if the `onUpdatedRan` property of the main background class is set to `true`", async () => {
|
it("skips updating the badge, context menu and notification bar if the `onUpdatedRan` property of the main background class is set to `true`", async () => {
|
||||||
@@ -218,7 +218,7 @@ describe("TabsBackground", () => {
|
|||||||
|
|
||||||
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
expect(mainBackground.refreshBadge).toHaveBeenCalled();
|
||||||
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
expect(mainBackground.refreshMenu).toHaveBeenCalled();
|
||||||
expect(overlayBackground.updateOverlayCiphers).toHaveBeenCalled();
|
expect(overlayBackground.updateInlineMenuCiphers).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sends a `tabChanged` message to the messaging service", async () => {
|
it("sends a `tabChanged` message to the messaging service", async () => {
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ export default class TabsBackground {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.overlayBackground.updateOverlayCiphers();
|
await this.overlayBackground.updateInlineMenuCiphers();
|
||||||
|
|
||||||
if (this.main.onUpdatedRan) {
|
if (this.main.onUpdatedRan) {
|
||||||
return;
|
return;
|
||||||
@@ -129,7 +129,7 @@ export default class TabsBackground {
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.main.refreshBadge(),
|
this.main.refreshBadge(),
|
||||||
this.main.refreshMenu(),
|
this.main.refreshMenu(),
|
||||||
this.overlayBackground.updateOverlayCiphers(),
|
this.overlayBackground.updateInlineMenuCiphers(),
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ export type AutofillExtensionMessage = {
|
|||||||
authStatus?: AuthenticationStatus;
|
authStatus?: AuthenticationStatus;
|
||||||
isOpeningFullAutofillInlineMenu?: boolean;
|
isOpeningFullAutofillInlineMenu?: boolean;
|
||||||
data?: {
|
data?: {
|
||||||
isOverlayCiphersPopulated?: boolean;
|
|
||||||
direction?: "previous" | "next" | "current";
|
direction?: "previous" | "next" | "current";
|
||||||
forceCloseAutofillInlineMenu?: boolean;
|
forceCloseAutofillInlineMenu?: boolean;
|
||||||
inlineMenuVisibility?: number;
|
inlineMenuVisibility?: number;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
|
|
||||||
import { OverlayCipherData } from "../../../background/abstractions/overlay.background";
|
import { InlineMenuCipherData } from "../../../background/abstractions/overlay.background";
|
||||||
|
|
||||||
type AutofillInlineMenuMenuContainerMessage = {
|
type AutofillInlineMenuMenuContainerMessage = {
|
||||||
command: string;
|
command: string;
|
||||||
@@ -14,7 +14,7 @@ export type InitInlineMenuElementMessage = AutofillInlineMenuMenuContainerMessag
|
|||||||
styleSheetUrl?: string;
|
styleSheetUrl?: string;
|
||||||
theme?: string;
|
theme?: string;
|
||||||
translations?: Record<string, string>;
|
translations?: Record<string, string>;
|
||||||
ciphers?: OverlayCipherData[];
|
ciphers?: InlineMenuCipherData[];
|
||||||
portName?: string;
|
portName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
|
|
||||||
import { OverlayCipherData } from "../../../background/abstractions/overlay.background";
|
import { InlineMenuCipherData } from "../../../background/abstractions/overlay.background";
|
||||||
|
|
||||||
type AutofillInlineMenuListMessage = { command: string };
|
type AutofillInlineMenuListMessage = { command: string };
|
||||||
|
|
||||||
export type UpdateAutofillInlineMenuListCiphersMessage = AutofillInlineMenuListMessage & {
|
export type UpdateAutofillInlineMenuListCiphersMessage = AutofillInlineMenuListMessage & {
|
||||||
ciphers: OverlayCipherData[];
|
ciphers: InlineMenuCipherData[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type InitAutofillInlineMenuListMessage = AutofillInlineMenuListMessage & {
|
export type InitAutofillInlineMenuListMessage = AutofillInlineMenuListMessage & {
|
||||||
@@ -13,7 +13,7 @@ export type InitAutofillInlineMenuListMessage = AutofillInlineMenuListMessage &
|
|||||||
styleSheetUrl: string;
|
styleSheetUrl: string;
|
||||||
theme: string;
|
theme: string;
|
||||||
translations: Record<string, string>;
|
translations: Record<string, string>;
|
||||||
ciphers?: OverlayCipherData[];
|
ciphers?: InlineMenuCipherData[];
|
||||||
portKey: string;
|
portKey: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ export type AutofillInlineMenuPageElementWindowMessageHandlers =
|
|||||||
export type AutofillInlineMenuPageElementWindowMessage = {
|
export type AutofillInlineMenuPageElementWindowMessage = {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
command: string;
|
command: string;
|
||||||
overlayCipherId?: string;
|
inlineMenuCipherId?: string;
|
||||||
height?: number;
|
height?: number;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ describe("AutofillInlineMenuList", () => {
|
|||||||
fillCipherButton.dispatchEvent(new Event("click"));
|
fillCipherButton.dispatchEvent(new Event("click"));
|
||||||
|
|
||||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||||
{ command: "fillSelectedAutofillInlineMenuListItem", overlayCipherId: "1", portKey },
|
{ command: "fillSelectedAutofillInlineMenuListItem", inlineMenuCipherId: "1", portKey },
|
||||||
"*",
|
"*",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -236,7 +236,7 @@ describe("AutofillInlineMenuList", () => {
|
|||||||
viewCipherButton.dispatchEvent(new Event("click"));
|
viewCipherButton.dispatchEvent(new Event("click"));
|
||||||
|
|
||||||
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
expect(globalThis.parent.postMessage).toHaveBeenCalledWith(
|
||||||
{ command: "viewSelectedCipher", overlayCipherId: "1", portKey },
|
{ command: "viewSelectedCipher", inlineMenuCipherId: "1", portKey },
|
||||||
"*",
|
"*",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import "lit/polyfill-support.js";
|
|||||||
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
||||||
import { EVENTS } from "@bitwarden/common/autofill/constants";
|
import { EVENTS } from "@bitwarden/common/autofill/constants";
|
||||||
|
|
||||||
import { OverlayCipherData } from "../../../../background/abstractions/overlay.background";
|
import { InlineMenuCipherData } from "../../../../background/abstractions/overlay.background";
|
||||||
import { buildSvgDomElement } from "../../../../utils";
|
import { buildSvgDomElement } from "../../../../utils";
|
||||||
import { globeIcon, lockIcon, plusIcon, viewCipherIcon } from "../../../../utils/svg-icons";
|
import { globeIcon, lockIcon, plusIcon, viewCipherIcon } from "../../../../utils/svg-icons";
|
||||||
import {
|
import {
|
||||||
@@ -16,7 +16,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
private inlineMenuListContainer: HTMLDivElement;
|
private inlineMenuListContainer: HTMLDivElement;
|
||||||
private resizeObserver: ResizeObserver;
|
private resizeObserver: ResizeObserver;
|
||||||
private eventHandlersMemo: { [key: string]: EventListener } = {};
|
private eventHandlersMemo: { [key: string]: EventListener } = {};
|
||||||
private ciphers: OverlayCipherData[] = [];
|
private ciphers: InlineMenuCipherData[] = [];
|
||||||
private ciphersList: HTMLUListElement;
|
private ciphersList: HTMLUListElement;
|
||||||
private cipherListScrollIsDebounced = false;
|
private cipherListScrollIsDebounced = false;
|
||||||
private cipherListScrollDebounceTimeout: number | NodeJS.Timeout;
|
private cipherListScrollDebounceTimeout: number | NodeJS.Timeout;
|
||||||
@@ -122,7 +122,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param ciphers - The ciphers to display in the inline menu list.
|
* @param ciphers - The ciphers to display in the inline menu list.
|
||||||
*/
|
*/
|
||||||
private updateListItems(ciphers: OverlayCipherData[]) {
|
private updateListItems(ciphers: InlineMenuCipherData[]) {
|
||||||
this.ciphers = ciphers;
|
this.ciphers = ciphers;
|
||||||
this.currentCipherIndex = 0;
|
this.currentCipherIndex = 0;
|
||||||
if (this.inlineMenuListContainer) {
|
if (this.inlineMenuListContainer) {
|
||||||
@@ -231,7 +231,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to build the list item for.
|
* @param cipher - The cipher to build the list item for.
|
||||||
*/
|
*/
|
||||||
private buildInlineMenuListActionsItem(cipher: OverlayCipherData) {
|
private buildInlineMenuListActionsItem(cipher: InlineMenuCipherData) {
|
||||||
const fillCipherElement = this.buildFillCipherElement(cipher);
|
const fillCipherElement = this.buildFillCipherElement(cipher);
|
||||||
const viewCipherElement = this.buildViewCipherElement(cipher);
|
const viewCipherElement = this.buildViewCipherElement(cipher);
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to build the fill cipher button for.
|
* @param cipher - The cipher to build the fill cipher button for.
|
||||||
*/
|
*/
|
||||||
private buildFillCipherElement(cipher: OverlayCipherData) {
|
private buildFillCipherElement(cipher: InlineMenuCipherData) {
|
||||||
const cipherIcon = this.buildCipherIconElement(cipher);
|
const cipherIcon = this.buildCipherIconElement(cipher);
|
||||||
const cipherDetailsElement = this.buildCipherDetailsElement(cipher);
|
const cipherDetailsElement = this.buildCipherDetailsElement(cipher);
|
||||||
|
|
||||||
@@ -281,12 +281,12 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to fill.
|
* @param cipher - The cipher to fill.
|
||||||
*/
|
*/
|
||||||
private handleFillCipherClickEvent = (cipher: OverlayCipherData) => {
|
private handleFillCipherClickEvent = (cipher: InlineMenuCipherData) => {
|
||||||
return this.useEventHandlersMemo(
|
return this.useEventHandlersMemo(
|
||||||
() =>
|
() =>
|
||||||
this.postMessageToParent({
|
this.postMessageToParent({
|
||||||
command: "fillSelectedAutofillInlineMenuListItem",
|
command: "fillSelectedAutofillInlineMenuListItem",
|
||||||
overlayCipherId: cipher.id,
|
inlineMenuCipherId: cipher.id,
|
||||||
}),
|
}),
|
||||||
`${cipher.id}-fill-cipher-button-click-handler`,
|
`${cipher.id}-fill-cipher-button-click-handler`,
|
||||||
);
|
);
|
||||||
@@ -326,7 +326,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to view.
|
* @param cipher - The cipher to view.
|
||||||
*/
|
*/
|
||||||
private buildViewCipherElement(cipher: OverlayCipherData) {
|
private buildViewCipherElement(cipher: InlineMenuCipherData) {
|
||||||
const viewCipherElement = globalThis.document.createElement("button");
|
const viewCipherElement = globalThis.document.createElement("button");
|
||||||
viewCipherElement.tabIndex = -1;
|
viewCipherElement.tabIndex = -1;
|
||||||
viewCipherElement.classList.add("view-cipher-button");
|
viewCipherElement.classList.add("view-cipher-button");
|
||||||
@@ -347,9 +347,10 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to view.
|
* @param cipher - The cipher to view.
|
||||||
*/
|
*/
|
||||||
private handleViewCipherClickEvent = (cipher: OverlayCipherData) => {
|
private handleViewCipherClickEvent = (cipher: InlineMenuCipherData) => {
|
||||||
return this.useEventHandlersMemo(
|
return this.useEventHandlersMemo(
|
||||||
() => this.postMessageToParent({ command: "viewSelectedCipher", overlayCipherId: cipher.id }),
|
() =>
|
||||||
|
this.postMessageToParent({ command: "viewSelectedCipher", inlineMenuCipherId: cipher.id }),
|
||||||
`${cipher.id}-view-cipher-button-click-handler`,
|
`${cipher.id}-view-cipher-button-click-handler`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -394,7 +395,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to build the icon for.
|
* @param cipher - The cipher to build the icon for.
|
||||||
*/
|
*/
|
||||||
private buildCipherIconElement(cipher: OverlayCipherData) {
|
private buildCipherIconElement(cipher: InlineMenuCipherData) {
|
||||||
const cipherIcon = globalThis.document.createElement("span");
|
const cipherIcon = globalThis.document.createElement("span");
|
||||||
cipherIcon.classList.add("cipher-icon");
|
cipherIcon.classList.add("cipher-icon");
|
||||||
cipherIcon.setAttribute("aria-hidden", "true");
|
cipherIcon.setAttribute("aria-hidden", "true");
|
||||||
@@ -432,7 +433,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to build the details for.
|
* @param cipher - The cipher to build the details for.
|
||||||
*/
|
*/
|
||||||
private buildCipherDetailsElement(cipher: OverlayCipherData) {
|
private buildCipherDetailsElement(cipher: InlineMenuCipherData) {
|
||||||
const cipherNameElement = this.buildCipherNameElement(cipher);
|
const cipherNameElement = this.buildCipherNameElement(cipher);
|
||||||
const cipherUserLoginElement = this.buildCipherUserLoginElement(cipher);
|
const cipherUserLoginElement = this.buildCipherUserLoginElement(cipher);
|
||||||
|
|
||||||
@@ -453,7 +454,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to build the name element for.
|
* @param cipher - The cipher to build the name element for.
|
||||||
*/
|
*/
|
||||||
private buildCipherNameElement(cipher: OverlayCipherData): HTMLSpanElement | null {
|
private buildCipherNameElement(cipher: InlineMenuCipherData): HTMLSpanElement | null {
|
||||||
if (!cipher.name) {
|
if (!cipher.name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -471,7 +472,7 @@ export class AutofillInlineMenuList extends AutofillInlineMenuPageElement {
|
|||||||
*
|
*
|
||||||
* @param cipher - The cipher to build the username login element for.
|
* @param cipher - The cipher to build the username login element for.
|
||||||
*/
|
*/
|
||||||
private buildCipherUserLoginElement(cipher: OverlayCipherData): HTMLSpanElement | null {
|
private buildCipherUserLoginElement(cipher: InlineMenuCipherData): HTMLSpanElement | null {
|
||||||
if (!cipher.login?.username) {
|
if (!cipher.login?.username) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { CipherType } from "@bitwarden/common/vault/enums";
|
|||||||
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
|
import { CipherRepromptType } from "@bitwarden/common/vault/enums/cipher-reprompt-type";
|
||||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||||
|
|
||||||
import { OverlayCipherData } from "../background/abstractions/overlay.background";
|
import { InlineMenuCipherData } from "../background/abstractions/overlay.background";
|
||||||
import AutofillField from "../models/autofill-field";
|
import AutofillField from "../models/autofill-field";
|
||||||
import AutofillForm from "../models/autofill-form";
|
import AutofillForm from "../models/autofill-form";
|
||||||
import AutofillPageDetails from "../models/autofill-page-details";
|
import AutofillPageDetails from "../models/autofill-page-details";
|
||||||
@@ -177,7 +177,10 @@ function createInitAutofillInlineMenuButtonMessageMock(
|
|||||||
...customFields,
|
...customFields,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function createAutofillOverlayCipherDataMock(index: number, customFields = {}): OverlayCipherData {
|
function createAutofillOverlayCipherDataMock(
|
||||||
|
index: number,
|
||||||
|
customFields = {},
|
||||||
|
): InlineMenuCipherData {
|
||||||
return {
|
return {
|
||||||
id: String(index),
|
id: String(index),
|
||||||
name: `website login ${index}`,
|
name: `website login ${index}`,
|
||||||
|
|||||||
@@ -1260,7 +1260,7 @@ export default class MainBackground {
|
|||||||
|
|
||||||
await this.refreshBadge();
|
await this.refreshBadge();
|
||||||
await this.refreshMenu();
|
await this.refreshMenu();
|
||||||
await this.overlayBackground?.updateOverlayCiphers(); // null in popup only contexts
|
await this.overlayBackground?.updateInlineMenuCiphers(); // null in popup only contexts
|
||||||
this.messagingService.send("goHome");
|
this.messagingService.send("goHome");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1283,7 +1283,7 @@ export default class MainBackground {
|
|||||||
this.messagingService.send("unlocked", { userId: userId });
|
this.messagingService.send("unlocked", { userId: userId });
|
||||||
await this.refreshBadge();
|
await this.refreshBadge();
|
||||||
await this.refreshMenu();
|
await this.refreshMenu();
|
||||||
await this.overlayBackground?.updateOverlayCiphers(); // null in popup only contexts
|
await this.overlayBackground?.updateInlineMenuCiphers(); // null in popup only contexts
|
||||||
await this.syncService.fullSync(false);
|
await this.syncService.fullSync(false);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
Reference in New Issue
Block a user