From 688647b2c69243b14ec14a37b51639da400a6bf2 Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Wed, 1 Oct 2025 13:21:11 -0700 Subject: [PATCH] [PM-25216] - handle extension already installed on new user creation (#16650) * handle extension already installed on new user creation * fix tests * remove comment --- .../setup-extension.component.html | 25 ++++++++++++++++--- .../setup-extension.component.spec.ts | 7 +----- .../setup-extension.component.ts | 6 +++-- .../setup-extension-redirect.guard.spec.ts | 7 ------ .../guards/setup-extension-redirect.guard.ts | 14 ----------- apps/web/src/locales/en/messages.json | 6 +++++ 6 files changed, 32 insertions(+), 33 deletions(-) diff --git a/apps/web/src/app/vault/components/setup-extension/setup-extension.component.html b/apps/web/src/app/vault/components/setup-extension/setup-extension.component.html index 41ee1b4707e..09bd38c8517 100644 --- a/apps/web/src/app/vault/components/setup-extension/setup-extension.component.html +++ b/apps/web/src/app/vault/components/setup-extension/setup-extension.component.html @@ -29,15 +29,32 @@ -
+
-

{{ "bitwardenExtensionInstalled" | i18n }}

+

+ {{ + (state === SetupExtensionState.Success + ? "bitwardenExtensionInstalled" + : "openTheBitwardenExtension" + ) | i18n + }} +

-

{{ "openExtensionToAutofill" | i18n }}

+

+ {{ + (state === SetupExtensionState.Success + ? "openExtensionToAutofill" + : "bitwardenExtensionInstalledOpenExtension" + ) | i18n + }} +

diff --git a/apps/web/src/app/vault/components/setup-extension/setup-extension.component.spec.ts b/apps/web/src/app/vault/components/setup-extension/setup-extension.component.spec.ts index 3be8251b1d7..f755c83832f 100644 --- a/apps/web/src/app/vault/components/setup-extension/setup-extension.component.spec.ts +++ b/apps/web/src/app/vault/components/setup-extension/setup-extension.component.spec.ts @@ -93,14 +93,9 @@ describe("SetupExtensionComponent", () => { }); describe("extensionInstalled$", () => { - it("redirects the user to the vault when the first emitted value is true", () => { - extensionInstalled$.next(true); - - expect(navigate).toHaveBeenCalledWith(["/vault"]); - }); - describe("success state", () => { beforeEach(() => { + update.mockClear(); // avoid initial redirect extensionInstalled$.next(false); diff --git a/apps/web/src/app/vault/components/setup-extension/setup-extension.component.ts b/apps/web/src/app/vault/components/setup-extension/setup-extension.component.ts index 558f0eb06c9..a04c529004c 100644 --- a/apps/web/src/app/vault/components/setup-extension/setup-extension.component.ts +++ b/apps/web/src/app/vault/components/setup-extension/setup-extension.component.ts @@ -36,6 +36,7 @@ export const SetupExtensionState = { Loading: "loading", NeedsExtension: "needs-extension", Success: "success", + AlreadyInstalled: "already-installed", ManualOpen: "manual-open", } as const; @@ -99,9 +100,10 @@ export class SetupExtensionComponent implements OnInit, OnDestroy { this.webBrowserExtensionInteractionService.extensionInstalled$ .pipe(takeUntilDestroyed(this.destroyRef), startWith(null), pairwise()) .subscribe(([previousState, currentState]) => { - // Initial state transitioned to extension installed, redirect the user + // User landed on the page and the extension is already installed, show already installed state if (previousState === null && currentState) { - void this.router.navigate(["/vault"]); + void this.dismissExtensionPage(); + this.state = SetupExtensionState.AlreadyInstalled; } // Extension was not installed and now it is, show success state diff --git a/apps/web/src/app/vault/guards/setup-extension-redirect.guard.spec.ts b/apps/web/src/app/vault/guards/setup-extension-redirect.guard.spec.ts index 14f6763dbf9..7520451df34 100644 --- a/apps/web/src/app/vault/guards/setup-extension-redirect.guard.spec.ts +++ b/apps/web/src/app/vault/guards/setup-extension-redirect.guard.spec.ts @@ -82,13 +82,6 @@ describe("setupExtensionRedirectGuard", () => { expect(await setupExtensionGuard()).toBe(true); }); - it("returns `true` when the user has the extension installed", async () => { - state$.next(false); - extensionInstalled$.next(true); - - expect(await setupExtensionGuard()).toBe(true); - }); - it('redirects the user to "/setup-extension" when all criteria do not pass', async () => { state$.next(false); extensionInstalled$.next(false); diff --git a/apps/web/src/app/vault/guards/setup-extension-redirect.guard.ts b/apps/web/src/app/vault/guards/setup-extension-redirect.guard.ts index 5355ebf7232..0c9e31ae77f 100644 --- a/apps/web/src/app/vault/guards/setup-extension-redirect.guard.ts +++ b/apps/web/src/app/vault/guards/setup-extension-redirect.guard.ts @@ -11,8 +11,6 @@ import { UserKeyDefinition, } from "@bitwarden/common/platform/state"; -import { WebBrowserInteractionService } from "../services/web-browser-interaction.service"; - export const SETUP_EXTENSION_DISMISSED = new UserKeyDefinition( SETUP_EXTENSION_DISMISSED_DISK, "setupExtensionDismissed", @@ -27,7 +25,6 @@ export const setupExtensionRedirectGuard: CanActivateFn = async () => { const accountService = inject(AccountService); const vaultProfileService = inject(VaultProfileService); const stateProvider = inject(StateProvider); - const webBrowserInteractionService = inject(WebBrowserInteractionService); const isMobile = Utils.isMobileBrowser; @@ -43,10 +40,6 @@ export const setupExtensionRedirectGuard: CanActivateFn = async () => { return router.createUrlTree(["/login"]); } - const hasExtensionInstalledPromise = firstValueFrom( - webBrowserInteractionService.extensionInstalled$, - ); - const dismissedExtensionPage = await firstValueFrom( stateProvider .getUser(currentAcct.id, SETUP_EXTENSION_DISMISSED) @@ -66,13 +59,6 @@ export const setupExtensionRedirectGuard: CanActivateFn = async () => { return true; } - // Checking for the extension is a more expensive operation, do it last to avoid unnecessary delays. - const hasExtensionInstalled = await hasExtensionInstalledPromise; - - if (hasExtensionInstalled) { - return true; - } - return router.createUrlTree(["/setup-extension"]); }; diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index e107b34d038..50b361f3d5a 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -11199,6 +11199,12 @@ "bitwardenExtensionInstalled": { "message": "Bitwarden extension installed!" }, + "openTheBitwardenExtension": { + "message": "Open the Bitwarden extension" + }, + "bitwardenExtensionInstalledOpenExtension": { + "message": "The Bitwarden extension is installed! Open the extension to log in and start autofilling." + }, "openExtensionToAutofill": { "message": "Open the extension to log in and start autofilling." },