diff --git a/.github/codecov.yml b/.github/codecov.yml index f375621bd87..d9d59f9de28 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -12,7 +12,7 @@ component_management: paths: - apps/browser/src/key-management/biometrics/** - apps/cli/src/key-management/cli-biometrics-service.ts - - apps/desktop/destkop_native/core/src/biometric/** + - apps/desktop/desktop_native/core/src/biometric/** - apps/desktop/src/key-management/biometrics/** - apps/desktop/src/services/biometric-message-handler.service.ts - apps/web/src/app/key-management/web-biometric.service.ts @@ -24,6 +24,7 @@ component_management: - apps/desktop/src/key-management/lock/** - apps/web/src/app/key-management/lock/** - libs/key-management-ui/src/lock/** + - libs/common/src/key-management/device-trust/** - component_id: key-management-ipc name: Key Management - IPC paths: diff --git a/apps/browser/src/autofill/content/components/notification/footer.ts b/apps/browser/src/autofill/content/components/notification/footer.ts index 6de4a333dfe..c604fcd196f 100644 --- a/apps/browser/src/autofill/content/components/notification/footer.ts +++ b/apps/browser/src/autofill/content/components/notification/footer.ts @@ -1,5 +1,5 @@ import { css } from "@emotion/css"; -import { html } from "lit"; +import { html, nothing } from "lit"; import { Theme } from "@bitwarden/common/platform/enums"; @@ -8,7 +8,6 @@ import { NotificationTypes, } from "../../../notification/abstractions/notification-bar"; import { spacing, themes } from "../constants/styles"; -import { ActionRow } from "../rows/action-row"; import { ButtonRow } from "../rows/button-row"; export function NotificationFooter({ @@ -23,18 +22,13 @@ export function NotificationFooter({ theme: Theme; }) { const isChangeNotification = notificationType === NotificationTypes.Change; - const saveNewItemText = i18n.saveAsNewLoginAction; const buttonText = i18n.saveAction; return html`
- ${isChangeNotification - ? ActionRow({ - itemText: saveNewItemText, - handleAction: handleSaveAction, - theme, - }) - : ButtonRow({ theme, buttonAction: handleSaveAction, buttonText })} + ${!isChangeNotification + ? ButtonRow({ theme, buttonAction: handleSaveAction, buttonText }) + : nothing}
`; } @@ -46,5 +40,6 @@ const notificationFooterStyles = ({ theme }: { theme: Theme }) => css` :last-child { border-radius: 0 0 ${spacing["4"]} ${spacing["4"]}; + padding-bottom: ${spacing[4]}; } `; diff --git a/apps/browser/src/autofill/content/components/rows/button-row.ts b/apps/browser/src/autofill/content/components/rows/button-row.ts index 1feef016a81..ed0ed5aac7d 100644 --- a/apps/browser/src/autofill/content/components/rows/button-row.ts +++ b/apps/browser/src/autofill/content/components/rows/button-row.ts @@ -57,6 +57,7 @@ const buttonRowStyles = css` width: 100%; max-height: 52px; white-space: nowrap; + padding-top: ${spacing[1]}; > button { max-width: min-content; diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html index 302b14247e9..8156525301b 100644 --- a/apps/browser/src/autofill/popup/settings/blocked-domains.component.html +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.html @@ -76,5 +76,8 @@ > {{ "save" | i18n }} + diff --git a/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts b/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts index 16e4b6f6751..c59ce24c7c4 100644 --- a/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts +++ b/apps/browser/src/autofill/popup/settings/blocked-domains.component.ts @@ -39,6 +39,7 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp import { PopupFooterComponent } from "../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; +import { PopupRouterCacheService } from "../../../platform/popup/view-cache/popup-router-cache.service"; @Component({ selector: "app-blocked-domains", @@ -88,6 +89,7 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy { private i18nService: I18nService, private toastService: ToastService, private formBuilder: FormBuilder, + private popupRouterCacheService: PopupRouterCacheService, ) {} get domainForms() { @@ -220,6 +222,10 @@ export class BlockedDomainsComponent implements AfterViewInit, OnDestroy { } } + async goBack() { + await this.popupRouterCacheService.back(); + } + trackByFunction(index: number, _: string) { return index; } diff --git a/apps/browser/src/autofill/popup/settings/excluded-domains.component.html b/apps/browser/src/autofill/popup/settings/excluded-domains.component.html index 92abef3730c..a963c2608a6 100644 --- a/apps/browser/src/autofill/popup/settings/excluded-domains.component.html +++ b/apps/browser/src/autofill/popup/settings/excluded-domains.component.html @@ -72,5 +72,8 @@ > {{ "save" | i18n }} + diff --git a/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts b/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts index 0447d8076c2..504d2dbfc17 100644 --- a/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts +++ b/apps/browser/src/autofill/popup/settings/excluded-domains.component.ts @@ -40,6 +40,7 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp import { PopupFooterComponent } from "../../../platform/popup/layout/popup-footer.component"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; +import { PopupRouterCacheService } from "../../../platform/popup/view-cache/popup-router-cache.service"; @Component({ selector: "app-excluded-domains", @@ -90,6 +91,7 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { private i18nService: I18nService, private toastService: ToastService, private formBuilder: FormBuilder, + private popupRouterCacheService: PopupRouterCacheService, ) { this.accountSwitcherEnabled = enableAccountSwitching(); } @@ -150,6 +152,10 @@ export class ExcludedDomainsComponent implements AfterViewInit, OnDestroy { await this.fieldChange(); } + async goBack() { + await this.popupRouterCacheService.back(); + } + async fieldChange() { if (this.dataIsPristine) { this.dataIsPristine = false; diff --git a/apps/browser/src/autofill/services/autofill.service.ts b/apps/browser/src/autofill/services/autofill.service.ts index e833420b859..ed8b2033209 100644 --- a/apps/browser/src/autofill/services/autofill.service.ts +++ b/apps/browser/src/autofill/services/autofill.service.ts @@ -1,7 +1,16 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { filter, firstValueFrom, merge, Observable, ReplaySubject, scan, startWith } from "rxjs"; -import { pairwise } from "rxjs/operators"; +import { + filter, + firstValueFrom, + merge, + Observable, + ReplaySubject, + scan, + startWith, + timer, +} from "rxjs"; +import { map, pairwise, share, takeUntil } from "rxjs/operators"; import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service"; import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; @@ -146,7 +155,19 @@ export default class AutofillService implements AutofillServiceInterface { pageDetailsFallback$.next([]); } - return merge(pageDetailsFromTab$, pageDetailsFallback$); + // Share the pageDetailsFromTab$ observable so that multiple subscribers don't trigger multiple executions. + const sharedPageDetailsFromTab$ = pageDetailsFromTab$.pipe(share()); + + // Create a timeout observable that emits an empty array if pageDetailsFromTab$ hasn't emitted within 1 second. + const pageDetailsTimeout$ = timer(1000).pipe( + map(() => []), + takeUntil(sharedPageDetailsFromTab$), + ); + + // Merge the responses so that if pageDetailsFromTab$ emits, that value is used. + // Otherwise, if it doesn't emit in time, the timeout observable emits an empty array. + // Also, pageDetailsFallback$ will emit in error cases. + return merge(sharedPageDetailsFromTab$, pageDetailsFallback$, pageDetailsTimeout$); } /** diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index 807767455a5..f8f86e6a277 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -32,7 +32,6 @@ import { ProviderService } from "@bitwarden/common/admin-console/services/provid import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service"; import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; @@ -44,7 +43,6 @@ import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/for import { AccountServiceImplementation } from "@bitwarden/common/auth/services/account.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { AvatarService } from "@bitwarden/common/auth/services/avatar.service"; -import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesServiceImplementation } from "@bitwarden/common/auth/services/devices/devices.service.implementation"; import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; import { SsoLoginService } from "@bitwarden/common/auth/services/sso-login.service"; @@ -78,6 +76,8 @@ import { BulkEncryptServiceImplementation } from "@bitwarden/common/key-manageme import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation"; import { FallbackBulkEncryptService } from "@bitwarden/common/key-management/crypto/services/fallback-bulk-encrypt.service"; import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/multithread-encrypt.service.implementation"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; +import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/services/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; @@ -267,6 +267,7 @@ import { OffscreenDocumentService } from "../platform/offscreen-document/abstrac import { DefaultOffscreenDocumentService } from "../platform/offscreen-document/offscreen-document.service"; import { BrowserTaskSchedulerService } from "../platform/services/abstractions/browser-task-scheduler.service"; import { BrowserEnvironmentService } from "../platform/services/browser-environment.service"; +import BrowserInitialInstallService from "../platform/services/browser-initial-install.service"; import BrowserLocalStorageService from "../platform/services/browser-local-storage.service"; import BrowserMemoryStorageService from "../platform/services/browser-memory-storage.service"; import { BrowserScriptInjectorService } from "../platform/services/browser-script-injector.service"; @@ -390,6 +391,7 @@ export default class MainBackground { kdfConfigService: KdfConfigService; offscreenDocumentService: OffscreenDocumentService; syncServiceListener: SyncServiceListener; + browserInitialInstallService: BrowserInitialInstallService; webPushConnectionService: WorkerWebPushConnectionService | UnsupportedWebPushConnectionService; themeStateService: DefaultThemeStateService; @@ -1043,6 +1045,8 @@ export default class MainBackground { this.organizationVaultExportService, ); + this.browserInitialInstallService = new BrowserInitialInstallService(this.stateProvider); + if (BrowserApi.isManifestVersion(3)) { const registration = (self as unknown as { registration: ServiceWorkerRegistration }) ?.registration; @@ -1146,6 +1150,7 @@ export default class MainBackground { this.accountService, lockService, this.billingAccountProfileStateService, + this.browserInitialInstallService, ); this.nativeMessagingBackground = new NativeMessagingBackground( this.keyService, diff --git a/apps/browser/src/background/runtime.background.ts b/apps/browser/src/background/runtime.background.ts index 32e7432174a..7db72f38139 100644 --- a/apps/browser/src/background/runtime.background.ts +++ b/apps/browser/src/background/runtime.background.ts @@ -28,6 +28,7 @@ import { LockedVaultPendingNotificationsData } from "../autofill/background/abst import { AutofillService } from "../autofill/services/abstractions/autofill.service"; import { BrowserApi } from "../platform/browser/browser-api"; import { BrowserEnvironmentService } from "../platform/services/browser-environment.service"; +import BrowserInitialInstallService from "../platform/services/browser-initial-install.service"; import { BrowserPlatformUtilsService } from "../platform/services/platform-utils/browser-platform-utils.service"; import MainBackground from "./main.background"; @@ -53,6 +54,7 @@ export default class RuntimeBackground { private accountService: AccountService, private readonly lockService: LockService, private billingAccountProfileStateService: BillingAccountProfileStateService, + private browserInitialInstallService: BrowserInitialInstallService, ) { // onInstalled listener must be wired up before anything else, so we do it in the ctor chrome.runtime.onInstalled.addListener((details: any) => { @@ -382,7 +384,10 @@ export default class RuntimeBackground { void this.autofillService.loadAutofillScriptsOnInstall(); if (this.onInstalledReason != null) { - if (this.onInstalledReason === "install") { + if ( + this.onInstalledReason === "install" && + !(await firstValueFrom(this.browserInitialInstallService.extensionInstalled$)) + ) { if (!devFlagEnabled("skipWelcomeOnInstall")) { void BrowserApi.createNewTab("https://bitwarden.com/browser-start/"); } @@ -394,6 +399,7 @@ export default class RuntimeBackground { if (await this.environmentService.hasManagedEnvironment()) { await this.environmentService.setUrlsToManagedEnvironment(); } + await this.browserInitialInstallService.setExtensionInstalled(true); } this.onInstalledReason = null; diff --git a/apps/browser/src/platform/services/browser-initial-install.service.ts b/apps/browser/src/platform/services/browser-initial-install.service.ts new file mode 100644 index 00000000000..12b2ea95b9c --- /dev/null +++ b/apps/browser/src/platform/services/browser-initial-install.service.ts @@ -0,0 +1,31 @@ +import { Observable, map } from "rxjs"; + +import { + GlobalState, + EXTENSION_INITIAL_INSTALL_DISK, + KeyDefinition, + StateProvider, +} from "@bitwarden/common/platform/state"; + +const EXTENSION_INSTALLED = new KeyDefinition( + EXTENSION_INITIAL_INSTALL_DISK, + "extensionInstalled", + { + deserializer: (obj) => obj, + }, +); + +export default class BrowserInitialInstallService { + private extensionInstalled: GlobalState = + this.stateProvider.getGlobal(EXTENSION_INSTALLED); + + readonly extensionInstalled$: Observable = this.extensionInstalled.state$.pipe( + map((x) => x ?? false), + ); + + constructor(private stateProvider: StateProvider) {} + + async setExtensionInstalled(value: boolean) { + await this.extensionInstalled.update(() => value); + } +} diff --git a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html index 152c500d6ca..21b298fb30a 100644 --- a/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html +++ b/apps/browser/src/vault/popup/components/vault-v2/add-edit/add-edit-v2.component.html @@ -2,7 +2,7 @@ @@ -27,6 +27,10 @@ {{ "save" | i18n }} + + + diff --git a/apps/cli/package.json b/apps/cli/package.json index f8f1c8a02d9..7d9f4af0ffe 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -68,7 +68,7 @@ "chalk": "4.1.2", "commander": "11.1.0", "form-data": "4.0.1", - "https-proxy-agent": "7.0.5", + "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", "jsdom": "26.0.0", "jszip": "3.10.1", diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index 75a74d42bbd..b7f423e8ff7 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -34,7 +34,6 @@ import { ProviderApiService } from "@bitwarden/common/admin-console/services/pro import { ProviderService } from "@bitwarden/common/admin-console/services/provider.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { MasterPasswordApiService as MasterPasswordApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; import { @@ -43,7 +42,6 @@ import { } from "@bitwarden/common/auth/services/account.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { AvatarService } from "@bitwarden/common/auth/services/avatar.service"; -import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; import { MasterPasswordApiService } from "@bitwarden/common/auth/services/master-password/master-password-api.service.implementation"; import { TokenService } from "@bitwarden/common/auth/services/token.service"; @@ -63,6 +61,8 @@ import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/bill import { ClientType } from "@bitwarden/common/enums"; import { EncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/encrypt.service.implementation"; import { FallbackBulkEncryptService } from "@bitwarden/common/key-management/crypto/services/fallback-bulk-encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; +import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/services/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { MasterPasswordService } from "@bitwarden/common/key-management/master-password/services/master-password.service"; diff --git a/apps/desktop/src/vault/app/vault/vault.component.ts b/apps/desktop/src/vault/app/vault/vault.component.ts index 2c669e388f8..d8be360170a 100644 --- a/apps/desktop/src/vault/app/vault/vault.component.ts +++ b/apps/desktop/src/vault/app/vault/vault.component.ts @@ -493,12 +493,14 @@ export class VaultComponent implements OnInit, OnDestroy { } async savedCipher(cipher: CipherView) { - this.cipherId = cipher.id; + this.cipherId = null; this.action = "view"; await this.vaultItemsComponent.refresh(); + this.cipherId = cipher.id; await this.cipherService.clearCache(this.activeUserId); - await this.viewComponent.load(); + await this.vaultItemsComponent.load(this.activeFilter.buildFilter()); this.go(); + await this.vaultItemsComponent.refresh(); } async deletedCipher(cipher: CipherView) { @@ -572,6 +574,8 @@ export class VaultComponent implements OnInit, OnDestroy { // eslint-disable-next-line @typescript-eslint/no-floating-promises this.viewCipher(cipher); await this.vaultItemsComponent.refresh(); + await this.cipherService.clearCache(this.activeUserId); + await this.vaultItemsComponent.load(this.activeFilter.buildFilter()); }); // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe this.modal.onClosed.subscribe(async () => { diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 41be86e584e..09dac7f4c48 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,4 +1,4 @@ -FROM bitwarden/server +FROM ghcr.io/bitwarden/server LABEL com.bitwarden.product="bitwarden" diff --git a/apps/web/src/app/auth/recover-two-factor.component.spec.ts b/apps/web/src/app/auth/recover-two-factor.component.spec.ts index 40182dee017..bf6d47e09e5 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.spec.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.spec.ts @@ -9,7 +9,6 @@ import { } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; -import { TwoFactorRecoveryRequest } from "@bitwarden/common/auth/models/request/two-factor-recovery.request"; 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"; @@ -85,15 +84,14 @@ describe("RecoverTwoFactorComponent", () => { describe("handleRecoveryLogin", () => { it("should log in successfully and navigate to the two-factor settings page", async () => { // Arrange - const request = new TwoFactorRecoveryRequest(); - request.recoveryCode = "testRecoveryCode"; - request.email = "test@example.com"; + const email = "test@example.com"; + const recoveryCode = "testRecoveryCode"; const authResult = new AuthResult(); mockLoginStrategyService.logIn.mockResolvedValue(authResult); // Act - await component["handleRecoveryLogin"](request); + await component["loginWithRecoveryCode"](email, recoveryCode); // Assert expect(mockLoginStrategyService.logIn).toHaveBeenCalledWith( @@ -112,15 +110,14 @@ describe("RecoverTwoFactorComponent", () => { it("should handle login errors and redirect to login page", async () => { // Arrange - const request = new TwoFactorRecoveryRequest(); - request.recoveryCode = "testRecoveryCode"; - request.email = "test@example.com"; + const email = "test@example.com"; + const recoveryCode = "testRecoveryCode"; const error = new Error("Login failed"); mockLoginStrategyService.logIn.mockRejectedValue(error); // Act - await component["handleRecoveryLogin"](request); + await component["loginWithRecoveryCode"](email, recoveryCode); // Assert expect(mockLogService.error).toHaveBeenCalledWith( @@ -128,7 +125,7 @@ describe("RecoverTwoFactorComponent", () => { error.message, ); expect(mockRouter.navigate).toHaveBeenCalledWith(["/login"], { - queryParams: { email: request.email }, + queryParams: { email: email }, }); }); }); diff --git a/apps/web/src/app/auth/recover-two-factor.component.ts b/apps/web/src/app/auth/recover-two-factor.component.ts index 996b324ce56..35aa1aab7c1 100644 --- a/apps/web/src/app/auth/recover-two-factor.component.ts +++ b/apps/web/src/app/auth/recover-two-factor.component.ts @@ -7,17 +7,11 @@ import { PasswordLoginCredentials, LoginSuccessHandlerService, } from "@bitwarden/auth/common"; -import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request"; -import { TwoFactorRecoveryRequest } from "@bitwarden/common/auth/models/request/two-factor-recovery.request"; -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"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; import { NewDeviceVerificationNoticeService } from "@bitwarden/vault"; @Component({ @@ -36,32 +30,18 @@ export class RecoverTwoFactorComponent implements OnInit { */ recoveryCodeMessage = ""; - /** - * Whether the recovery code login feature flag is enabled - */ - private recoveryCodeLoginFeatureFlagEnabled = false; - constructor( private router: Router, - private apiService: ApiService, - private platformUtilsService: PlatformUtilsService, private i18nService: I18nService, - private keyService: KeyService, private loginStrategyService: LoginStrategyServiceAbstraction, private toastService: ToastService, - private configService: ConfigService, private loginSuccessHandlerService: LoginSuccessHandlerService, private logService: LogService, private newDeviceVerificationNoticeService: NewDeviceVerificationNoticeService, ) {} async ngOnInit() { - this.recoveryCodeLoginFeatureFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.RecoveryCodeLogin, - ); - this.recoveryCodeMessage = this.recoveryCodeLoginFeatureFlagEnabled - ? this.i18nService.t("logInBelowUsingYourSingleUseRecoveryCode") - : this.i18nService.t("recoverAccountTwoStepDesc"); + this.recoveryCodeMessage = this.i18nService.t("logInBelowUsingYourSingleUseRecoveryCode"); } get email(): string { @@ -85,38 +65,25 @@ export class RecoverTwoFactorComponent implements OnInit { return; } - const request = new TwoFactorRecoveryRequest(); - request.recoveryCode = this.recoveryCode.replace(/\s/g, "").toLowerCase(); - request.email = this.email.trim().toLowerCase(); - const key = await this.loginStrategyService.makePreloginKey(this.masterPassword, request.email); - request.masterPasswordHash = await this.keyService.hashMasterKey(this.masterPassword, key); + const email = this.email.trim().toLowerCase(); + const recoveryCode = this.recoveryCode.replace(/\s/g, "").toLowerCase(); - if (this.recoveryCodeLoginFeatureFlagEnabled) { - await this.handleRecoveryLogin(request); - } else { - await this.apiService.postTwoFactorRecover(request); - this.toastService.showToast({ - variant: "success", - title: "", - message: this.i18nService.t("twoStepRecoverDisabled"), - }); - await this.router.navigate(["/"]); - } + await this.loginWithRecoveryCode(email, recoveryCode); }; /** * Handles the login process after a successful account recovery. */ - private async handleRecoveryLogin(request: TwoFactorRecoveryRequest) { + private async loginWithRecoveryCode(email: string, recoveryCode: string) { // Build two-factor request to pass into PasswordLoginCredentials request using the 2FA recovery code and RecoveryCode type const twoFactorRequest: TokenTwoFactorRequest = { provider: TwoFactorProviderType.RecoveryCode, - token: request.recoveryCode, + token: recoveryCode, remember: false, }; const credentials = new PasswordLoginCredentials( - request.email, + email, this.masterPassword, "", twoFactorRequest, @@ -148,7 +115,7 @@ export class RecoverTwoFactorComponent implements OnInit { } catch (error) { // If login errors, redirect to login page per product. Don't show error this.logService.error("Error logging in automatically: ", (error as Error).message); - await this.router.navigate(["/login"], { queryParams: { email: request.email } }); + await this.router.navigate(["/login"], { queryParams: { email: email } }); } } } diff --git a/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts b/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts index a76505930d4..83c9ff23f3c 100644 --- a/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts +++ b/apps/web/src/app/auth/settings/two-factor/two-factor-setup.component.ts @@ -29,7 +29,6 @@ import { TwoFactorProviders } from "@bitwarden/common/auth/services/two-factor.s import { AuthResponse } from "@bitwarden/common/auth/types/auth-response"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { ProductTierType } from "@bitwarden/common/billing/enums"; -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 { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; @@ -85,12 +84,7 @@ export class TwoFactorSetupComponent implements OnInit, OnDestroy { } async ngOnInit() { - const recoveryCodeLoginFeatureFlagEnabled = await this.configService.getFeatureFlag( - FeatureFlag.RecoveryCodeLogin, - ); - this.recoveryCodeWarningMessage = recoveryCodeLoginFeatureFlagEnabled - ? this.i18nService.t("yourSingleUseRecoveryCode") - : this.i18nService.t("twoStepLoginRecoveryWarning"); + this.recoveryCodeWarningMessage = this.i18nService.t("yourSingleUseRecoveryCode"); for (const key in TwoFactorProviders) { // eslint-disable-next-line diff --git a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts index 3a6ff1585b7..09d35d34da8 100644 --- a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts +++ b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.spec.ts @@ -2,10 +2,10 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; import { OrganizationUserResetPasswordWithIdRequest } from "@bitwarden/admin-console/common"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { WebauthnRotateCredentialRequest } from "@bitwarden/common/auth/models/request/webauthn-rotate-credential.request"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; diff --git a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts index dd257282cfa..d200fff256c 100644 --- a/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts +++ b/apps/web/src/app/key-management/key-rotation/user-key-rotation.service.ts @@ -2,11 +2,11 @@ import { Injectable } from "@angular/core"; import { firstValueFrom } from "rxjs"; import { Account } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { MasterPasswordVerification } from "@bitwarden/common/auth/types/verification"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; diff --git a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts index f7169d9dbd4..b2adeecbf69 100644 --- a/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts +++ b/apps/web/src/app/vault/components/vault-item-dialog/vault-item-dialog.component.ts @@ -233,10 +233,10 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy { * A user may restore items if they have delete permissions and the item is in the trash. */ protected async canUserRestore() { - const featureFlagEnabled = await firstValueFrom(this.limitItemDeletion$); - return this.isTrashFilter && this.cipher?.isDeleted && featureFlagEnabled - ? this.cipher?.permissions.restore - : this.canDelete; + if (await firstValueFrom(this.limitItemDeletion$)) { + return this.isTrashFilter && this.cipher?.isDeleted && this.cipher?.permissions.restore; + } + return this.isTrashFilter && this.cipher?.isDeleted && this.canDelete; } protected showRestore: boolean; diff --git a/apps/web/src/app/vault/individual-vault/vault-header/vault-header.component.ts b/apps/web/src/app/vault/individual-vault/vault-header/vault-header.component.ts index 489f42649f9..e9122864447 100644 --- a/apps/web/src/app/vault/individual-vault/vault-header/vault-header.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault-header/vault-header.component.ts @@ -219,23 +219,24 @@ export class VaultHeaderComponent implements OnInit { } async addCollection(): Promise { - const organization = this.organizations?.find( - (org) => org.productTierType === ProductTierType.Free, - ); const isBreadcrumbEventLogsEnabled = await firstValueFrom( this.configService.getFeatureFlag$(FeatureFlag.PM12276_BreadcrumbEventLogs), ); - if ( - this.organizations.length == 1 && - organization.productTierType === ProductTierType.Free && - isBreadcrumbEventLogsEnabled - ) { - const collections = await this.collectionAdminService.getAll(organization.id); - if (collections.length === organization.maxCollections) { - await this.showFreeOrgUpgradeDialog(organization); - return; + + if (isBreadcrumbEventLogsEnabled) { + const organization = this.organizations?.find( + (org) => org.productTierType === ProductTierType.Free, + ); + + if (this.organizations?.length == 1 && !!organization) { + const collections = await this.collectionAdminService.getAll(organization.id); + if (collections.length === organization.maxCollections) { + await this.showFreeOrgUpgradeDialog(organization); + return; + } } } + this.onAddCollection.emit(); } diff --git a/libs/angular/src/auth/guards/lock.guard.spec.ts b/libs/angular/src/auth/guards/lock.guard.spec.ts index 1b09a415999..32b8ecbb9dd 100644 --- a/libs/angular/src/auth/guards/lock.guard.spec.ts +++ b/libs/angular/src/auth/guards/lock.guard.spec.ts @@ -11,10 +11,10 @@ import { AccountService, } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { ClientType } from "@bitwarden/common/enums"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/angular/src/auth/guards/lock.guard.ts b/libs/angular/src/auth/guards/lock.guard.ts index c7627442c69..10ad4917f32 100644 --- a/libs/angular/src/auth/guards/lock.guard.ts +++ b/libs/angular/src/auth/guards/lock.guard.ts @@ -9,10 +9,10 @@ import { firstValueFrom } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { ClientType } from "@bitwarden/common/enums"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; diff --git a/libs/angular/src/auth/guards/redirect.guard.ts b/libs/angular/src/auth/guards/redirect.guard.ts index f79f5d3c4b4..00dd20c9909 100644 --- a/libs/angular/src/auth/guards/redirect.guard.ts +++ b/libs/angular/src/auth/guards/redirect.guard.ts @@ -3,8 +3,8 @@ import { CanActivateFn, Router } from "@angular/router"; import { firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { KeyService } from "@bitwarden/key-management"; diff --git a/libs/angular/src/auth/guards/tde-decryption-required.guard.ts b/libs/angular/src/auth/guards/tde-decryption-required.guard.ts index 6bb83021fd0..1d98b1fa740 100644 --- a/libs/angular/src/auth/guards/tde-decryption-required.guard.ts +++ b/libs/angular/src/auth/guards/tde-decryption-required.guard.ts @@ -8,8 +8,8 @@ import { import { firstValueFrom } from "rxjs"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { KeyService } from "@bitwarden/key-management"; diff --git a/libs/angular/src/auth/guards/unauth.guard.spec.ts b/libs/angular/src/auth/guards/unauth.guard.spec.ts index ec36b146a03..ad0ce680a1f 100644 --- a/libs/angular/src/auth/guards/unauth.guard.spec.ts +++ b/libs/angular/src/auth/guards/unauth.guard.spec.ts @@ -7,8 +7,8 @@ import { BehaviorSubject } from "rxjs"; import { EmptyComponent } from "@bitwarden/angular/platform/guard/feature-flag.guard.spec"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { UserId } from "@bitwarden/common/types/guid"; import { KeyService } from "@bitwarden/key-management"; diff --git a/libs/angular/src/auth/guards/unauth.guard.ts b/libs/angular/src/auth/guards/unauth.guard.ts index 1ac0eebb458..6764b46843e 100644 --- a/libs/angular/src/auth/guards/unauth.guard.ts +++ b/libs/angular/src/auth/guards/unauth.guard.ts @@ -4,8 +4,8 @@ import { firstValueFrom } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { KeyService } from "@bitwarden/key-management"; diff --git a/libs/angular/src/auth/services/device-trust-toast.service.implementation.ts b/libs/angular/src/auth/services/device-trust-toast.service.implementation.ts index 330519683f3..4013cf8df96 100644 --- a/libs/angular/src/auth/services/device-trust-toast.service.implementation.ts +++ b/libs/angular/src/auth/services/device-trust-toast.service.implementation.ts @@ -1,7 +1,7 @@ import { merge, Observable, tap } from "rxjs"; import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ToastService } from "@bitwarden/components"; diff --git a/libs/angular/src/auth/services/device-trust-toast.service.spec.ts b/libs/angular/src/auth/services/device-trust-toast.service.spec.ts index cd9c6b0acf5..96b7db9d0ce 100644 --- a/libs/angular/src/auth/services/device-trust-toast.service.spec.ts +++ b/libs/angular/src/auth/services/device-trust-toast.service.spec.ts @@ -2,7 +2,7 @@ import { mock, MockProxy } from "jest-mock-extended"; import { EMPTY, of } from "rxjs"; import { AuthRequestServiceAbstraction } from "@bitwarden/auth/common"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { ToastService } from "@bitwarden/components"; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 4b4173c6a05..04bcb42aa53 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -87,7 +87,6 @@ import { import { AnonymousHubService as AnonymousHubServiceAbstraction } from "@bitwarden/common/auth/abstractions/anonymous-hub.service"; import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service"; import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/auth/abstractions/avatar.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { DevicesServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices/devices.service.abstraction"; import { DevicesApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/devices-api.service.abstraction"; import { MasterPasswordApiService as MasterPasswordApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password-api.service.abstraction"; @@ -105,7 +104,6 @@ import { AccountServiceImplementation } from "@bitwarden/common/auth/services/ac import { AnonymousHubService } from "@bitwarden/common/auth/services/anonymous-hub.service"; import { AuthService } from "@bitwarden/common/auth/services/auth.service"; import { AvatarService } from "@bitwarden/common/auth/services/avatar.service"; -import { DeviceTrustService } from "@bitwarden/common/auth/services/device-trust.service.implementation"; import { DevicesServiceImplementation } from "@bitwarden/common/auth/services/devices/devices.service.implementation"; import { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; import { MasterPasswordApiService } from "@bitwarden/common/auth/services/master-password/master-password-api.service.implementation"; @@ -148,6 +146,8 @@ import { BulkEncryptService } from "@bitwarden/common/key-management/crypto/abst import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; import { BulkEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/bulk-encrypt.service.implementation"; import { MultithreadEncryptServiceImplementation } from "@bitwarden/common/key-management/crypto/services/multithread-encrypt.service.implementation"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; +import { DeviceTrustService } from "@bitwarden/common/key-management/device-trust/services/device-trust.service.implementation"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/services/key-connector.service"; import { diff --git a/libs/angular/src/vault/vault-filter/components/collection-filter.component.ts b/libs/angular/src/vault/vault-filter/components/collection-filter.component.ts index 168afbdd72a..d104026f2f6 100644 --- a/libs/angular/src/vault/vault-filter/components/collection-filter.component.ts +++ b/libs/angular/src/vault/vault-filter/components/collection-filter.component.ts @@ -1,6 +1,6 @@ // FIXME: Update this file to be type safe and remove this and next line // @ts-strict-ignore -import { Directive, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Directive, EventEmitter, Input, Output } from "@angular/core"; import { CollectionView } from "@bitwarden/admin-console/common"; import { ITreeNodeObject } from "@bitwarden/common/vault/models/domain/tree-node"; @@ -10,7 +10,7 @@ import { TopLevelTreeNode } from "../models/top-level-tree-node.model"; import { VaultFilter } from "../models/vault-filter.model"; @Directive() -export class CollectionFilterComponent implements OnInit { +export class CollectionFilterComponent { @Input() hide = false; @Input() collapsedFilterNodes: Set; @Input() collectionNodes: DynamicTreeNode; @@ -51,13 +51,4 @@ export class CollectionFilterComponent implements OnInit { async toggleCollapse(node: ITreeNodeObject) { this.onNodeCollapseStateChange.emit(node); } - - ngOnInit() { - // Populate the set with all node IDs so all nodes are collapsed initially. - if (this.collectionNodes?.fullList) { - this.collectionNodes.fullList.forEach((node) => { - this.collapsedFilterNodes.add(node.id); - }); - } - } } diff --git a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts index 4c93c79d6fe..62fbeae26b6 100644 --- a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts +++ b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts @@ -16,10 +16,10 @@ import { import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { PasswordResetEnrollmentServiceAbstraction } from "@bitwarden/common/auth/abstractions/password-reset-enrollment.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { ClientType } from "@bitwarden/common/enums"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; diff --git a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts index dab516e0916..266ee3c4acc 100644 --- a/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts +++ b/libs/auth/src/angular/login-via-auth-request/login-via-auth-request.component.ts @@ -17,7 +17,6 @@ import { import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AnonymousHubService } from "@bitwarden/common/auth/abstractions/anonymous-hub.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthRequestType } from "@bitwarden/common/auth/enums/auth-request-type"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable"; @@ -26,6 +25,7 @@ import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/for import { AuthRequest } from "@bitwarden/common/auth/models/request/auth.request"; import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { ClientType, HttpStatusCode } from "@bitwarden/common/enums"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; diff --git a/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts index 3efc4522e27..842dfb3f4e3 100644 --- a/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/auth-request-login.strategy.spec.ts @@ -2,12 +2,12 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service"; import { VaultTimeoutAction, diff --git a/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts b/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts index e546f89032b..3d91adf35cf 100644 --- a/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts +++ b/libs/auth/src/common/login-strategies/auth-request-login.strategy.ts @@ -3,11 +3,11 @@ import { firstValueFrom, Observable, map, BehaviorSubject } from "rxjs"; import { Jsonify } from "type-fest"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { PasswordTokenRequest } from "@bitwarden/common/auth/models/request/identity-token/password-token.request"; import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request"; import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { UserId } from "@bitwarden/common/types/guid"; import { AuthRequestLoginCredentials } from "../models/domain/login-credentials"; diff --git a/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts index 0e340407eef..546fa0c5fa7 100644 --- a/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/sso-login.strategy.spec.ts @@ -2,7 +2,6 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { AdminAuthRequestStorable } from "@bitwarden/common/auth/models/domain/admin-auth-req-storable"; @@ -11,6 +10,7 @@ import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/id import { IUserDecryptionOptionsServerResponse } from "@bitwarden/common/auth/models/response/user-decryption-options/user-decryption-options.response"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service"; import { diff --git a/libs/auth/src/common/login-strategies/sso-login.strategy.ts b/libs/auth/src/common/login-strategies/sso-login.strategy.ts index 91d9dd43be2..1dd01d6fc75 100644 --- a/libs/auth/src/common/login-strategies/sso-login.strategy.ts +++ b/libs/auth/src/common/login-strategies/sso-login.strategy.ts @@ -3,12 +3,12 @@ import { firstValueFrom, Observable, map, BehaviorSubject } from "rxjs"; import { Jsonify } from "type-fest"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { SsoTokenRequest } from "@bitwarden/common/auth/models/request/identity-token/sso-token.request"; import { AuthRequestResponse } from "@bitwarden/common/auth/models/response/auth-request.response"; import { IdentityTokenResponse } from "@bitwarden/common/auth/models/response/identity-token.response"; import { HttpStatusCode } from "@bitwarden/common/enums"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { ErrorResponse } from "@bitwarden/common/models/response/error.response"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; diff --git a/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts b/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts index 5c368cdfb19..1dc05cafa00 100644 --- a/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts +++ b/libs/auth/src/common/services/login-strategies/login-strategy.service.spec.ts @@ -3,7 +3,6 @@ import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; @@ -14,6 +13,7 @@ import { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/respons import { PreloginResponse } from "@bitwarden/common/auth/models/response/prelogin.response"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { FakeMasterPasswordService } from "@bitwarden/common/key-management/master-password/services/fake-master-password.service"; import { diff --git a/libs/auth/src/common/services/login-strategies/login-strategy.service.ts b/libs/auth/src/common/services/login-strategies/login-strategy.service.ts index 6964e871e1f..2adea85a9ec 100644 --- a/libs/auth/src/common/services/login-strategies/login-strategy.service.ts +++ b/libs/auth/src/common/services/login-strategies/login-strategy.service.ts @@ -12,7 +12,6 @@ import { import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { AuthenticationType } from "@bitwarden/common/auth/enums/authentication-type"; @@ -20,6 +19,7 @@ import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { TokenTwoFactorRequest } from "@bitwarden/common/auth/models/request/identity-token/token-two-factor.request"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { EncryptService } from "@bitwarden/common/key-management/crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { KeyConnectorService } from "@bitwarden/common/key-management/key-connector/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout"; diff --git a/libs/common/src/abstractions/api.service.ts b/libs/common/src/abstractions/api.service.ts index cfef1faa7ba..f186787f7c0 100644 --- a/libs/common/src/abstractions/api.service.ts +++ b/libs/common/src/abstractions/api.service.ts @@ -51,7 +51,6 @@ import { PasswordlessAuthRequest } from "../auth/models/request/passwordless-aut import { SecretVerificationRequest } from "../auth/models/request/secret-verification.request"; import { TwoFactorEmailRequest } from "../auth/models/request/two-factor-email.request"; import { TwoFactorProviderRequest } from "../auth/models/request/two-factor-provider.request"; -import { TwoFactorRecoveryRequest } from "../auth/models/request/two-factor-recovery.request"; import { UpdateProfileRequest } from "../auth/models/request/update-profile.request"; import { UpdateTwoFactorAuthenticatorRequest } from "../auth/models/request/update-two-factor-authenticator.request"; import { UpdateTwoFactorDuoRequest } from "../auth/models/request/update-two-factor-duo.request"; @@ -344,7 +343,6 @@ export abstract class ApiService { organizationId: string, request: TwoFactorProviderRequest, ) => Promise; - postTwoFactorRecover: (request: TwoFactorRecoveryRequest) => Promise; postTwoFactorEmailSetup: (request: TwoFactorEmailRequest) => Promise; postTwoFactorEmail: (request: TwoFactorEmailRequest) => Promise; getDeviceVerificationSettings: () => Promise; diff --git a/libs/common/src/auth/models/request/two-factor-recovery.request.ts b/libs/common/src/auth/models/request/two-factor-recovery.request.ts deleted file mode 100644 index 79ef6da280c..00000000000 --- a/libs/common/src/auth/models/request/two-factor-recovery.request.ts +++ /dev/null @@ -1,8 +0,0 @@ -// FIXME: Update this file to be type safe and remove this and next line -// @ts-strict-ignore -import { SecretVerificationRequest } from "./secret-verification.request"; - -export class TwoFactorRecoveryRequest extends SecretVerificationRequest { - recoveryCode: string; - email: string; -} diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 93d2c7b0ed9..e71e46dcd7f 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -44,7 +44,6 @@ export enum FeatureFlag { ResellerManagedOrgAlert = "PM-15814-alert-owners-of-reseller-managed-orgs", AccountDeprovisioningBanner = "pm-17120-account-deprovisioning-admin-console-banner", PM15179_AddExistingOrgsFromProviderPortal = "pm-15179-add-existing-orgs-from-provider-portal", - RecoveryCodeLogin = "pm-17128-recovery-code-login", PM12276_BreadcrumbEventLogs = "pm-12276-breadcrumbing-for-business-features", PM9115_TwoFactorFormPersistence = "pm-9115-two-factor-form-persistence", PM18794_ProviderPaymentMethod = "pm-18794-provider-payment-method", @@ -102,7 +101,6 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.ResellerManagedOrgAlert]: FALSE, [FeatureFlag.AccountDeprovisioningBanner]: FALSE, [FeatureFlag.PM15179_AddExistingOrgsFromProviderPortal]: FALSE, - [FeatureFlag.RecoveryCodeLogin]: FALSE, [FeatureFlag.PM12276_BreadcrumbEventLogs]: FALSE, [FeatureFlag.PM9115_TwoFactorFormPersistence]: FALSE, [FeatureFlag.PM18794_ProviderPaymentMethod]: FALSE, diff --git a/libs/common/src/auth/abstractions/device-trust.service.abstraction.ts b/libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts similarity index 88% rename from libs/common/src/auth/abstractions/device-trust.service.abstraction.ts rename to libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts index 2de63b36cc7..882625fa231 100644 --- a/libs/common/src/auth/abstractions/device-trust.service.abstraction.ts +++ b/libs/common/src/key-management/device-trust/abstractions/device-trust.service.abstraction.ts @@ -2,11 +2,10 @@ // @ts-strict-ignore import { Observable } from "rxjs"; -import { EncString } from "../../platform/models/domain/enc-string"; -import { UserId } from "../../types/guid"; -import { DeviceKey, UserKey } from "../../types/key"; - -import { DeviceResponse } from "./devices/responses/device.response"; +import { DeviceResponse } from "../../../auth/abstractions/devices/responses/device.response"; +import { EncString } from "../../../platform/models/domain/enc-string"; +import { UserId } from "../../../types/guid"; +import { DeviceKey, UserKey } from "../../../types/key"; export abstract class DeviceTrustServiceAbstraction { /** diff --git a/libs/common/src/auth/services/device-trust.service.implementation.ts b/libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts similarity index 89% rename from libs/common/src/auth/services/device-trust.service.implementation.ts rename to libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts index 4a1b901d5ef..579fe9360a6 100644 --- a/libs/common/src/auth/services/device-trust.service.implementation.ts +++ b/libs/common/src/key-management/device-trust/services/device-trust.service.implementation.ts @@ -5,30 +5,30 @@ import { firstValueFrom, map, Observable, Subject } from "rxjs"; import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common"; import { KeyService } from "@bitwarden/key-management"; -import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; -import { AppIdService } from "../../platform/abstractions/app-id.service"; -import { ConfigService } from "../../platform/abstractions/config/config.service"; -import { CryptoFunctionService } from "../../platform/abstractions/crypto-function.service"; -import { I18nService } from "../../platform/abstractions/i18n.service"; -import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; -import { LogService } from "../../platform/abstractions/log.service"; -import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service"; -import { AbstractStorageService } from "../../platform/abstractions/storage.service"; -import { StorageLocation } from "../../platform/enums"; -import { EncString } from "../../platform/models/domain/enc-string"; -import { StorageOptions } from "../../platform/models/domain/storage-options"; -import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; -import { DEVICE_TRUST_DISK_LOCAL, StateProvider, UserKeyDefinition } from "../../platform/state"; -import { UserId } from "../../types/guid"; -import { UserKey, DeviceKey } from "../../types/key"; -import { DeviceTrustServiceAbstraction } from "../abstractions/device-trust.service.abstraction"; -import { DeviceResponse } from "../abstractions/devices/responses/device.response"; -import { DevicesApiServiceAbstraction } from "../abstractions/devices-api.service.abstraction"; -import { SecretVerificationRequest } from "../models/request/secret-verification.request"; +import { DeviceResponse } from "../../../auth/abstractions/devices/responses/device.response"; +import { DevicesApiServiceAbstraction } from "../../../auth/abstractions/devices-api.service.abstraction"; +import { SecretVerificationRequest } from "../../../auth/models/request/secret-verification.request"; import { DeviceKeysUpdateRequest, UpdateDevicesTrustRequest, -} from "../models/request/update-devices-trust.request"; +} from "../../../auth/models/request/update-devices-trust.request"; +import { AppIdService } from "../../../platform/abstractions/app-id.service"; +import { ConfigService } from "../../../platform/abstractions/config/config.service"; +import { CryptoFunctionService } from "../../../platform/abstractions/crypto-function.service"; +import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; +import { LogService } from "../../../platform/abstractions/log.service"; +import { PlatformUtilsService } from "../../../platform/abstractions/platform-utils.service"; +import { AbstractStorageService } from "../../../platform/abstractions/storage.service"; +import { StorageLocation } from "../../../platform/enums"; +import { EncString } from "../../../platform/models/domain/enc-string"; +import { StorageOptions } from "../../../platform/models/domain/storage-options"; +import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; +import { DEVICE_TRUST_DISK_LOCAL, StateProvider, UserKeyDefinition } from "../../../platform/state"; +import { UserId } from "../../../types/guid"; +import { UserKey, DeviceKey } from "../../../types/key"; +import { EncryptService } from "../../crypto/abstractions/encrypt.service"; +import { DeviceTrustServiceAbstraction } from "../abstractions/device-trust.service.abstraction"; /** Uses disk storage so that the device key can persist after log out and tab removal. */ export const DEVICE_KEY = new UserKeyDefinition( diff --git a/libs/common/src/auth/services/device-trust.service.spec.ts b/libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts similarity index 93% rename from libs/common/src/auth/services/device-trust.service.spec.ts rename to libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts index e689c93395d..1893b097ec6 100644 --- a/libs/common/src/auth/services/device-trust.service.spec.ts +++ b/libs/common/src/key-management/device-trust/services/device-trust.service.spec.ts @@ -3,38 +3,38 @@ import { matches, mock } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom, of } from "rxjs"; -import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common"; +import { + UserDecryptionOptionsServiceAbstraction, + UserDecryptionOptions, +} from "@bitwarden/auth/common"; import { KeyService } from "@bitwarden/key-management"; -// FIXME: remove `src` and fix import -// eslint-disable-next-line no-restricted-imports -import { UserDecryptionOptions } from "../../../../auth/src/common/models/domain/user-decryption-options"; -import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service"; -import { FakeActiveUserState } from "../../../spec/fake-state"; -import { FakeStateProvider } from "../../../spec/fake-state-provider"; -import { DeviceType } from "../../enums"; -import { EncryptService } from "../../key-management/crypto/abstractions/encrypt.service"; -import { AppIdService } from "../../platform/abstractions/app-id.service"; -import { ConfigService } from "../../platform/abstractions/config/config.service"; -import { CryptoFunctionService } from "../../platform/abstractions/crypto-function.service"; -import { I18nService } from "../../platform/abstractions/i18n.service"; -import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; -import { LogService } from "../../platform/abstractions/log.service"; -import { PlatformUtilsService } from "../../platform/abstractions/platform-utils.service"; -import { AbstractStorageService } from "../../platform/abstractions/storage.service"; -import { StorageLocation } from "../../platform/enums"; -import { EncryptionType } from "../../platform/enums/encryption-type.enum"; -import { Utils } from "../../platform/misc/utils"; -import { EncString } from "../../platform/models/domain/enc-string"; -import { StorageOptions } from "../../platform/models/domain/storage-options"; -import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; -import { CsprngArray } from "../../types/csprng"; -import { UserId } from "../../types/guid"; -import { DeviceKey, UserKey } from "../../types/key"; -import { DeviceResponse } from "../abstractions/devices/responses/device.response"; -import { DevicesApiServiceAbstraction } from "../abstractions/devices-api.service.abstraction"; -import { UpdateDevicesTrustRequest } from "../models/request/update-devices-trust.request"; -import { ProtectedDeviceResponse } from "../models/response/protected-device.response"; +import { FakeAccountService, mockAccountServiceWith } from "../../../../spec/fake-account-service"; +import { FakeActiveUserState } from "../../../../spec/fake-state"; +import { FakeStateProvider } from "../../../../spec/fake-state-provider"; +import { DeviceResponse } from "../../../auth/abstractions/devices/responses/device.response"; +import { DevicesApiServiceAbstraction } from "../../../auth/abstractions/devices-api.service.abstraction"; +import { UpdateDevicesTrustRequest } from "../../../auth/models/request/update-devices-trust.request"; +import { ProtectedDeviceResponse } from "../../../auth/models/response/protected-device.response"; +import { DeviceType } from "../../../enums"; +import { AppIdService } from "../../../platform/abstractions/app-id.service"; +import { ConfigService } from "../../../platform/abstractions/config/config.service"; +import { CryptoFunctionService } from "../../../platform/abstractions/crypto-function.service"; +import { I18nService } from "../../../platform/abstractions/i18n.service"; +import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; +import { LogService } from "../../../platform/abstractions/log.service"; +import { PlatformUtilsService } from "../../../platform/abstractions/platform-utils.service"; +import { AbstractStorageService } from "../../../platform/abstractions/storage.service"; +import { StorageLocation } from "../../../platform/enums"; +import { EncryptionType } from "../../../platform/enums/encryption-type.enum"; +import { Utils } from "../../../platform/misc/utils"; +import { EncString } from "../../../platform/models/domain/enc-string"; +import { StorageOptions } from "../../../platform/models/domain/storage-options"; +import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key"; +import { CsprngArray } from "../../../types/csprng"; +import { UserId } from "../../../types/guid"; +import { DeviceKey, UserKey } from "../../../types/key"; +import { EncryptService } from "../../crypto/abstractions/encrypt.service"; import { SHOULD_TRUST_DEVICE, diff --git a/libs/common/src/platform/state/state-definitions.ts b/libs/common/src/platform/state/state-definitions.ts index 82cb8bb1e37..b37aeb442ed 100644 --- a/libs/common/src/platform/state/state-definitions.ts +++ b/libs/common/src/platform/state/state-definitions.ts @@ -131,6 +131,10 @@ export const THEMING_DISK = new StateDefinition("theming", "disk", { web: "disk- export const TRANSLATION_DISK = new StateDefinition("translation", "disk", { web: "disk-local" }); export const ANIMATION_DISK = new StateDefinition("animation", "disk"); export const TASK_SCHEDULER_DISK = new StateDefinition("taskScheduler", "disk"); +export const EXTENSION_INITIAL_INSTALL_DISK = new StateDefinition( + "extensionInitialInstall", + "disk", +); // Design System diff --git a/libs/common/src/services/api.service.ts b/libs/common/src/services/api.service.ts index db4e5fdbc8f..2ff2fb01c87 100644 --- a/libs/common/src/services/api.service.ts +++ b/libs/common/src/services/api.service.ts @@ -59,7 +59,6 @@ import { PasswordlessAuthRequest } from "../auth/models/request/passwordless-aut import { SecretVerificationRequest } from "../auth/models/request/secret-verification.request"; import { TwoFactorEmailRequest } from "../auth/models/request/two-factor-email.request"; import { TwoFactorProviderRequest } from "../auth/models/request/two-factor-provider.request"; -import { TwoFactorRecoveryRequest } from "../auth/models/request/two-factor-recovery.request"; import { UpdateProfileRequest } from "../auth/models/request/update-profile.request"; import { UpdateTwoFactorAuthenticatorRequest } from "../auth/models/request/update-two-factor-authenticator.request"; import { UpdateTwoFactorDuoRequest } from "../auth/models/request/update-two-factor-duo.request"; @@ -1064,10 +1063,6 @@ export class ApiService implements ApiServiceAbstraction { return new TwoFactorProviderResponse(r); } - postTwoFactorRecover(request: TwoFactorRecoveryRequest): Promise { - return this.send("POST", "/two-factor/recover", request, false, false); - } - postTwoFactorEmailSetup(request: TwoFactorEmailRequest): Promise { return this.send("POST", "/two-factor/send-email", request, true, false); } diff --git a/libs/key-management-ui/src/lock/components/lock.component.ts b/libs/key-management-ui/src/lock/components/lock.component.ts index 68b2923ef6e..b50c7d23337 100644 --- a/libs/key-management-ui/src/lock/components/lock.component.ts +++ b/libs/key-management-ui/src/lock/components/lock.component.ts @@ -19,7 +19,6 @@ import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { InternalPolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; @@ -28,6 +27,7 @@ import { MasterPasswordVerificationResponse, } from "@bitwarden/common/auth/types/verification"; import { ClientType, DeviceType } from "@bitwarden/common/enums"; +import { DeviceTrustServiceAbstraction } from "@bitwarden/common/key-management/device-trust/abstractions/device-trust.service.abstraction"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/key-management/master-password/abstractions/master-password.service.abstraction"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; diff --git a/package-lock.json b/package-lock.json index 023b36afadc..eaf5c0f24ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "@angular/platform-browser": "18.2.13", "@angular/platform-browser-dynamic": "18.2.13", "@angular/router": "18.2.13", - "@bitwarden/sdk-internal": "0.2.0-main.107", + "@bitwarden/sdk-internal": "0.2.0-main.124", "@electron/fuses": "1.8.0", "@emotion/css": "11.13.5", "@koa/multer": "3.0.2", @@ -43,7 +43,7 @@ "commander": "11.1.0", "core-js": "3.40.0", "form-data": "4.0.1", - "https-proxy-agent": "7.0.5", + "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", "jquery": "3.7.1", "jsdom": "26.0.0", @@ -204,7 +204,7 @@ "chalk": "4.1.2", "commander": "11.1.0", "form-data": "4.0.1", - "https-proxy-agent": "7.0.5", + "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", "jsdom": "26.0.0", "jszip": "3.10.1", @@ -759,6 +759,16 @@ "@types/send": "*" } }, + "node_modules/@angular-devkit/build-angular/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/babel-loader": { "version": "9.1.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", @@ -880,6 +890,20 @@ "node": ">= 6" } }, + "node_modules/@angular-devkit/build-angular/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@angular-devkit/build-angular/node_modules/immutable": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", @@ -2090,6 +2114,16 @@ "semver": "bin/semver.js" } }, + "node_modules/@angular/build/node_modules/agent-base": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/@angular/build/node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -2135,6 +2169,20 @@ "node": ">= 6" } }, + "node_modules/@angular/build/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/@angular/build/node_modules/immutable": { "version": "4.3.7", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", @@ -4650,10 +4698,9 @@ "link": true }, "node_modules/@bitwarden/sdk-internal": { - "version": "0.2.0-main.107", - "resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.107.tgz", - "integrity": "sha512-xpOF6NAS0/em3jFBv4FI1ASy1Nuc7I1v41TVmG56wS+80y+NH1RnfGjp+a+XiO7Xxh3jssrxmjzihJjWQQA0rg==", - "license": "GPL-3.0" + "version": "0.2.0-main.124", + "resolved": "https://registry.npmjs.org/@bitwarden/sdk-internal/-/sdk-internal-0.2.0-main.124.tgz", + "integrity": "sha512-7F+DlPFng/thT4EVIQk2tRC7kff6G2B7alHAIxBdioJc9vE64Z5R5pviUyMZzqLnA5e9y8EnQdtWsQzUkHxisQ==" }, "node_modules/@bitwarden/send-ui": { "resolved": "libs/tools/send/send-ui", @@ -21272,12 +21319,12 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { - "agent-base": "^7.0.2", + "agent-base": "^7.1.2", "debug": "4" }, "engines": { @@ -24154,19 +24201,6 @@ "node": ">= 14" } }, - "node_modules/jsdom/node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/jsdom/node_modules/tough-cookie": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.1.tgz", diff --git a/package.json b/package.json index 571ec82fcda..943fde5fcf3 100644 --- a/package.json +++ b/package.json @@ -154,7 +154,7 @@ "@angular/platform-browser": "18.2.13", "@angular/platform-browser-dynamic": "18.2.13", "@angular/router": "18.2.13", - "@bitwarden/sdk-internal": "0.2.0-main.107", + "@bitwarden/sdk-internal": "0.2.0-main.124", "@electron/fuses": "1.8.0", "@emotion/css": "11.13.5", "@koa/multer": "3.0.2", @@ -173,7 +173,7 @@ "commander": "11.1.0", "core-js": "3.40.0", "form-data": "4.0.1", - "https-proxy-agent": "7.0.5", + "https-proxy-agent": "7.0.6", "inquirer": "8.2.6", "jquery": "3.7.1", "jsdom": "26.0.0",