diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index f59b6648486..fecc47af981 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -726,17 +726,6 @@ export default class MainBackground { const pinStateService = new PinStateService(this.stateProvider); - this.pinService = new PinService( - this.accountService, - this.encryptService, - this.kdfConfigService, - this.keyGenerationService, - this.logService, - this.keyService, - this.sdkService, - pinStateService, - ); - this.appIdService = new AppIdService(this.storageService, this.logService); this.userDecryptionOptionsService = new UserDecryptionOptionsService(this.stateProvider); @@ -756,16 +745,6 @@ export default class MainBackground { VaultTimeoutStringType.OnRestart, // default vault timeout ); - this.biometricsService = new BackgroundBrowserBiometricsService( - runtimeNativeMessagingBackground, - this.logService, - this.keyService, - this.biometricStateService, - this.messagingService, - this.vaultTimeoutSettingsService, - this.pinService, - ); - this.apiService = new ApiService( this.tokenService, this.platformUtilsService, @@ -849,6 +828,27 @@ export default class MainBackground { this.configService, ); + this.pinService = new PinService( + this.accountService, + this.encryptService, + this.kdfConfigService, + this.keyGenerationService, + this.logService, + this.keyService, + this.sdkService, + pinStateService, + ); + + this.biometricsService = new BackgroundBrowserBiometricsService( + runtimeNativeMessagingBackground, + this.logService, + this.keyService, + this.biometricStateService, + this.messagingService, + this.vaultTimeoutSettingsService, + this.pinService, + ); + this.passwordStrengthService = new PasswordStrengthService(); this.passwordGenerationService = legacyPasswordGenerationServiceFactory( diff --git a/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts b/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts index e33ab0d4c3b..4dcf05a4220 100644 --- a/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts +++ b/apps/desktop/src/autofill/main/main-desktop-autotype.service.ts @@ -5,6 +5,7 @@ import { LogService } from "@bitwarden/logging"; import { WindowMain } from "../../main/window.main"; import { stringIsNotUndefinedNullAndEmpty } from "../../utils"; +import { AutotypeMatchError } from "../models/autotype-errors"; import { AutotypeVaultData } from "../models/autotype-vault-data"; import { AutotypeKeyboardShortcut } from "../models/main-autotype-keyboard-shortcut"; @@ -56,6 +57,14 @@ export class MainDesktopAutotypeService { this.doAutotype(vaultData, this.autotypeKeyboardShortcut.getArrayFormat()); } }); + + ipcMain.on("autofill.completeAutotypeError", (_event, matchError: AutotypeMatchError) => { + this.logService.debug( + "autofill.completeAutotypeError", + "No match for window: " + matchError.windowTitle, + ); + this.logService.error("autofill.completeAutotypeError", matchError.errorMessage); + }); } disableAutotype() { diff --git a/apps/desktop/src/autofill/models/autotype-errors.ts b/apps/desktop/src/autofill/models/autotype-errors.ts new file mode 100644 index 00000000000..9e59b102302 --- /dev/null +++ b/apps/desktop/src/autofill/models/autotype-errors.ts @@ -0,0 +1,8 @@ +/** + * This error is surfaced when there is no matching + * vault item found. + */ +export interface AutotypeMatchError { + windowTitle: string; + errorMessage: string; +} diff --git a/apps/desktop/src/autofill/preload.ts b/apps/desktop/src/autofill/preload.ts index 22b5cdf9463..e839ac223b7 100644 --- a/apps/desktop/src/autofill/preload.ts +++ b/apps/desktop/src/autofill/preload.ts @@ -5,6 +5,7 @@ import type { autofill } from "@bitwarden/desktop-napi"; import { Command } from "../platform/main/autofill/command"; import { RunCommandParams, RunCommandResult } from "../platform/main/autofill/native-autofill.main"; +import { AutotypeMatchError } from "./models/autotype-errors"; import { AutotypeVaultData } from "./models/autotype-vault-data"; export default { @@ -141,7 +142,7 @@ export default { ipcRenderer.on( "autofill.listenAutotypeRequest", ( - event, + _event, data: { windowTitle: string; }, @@ -150,10 +151,11 @@ export default { fn(windowTitle, (error, vaultData) => { if (error) { - ipcRenderer.send("autofill.completeError", { + const matchError: AutotypeMatchError = { windowTitle, - error: error.message, - }); + errorMessage: error.message, + }; + ipcRenderer.send("autofill.completeAutotypeError", matchError); return; } if (vaultData !== null) { diff --git a/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.spec.ts b/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.spec.ts index a19606f6d9c..b31759a1fe1 100644 --- a/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.spec.ts +++ b/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.spec.ts @@ -166,8 +166,8 @@ describe("BrowserExtensionPromptComponent", () => { it("shows manual open error message", () => { const manualText = fixture.debugElement.query(By.css("p")).nativeElement; - expect(manualText.textContent.trim()).toContain("openExtensionManuallyPart1"); - expect(manualText.textContent.trim()).toContain("openExtensionManuallyPart2"); + expect(manualText.textContent.trim()).toContain("openExtensionFromToolbarPart1"); + expect(manualText.textContent.trim()).toContain("openExtensionFromToolbarPart2"); }); }); }); diff --git a/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.ts b/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.ts index cb927d0848c..505a0df5032 100644 --- a/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.ts +++ b/apps/web/src/app/vault/components/browser-extension-prompt/browser-extension-prompt.component.ts @@ -1,5 +1,5 @@ import { CommonModule, DOCUMENT } from "@angular/common"; -import { Component, Inject, OnDestroy, OnInit } from "@angular/core"; +import { Component, Inject, OnDestroy, OnInit, ChangeDetectionStrategy } from "@angular/core"; import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ActivatedRoute } from "@angular/router"; import { map, Observable, of, tap } from "rxjs"; @@ -14,12 +14,11 @@ import { } from "../../services/browser-extension-prompt.service"; import { ManuallyOpenExtensionComponent } from "../manually-open-extension/manually-open-extension.component"; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "vault-browser-extension-prompt", templateUrl: "./browser-extension-prompt.component.html", imports: [CommonModule, I18nPipe, ButtonComponent, IconModule, ManuallyOpenExtensionComponent], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class BrowserExtensionPromptComponent implements OnInit, OnDestroy { protected VaultMessages = VaultMessages; diff --git a/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.html b/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.html index 22c36e51177..d15cdaa712b 100644 --- a/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.html +++ b/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.html @@ -1,8 +1,8 @@ -

- {{ "openExtensionManuallyPart1" | i18n }} +

+ {{ "openExtensionFromToolbarPart1" | i18n }} - {{ "openExtensionManuallyPart2" | i18n }} + {{ "openExtensionFromToolbarPart2" | i18n }}

diff --git a/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.ts b/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.ts index 6105aeacf9c..435e847f6e9 100644 --- a/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.ts +++ b/apps/web/src/app/vault/components/manually-open-extension/manually-open-extension.component.ts @@ -1,12 +1,11 @@ -import { Component } from "@angular/core"; +import { Component, ChangeDetectionStrategy } from "@angular/core"; import { BitwardenIcon } from "@bitwarden/assets/svg"; import { IconModule } from "@bitwarden/components"; import { I18nPipe } from "@bitwarden/ui-common"; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, selector: "vault-manually-open-extension", templateUrl: "./manually-open-extension.component.html", imports: [I18nPipe, IconModule], 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 038c258d4b6..1976321b4ee 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,10 +29,7 @@ -
+
@@ -40,20 +37,15 @@ {{ (state === SetupExtensionState.Success ? "bitwardenExtensionInstalled" - : "openTheBitwardenExtension" + : "bitwardenExtensionIsInstalled" ) | i18n }}

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

-

+ +

{{ "gettingStartedWithBitwardenPart1" | i18n }} {{ "gettingStartedWithBitwardenPart2" | i18n }} @@ -73,7 +73,3 @@

- -
- -
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 fbf61f9a277..ef67e072116 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 @@ -4,7 +4,6 @@ import { Router, RouterModule } from "@angular/router"; import { BehaviorSubject } from "rxjs"; import { SYSTEM_THEME_OBSERVABLE } from "@bitwarden/angular/services/injection-tokens"; -import { BrowserExtensionIcon } from "@bitwarden/assets/svg"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { DeviceType } from "@bitwarden/common/enums"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -12,7 +11,6 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { Utils } from "@bitwarden/common/platform/misc/utils"; import { StateProvider } from "@bitwarden/common/platform/state"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; -import { AnonLayoutWrapperDataService } from "@bitwarden/components"; import { WebBrowserInteractionService } from "../../services/web-browser-interaction.service"; @@ -25,14 +23,12 @@ describe("SetupExtensionComponent", () => { const navigate = jest.fn().mockResolvedValue(true); const openExtension = jest.fn().mockResolvedValue(true); const update = jest.fn().mockResolvedValue(true); - const setAnonLayoutWrapperData = jest.fn(); const extensionInstalled$ = new BehaviorSubject(null); beforeEach(async () => { navigate.mockClear(); openExtension.mockClear(); update.mockClear(); - setAnonLayoutWrapperData.mockClear(); window.matchMedia = jest.fn().mockReturnValue(false); await TestBed.configureTestingModule({ @@ -43,7 +39,6 @@ describe("SetupExtensionComponent", () => { { provide: PlatformUtilsService, useValue: { getDevice: () => DeviceType.UnknownBrowser } }, { provide: SYSTEM_THEME_OBSERVABLE, useValue: new BehaviorSubject("system") }, { provide: ThemeStateService, useValue: { selectedTheme$: new BehaviorSubject("system") } }, - { provide: AnonLayoutWrapperDataService, useValue: { setAnonLayoutWrapperData } }, { provide: AccountService, useValue: { activeAccount$: new BehaviorSubject({ account: { id: "account-id" } }) }, @@ -133,14 +128,6 @@ describe("SetupExtensionComponent", () => { tick(); expect(component["state"]).toBe(SetupExtensionState.ManualOpen); - expect(setAnonLayoutWrapperData).toHaveBeenCalledWith({ - pageTitle: { - key: "somethingWentWrong", - }, - pageIcon: BrowserExtensionIcon, - hideCardWrapper: false, - maxWidth: "md", - }); })); }); }); 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 974e73bc91e..809e404f5f1 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 @@ -5,7 +5,7 @@ import { Router, RouterModule } from "@angular/router"; import { firstValueFrom, pairwise, startWith } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; -import { BrowserExtensionIcon, Party } from "@bitwarden/assets/svg"; +import { Party } from "@bitwarden/assets/svg"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -14,7 +14,6 @@ import { StateProvider } from "@bitwarden/common/platform/state"; import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values"; import { getWebStoreUrl } from "@bitwarden/common/vault/utils/get-web-store-url"; import { - AnonLayoutWrapperDataService, ButtonComponent, CenterPositionStrategy, DialogRef, @@ -68,7 +67,6 @@ export class SetupExtensionComponent implements OnInit, OnDestroy { private stateProvider = inject(StateProvider); private accountService = inject(AccountService); private document = inject(DOCUMENT); - private anonLayoutWrapperDataService = inject(AnonLayoutWrapperDataService); protected SetupExtensionState = SetupExtensionState; protected PartyIcon = Party; @@ -144,6 +142,16 @@ export class SetupExtensionComponent implements OnInit, OnDestroy { } } + get showSuccessUI(): boolean { + const successStates = [ + SetupExtensionState.Success, + SetupExtensionState.AlreadyInstalled, + SetupExtensionState.ManualOpen, + ] as string[]; + + return successStates.includes(this.state); + } + /** Opens the add extension later dialog */ addItLater() { this.dialogRef = this.dialogService.open( @@ -161,16 +169,6 @@ export class SetupExtensionComponent implements OnInit, OnDestroy { async openExtension() { await this.webBrowserExtensionInteractionService.openExtension().catch(() => { this.state = SetupExtensionState.ManualOpen; - - // Update the anon layout data to show the proper error design - this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({ - pageTitle: { - key: "somethingWentWrong", - }, - pageIcon: BrowserExtensionIcon, - hideCardWrapper: false, - maxWidth: "md", - }); }); } diff --git a/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts b/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts index 981e5703cb3..3b707f2d78c 100644 --- a/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault-filter/components/organization-options.component.ts @@ -25,7 +25,6 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { getUserId } from "@bitwarden/common/auth/services/account.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; @@ -181,13 +180,7 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy { message: this.i18nService.t("unlinkedSso"), }); - const disableAlternateLoginMethodsFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.PM22110_DisableAlternateLoginMethods, - ); - - if (disableAlternateLoginMethodsFlagEnabled) { - await this.removeEmailFromSsoRequiredCacheIfPresent(); - } + await this.removeEmailFromSsoRequiredCacheIfPresent(); } catch (e) { this.logService.error(e); } @@ -214,13 +207,7 @@ export class OrganizationOptionsComponent implements OnInit, OnDestroy { message: this.i18nService.t("leftOrganization"), }); - const disableAlternateLoginMethodsFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.PM22110_DisableAlternateLoginMethods, - ); - - if (disableAlternateLoginMethodsFlagEnabled) { - await this.removeEmailFromSsoRequiredCacheIfPresent(); - } + await this.removeEmailFromSsoRequiredCacheIfPresent(); } catch (e) { this.logService.error(e); } diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index dccb6d28af5..90468c61d5c 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -11351,14 +11351,6 @@ "openedExtensionViewAtRiskPasswords": { "message": "Successfully opened the Bitwarden browser extension. You can now review your at-risk passwords." }, - "openExtensionManuallyPart1": { - "message": "We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon", - "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon [Bitwarden Icon] from the toolbar.'" - }, - "openExtensionManuallyPart2": { - "message": "from the toolbar.", - "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'We had trouble opening the Bitwarden browser extension. Open the Bitwarden icon [Bitwarden Icon] from the toolbar.'" - }, "resellerRenewalWarningMsg": { "message": "Your subscription will renew soon. To ensure uninterrupted service, contact $RESELLER$ to confirm your renewal before $RENEWAL_DATE$.", "placeholders": { @@ -11679,11 +11671,8 @@ "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." + "bitwardenExtensionIsInstalled": { + "message": "Bitwarden extension is installed!" }, "openExtensionToAutofill": { "message": "Open the extension to log in and start autofilling." @@ -11699,6 +11688,14 @@ "message": "Learning Center", "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'For tips on getting started with Bitwarden visit the Learning Center and Help Center'" }, + "openExtensionFromToolbarPart1": { + "message": "If the extension didn't open, you may need to open Bitwarden from the icon ", + "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'If the extension didn't open, you may need to open Bitwarden from the icon [Bitwarden Icon] on the toolbar.'" + }, + "openExtensionFromToolbarPart2": { + "message": " on the toolbar.", + "description": "This will be used as part of a larger sentence, broken up to include the Bitwarden icon. The full sentence will read 'If the extension didn't open, you may need to open Bitwarden from the icon [Bitwarden Icon] on the toolbar.'" + }, "gettingStartedWithBitwardenPart3": { "message": "Help Center", "description": "This will be displayed as part of a larger sentence. The whole sentence reads: 'For tips on getting started with Bitwarden visit the Learning Center and Help Center'" diff --git a/libs/auth/src/angular/login/login.component.ts b/libs/auth/src/angular/login/login.component.ts index 51379ed213e..0b011b5641f 100644 --- a/libs/auth/src/angular/login/login.component.ts +++ b/libs/auth/src/angular/login/login.component.ts @@ -205,14 +205,9 @@ export class LoginComponent implements OnInit, OnDestroy { await this.loadRememberedEmail(); } - const disableAlternateLoginMethodsFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.PM22110_DisableAlternateLoginMethods, - ); - if (disableAlternateLoginMethodsFlagEnabled) { - // This SSO required check should come after email has had a chance to be pre-filled (if it - // was found in query params or was the remembered email) - await this.determineIfSsoRequired(); - } + // This SSO required check should come after email has had a chance to be pre-filled (if it + // was found in query params or was the remembered email) + await this.determineIfSsoRequired(); } private async desktopOnInit(): Promise { diff --git a/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.spec.ts b/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.spec.ts index 86f7be8dfc7..975e065e21e 100644 --- a/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.spec.ts +++ b/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.spec.ts @@ -1,7 +1,6 @@ import { MockProxy, mock } from "jest-mock-extended"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { UserId } from "@bitwarden/common/types/guid"; @@ -58,62 +57,35 @@ describe("DefaultLoginSuccessHandlerService", () => { expect(loginEmailService.clearLoginEmail).toHaveBeenCalled(); }); - describe("when PM22110_DisableAlternateLoginMethods flag is disabled", () => { + it("should get SSO email", async () => { + await service.run(userId); + + expect(ssoLoginService.getSsoEmail).toHaveBeenCalled(); + }); + + describe("given SSO email is not found", () => { beforeEach(() => { - configService.getFeatureFlag.mockResolvedValue(false); + ssoLoginService.getSsoEmail.mockResolvedValue(null); }); - it("should not check SSO requirements", async () => { + it("should log error and return early", async () => { await service.run(userId); - expect(ssoLoginService.getSsoEmail).not.toHaveBeenCalled(); + expect(logService.error).toHaveBeenCalledWith("SSO login email not found."); expect(ssoLoginService.updateSsoRequiredCache).not.toHaveBeenCalled(); }); }); - describe("given PM22110_DisableAlternateLoginMethods flag is enabled", () => { + describe("given SSO email is found", () => { beforeEach(() => { - configService.getFeatureFlag.mockResolvedValue(true); + ssoLoginService.getSsoEmail.mockResolvedValue(testEmail); }); - it("should check feature flag", async () => { + it("should call updateSsoRequiredCache() and clearSsoEmail()", async () => { await service.run(userId); - expect(configService.getFeatureFlag).toHaveBeenCalledWith( - FeatureFlag.PM22110_DisableAlternateLoginMethods, - ); - }); - - it("should get SSO email", async () => { - await service.run(userId); - - expect(ssoLoginService.getSsoEmail).toHaveBeenCalled(); - }); - - describe("given SSO email is not found", () => { - beforeEach(() => { - ssoLoginService.getSsoEmail.mockResolvedValue(null); - }); - - it("should log error and return early", async () => { - await service.run(userId); - - expect(logService.error).toHaveBeenCalledWith("SSO login email not found."); - expect(ssoLoginService.updateSsoRequiredCache).not.toHaveBeenCalled(); - }); - }); - - describe("given SSO email is found", () => { - beforeEach(() => { - ssoLoginService.getSsoEmail.mockResolvedValue(testEmail); - }); - - it("should call updateSsoRequiredCache() and clearSsoEmail()", async () => { - await service.run(userId); - - expect(ssoLoginService.updateSsoRequiredCache).toHaveBeenCalledWith(testEmail, userId); - expect(ssoLoginService.clearSsoEmail).toHaveBeenCalled(); - }); + expect(ssoLoginService.updateSsoRequiredCache).toHaveBeenCalledWith(testEmail, userId); + expect(ssoLoginService.clearSsoEmail).toHaveBeenCalled(); }); }); }); diff --git a/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.ts b/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.ts index 78003a4fca0..27d058c311a 100644 --- a/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.ts +++ b/libs/auth/src/common/services/login-success-handler/default-login-success-handler.service.ts @@ -1,5 +1,4 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { SyncService } from "@bitwarden/common/platform/sync"; import { UserId } from "@bitwarden/common/types/guid"; @@ -23,20 +22,14 @@ export class DefaultLoginSuccessHandlerService implements LoginSuccessHandlerSer await this.userAsymmetricKeysRegenerationService.regenerateIfNeeded(userId); await this.loginEmailService.clearLoginEmail(); - const disableAlternateLoginMethodsFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.PM22110_DisableAlternateLoginMethods, - ); + const ssoLoginEmail = await this.ssoLoginService.getSsoEmail(); - if (disableAlternateLoginMethodsFlagEnabled) { - const ssoLoginEmail = await this.ssoLoginService.getSsoEmail(); - - if (!ssoLoginEmail) { - this.logService.error("SSO login email not found."); - return; - } - - await this.ssoLoginService.updateSsoRequiredCache(ssoLoginEmail, userId); - await this.ssoLoginService.clearSsoEmail(); + if (!ssoLoginEmail) { + this.logService.error("SSO login email not found."); + return; } + + await this.ssoLoginService.updateSsoRequiredCache(ssoLoginEmail, userId); + await this.ssoLoginService.clearSsoEmail(); } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index d06a14d242f..17d5f4e9df5 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -16,7 +16,6 @@ export enum FeatureFlag { BlockClaimedDomainAccountCreation = "block-claimed-domain-account-creation", /* Auth */ - PM22110_DisableAlternateLoginMethods = "pm-22110-disable-alternate-login-methods", PM23801_PrefetchPasswordPrelogin = "pm-23801-prefetch-password-prelogin", /* Autofill */ @@ -118,7 +117,6 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.VaultLoadingSkeletons]: FALSE, /* Auth */ - [FeatureFlag.PM22110_DisableAlternateLoginMethods]: FALSE, [FeatureFlag.PM23801_PrefetchPasswordPrelogin]: FALSE, /* Billing */ diff --git a/package-lock.json b/package-lock.json index 005eb38d80b..9ec580e3a5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@nx/js": "21.6.8", "@nx/webpack": "21.6.8", "big-integer": "1.6.52", - "braintree-web-drop-in": "1.44.0", + "braintree-web-drop-in": "1.46.0", "buffer": "6.0.3", "bufferutil": "4.0.9", "chalk": "4.1.2", @@ -4798,15 +4798,15 @@ "link": true }, "node_modules/@braintree/asset-loader": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@braintree/asset-loader/-/asset-loader-2.0.1.tgz", - "integrity": "sha512-OGAoBA5MRVsr5qg0sXM6NMJbqHnYZhBudtM6WGgpQnoX42fjUYbE6Y6qFuuerD5z3lsOAjnu80DooBs1VBuh5Q==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@braintree/asset-loader/-/asset-loader-2.0.3.tgz", + "integrity": "sha512-uREap1j30wKRlC0mK99nNPMpEp77NtB6XixpDfFJPZHmkrmw7IB4skKe+26LZBK1H6oSainFhAyKoP7x3eyOKA==", "license": "MIT" }, "node_modules/@braintree/browser-detection": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@braintree/browser-detection/-/browser-detection-2.0.1.tgz", - "integrity": "sha512-wpRI7AXEUh6o3ILrJbpNOYE7ItfjX/S8JZP7Z5FF66ULngBGYOqE8SeLlLKXG69Nc07HtlL/6nk/h539iz9hcQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@braintree/browser-detection/-/browser-detection-2.0.2.tgz", + "integrity": "sha512-Zrv/pyodvwv/hsjsBKXKVcwHZOkx4A/5Cy2hViXtqghAhLd3483bYUIfHZJE5JKTrd018ny1FI5pN1PHFtW7vw==", "license": "MIT" }, "node_modules/@braintree/event-emitter": { @@ -4822,9 +4822,9 @@ "license": "MIT" }, "node_modules/@braintree/iframer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@braintree/iframer/-/iframer-2.0.0.tgz", - "integrity": "sha512-x1kHOyIJNDvi4P1s6pVBZhqhBa1hqDG9+yzcsCR1oNVC0LxH9CAP8bKxioT8/auY1sUyy+D8T4Vp/jv7QqSqLQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@braintree/iframer/-/iframer-2.0.1.tgz", + "integrity": "sha512-t1zJX5+f1yxHAzBJPaQT/XVMocKodUqjTE+hYvuxxWjqEZIbH8/eT5b5n767jY16mYw3+XiDkKHqcp4Pclq1wg==", "license": "MIT" }, "node_modules/@braintree/sanitize-url": { @@ -4834,9 +4834,9 @@ "license": "MIT" }, "node_modules/@braintree/uuid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@braintree/uuid/-/uuid-1.0.0.tgz", - "integrity": "sha512-AtI5hfttWSuWAgcwLUZdcZ7Fp/8jCCUf9JTs7+Xow9ditU28zuoBovqq083yph2m3SxPYb84lGjOq+cXlXBvJg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@braintree/uuid/-/uuid-1.0.1.tgz", + "integrity": "sha512-Tgu5GoODkf4oj4aLlVIapEPEfjitIHrg5ftqY6pa5Ghr4ZUA9XtZIIZ6ZPdP9x8/X0lt/FB8tRq83QuCQCwOrA==", "license": "ISC" }, "node_modules/@braintree/wrap-promise": { @@ -17762,40 +17762,40 @@ } }, "node_modules/braintree-web": { - "version": "3.113.0", - "resolved": "https://registry.npmjs.org/braintree-web/-/braintree-web-3.113.0.tgz", - "integrity": "sha512-qykYxZyld4X1tRNgXZQ3ZGzmhDGTBTRQ6Q24KaG9PuYqo+P2TVDEDOVC6tRbkx2RUIdXLv2M6WpkG7oLqEia9Q==", + "version": "3.123.2", + "resolved": "https://registry.npmjs.org/braintree-web/-/braintree-web-3.123.2.tgz", + "integrity": "sha512-N4IH75vKY67eONc0Ao4e7F+XagFW+3ok+Nfs/eOjw5D/TUt03diMAQ8woOwJghi2ql6/yjqNzZi2zE/sTWXmJg==", "license": "MIT", "dependencies": { - "@braintree/asset-loader": "2.0.1", - "@braintree/browser-detection": "2.0.1", + "@braintree/asset-loader": "2.0.3", + "@braintree/browser-detection": "2.0.2", "@braintree/event-emitter": "0.4.1", "@braintree/extended-promise": "1.0.0", - "@braintree/iframer": "2.0.0", + "@braintree/iframer": "2.0.1", "@braintree/sanitize-url": "7.0.4", - "@braintree/uuid": "1.0.0", + "@braintree/uuid": "1.0.1", "@braintree/wrap-promise": "2.1.0", "@paypal/accelerated-checkout-loader": "1.1.0", - "card-validator": "10.0.0", - "credit-card-type": "10.0.1", - "framebus": "6.0.0", - "inject-stylesheet": "6.0.1", + "card-validator": "10.0.3", + "credit-card-type": "10.0.2", + "framebus": "6.0.3", + "inject-stylesheet": "6.0.2", "promise-polyfill": "8.2.3", - "restricted-input": "3.0.5" + "restricted-input": "4.0.3" } }, "node_modules/braintree-web-drop-in": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/braintree-web-drop-in/-/braintree-web-drop-in-1.44.0.tgz", - "integrity": "sha512-maOq9SwiXztIzixJhOras7K44x4UIqqnkyQMYAJqxQ8WkADv9AkflCu2j3IeVYCus/Th9gWWFHcBugn3C4sZGw==", + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/braintree-web-drop-in/-/braintree-web-drop-in-1.46.0.tgz", + "integrity": "sha512-KxCjJpaigoMajYD/iIA+ohXaI6Olt2Bj/Yu45WpJOjolKO9n1UmXl9bsq9UIiGOFIGqi/JWva1wI4cIHHvcI1A==", "license": "MIT", "dependencies": { - "@braintree/asset-loader": "2.0.1", - "@braintree/browser-detection": "2.0.1", + "@braintree/asset-loader": "2.0.3", + "@braintree/browser-detection": "2.0.2", "@braintree/event-emitter": "0.4.1", - "@braintree/uuid": "1.0.0", + "@braintree/uuid": "1.0.1", "@braintree/wrap-promise": "2.1.0", - "braintree-web": "3.113.0" + "braintree-web": "3.123.2" } }, "node_modules/browser-assert": { @@ -18444,20 +18444,14 @@ "license": "CC-BY-4.0" }, "node_modules/card-validator": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/card-validator/-/card-validator-10.0.0.tgz", - "integrity": "sha512-2fLyCBOxO7/b56sxoYav8FeJqv9bWpZSyKq8sXKxnpxTGXHnM/0c8WEKG+ZJ+OXFcabnl98pD0EKBtTn+Tql0g==", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/card-validator/-/card-validator-10.0.3.tgz", + "integrity": "sha512-xOEDsK3hojV0OIpmrR64eZGpngnOqRDEP20O+WSRtvjLSW6nyekW4i2N9SzYg679uFO3RyHcFHxb+mml5tXc4A==", "license": "MIT", "dependencies": { - "credit-card-type": "^9.1.0" + "credit-card-type": "^10.0.2" } }, - "node_modules/card-validator/node_modules/credit-card-type": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/credit-card-type/-/credit-card-type-9.1.0.tgz", - "integrity": "sha512-CpNFuLxiPFxuZqhSKml3M+t0K/484pMAnfYWH14JoD7OZMnmC0Lmo+P7JX9SobqFpRoo7ifA18kOHdxJywYPEA==", - "license": "MIT" - }, "node_modules/case-sensitive-paths-webpack-plugin": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", @@ -19692,9 +19686,9 @@ "license": "MIT" }, "node_modules/credit-card-type": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/credit-card-type/-/credit-card-type-10.0.1.tgz", - "integrity": "sha512-vQOuWmBgsgG1ovGeDi8m6Zeu1JaqH/JncrxKmaqMbv/LunyOQdLiQhPHtOsNlbUI05TocR5nod/Mbs3HYtr6sQ==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/credit-card-type/-/credit-card-type-10.0.2.tgz", + "integrity": "sha512-vt/iQokU0mtrT7ceRU75FSmWnIh5JFpLsUUUWYRmztYekOGm0ZbCuzwFTbNkq41k92y+0B8ChscFhRN9DhVZEA==", "license": "MIT" }, "node_modules/cross-dirname": { @@ -23410,20 +23404,14 @@ } }, "node_modules/framebus": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/framebus/-/framebus-6.0.0.tgz", - "integrity": "sha512-bL9V68hVaVBCY9rveoWbPFFI9hAXIJtESs51B+9XmzvMt38+wP8b4VdiJsavjMS6NfPZ/afQ/jc2qaHmSGI1kQ==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/framebus/-/framebus-6.0.3.tgz", + "integrity": "sha512-G/N2p+kFZ1xPBge7tbtTq2KcTR1kSKs1rVbTqH//WdtvJSexS33fsTTOq3yfUWvUczqhujyaFc+omawC9YyRBg==", "license": "MIT", "dependencies": { - "@braintree/uuid": "^0.1.0" + "@braintree/uuid": "^1.0.0" } }, - "node_modules/framebus/node_modules/@braintree/uuid": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@braintree/uuid/-/uuid-0.1.0.tgz", - "integrity": "sha512-YvZJdlNcK5EnR+7M8AjgEAf4Qx696+FOSYlPfy5ePn80vODtVAUU0FxHnzKZC0og1VbDNQDDiwhthR65D4Na0g==", - "license": "ISC" - }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -24987,9 +24975,9 @@ } }, "node_modules/inject-stylesheet": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/inject-stylesheet/-/inject-stylesheet-6.0.1.tgz", - "integrity": "sha512-2fvune1D4+8mvJoLVo95ncY4HrDkIaYIReRzXv8tkWFgdG9iuc5QuX57gtSDPWTWQI/f5BGwwtH85wxHouzucg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/inject-stylesheet/-/inject-stylesheet-6.0.2.tgz", + "integrity": "sha512-sswMueya1LXEfwcy7KXPuq3zAW6HvgAeViApEhIaCviCkP4XYoKrQj8ftEmxPmIHn88X4R3xOAsnN/QCPvVKWw==", "license": "MIT" }, "node_modules/inquirer": { @@ -36154,12 +36142,12 @@ "license": "ISC" }, "node_modules/restricted-input": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/restricted-input/-/restricted-input-3.0.5.tgz", - "integrity": "sha512-lUuXZ3wUnHURRarj5/0C8vomWIfWJO+p7T6RYwB46v7Oyuyr3yyupU+i7SjqUv4S6RAeAAZt1C/QCLJ9xhQBow==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/restricted-input/-/restricted-input-4.0.3.tgz", + "integrity": "sha512-VpkwT5Fr3DhvoRZfPnmHDhnYAYETjjNzDlvA4NlW0iknFS47C5X4OCHEpOOxaPjvmka5V8d1ty1jVVoorZKvHg==", "license": "MIT", "dependencies": { - "@braintree/browser-detection": "^1.12.1" + "@braintree/browser-detection": "^1.17.2" } }, "node_modules/restricted-input/node_modules/@braintree/browser-detection": { diff --git a/package.json b/package.json index 7ca866b3c4d..87a78a30796 100644 --- a/package.json +++ b/package.json @@ -175,7 +175,7 @@ "@nx/js": "21.6.8", "@nx/webpack": "21.6.8", "big-integer": "1.6.52", - "braintree-web-drop-in": "1.44.0", + "braintree-web-drop-in": "1.46.0", "buffer": "6.0.3", "bufferutil": "4.0.9", "chalk": "4.1.2",