diff --git a/apps/browser/src/autofill/content/content-message-handler.ts b/apps/browser/src/autofill/content/content-message-handler.ts index 55e0c071a55..60f093f8c10 100644 --- a/apps/browser/src/autofill/content/content-message-handler.ts +++ b/apps/browser/src/autofill/content/content-message-handler.ts @@ -17,7 +17,7 @@ const windowMessageHandlers: ContentMessageWindowEventHandlers = { [VaultMessages.checkBwInstalled]: () => handleExtensionInstallCheck(), duoResult: ({ data, referrer }: { data: any; referrer: string }) => handleDuoResultMessage(data, referrer), - [VaultMessages.OpenPopup]: () => handleOpenPopupMessage(), + [VaultMessages.OpenAtRiskPasswords]: () => handleOpenAtRiskPasswordsMessage(), }; /** @@ -73,8 +73,8 @@ function handleWebAuthnResultMessage(data: ContentMessageWindowData, referrer: s sendExtensionRuntimeMessage({ command, data: data.data, remember, referrer }); } -function handleOpenPopupMessage() { - sendExtensionRuntimeMessage({ command: VaultMessages.OpenPopup }); +function handleOpenAtRiskPasswordsMessage() { + sendExtensionRuntimeMessage({ command: VaultMessages.OpenAtRiskPasswords }); } /** diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index dba1235d3a2..ffce7827358 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -1620,6 +1620,26 @@ export default class MainBackground { } } + /** Opens the `/at-risk-passwords` page within the popup */ + async openAtRisksPasswordsPage() { + const browserAction = BrowserApi.getBrowserAction(); + + try { + // Set route of the popup before attempting to open it. + // If the vault is locked, this won't have an effect as the auth guards will + // redirect the user to the login page. + await browserAction.setPopup({ popup: "popup/index.html#/at-risk-passwords" }); + + await this.openPopup(); + } finally { + // Reset the popup route to the default route so any subsequent + // popup openings will not open to the at-risk-passwords page. + await browserAction.setPopup({ + popup: "popup/index.html#/", + }); + } + } + async reseedStorage() { if ( !this.platformUtilsService.isChrome() && diff --git a/apps/browser/src/background/runtime.background.ts b/apps/browser/src/background/runtime.background.ts index c1719abbb3a..ec8ff7376e0 100644 --- a/apps/browser/src/background/runtime.background.ts +++ b/apps/browser/src/background/runtime.background.ts @@ -17,6 +17,7 @@ import { devFlagEnabled } from "@bitwarden/common/platform/misc/flags"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { NotificationsService } from "@bitwarden/common/platform/notifications"; import { CipherType } from "@bitwarden/common/vault/enums"; +import { VaultMessages } from "@bitwarden/common/vault/enums/vault-messages.enum"; import { BiometricsCommands } from "@bitwarden/key-management"; import { @@ -289,6 +290,10 @@ export default class RuntimeBackground { case "openPopup": await this.openPopup(); break; + case VaultMessages.OpenAtRiskPasswords: + await this.main.openAtRisksPasswordsPage(); + this.announcePopupOpen(); + break; case "bgUpdateContextMenu": case "editedCipher": case "addedCipher": @@ -418,24 +423,6 @@ export default class RuntimeBackground { private async openPopup() { await this.main.openPopup(); - - const announcePopupOpen = async () => { - const isOpen = await this.platformUtilsService.isViewOpen(); - const tabs = await this.getBwTabs(); - - if (isOpen && tabs.length > 0) { - // Send message to all vault tabs that the extension has opened - for (const tab of tabs) { - await BrowserApi.executeScriptInTab(tab.id, { - file: "content/send-popup-open-message.js", - runAt: "document_end", - }); - } - } - }; - - // Give the popup a buffer to open - setTimeout(announcePopupOpen, 100); } async sendBwInstalledMessageToVault() { @@ -456,4 +443,25 @@ export default class RuntimeBackground { this.logService.error(`Error sending on installed message to vault: ${e}`); } } + + /** Sends a message to each tab that the popup was opened */ + private announcePopupOpen() { + const announceToAllTabs = async () => { + const isOpen = await this.platformUtilsService.isViewOpen(); + const tabs = await this.getBwTabs(); + + if (isOpen && tabs.length > 0) { + // Send message to all vault tabs that the extension has opened + for (const tab of tabs) { + await BrowserApi.executeScriptInTab(tab.id, { + file: "content/send-popup-open-message.js", + runAt: "document_end", + }); + } + } + }; + + // Give the popup a buffer to complete opening + setTimeout(announceToAllTabs, 100); + } } diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html index cd93401c861..87629ce5700 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.html @@ -1,5 +1,10 @@ - + diff --git a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts index 6711673751c..37c445f6c30 100644 --- a/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts +++ b/apps/browser/src/vault/popup/components/at-risk-passwords/at-risk-passwords.component.ts @@ -222,4 +222,13 @@ export class AtRiskPasswordsComponent implements OnInit { this.launchingCipher.set(null); } }; + + /** + * This page can be the first page the user sees when the extension launches, + * which can conflict with the `PopupRouterCacheService`. This replaces the + * built-in back button behavior so the user always navigates to the vault. + */ + protected async navigateToVault() { + await this.router.navigate(["/tabs/vault"]); + } } diff --git a/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts b/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts index 3114547df1d..f6f4ec4fdb4 100644 --- a/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts +++ b/apps/web/src/app/vault/services/browser-extension-prompt.service.spec.ts @@ -68,7 +68,9 @@ describe("BrowserExtensionPromptService", () => { ); expect(window.postMessage).toHaveBeenCalledTimes(2); - expect(window.postMessage).toHaveBeenCalledWith({ command: VaultMessages.OpenPopup }); + expect(window.postMessage).toHaveBeenCalledWith({ + command: VaultMessages.OpenAtRiskPasswords, + }); }); }); diff --git a/apps/web/src/app/vault/services/browser-extension-prompt.service.ts b/apps/web/src/app/vault/services/browser-extension-prompt.service.ts index d59175d4e73..5617d4aef75 100644 --- a/apps/web/src/app/vault/services/browser-extension-prompt.service.ts +++ b/apps/web/src/app/vault/services/browser-extension-prompt.service.ts @@ -55,7 +55,7 @@ export class BrowserExtensionPromptService { /** Post a message to the extension to open */ openExtension(setManualErrorTimeout = false) { - window.postMessage({ command: VaultMessages.OpenPopup }); + window.postMessage({ command: VaultMessages.OpenAtRiskPasswords }); // Optionally, configure timeout to show the manual open error state if // the extension does not open within one second. diff --git a/libs/common/src/vault/enums/vault-messages.enum.ts b/libs/common/src/vault/enums/vault-messages.enum.ts index 4cc038be849..73272564432 100644 --- a/libs/common/src/vault/enums/vault-messages.enum.ts +++ b/libs/common/src/vault/enums/vault-messages.enum.ts @@ -1,7 +1,7 @@ const VaultMessages = { HasBwInstalled: "hasBwInstalled", checkBwInstalled: "checkIfBWExtensionInstalled", - OpenPopup: "openPopup", + OpenAtRiskPasswords: "openAtRiskPasswords", PopupOpened: "popupOpened", } as const;