From 9e15f7dc29892518d4fe1726eae30d377a876047 Mon Sep 17 00:00:00 2001 From: Opeyemi Date: Wed, 20 Nov 2024 07:05:46 -0800 Subject: [PATCH 01/16] [BRE-443] - Fix Linting pre bwwl Deployment (#12066) --- .github/workflows/build-cli.yml | 4 ++-- .github/workflows/build-desktop.yml | 2 +- .github/workflows/deploy-web.yml | 6 ++++-- .github/workflows/test.yml | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index 883dc61f49f..d480879fb15 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -72,7 +72,7 @@ jobs: echo "node_version=$NODE_VERSION" >> $GITHUB_OUTPUT cli: - name: "${{ matrix.os.base }} - ${{ matrix.license_type.readable }}" + name: CLI ${{ matrix.os.base }} - ${{ matrix.license_type.readable }} strategy: matrix: os: @@ -177,7 +177,7 @@ jobs: if-no-files-found: error cli-windows: - name: "windows - ${{ matrix.license_type.readable }}" + name: Windows - ${{ matrix.license_type.readable }} strategy: matrix: license_type: diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 27995f1c787..dc15f841c2b 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -272,7 +272,7 @@ jobs: name: ${{ needs.setup.outputs.release_channel }}-linux.yml path: apps/desktop/dist/${{ needs.setup.outputs.release_channel }}-linux.yml if-no-files-found: error - + - name: Build flatpak working-directory: apps/desktop run: | diff --git a/.github/workflows/deploy-web.yml b/.github/workflows/deploy-web.yml index 5cc4eb90861..b5e84ff875b 100644 --- a/.github/workflows/deploy-web.yml +++ b/.github/workflows/deploy-web.yml @@ -266,7 +266,8 @@ jobs: channel_id: ${{ steps.slack-message.outputs.channel_id }} ts: ${{ steps.slack-message.outputs.ts }} steps: - - uses: bitwarden/gh-actions/report-deployment-status-to-slack@main + - name: Notify Slack with start message + uses: bitwarden/gh-actions/report-deployment-status-to-slack@main id: slack-message with: project: Clients @@ -419,7 +420,8 @@ jobs: - azure-deploy - artifact-check steps: - - uses: bitwarden/gh-actions/report-deployment-status-to-slack@main + - name: Notify Slack with result + uses: bitwarden/gh-actions/report-deployment-status-to-slack@main with: project: Clients environment: ${{ needs.setup.outputs.environment-name }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0c324cb8748..72bc3594beb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -98,14 +98,14 @@ jobs: rust: name: Run Rust tests on ${{ matrix.os }} - runs-on: ${{ matrix.os || 'ubuntu-latest' }} + runs-on: ${{ matrix.os || 'ubuntu-22.04' }} permissions: contents: read strategy: matrix: os: - - ubuntu-latest + - ubuntu-22.04 - macos-latest - windows-latest From e073c47c17f5e896f3df93ff6989c251c19c6198 Mon Sep 17 00:00:00 2001 From: Alec Rippberger <127791530+alec-livefront@users.noreply.github.com> Date: Wed, 20 Nov 2024 09:56:40 -0600 Subject: [PATCH 02/16] Remove `startWith` to prevent log out toast warning from showing on page init (#12044) --- .../src/auth/popup/settings/account-security.component.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/browser/src/auth/popup/settings/account-security.component.ts b/apps/browser/src/auth/popup/settings/account-security.component.ts index 1617ed84767..68b46ad8810 100644 --- a/apps/browser/src/auth/popup/settings/account-security.component.ts +++ b/apps/browser/src/auth/popup/settings/account-security.component.ts @@ -215,7 +215,6 @@ export class AccountSecurityComponent implements OnInit, OnDestroy { this.form.controls.vaultTimeoutAction.valueChanges .pipe( - startWith(initialValues.vaultTimeoutAction), // emit to init pairwise map(async (value) => { await this.saveVaultTimeoutAction(value); }), From 234a832fc445e43d799989a93bbd78428542f06e Mon Sep 17 00:00:00 2001 From: Alec Rippberger <127791530+alec-livefront@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:45:00 -0600 Subject: [PATCH 03/16] /register does not redirect to /signup when email-verification flag is enabled (#12001) * Manually route to signup page when the email verification feature flag is enabled * Revert "Manually route to signup page when the email verification feature flag is enabled" This reverts commit f3a2b412b948cf47f86739df41acad851c6c2ff4. * Do not show toast when redirecting to signup --- apps/web/src/app/oss-routing.module.ts | 2 +- .../src/platform/guard/feature-flag.guard.ts | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 614401e8708..20361c7edc2 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -112,7 +112,7 @@ const routes: Routes = [ path: "register", component: TrialInitiationComponent, canActivate: [ - canAccessFeature(FeatureFlag.EmailVerification, false, "/signup"), + canAccessFeature(FeatureFlag.EmailVerification, false, "/signup", false), unauthGuardFn(), ], data: { titleId: "createAccount" } satisfies RouteDataProperties, diff --git a/libs/angular/src/platform/guard/feature-flag.guard.ts b/libs/angular/src/platform/guard/feature-flag.guard.ts index 1f82d810e36..65a29e4d8d8 100644 --- a/libs/angular/src/platform/guard/feature-flag.guard.ts +++ b/libs/angular/src/platform/guard/feature-flag.guard.ts @@ -16,11 +16,13 @@ type FlagValue = boolean | number | string; * @param featureFlag - The feature flag to check * @param requiredFlagValue - Optional value to the feature flag must be equal to, defaults to true * @param redirectUrlOnDisabled - Optional url to redirect to if the feature flag is disabled + * @param showToast - Optional boolean to show a toast if the feature flag is disabled - defaults to true */ export const canAccessFeature = ( featureFlag: FeatureFlag, requiredFlagValue: FlagValue = true, redirectUrlOnDisabled?: string, + showToast = true, ): CanActivateFn => { return async () => { const configService = inject(ConfigService); @@ -36,11 +38,13 @@ export const canAccessFeature = ( return true; } - toastService.showToast({ - variant: "error", - title: null, - message: i18nService.t("accessDenied"), - }); + if (showToast) { + toastService.showToast({ + variant: "error", + title: null, + message: i18nService.t("accessDenied"), + }); + } if (redirectUrlOnDisabled != null) { return router.createUrlTree([redirectUrlOnDisabled]); From 365c7dd65e40b6f5cf192bef540d8cd509e8870a Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Thu, 21 Nov 2024 04:06:07 +1000 Subject: [PATCH 04/16] [CL] add `hideIfEmpty` input to bit-nav-group (#12046) --- .../src/navigation/nav-group.component.html | 98 ++++++++++--------- .../src/navigation/nav-group.component.ts | 7 ++ .../src/navigation/nav-group.stories.ts | 24 +++++ 3 files changed, 81 insertions(+), 48 deletions(-) diff --git a/libs/components/src/navigation/nav-group.component.html b/libs/components/src/navigation/nav-group.component.html index c22a067ffed..9f6d9ac034d 100644 --- a/libs/components/src/navigation/nav-group.component.html +++ b/libs/components/src/navigation/nav-group.component.html @@ -1,54 +1,56 @@ - - - - + + + + + - - - - - - - + + - - + + + + + + + - - -
- -
+ + +
+ +
+
diff --git a/libs/components/src/navigation/nav-group.component.ts b/libs/components/src/navigation/nav-group.component.ts index 1ebe7338648..07494c0b7da 100644 --- a/libs/components/src/navigation/nav-group.component.ts +++ b/libs/components/src/navigation/nav-group.component.ts @@ -1,5 +1,6 @@ import { AfterContentInit, + booleanAttribute, Component, ContentChildren, EventEmitter, @@ -40,6 +41,12 @@ export class NavGroupComponent extends NavBaseComponent implements AfterContentI @Input() open = false; + /** + * Automatically hide the nav group if there are no child buttons + */ + @Input({ transform: booleanAttribute }) + hideIfEmpty = false; + @Output() openChange = new EventEmitter(); diff --git a/libs/components/src/navigation/nav-group.stories.ts b/libs/components/src/navigation/nav-group.stories.ts index de150ebc0d7..a6fa53ff187 100644 --- a/libs/components/src/navigation/nav-group.stories.ts +++ b/libs/components/src/navigation/nav-group.stories.ts @@ -88,6 +88,30 @@ export const Default: StoryObj = { }), }; +export const HideEmptyGroups: StoryObj = { + args: { + hideIfEmpty: true, + renderChildren: false, + }, + render: (args) => ({ + props: args, + template: /*html*/ ` + + + + + + + + + + + + + `, + }), +}; + export const Tree: StoryObj = { render: (args) => ({ props: args, From d1499da7932cbc4ebc1407d0ca3ed435003320d5 Mon Sep 17 00:00:00 2001 From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com> Date: Wed, 20 Nov 2024 13:54:27 -0500 Subject: [PATCH 05/16] Auth/PM-12077 - Web Process Reload (#11781) * PM-12077 - Initial work on web process reload - more testing required. * PM-12077 - Clarify comment * PM-12077 - Improving UX of logout with process reload. * PM-12077 - Final tweaks for process reload * PM-12077 - Remove no longer accurate comment. * PM-12077 - Per PR feedback, clean up logout reason --------- Co-authored-by: Matt Bishop --- .../browser/src/background/main.background.ts | 4 +- .../src/app/services/services.module.ts | 4 +- apps/web/src/app/app.component.html | 20 ++++++- apps/web/src/app/app.component.ts | 60 ++++++++----------- apps/web/src/app/core/core.module.ts | 7 +++ .../services/web-process-reload.service.ts | 14 +++++ apps/web/src/index.html | 1 + libs/angular/src/auth/guards/lock.guard.ts | 6 ++ ...e.ts => default-process-reload.service.ts} | 2 +- 9 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 apps/web/src/app/key-management/services/web-process-reload.service.ts rename libs/common/src/key-management/services/{process-reload.service.ts => default-process-reload.service.ts} (97%) diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index fdfd5740ba0..a74f187c766 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -76,7 +76,7 @@ import { DefaultBillingAccountProfileStateService } from "@bitwarden/common/bill import { ClientType } from "@bitwarden/common/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; -import { ProcessReloadService } from "@bitwarden/common/key-management/services/process-reload.service"; +import { DefaultProcessReloadService } from "@bitwarden/common/key-management/services/default-process-reload.service"; import { AppIdService as AppIdServiceAbstraction } from "@bitwarden/common/platform/abstractions/app-id.service"; import { ConfigApiServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config-api.service.abstraction"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; @@ -1068,7 +1068,7 @@ export default class MainBackground { this.taskSchedulerService, ); - this.processReloadService = new ProcessReloadService( + this.processReloadService = new DefaultProcessReloadService( this.pinService, this.messagingService, systemUtilsServiceReloadCallback, diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index a2195fbd5a8..d07feabd3b2 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -50,7 +50,7 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/ import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; import { ClientType } from "@bitwarden/common/enums"; import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; -import { ProcessReloadService } from "@bitwarden/common/key-management/services/process-reload.service"; +import { DefaultProcessReloadService } from "@bitwarden/common/key-management/services/default-process-reload.service"; import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -221,7 +221,7 @@ const safeProviders: SafeProvider[] = [ }), safeProvider({ provide: ProcessReloadServiceAbstraction, - useClass: ProcessReloadService, + useClass: DefaultProcessReloadService, deps: [ PinServiceAbstraction, MessagingServiceAbstraction, diff --git a/apps/web/src/app/app.component.html b/apps/web/src/app/app.component.html index 0680b43f9c6..a39c045e0e3 100644 --- a/apps/web/src/app/app.component.html +++ b/apps/web/src/app/app.component.html @@ -1 +1,19 @@ - + + +
+ Bitwarden +
+ +
+
+
+ + + + diff --git a/apps/web/src/app/app.component.ts b/apps/web/src/app/app.component.ts index 704960c14c6..468ae88e0c6 100644 --- a/apps/web/src/app/app.component.ts +++ b/apps/web/src/app/app.component.ts @@ -6,7 +6,6 @@ import * as jq from "jquery"; import { Subject, filter, firstValueFrom, map, takeUntil, timeout, catchError, of } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; -import { LogoutReason } from "@bitwarden/auth/common"; import { EventUploadService } from "@bitwarden/common/abstractions/event/event-upload.service"; import { NotificationsService } from "@bitwarden/common/abstractions/notifications.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; @@ -17,6 +16,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; +import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -28,7 +28,7 @@ import { StateEventRunnerService } from "@bitwarden/common/platform/state"; import { SyncService } from "@bitwarden/common/platform/sync"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { InternalFolderService } from "@bitwarden/common/vault/abstractions/folder/folder.service.abstraction"; -import { DialogService, ToastOptions, ToastService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { KeyService, BiometricStateService } from "@bitwarden/key-management"; @@ -60,6 +60,8 @@ export class AppComponent implements OnDestroy, OnInit { private isIdle = false; private destroy$ = new Subject(); + loading = false; + constructor( @Inject(DOCUMENT) private document: Document, private broadcasterService: BroadcasterService, @@ -91,6 +93,7 @@ export class AppComponent implements OnDestroy, OnInit { private accountService: AccountService, private logService: LogService, private sdkService: SdkService, + private processReloadService: ProcessReloadServiceAbstraction, ) { if (flagEnabled("sdk")) { // Warn if the SDK for some reason can't be initialized @@ -161,7 +164,8 @@ export class AppComponent implements OnDestroy, OnInit { this.router.navigate(["/"]); break; case "logout": - await this.logOut(message.logoutReason, message.redirect); + // note: the message.logoutReason isn't consumed anymore because of the process reload clearing any toasts. + await this.logOut(message.redirect); break; case "lockVault": await this.vaultTimeoutService.lock(); @@ -170,9 +174,8 @@ export class AppComponent implements OnDestroy, OnInit { // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. // eslint-disable-next-line @typescript-eslint/no-floating-promises this.notificationsService.updateConnection(false); - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["lock"]); + + await this.processReloadService.startProcessReload(this.authService); break; case "lockedUrl": break; @@ -272,33 +275,16 @@ export class AppComponent implements OnDestroy, OnInit { this.destroy$.complete(); } - private async displayLogoutReason(logoutReason: LogoutReason) { - let toastOptions: ToastOptions; - switch (logoutReason) { - case "invalidSecurityStamp": - case "sessionExpired": { - toastOptions = { - variant: "warning", - title: this.i18nService.t("loggedOut"), - message: this.i18nService.t("loginExpired"), - }; - break; - } - default: { - toastOptions = { - variant: "info", - title: this.i18nService.t("loggedOut"), - message: this.i18nService.t("loggedOutDesc"), - }; - break; - } - } + private async logOut(redirect = true) { + // Ensure the loading state is applied before proceeding to avoid a flash + // of the login screen before the process reload fires. + this.ngZone.run(() => { + this.loading = true; + document.body.classList.add("layout_frontend"); + }); - this.toastService.showToast(toastOptions); - } - - private async logOut(logoutReason: LogoutReason, redirect = true) { - await this.displayLogoutReason(logoutReason); + // Note: we don't display a toast logout reason anymore as the process reload + // will prevent any toasts from being displayed long enough to be read await this.eventUploadService.uploadEvents(); const userId = await firstValueFrom(this.accountService.activeAccount$.pipe(map((a) => a?.id))); @@ -334,10 +320,14 @@ export class AppComponent implements OnDestroy, OnInit { await logoutPromise; if (redirect) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.router.navigate(["/"]); + await this.router.navigate(["/"]); } + + await this.processReloadService.startProcessReload(this.authService); + + // Normally we would need to reset the loading state to false or remove the layout_frontend + // class from the body here, but the process reload completely reloads the app so + // it handles it. }, userId); } diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index d1fa3f8ba8c..2209a10d58c 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -49,6 +49,7 @@ import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { ClientType } from "@bitwarden/common/enums"; +import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; import { AppIdService } from "@bitwarden/common/platform/abstractions/app-id.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; @@ -95,6 +96,7 @@ import { import { AcceptOrganizationInviteService } from "../auth/organization-invite/accept-organization.service"; import { HtmlStorageService } from "../core/html-storage.service"; import { I18nService } from "../core/i18n.service"; +import { WebProcessReloadService } from "../key-management/services/web-process-reload.service"; import { WebBiometricsService } from "../key-management/web-biometric.service"; import { WebEnvironmentService } from "../platform/web-environment.service"; import { WebMigrationRunner } from "../platform/web-migration-runner"; @@ -281,6 +283,11 @@ const safeProviders: SafeProvider[] = [ useClass: flagEnabled("sdk") ? WebSdkClientFactory : NoopSdkClientFactory, deps: [], }), + safeProvider({ + provide: ProcessReloadServiceAbstraction, + useClass: WebProcessReloadService, + deps: [WINDOW], + }), safeProvider({ provide: LoginEmailService, useClass: LoginEmailService, diff --git a/apps/web/src/app/key-management/services/web-process-reload.service.ts b/apps/web/src/app/key-management/services/web-process-reload.service.ts new file mode 100644 index 00000000000..c542c97c0e0 --- /dev/null +++ b/apps/web/src/app/key-management/services/web-process-reload.service.ts @@ -0,0 +1,14 @@ +import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; +import { ProcessReloadServiceAbstraction } from "@bitwarden/common/key-management/abstractions/process-reload.service"; + +export class WebProcessReloadService implements ProcessReloadServiceAbstraction { + constructor(private window: Window) {} + + async startProcessReload(authService: AuthService): Promise { + this.window.location.reload(); + } + + cancelProcessReload(): void { + return; + } +} diff --git a/apps/web/src/index.html b/apps/web/src/index.html index ce1a955b88c..0b8ea864914 100644 --- a/apps/web/src/index.html +++ b/apps/web/src/index.html @@ -15,6 +15,7 @@ +
Bitwarden
diff --git a/libs/angular/src/auth/guards/lock.guard.ts b/libs/angular/src/auth/guards/lock.guard.ts index 8665c09b1ee..244e9935281 100644 --- a/libs/angular/src/auth/guards/lock.guard.ts +++ b/libs/angular/src/auth/guards/lock.guard.ts @@ -42,6 +42,12 @@ export function lockGuard(): CanActivateFn { const activeUser = await firstValueFrom(accountService.activeAccount$); + // If no active user, redirect to root: + // scenario context: user logs out on lock screen and app will reload lock comp without active user + if (!activeUser) { + return router.createUrlTree(["/"]); + } + const authStatus = await firstValueFrom(authService.authStatusFor$(activeUser.id)); if (authStatus !== AuthenticationStatus.Locked) { return router.createUrlTree(["/"]); diff --git a/libs/common/src/key-management/services/process-reload.service.ts b/libs/common/src/key-management/services/default-process-reload.service.ts similarity index 97% rename from libs/common/src/key-management/services/process-reload.service.ts rename to libs/common/src/key-management/services/default-process-reload.service.ts index 2f25d63b0fd..63082493622 100644 --- a/libs/common/src/key-management/services/process-reload.service.ts +++ b/libs/common/src/key-management/services/default-process-reload.service.ts @@ -12,7 +12,7 @@ import { VaultTimeoutAction } from "../../enums/vault-timeout-action.enum"; import { UserId } from "../../types/guid"; import { ProcessReloadServiceAbstraction } from "../abstractions/process-reload.service"; -export class ProcessReloadService implements ProcessReloadServiceAbstraction { +export class DefaultProcessReloadService implements ProcessReloadServiceAbstraction { private reloadInterval: any = null; constructor( From 34e20b7ae86b0ac3737fd5e096303077dfa91a19 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:36:52 -0500 Subject: [PATCH 06/16] Update bank account verification to use statement descriptor (#12055) --- .../shared/payment/payment-v2.component.html | 6 +++--- .../verify-bank-account.component.html | 18 ++++++------------ .../verify-bank-account.component.ts | 16 ++++------------ apps/web/src/locales/en/messages.json | 9 +++++++++ .../request/verify-bank-account.request.ts | 8 +++----- 5 files changed, 25 insertions(+), 32 deletions(-) diff --git a/apps/web/src/app/billing/shared/payment/payment-v2.component.html b/apps/web/src/app/billing/shared/payment/payment-v2.component.html index 51fdb1738f5..9804e6bc86f 100644 --- a/apps/web/src/app/billing/shared/payment/payment-v2.component.html +++ b/apps/web/src/app/billing/shared/payment/payment-v2.component.html @@ -80,9 +80,9 @@ - - {{ "verifyBankAccountInitialDesc" | i18n }} {{ "verifyBankAccountFailureWarning" | i18n }} - + + {{ "verifyBankAccountWithStatementDescriptorWarning" | i18n }} +
{{ "routingNumber" | i18n }} diff --git a/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.html b/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.html index 1b09f4bed51..1367e6e3082 100644 --- a/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.html +++ b/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.html @@ -1,18 +1,12 @@ - -

{{ "verifyBankAccountDesc" | i18n }} {{ "verifyBankAccountFailureWarning" | i18n }}

+ +

{{ "verifyBankAccountWithStatementDescriptorInstructions" | i18n }}

- - {{ "amountX" | i18n: "1" }} - - $0. - - - {{ "amountX" | i18n: "2" }} - - $0. + + {{ "descriptorCode" | i18n }} + -
+ diff --git a/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.ts b/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.ts index 2f9e34f877b..6f98ddad35d 100644 --- a/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.ts +++ b/apps/web/src/app/billing/shared/verify-bank-account/verify-bank-account.component.ts @@ -16,25 +16,17 @@ export class VerifyBankAccountComponent { @Output() submitted = new EventEmitter(); protected formGroup = this.formBuilder.group({ - amount1: new FormControl(null, [ + descriptorCode: new FormControl(null, [ Validators.required, - Validators.min(0), - Validators.max(99), - ]), - amount2: new FormControl(null, [ - Validators.required, - Validators.min(0), - Validators.max(99), + Validators.minLength(6), + Validators.maxLength(6), ]), }); constructor(private formBuilder: FormBuilder) {} submit = async () => { - const request = new VerifyBankAccountRequest( - this.formGroup.value.amount1, - this.formGroup.value.amount2, - ); + const request = new VerifyBankAccountRequest(this.formGroup.value.descriptorCode); await this.onSubmit?.(request); this.submitted.emit(); }; diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index a0b4793916d..ff3f0505699 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -9751,5 +9751,14 @@ }, "freeFamiliesSponsorshipPolicyDesc": { "message": "Do not allow members to redeem a Families plan through this organization." + }, + "verifyBankAccountWithStatementDescriptorWarning": { + "message": "Payment with a bank account is only available to customers in the United States. You will be required to verify your bank account. We will make a micro-deposit within the next 1-2 business days. Enter the statement descriptor code from this deposit on the organization's billing page to verify the bank account. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + }, + "verifyBankAccountWithStatementDescriptorInstructions": { + "message": "We have made a micro-deposit to your bank account (this may take 1-2 business days). Enter the six-digit code starting with 'SM' found on the deposit description. Failure to verify the bank account will result in a missed payment and your subscription being suspended." + }, + "descriptorCode": { + "message": "Descriptor code" } } diff --git a/libs/common/src/billing/models/request/verify-bank-account.request.ts b/libs/common/src/billing/models/request/verify-bank-account.request.ts index cadf4b97099..ee85d1a2aad 100644 --- a/libs/common/src/billing/models/request/verify-bank-account.request.ts +++ b/libs/common/src/billing/models/request/verify-bank-account.request.ts @@ -1,9 +1,7 @@ export class VerifyBankAccountRequest { - amount1: number; - amount2: number; + descriptorCode: string; - constructor(amount1: number, amount2: number) { - this.amount1 = amount1; - this.amount2 = amount2; + constructor(descriptorCode: string) { + this.descriptorCode = descriptorCode; } } From eea460e39762f95bc476700ebf040bf0bf02bd1b Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 21 Nov 2024 04:16:44 -0800 Subject: [PATCH 07/16] Fix missing i18n (#12083) --- apps/browser/src/_locales/en/messages.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 26fe9186cfe..0dc93dd0b32 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1851,6 +1851,9 @@ "secureNotes": { "message": "Secure notes" }, + "sshKeys": { + "message": "SSH Keys" + }, "clear": { "message": "Clear", "description": "To clear something out. example: To clear browser history." From 38c4eeb27db8006715c8c54d393c33222f28c087 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 21 Nov 2024 04:45:28 -0800 Subject: [PATCH 08/16] [PM-14542] Move kdf to km ownership (#11877) * Move kdf to km ownership * Fix duplicate import * Remove whitespace * Fix double imports * Fix desktop build * Fix test error * Fix imports * Move ownership of kdftype to km * Fix imports --------- Co-authored-by: Matt Bishop --- apps/browser/src/auth/popup/lock.component.ts | 8 +++++-- .../browser/src/background/main.background.ts | 8 +++---- .../src/key-management/browser-key.service.ts | 2 +- .../src/popup/services/services.module.ts | 8 +++++-- apps/cli/src/auth/commands/login.command.ts | 3 +-- .../service-container/service-container.ts | 8 +++---- .../src/app/services/services.module.ts | 7 ++---- apps/desktop/src/auth/lock.component.spec.ts | 2 +- apps/desktop/src/auth/lock.component.ts | 8 +++++-- .../src/auth/set-password.component.ts | 3 +-- .../services/electron-key.service.spec.ts | 3 +-- .../platform/services/electron-key.service.ts | 7 ++++-- ...zation-user-reset-password.service.spec.ts | 4 ++-- ...rganization-user-reset-password.service.ts | 15 ++++++------ .../web-registration-finish.service.spec.ts | 3 +-- .../models/emergency-access.ts | 2 +- .../response/emergency-access.response.ts | 2 +- .../services/emergency-access.service.spec.ts | 4 ++-- .../services/emergency-access.service.ts | 15 ++++++------ .../account/change-email.component.ts | 3 +-- .../settings/change-password.component.ts | 3 +-- .../emergency-access-takeover.component.ts | 4 +--- .../change-kdf-confirmation.component.ts | 4 +--- .../change-kdf/change-kdf.component.ts | 8 +++---- apps/web/src/app/core/core.module.ts | 7 ++++-- .../services/vault-banners.service.spec.ts | 3 +-- .../services/vault-banners.service.ts | 4 +--- .../responses/organization-user.response.ts | 2 +- .../components/change-password.component.ts | 4 +--- .../src/auth/components/lock.component.ts | 8 +++++-- .../src/auth/components/register.component.ts | 3 +-- .../auth/components/set-password.component.ts | 4 +--- .../components/update-password.component.ts | 3 +-- .../update-temp-password.component.ts | 3 +-- .../src/services/jslib-services.module.ts | 24 +++++++++---------- .../input-password.component.ts | 3 +-- .../input-password/password-input-result.ts | 2 +- ...efault-registration-finish.service.spec.ts | 3 +-- .../default-set-password-jit.service.spec.ts | 4 +--- .../default-set-password-jit.service.ts | 4 +--- .../set-password-jit.service.abstraction.ts | 2 +- .../abstractions/pin.service.abstraction.ts | 2 +- .../auth-request-login.strategy.spec.ts | 3 +-- .../login-strategies/login.strategy.spec.ts | 3 +-- .../common/login-strategies/login.strategy.ts | 11 +++++---- .../password-login.strategy.spec.ts | 3 +-- .../sso-login.strategy.spec.ts | 3 +-- .../user-api-login.strategy.spec.ts | 3 +-- .../webauthn-login.strategy.spec.ts | 3 +-- .../login-strategy.service.spec.ts | 5 +--- .../login-strategy.service.ts | 16 ++++++------- .../pin/pin.service.implementation.ts | 3 +-- .../common/services/pin/pin.service.spec.ts | 3 +-- .../registration/register-finish.request.ts | 3 ++- .../request/set-key-connector-key.request.ts | 4 ++-- .../models/request/set-password.request.ts | 3 ++- .../response/identity-token.response.ts | 3 ++- .../auth/models/response/prelogin.response.ts | 3 ++- .../auth/services/key-connector.service.ts | 10 +++++--- .../user-verification.service.spec.ts | 5 ++-- .../user-verification.service.ts | 3 +-- libs/common/src/models/request/kdf.request.ts | 3 ++- .../src/models/request/register.request.ts | 3 ++- .../abstractions/key-generation.service.ts | 3 ++- libs/common/src/platform/enums/index.ts | 1 - .../services/key-generation.service.spec.ts | 3 ++- .../services/key-generation.service.ts | 4 ++-- .../services/sdk/default-sdk.service.spec.ts | 4 +--- .../services/sdk/default-sdk.service.ts | 5 +--- .../src/tools/send/services/send.service.ts | 4 ++-- libs/common/tsconfig.json | 9 +------ ...warden-password-protected-importer.spec.ts | 3 +-- .../bitwarden-password-protected-importer.ts | 16 ++++++------- .../src}/abstractions/kdf-config.service.ts | 5 ++-- .../src/abstractions/key.service.ts | 2 +- .../src}/enums/kdf-type.enum.ts | 0 libs/key-management/src/index.ts | 9 +++++++ .../src}/kdf-config.service.spec.ts | 19 +++++++++------ .../src}/kdf-config.service.ts | 14 ++++++----- libs/key-management/src/key.service.spec.ts | 5 ++-- libs/key-management/src/key.service.ts | 4 ++-- .../src/models}/kdf-config.ts | 4 ++-- .../src/services/base-vault-export.service.ts | 4 +--- .../individual-vault-export.service.spec.ts | 14 +++++------ .../individual-vault-export.service.ts | 3 +-- .../src/services/org-vault-export.service.ts | 3 +-- .../src/services/vault-export.service.spec.ts | 14 +++++------ 87 files changed, 232 insertions(+), 235 deletions(-) rename libs/{common/src/auth => key-management/src}/abstractions/kdf-config.service.ts (71%) rename libs/{common/src/platform => key-management/src}/enums/kdf-type.enum.ts (100%) rename libs/{common/src/auth/services => key-management/src}/kdf-config.service.spec.ts (91%) rename libs/{common/src/auth/services => key-management/src}/kdf-config.service.ts (76%) rename libs/{common/src/auth/models/domain => key-management/src/models}/kdf-config.ts (96%) diff --git a/apps/browser/src/auth/popup/lock.component.ts b/apps/browser/src/auth/popup/lock.component.ts index c7fb108de80..1d1ed619995 100644 --- a/apps/browser/src/auth/popup/lock.component.ts +++ b/apps/browser/src/auth/popup/lock.component.ts @@ -12,7 +12,6 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti 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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status"; @@ -25,7 +24,12 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; -import { KeyService, BiometricsService, BiometricStateService } from "@bitwarden/key-management"; +import { + KdfConfigService, + KeyService, + BiometricsService, + BiometricStateService, +} from "@bitwarden/key-management"; import { BiometricErrors, BiometricErrorTypes } from "../../models/biometricErrors"; import { BrowserRouterService } from "../../platform/popup/services/browser-router.service"; diff --git a/apps/browser/src/background/main.background.ts b/apps/browser/src/background/main.background.ts index a74f187c766..764304f4ff9 100644 --- a/apps/browser/src/background/main.background.ts +++ b/apps/browser/src/background/main.background.ts @@ -33,7 +33,6 @@ import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/aut 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 { KdfConfigService as kdfConfigServiceAbstraction } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; @@ -48,7 +47,6 @@ 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 { KdfConfigService } from "@bitwarden/common/auth/services/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; import { MasterPasswordService } from "@bitwarden/common/auth/services/master-password/master-password.service"; import { SsoLoginService } from "@bitwarden/common/auth/services/sso-login.service"; @@ -201,6 +199,8 @@ import { ImportServiceAbstraction, } from "@bitwarden/importer/core"; import { + DefaultKdfConfigService, + KdfConfigService, BiometricStateService, BiometricsService, DefaultBiometricStateService, @@ -369,7 +369,7 @@ export default class MainBackground { intraprocessMessagingSubject: Subject>>; userAutoUnlockKeyService: UserAutoUnlockKeyService; scriptInjectorService: BrowserScriptInjectorService; - kdfConfigService: kdfConfigServiceAbstraction; + kdfConfigService: KdfConfigService; offscreenDocumentService: OffscreenDocumentService; syncServiceListener: SyncServiceListener; themeStateService: DefaultThemeStateService; @@ -630,7 +630,7 @@ export default class MainBackground { runtimeNativeMessagingBackground, ); - this.kdfConfigService = new KdfConfigService(this.stateProvider); + this.kdfConfigService = new DefaultKdfConfigService(this.stateProvider); this.pinService = new PinService( this.accountService, diff --git a/apps/browser/src/key-management/browser-key.service.ts b/apps/browser/src/key-management/browser-key.service.ts index 1fa3e111fed..ad2524dbc4b 100644 --- a/apps/browser/src/key-management/browser-key.service.ts +++ b/apps/browser/src/key-management/browser-key.service.ts @@ -2,7 +2,6 @@ import { firstValueFrom } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -16,6 +15,7 @@ import { StateProvider } from "@bitwarden/common/platform/state"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; import { + KdfConfigService, DefaultKeyService, BiometricsService, BiometricStateService, diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index c4b79fcae58..9a1acb54ab7 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -34,7 +34,6 @@ import { AccountService as AccountServiceAbstraction, } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; @@ -105,7 +104,12 @@ import { TotpService as TotpServiceAbstraction } from "@bitwarden/common/vault/a import { TotpService } from "@bitwarden/common/vault/services/totp.service"; import { CompactModeService, DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { BiometricStateService, BiometricsService, KeyService } from "@bitwarden/key-management"; +import { + KdfConfigService, + KeyService, + BiometricStateService, + BiometricsService, +} from "@bitwarden/key-management"; import { PasswordRepromptService } from "@bitwarden/vault"; import { ForegroundLockService } from "../../auth/popup/accounts/foreground-lock.service"; diff --git a/apps/cli/src/auth/commands/login.command.ts b/apps/cli/src/auth/commands/login.command.ts index 57477ee2bc8..db7ddb2e51c 100644 --- a/apps/cli/src/auth/commands/login.command.ts +++ b/apps/cli/src/auth/commands/login.command.ts @@ -17,7 +17,6 @@ import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abs import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; @@ -37,7 +36,7 @@ import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/sym import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { NodeUtils } from "@bitwarden/node/node-utils"; import { Response } from "../../models/response"; diff --git a/apps/cli/src/service-container/service-container.ts b/apps/cli/src/service-container/service-container.ts index ae627e82e75..21e8f9f2082 100644 --- a/apps/cli/src/service-container/service-container.ts +++ b/apps/cli/src/service-container/service-container.ts @@ -33,14 +33,12 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv 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 { KdfConfigService as KdfConfigServiceAbstraction } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; 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 { DevicesApiServiceImplementation } from "@bitwarden/common/auth/services/devices-api.service.implementation"; -import { KdfConfigService } from "@bitwarden/common/auth/services/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; import { MasterPasswordService } from "@bitwarden/common/auth/services/master-password/master-password.service"; import { TokenService } from "@bitwarden/common/auth/services/token.service"; @@ -149,6 +147,8 @@ import { ImportServiceAbstraction, } from "@bitwarden/importer/core"; import { + DefaultKdfConfigService, + KdfConfigService, DefaultKeyService as KeyService, BiometricStateService, DefaultBiometricStateService, @@ -260,7 +260,7 @@ export class ServiceContainer { billingAccountProfileStateService: BillingAccountProfileStateService; providerApiService: ProviderApiServiceAbstraction; userAutoUnlockKeyService: UserAutoUnlockKeyService; - kdfConfigService: KdfConfigServiceAbstraction; + kdfConfigService: KdfConfigService; taskSchedulerService: TaskSchedulerService; sdkService: SdkService; cipherAuthorizationService: CipherAuthorizationService; @@ -407,7 +407,7 @@ export class ServiceContainer { this.logService, ); - this.kdfConfigService = new KdfConfigService(this.stateProvider); + this.kdfConfigService = new DefaultKdfConfigService(this.stateProvider); this.pinService = new PinService( this.accountService, diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index d07feabd3b2..2a11c78a579 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -41,10 +41,6 @@ import { AuthService, AuthService as AuthServiceAbstraction, } from "@bitwarden/common/auth/abstractions/auth.service"; -import { - KdfConfigService, - KdfConfigService as KdfConfigServiceAbstraction, -} from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; @@ -84,6 +80,7 @@ import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vau import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; import { + KdfConfigService, KeyService, KeyService as KeyServiceAbstraction, BiometricStateService, @@ -289,7 +286,7 @@ const safeProviders: SafeProvider[] = [ AccountServiceAbstraction, StateProvider, BiometricStateService, - KdfConfigServiceAbstraction, + KdfConfigService, ], }), safeProvider({ diff --git a/apps/desktop/src/auth/lock.component.spec.ts b/apps/desktop/src/auth/lock.component.spec.ts index b67a386845f..6890754fca9 100644 --- a/apps/desktop/src/auth/lock.component.spec.ts +++ b/apps/desktop/src/auth/lock.component.spec.ts @@ -15,7 +15,6 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti 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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; @@ -33,6 +32,7 @@ import { UserId } from "@bitwarden/common/types/guid"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; import { + KdfConfigService, KeyService, BiometricsService as AbstractBiometricService, BiometricStateService, diff --git a/apps/desktop/src/auth/lock.component.ts b/apps/desktop/src/auth/lock.component.ts index cc062965f35..f0323f3e7da 100644 --- a/apps/desktop/src/auth/lock.component.ts +++ b/apps/desktop/src/auth/lock.component.ts @@ -12,7 +12,6 @@ import { InternalPolicyService } from "@bitwarden/common/admin-console/abstracti 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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { DeviceType } from "@bitwarden/common/enums"; @@ -26,7 +25,12 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; -import { KeyService, BiometricsService, BiometricStateService } from "@bitwarden/key-management"; +import { + KdfConfigService, + KeyService, + BiometricsService, + BiometricStateService, +} from "@bitwarden/key-management"; const BroadcasterSubscriptionId = "LockComponent"; diff --git a/apps/desktop/src/auth/set-password.component.ts b/apps/desktop/src/auth/set-password.component.ts index 61ab198b613..902fa59791c 100644 --- a/apps/desktop/src/auth/set-password.component.ts +++ b/apps/desktop/src/auth/set-password.component.ts @@ -9,7 +9,6 @@ import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-conso import { PolicyApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy-api.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; @@ -23,7 +22,7 @@ import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; const BroadcasterSubscriptionId = "SetPasswordComponent"; diff --git a/apps/desktop/src/platform/services/electron-key.service.spec.ts b/apps/desktop/src/platform/services/electron-key.service.spec.ts index 8705f1fba6e..e85bfe4ee03 100644 --- a/apps/desktop/src/platform/services/electron-key.service.spec.ts +++ b/apps/desktop/src/platform/services/electron-key.service.spec.ts @@ -2,7 +2,6 @@ import { FakeStateProvider } from "@bitwarden/common/../spec/fake-state-provider import { mock } from "jest-mock-extended"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -15,7 +14,7 @@ import { makeEncString } from "@bitwarden/common/spec"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; -import { BiometricStateService } from "@bitwarden/key-management"; +import { KdfConfigService, BiometricStateService } from "@bitwarden/key-management"; import { FakeAccountService, diff --git a/apps/desktop/src/platform/services/electron-key.service.ts b/apps/desktop/src/platform/services/electron-key.service.ts index f7cfb3cf92f..c8beef76c0a 100644 --- a/apps/desktop/src/platform/services/electron-key.service.ts +++ b/apps/desktop/src/platform/services/electron-key.service.ts @@ -2,7 +2,6 @@ import { firstValueFrom } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -17,7 +16,11 @@ import { StateProvider } from "@bitwarden/common/platform/state"; import { CsprngString } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; -import { DefaultKeyService, BiometricStateService } from "@bitwarden/key-management"; +import { + KdfConfigService, + DefaultKeyService, + BiometricStateService, +} from "@bitwarden/key-management"; export class ElectronKeyService extends DefaultKeyService { constructor( diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts index feb95df40c3..1178b4d65e9 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.spec.ts @@ -10,13 +10,13 @@ import { OrganizationKeysResponse } from "@bitwarden/common/admin-console/models import { OrganizationApiService } from "@bitwarden/common/admin-console/services/organization/organization-api.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { EncryptionType, KdfType } from "@bitwarden/common/platform/enums"; +import { EncryptionType } from "@bitwarden/common/platform/enums"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey, OrgKey, MasterKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfType, KeyService } from "@bitwarden/key-management"; import { OrganizationUserResetPasswordService } from "./organization-user-reset-password.service"; diff --git a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts index 88cb75b087e..002a6613079 100644 --- a/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts +++ b/apps/web/src/app/admin-console/organizations/members/services/organization-user-reset-password/organization-user-reset-password.service.ts @@ -7,20 +7,21 @@ import { } from "@bitwarden/admin-console/common"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { - Argon2KdfConfig, - KdfConfig, - PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; -import { UserKeyRotationDataProvider, KeyService } from "@bitwarden/key-management"; +import { + Argon2KdfConfig, + KdfConfig, + PBKDF2KdfConfig, + UserKeyRotationDataProvider, + KeyService, + KdfType, +} from "@bitwarden/key-management"; @Injectable({ providedIn: "root", diff --git a/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts b/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts index 1c1e970b7eb..f2ea13832df 100644 --- a/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts +++ b/apps/web/src/app/auth/core/services/registration/web-registration-finish.service.spec.ts @@ -7,13 +7,12 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; import { AcceptOrganizationInviteService } from "../../../organization-invite/accept-organization.service"; import { OrganizationInvite } from "../../../organization-invite/organization-invite"; diff --git a/apps/web/src/app/auth/emergency-access/models/emergency-access.ts b/apps/web/src/app/auth/emergency-access/models/emergency-access.ts index adf77ed5730..fb56ee30311 100644 --- a/apps/web/src/app/auth/emergency-access/models/emergency-access.ts +++ b/apps/web/src/app/auth/emergency-access/models/emergency-access.ts @@ -1,5 +1,5 @@ -import { KdfType } from "@bitwarden/common/platform/enums"; import { CipherResponse } from "@bitwarden/common/vault/models/response/cipher.response"; +import { KdfType } from "@bitwarden/key-management"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; diff --git a/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts b/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts index 2d50da8fe30..1c58bd7dd5d 100644 --- a/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts +++ b/apps/web/src/app/auth/emergency-access/response/emergency-access.response.ts @@ -1,6 +1,6 @@ import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { CipherResponse } from "@bitwarden/common/vault/models/response/cipher.response"; +import { KdfType } from "@bitwarden/key-management"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts index c5aa27324dc..f790fae78dc 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.spec.ts @@ -8,14 +8,14 @@ import { BulkEncryptService } from "@bitwarden/common/platform/abstractions/bulk import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { EncryptionType, KdfType } from "@bitwarden/common/platform/enums"; +import { EncryptionType } from "@bitwarden/common/platform/enums"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfType, KeyService } from "@bitwarden/key-management"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; diff --git a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts index 39eb6570df9..0aea145fad2 100644 --- a/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts +++ b/apps/web/src/app/auth/emergency-access/services/emergency-access.service.ts @@ -3,17 +3,11 @@ import { Injectable } from "@angular/core"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyData } from "@bitwarden/common/admin-console/models/data/policy.data"; import { Policy } from "@bitwarden/common/admin-console/models/domain/policy"; -import { - Argon2KdfConfig, - KdfConfig, - PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { BulkEncryptService } from "@bitwarden/common/platform/abstractions/bulk-encrypt.service"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; @@ -22,7 +16,14 @@ import { UserKey } from "@bitwarden/common/types/key"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { UserKeyRotationDataProvider, KeyService } from "@bitwarden/key-management"; +import { + Argon2KdfConfig, + KdfConfig, + PBKDF2KdfConfig, + UserKeyRotationDataProvider, + KeyService, + KdfType, +} from "@bitwarden/key-management"; import { EmergencyAccessStatusType } from "../enums/emergency-access-status-type"; import { EmergencyAccessType } from "../enums/emergency-access-type"; diff --git a/apps/web/src/app/auth/settings/account/change-email.component.ts b/apps/web/src/app/auth/settings/account/change-email.component.ts index 734df682957..95e9dba884a 100644 --- a/apps/web/src/app/auth/settings/account/change-email.component.ts +++ b/apps/web/src/app/auth/settings/account/change-email.component.ts @@ -2,7 +2,6 @@ import { Component, OnInit } from "@angular/core"; import { FormBuilder, Validators } from "@angular/forms"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { TwoFactorProviderType } from "@bitwarden/common/auth/enums/two-factor-provider-type"; import { EmailTokenRequest } from "@bitwarden/common/auth/models/request/email-token.request"; import { EmailRequest } from "@bitwarden/common/auth/models/request/email.request"; @@ -12,7 +11,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; import { ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; @Component({ selector: "app-change-email", diff --git a/apps/web/src/app/auth/settings/change-password.component.ts b/apps/web/src/app/auth/settings/change-password.component.ts index f5f3e80b6bb..67cac277be9 100644 --- a/apps/web/src/app/auth/settings/change-password.component.ts +++ b/apps/web/src/app/auth/settings/change-password.component.ts @@ -7,7 +7,6 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { PasswordRequest } from "@bitwarden/common/auth/models/request/password.request"; @@ -23,7 +22,7 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { UserKeyRotationService } from "../../key-management/key-rotation/user-key-rotation.service"; diff --git a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts index c567508e050..44ad65ee7a2 100644 --- a/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts +++ b/apps/web/src/app/auth/settings/emergency-access/takeover/emergency-access-takeover.component.ts @@ -6,17 +6,15 @@ import { takeUntil } from "rxjs"; import { ChangePasswordComponent } from "@bitwarden/angular/auth/components/change-password.component"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfType, KdfConfigService, KeyService } from "@bitwarden/key-management"; import { EmergencyAccessService } from "../../../emergency-access"; diff --git a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts index 17954b3ee8b..a3eb2f8a2e1 100644 --- a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts +++ b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf-confirmation.component.ts @@ -5,14 +5,12 @@ import { firstValueFrom, map } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { KdfRequest } from "@bitwarden/common/models/request/kdf.request"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { ToastService } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfig, KdfType, KeyService } from "@bitwarden/key-management"; @Component({ selector: "app-change-kdf-confirmation", diff --git a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts index 45ceaeccd07..79f1d78dec8 100644 --- a/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts +++ b/apps/web/src/app/auth/settings/security/change-kdf/change-kdf.component.ts @@ -2,15 +2,15 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { FormBuilder, FormControl, ValidatorFn, Validators } from "@angular/forms"; import { Subject, takeUntil } from "rxjs"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; +import { DialogService } from "@bitwarden/components"; import { + KdfConfigService, Argon2KdfConfig, DEFAULT_KDF_CONFIG, KdfConfig, PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; -import { KdfType } from "@bitwarden/common/platform/enums"; -import { DialogService } from "@bitwarden/components"; + KdfType, +} from "@bitwarden/key-management"; import { ChangeKdfConfirmationComponent } from "./change-kdf-confirmation.component"; diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 2209a10d58c..cfca5659c38 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -45,7 +45,6 @@ import { import { AccountApiService as AccountApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/account-api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { ClientType } from "@bitwarden/common/enums"; @@ -83,7 +82,11 @@ import { } from "@bitwarden/common/platform/theming/theme-state.service"; import { VaultTimeout, VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService as KeyServiceAbstraction, BiometricsService } from "@bitwarden/key-management"; +import { + KdfConfigService, + KeyService as KeyServiceAbstraction, + BiometricsService, +} from "@bitwarden/key-management"; import { flagEnabled } from "../../utils/flags"; import { PolicyListService } from "../admin-console/core/policy-list.service"; diff --git a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts index c09451addda..9a5537985b8 100644 --- a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts +++ b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.spec.ts @@ -1,16 +1,15 @@ import { TestBed } from "@angular/core/testing"; import { BehaviorSubject, firstValueFrom } from "rxjs"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { StateProvider } from "@bitwarden/common/platform/state"; import { FakeStateProvider, mockAccountServiceWith } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { KdfConfigService, KdfType } from "@bitwarden/key-management"; import { PREMIUM_BANNER_REPROMPT_KEY, diff --git a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts index 172d81c48af..6ab37ea0cdd 100644 --- a/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts +++ b/apps/web/src/app/vault/individual-vault/vault-banners/services/vault-banners.service.ts @@ -2,13 +2,10 @@ import { Injectable } from "@angular/core"; import { Subject, Observable, combineLatest, firstValueFrom, map } from "rxjs"; import { mergeMap, take } from "rxjs/operators"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; -import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { StateProvider, ActiveUserState, @@ -17,6 +14,7 @@ import { UserKeyDefinition, } from "@bitwarden/common/platform/state"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; +import { PBKDF2KdfConfig, KdfConfigService, KdfType } from "@bitwarden/key-management"; export enum VisibleVaultBanner { KDFSettings = "kdf-settings", diff --git a/libs/admin-console/src/common/organization-user/models/responses/organization-user.response.ts b/libs/admin-console/src/common/organization-user/models/responses/organization-user.response.ts index f61d9325c2a..1e426696d92 100644 --- a/libs/admin-console/src/common/organization-user/models/responses/organization-user.response.ts +++ b/libs/admin-console/src/common/organization-user/models/responses/organization-user.response.ts @@ -5,7 +5,7 @@ import { import { PermissionsApi } from "@bitwarden/common/admin-console/models/api/permissions.api"; import { SelectionReadOnlyResponse } from "@bitwarden/common/admin-console/models/response/selection-read-only.response"; import { BaseResponse } from "@bitwarden/common/models/response/base.response"; -import { KdfType } from "@bitwarden/common/platform/enums"; +import { KdfType } from "@bitwarden/key-management"; export class OrganizationUserResponse extends BaseResponse { id: string; diff --git a/libs/angular/src/auth/components/change-password.component.ts b/libs/angular/src/auth/components/change-password.component.ts index 92b34c08f4a..dc181c54066 100644 --- a/libs/angular/src/auth/components/change-password.component.ts +++ b/libs/angular/src/auth/components/change-password.component.ts @@ -4,9 +4,7 @@ import { Subject, firstValueFrom, map, takeUntil } from "rxjs"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; -import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; @@ -16,7 +14,7 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfig, KdfConfigService, KeyService } from "@bitwarden/key-management"; import { PasswordColorText } from "../../tools/password-strength/password-strength.component"; diff --git a/libs/angular/src/auth/components/lock.component.ts b/libs/angular/src/auth/components/lock.component.ts index f28156803c1..f0d1163c24d 100644 --- a/libs/angular/src/auth/components/lock.component.ts +++ b/libs/angular/src/auth/components/lock.component.ts @@ -13,7 +13,6 @@ import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/mod 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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; @@ -35,7 +34,12 @@ import { UserId } from "@bitwarden/common/types/guid"; import { UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; -import { KeyService, BiometricStateService, BiometricsService } from "@bitwarden/key-management"; +import { + KdfConfigService, + KeyService, + BiometricStateService, + BiometricsService, +} from "@bitwarden/key-management"; @Directive() export class LockComponent implements OnInit, OnDestroy { diff --git a/libs/angular/src/auth/components/register.component.ts b/libs/angular/src/auth/components/register.component.ts index 94f60ff637e..ec78a1692ad 100644 --- a/libs/angular/src/auth/components/register.component.ts +++ b/libs/angular/src/auth/components/register.component.ts @@ -5,7 +5,6 @@ import { Router } from "@angular/router"; import { LoginStrategyServiceAbstraction, PasswordLoginCredentials } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { RegisterResponse } from "@bitwarden/common/auth/models/response/register.response"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { ReferenceEventRequest } from "@bitwarden/common/models/request/reference-event.request"; @@ -18,7 +17,7 @@ import { StateService } from "@bitwarden/common/platform/abstractions/state.serv import { Utils } from "@bitwarden/common/platform/misc/utils"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; import { AllValidationErrors, diff --git a/libs/angular/src/auth/components/set-password.component.ts b/libs/angular/src/auth/components/set-password.component.ts index 81981de79d2..b323f7ef1a4 100644 --- a/libs/angular/src/auth/components/set-password.component.ts +++ b/libs/angular/src/auth/components/set-password.component.ts @@ -15,11 +15,9 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { OrganizationAutoEnrollStatusResponse } from "@bitwarden/common/admin-console/models/response/organization-auto-enroll-status.response"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/sso-login.service.abstraction"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -35,7 +33,7 @@ import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { DEFAULT_KDF_CONFIG, KdfConfigService, KeyService } from "@bitwarden/key-management"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; diff --git a/libs/angular/src/auth/components/update-password.component.ts b/libs/angular/src/auth/components/update-password.component.ts index bc31be283e0..3c442b7913e 100644 --- a/libs/angular/src/auth/components/update-password.component.ts +++ b/libs/angular/src/auth/components/update-password.component.ts @@ -5,7 +5,6 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; @@ -20,7 +19,7 @@ import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; diff --git a/libs/angular/src/auth/components/update-temp-password.component.ts b/libs/angular/src/auth/components/update-temp-password.component.ts index 2019d6f73c9..e00e21fe811 100644 --- a/libs/angular/src/auth/components/update-temp-password.component.ts +++ b/libs/angular/src/auth/components/update-temp-password.component.ts @@ -6,7 +6,6 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { UserVerificationService } from "@bitwarden/common/auth/abstractions/user-verification/user-verification.service.abstraction"; import { VerificationType } from "@bitwarden/common/auth/enums/verification-type"; @@ -25,7 +24,7 @@ import { MasterKey, UserKey } from "@bitwarden/common/types/key"; import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { DialogService, ToastService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { ChangePasswordComponent as BaseChangePasswordComponent } from "./change-password.component"; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 251223d1bef..9d1cd6e502d 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -80,7 +80,6 @@ import { AvatarService as AvatarServiceAbstraction } from "@bitwarden/common/aut 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 { KdfConfigService as KdfConfigServiceAbstraction } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction, @@ -103,7 +102,6 @@ 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 { KdfConfigService } from "@bitwarden/common/auth/services/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/services/key-connector.service"; import { MasterPasswordService } from "@bitwarden/common/auth/services/master-password/master-password.service"; import { PasswordResetEnrollmentServiceImplementation } from "@bitwarden/common/auth/services/password-reset-enrollment.service.implementation"; @@ -277,6 +275,8 @@ import { DefaultKeyService as KeyService, BiometricStateService, DefaultBiometricStateService, + KdfConfigService, + DefaultKdfConfigService, } from "@bitwarden/key-management"; import { PasswordRepromptService } from "@bitwarden/vault"; import { @@ -436,7 +436,7 @@ const safeProviders: SafeProvider[] = [ GlobalStateProvider, BillingAccountProfileStateService, VaultTimeoutSettingsServiceAbstraction, - KdfConfigServiceAbstraction, + KdfConfigService, TaskSchedulerService, ], }), @@ -605,7 +605,7 @@ const safeProviders: SafeProvider[] = [ StateServiceAbstraction, AccountServiceAbstraction, StateProvider, - KdfConfigServiceAbstraction, + KdfConfigService, ], }), safeProvider({ @@ -824,7 +824,7 @@ const safeProviders: SafeProvider[] = [ KeyServiceAbstraction, EncryptService, CryptoFunctionServiceAbstraction, - KdfConfigServiceAbstraction, + KdfConfigService, AccountServiceAbstraction, ], }), @@ -839,7 +839,7 @@ const safeProviders: SafeProvider[] = [ EncryptService, CryptoFunctionServiceAbstraction, CollectionService, - KdfConfigServiceAbstraction, + KdfConfigService, AccountServiceAbstraction, ], }), @@ -966,7 +966,7 @@ const safeProviders: SafeProvider[] = [ LogService, VaultTimeoutSettingsServiceAbstraction, PlatformUtilsServiceAbstraction, - KdfConfigServiceAbstraction, + KdfConfigService, ], }), safeProvider({ @@ -1132,7 +1132,7 @@ const safeProviders: SafeProvider[] = [ AccountServiceAbstraction, CryptoFunctionServiceAbstraction, EncryptService, - KdfConfigServiceAbstraction, + KdfConfigService, KeyGenerationServiceAbstraction, LogService, MasterPasswordServiceAbstraction, @@ -1306,8 +1306,8 @@ const safeProviders: SafeProvider[] = [ deps: [ApiServiceAbstraction], }), safeProvider({ - provide: KdfConfigServiceAbstraction, - useClass: KdfConfigService, + provide: KdfConfigService, + useClass: DefaultKdfConfigService, deps: [StateProvider], }), safeProvider({ @@ -1318,7 +1318,7 @@ const safeProviders: SafeProvider[] = [ KeyServiceAbstraction, EncryptService, I18nServiceAbstraction, - KdfConfigServiceAbstraction, + KdfConfigService, InternalMasterPasswordServiceAbstraction, OrganizationApiServiceAbstraction, OrganizationUserApiService, @@ -1369,7 +1369,7 @@ const safeProviders: SafeProvider[] = [ EnvironmentService, PlatformUtilsServiceAbstraction, AccountServiceAbstraction, - KdfConfigServiceAbstraction, + KdfConfigService, KeyServiceAbstraction, ApiServiceAbstraction, ], diff --git a/libs/auth/src/angular/input-password/input-password.component.ts b/libs/auth/src/angular/input-password/input-password.component.ts index e110d2d53e3..8d5d4a56dcc 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -9,7 +9,6 @@ import { import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/models/domain/master-password-policy-options"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { HashPurpose } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -23,7 +22,7 @@ import { InputModule, ToastService, } from "@bitwarden/components"; -import { KeyService } from "@bitwarden/key-management"; +import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; import { InputsFieldMatch } from "../../../../angular/src/auth/validators/inputs-field-match.validator"; import { SharedModule } from "../../../../components/src/shared"; diff --git a/libs/auth/src/angular/input-password/password-input-result.ts b/libs/auth/src/angular/input-password/password-input-result.ts index 66bb338dc16..07157aaf4ca 100644 --- a/libs/auth/src/angular/input-password/password-input-result.ts +++ b/libs/auth/src/angular/input-password/password-input-result.ts @@ -1,5 +1,5 @@ -import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { MasterKey } from "@bitwarden/common/types/key"; +import { PBKDF2KdfConfig } from "@bitwarden/key-management"; export interface PasswordInputResult { masterKey: MasterKey; diff --git a/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts b/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts index e034e23de43..14600cebf1d 100644 --- a/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts +++ b/libs/auth/src/angular/registration/registration-finish/default-registration-finish.service.spec.ts @@ -1,12 +1,11 @@ import { MockProxy, mock } from "jest-mock-extended"; import { AccountApiService } from "@bitwarden/common/auth/abstractions/account-api.service"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; import { CsprngArray } from "@bitwarden/common/types/csprng"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { DEFAULT_KDF_CONFIG, KeyService } from "@bitwarden/key-management"; import { PasswordInputResult } from "../../input-password/password-input-result"; diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts index da49067d7b6..7a2b334eb42 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.spec.ts @@ -9,9 +9,7 @@ import { import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationKeysResponse } from "@bitwarden/common/admin-console/models/response/organization-keys.response"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -22,7 +20,7 @@ import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/sym import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { DEFAULT_KDF_CONFIG, KdfConfigService, KeyService } from "@bitwarden/key-management"; import { PasswordInputResult } from "../input-password/password-input-result"; diff --git a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts index 76477a0e5df..a2163025771 100644 --- a/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts +++ b/libs/auth/src/angular/set-password-jit/default-set-password-jit.service.ts @@ -7,10 +7,8 @@ import { import { InternalUserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; -import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { SetPasswordRequest } from "@bitwarden/common/auth/models/request/set-password.request"; import { KeysRequest } from "@bitwarden/common/models/request/keys.request"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -19,7 +17,7 @@ import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { PBKDF2KdfConfig, KdfConfigService, KeyService } from "@bitwarden/key-management"; import { SetPasswordCredentials, diff --git a/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts b/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts index 165b4a61805..fc0756458c9 100644 --- a/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts +++ b/libs/auth/src/angular/set-password-jit/set-password-jit.service.abstraction.ts @@ -1,6 +1,6 @@ -import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey } from "@bitwarden/common/types/key"; +import { PBKDF2KdfConfig } from "@bitwarden/key-management"; export interface SetPasswordCredentials { masterKey: MasterKey; diff --git a/libs/auth/src/common/abstractions/pin.service.abstraction.ts b/libs/auth/src/common/abstractions/pin.service.abstraction.ts index 00ccf934f61..eb1cfaf0ec3 100644 --- a/libs/auth/src/common/abstractions/pin.service.abstraction.ts +++ b/libs/auth/src/common/abstractions/pin.service.abstraction.ts @@ -1,7 +1,7 @@ -import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { EncString, EncryptedString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; import { PinKey, UserKey } from "@bitwarden/common/types/key"; +import { KdfConfig } from "@bitwarden/key-management"; import { PinLockType } from "../services"; 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 c0e7d2c00ae..cec4481cd8d 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 @@ -3,7 +3,6 @@ import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; 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"; @@ -23,7 +22,7 @@ import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/sp import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; import { AuthRequestLoginCredentials } from "../models/domain/login-credentials"; diff --git a/libs/auth/src/common/login-strategies/login.strategy.spec.ts b/libs/auth/src/common/login-strategies/login.strategy.spec.ts index 49140cc2cc0..50443bab0ea 100644 --- a/libs/auth/src/common/login-strategies/login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/login.strategy.spec.ts @@ -4,7 +4,6 @@ import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; 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"; @@ -38,7 +37,7 @@ import { import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { LoginStrategyServiceAbstraction } from "../abstractions"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; diff --git a/libs/auth/src/common/login-strategies/login.strategy.ts b/libs/auth/src/common/login-strategies/login.strategy.ts index 67a286d8195..e440e1d35b6 100644 --- a/libs/auth/src/common/login-strategies/login.strategy.ts +++ b/libs/auth/src/common/login-strategies/login.strategy.ts @@ -3,14 +3,12 @@ import { BehaviorSubject, filter, firstValueFrom, timeout } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.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"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; -import { Argon2KdfConfig, PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { DeviceRequest } from "@bitwarden/common/auth/models/request/identity-token/device.request"; import { PasswordTokenRequest } from "@bitwarden/common/auth/models/request/identity-token/password-token.request"; import { SsoTokenRequest } from "@bitwarden/common/auth/models/request/identity-token/sso-token.request"; @@ -30,10 +28,15 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Account, AccountProfile } from "@bitwarden/common/platform/models/domain/account"; import { UserId } from "@bitwarden/common/types/guid"; -import { KeyService } from "@bitwarden/key-management"; +import { + KeyService, + Argon2KdfConfig, + PBKDF2KdfConfig, + KdfConfigService, + KdfType, +} from "@bitwarden/key-management"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; import { diff --git a/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts index 4da6272ccab..4ee4fcaeb38 100644 --- a/libs/auth/src/common/login-strategies/password-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/password-login.strategy.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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; 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"; @@ -32,7 +31,7 @@ import { import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { LoginStrategyServiceAbstraction } from "../abstractions"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; 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 7b5ad4a31b6..ec3ec43134f 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 @@ -3,7 +3,6 @@ import { BehaviorSubject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { DeviceTrustServiceAbstraction } from "@bitwarden/common/auth/abstractions/device-trust.service.abstraction"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; @@ -29,7 +28,7 @@ import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/sp import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { DeviceKey, UserKey, MasterKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { AuthRequestServiceAbstraction, diff --git a/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts index 07d06a7567d..2bb41faa0e1 100644 --- a/libs/auth/src/common/login-strategies/user-api-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/user-api-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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; @@ -26,7 +25,7 @@ import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/sp import { CsprngArray } from "@bitwarden/common/types/csprng"; import { UserId } from "@bitwarden/common/types/guid"; import { UserKey, MasterKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; import { UserApiLoginCredentials } from "../models/domain/login-credentials"; diff --git a/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts b/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts index 88392b57c53..9dacce2cf00 100644 --- a/libs/auth/src/common/login-strategies/webauthn-login.strategy.spec.ts +++ b/libs/auth/src/common/login-strategies/webauthn-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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { TokenService } from "@bitwarden/common/auth/abstractions/token.service"; import { TwoFactorService } from "@bitwarden/common/auth/abstractions/two-factor.service"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; @@ -24,7 +23,7 @@ import { VaultTimeoutSettingsService } from "@bitwarden/common/services/vault-ti import { FakeAccountService, mockAccountServiceWith } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; import { PrfKey, UserKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../abstractions/user-decryption-options.service.abstraction"; import { WebAuthnLoginCredentials } from "../models/domain/login-credentials"; 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 b0d9228f446..5fcbefbef2f 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 @@ -5,13 +5,11 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.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 { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; 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"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; -import { PBKDF2KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; 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 { IdentityTwoFactorResponse } from "@bitwarden/common/auth/models/response/identity-two-factor.response"; @@ -27,7 +25,6 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { TaskSchedulerService } from "@bitwarden/common/platform/scheduling"; import { FakeAccountService, @@ -37,7 +34,7 @@ import { } from "@bitwarden/common/spec"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { UserId } from "@bitwarden/common/types/guid"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KdfType, KeyService, PBKDF2KdfConfig } from "@bitwarden/key-management"; import { AuthRequestServiceAbstraction, 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 721ee984974..b86d1e3f3b4 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,18 +12,12 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { KeyConnectorService } from "@bitwarden/common/auth/abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.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"; import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; -import { - Argon2KdfConfig, - KdfConfig, - PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; 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 { PreloginRequest } from "@bitwarden/common/models/request/prelogin.request"; @@ -36,13 +30,19 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service" import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { StateService } from "@bitwarden/common/platform/abstractions/state.service"; -import { KdfType } from "@bitwarden/common/platform/enums/kdf-type.enum"; import { TaskSchedulerService, ScheduledTaskNames } from "@bitwarden/common/platform/scheduling"; import { GlobalState, GlobalStateProvider } from "@bitwarden/common/platform/state"; import { DeviceTrustServiceAbstraction } from "@bitwarden/common/src/auth/abstractions/device-trust.service.abstraction"; import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength"; import { MasterKey } from "@bitwarden/common/types/key"; -import { KeyService } from "@bitwarden/key-management"; +import { + KdfType, + KeyService, + Argon2KdfConfig, + KdfConfig, + PBKDF2KdfConfig, + KdfConfigService, +} from "@bitwarden/key-management"; import { AuthRequestServiceAbstraction, LoginStrategyServiceAbstraction } from "../../abstractions"; import { InternalUserDecryptionOptionsServiceAbstraction } from "../../abstractions/user-decryption-options.service.abstraction"; diff --git a/libs/auth/src/common/services/pin/pin.service.implementation.ts b/libs/auth/src/common/services/pin/pin.service.implementation.ts index 2a01802fa57..0f3d16fb625 100644 --- a/libs/auth/src/common/services/pin/pin.service.implementation.ts +++ b/libs/auth/src/common/services/pin/pin.service.implementation.ts @@ -1,9 +1,7 @@ import { firstValueFrom, map } from "rxjs"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { MasterPasswordServiceAbstraction } from "@bitwarden/common/auth/abstractions/master-password.service.abstraction"; -import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { KeyGenerationService } from "@bitwarden/common/platform/abstractions/key-generation.service"; @@ -19,6 +17,7 @@ import { } from "@bitwarden/common/platform/state"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, PinKey, UserKey } from "@bitwarden/common/types/key"; +import { KdfConfig, KdfConfigService } from "@bitwarden/key-management"; import { PinServiceAbstraction } from "../../abstractions/pin.service.abstraction"; diff --git a/libs/auth/src/common/services/pin/pin.service.spec.ts b/libs/auth/src/common/services/pin/pin.service.spec.ts index 6befec06994..d254be4e875 100644 --- a/libs/auth/src/common/services/pin/pin.service.spec.ts +++ b/libs/auth/src/common/services/pin/pin.service.spec.ts @@ -1,7 +1,5 @@ import { mock } from "jest-mock-extended"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; -import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { FakeMasterPasswordService } from "@bitwarden/common/auth/services/master-password/fake-master-password.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -18,6 +16,7 @@ import { } from "@bitwarden/common/spec"; import { UserId } from "@bitwarden/common/types/guid"; import { MasterKey, PinKey, UserKey } from "@bitwarden/common/types/key"; +import { DEFAULT_KDF_CONFIG, KdfConfigService } from "@bitwarden/key-management"; import { PinService, diff --git a/libs/common/src/auth/models/request/registration/register-finish.request.ts b/libs/common/src/auth/models/request/registration/register-finish.request.ts index 7ffac6bfe6c..645bcf05b1b 100644 --- a/libs/common/src/auth/models/request/registration/register-finish.request.ts +++ b/libs/common/src/auth/models/request/registration/register-finish.request.ts @@ -1,5 +1,6 @@ +import { KdfType } from "@bitwarden/key-management"; + import { KeysRequest } from "../../../../models/request/keys.request"; -import { KdfType } from "../../../../platform/enums"; import { EncryptedString } from "../../../../platform/models/domain/enc-string"; export class RegisterFinishRequest { diff --git a/libs/common/src/auth/models/request/set-key-connector-key.request.ts b/libs/common/src/auth/models/request/set-key-connector-key.request.ts index c8081bdec2a..14132ab79f2 100644 --- a/libs/common/src/auth/models/request/set-key-connector-key.request.ts +++ b/libs/common/src/auth/models/request/set-key-connector-key.request.ts @@ -1,6 +1,6 @@ +import { KdfConfig, KdfType } from "@bitwarden/key-management"; + import { KeysRequest } from "../../../models/request/keys.request"; -import { KdfType } from "../../../platform/enums"; -import { KdfConfig } from "../domain/kdf-config"; export class SetKeyConnectorKeyRequest { key: string; diff --git a/libs/common/src/auth/models/request/set-password.request.ts b/libs/common/src/auth/models/request/set-password.request.ts index 0fc5d84c097..5aa74068591 100644 --- a/libs/common/src/auth/models/request/set-password.request.ts +++ b/libs/common/src/auth/models/request/set-password.request.ts @@ -1,5 +1,6 @@ +import { KdfType } from "@bitwarden/key-management"; + import { KeysRequest } from "../../../models/request/keys.request"; -import { KdfType } from "../../../platform/enums"; export class SetPasswordRequest { masterPasswordHash: string; diff --git a/libs/common/src/auth/models/response/identity-token.response.ts b/libs/common/src/auth/models/response/identity-token.response.ts index 9ddec9d0f70..c85e7a9444a 100644 --- a/libs/common/src/auth/models/response/identity-token.response.ts +++ b/libs/common/src/auth/models/response/identity-token.response.ts @@ -1,5 +1,6 @@ +import { KdfType } from "@bitwarden/key-management"; + import { BaseResponse } from "../../../models/response/base.response"; -import { KdfType } from "../../../platform/enums"; import { MasterPasswordPolicyResponse } from "./master-password-policy.response"; import { UserDecryptionOptionsResponse } from "./user-decryption-options/user-decryption-options.response"; diff --git a/libs/common/src/auth/models/response/prelogin.response.ts b/libs/common/src/auth/models/response/prelogin.response.ts index c6762e22376..b5ca78c3b79 100644 --- a/libs/common/src/auth/models/response/prelogin.response.ts +++ b/libs/common/src/auth/models/response/prelogin.response.ts @@ -1,5 +1,6 @@ +import { KdfType } from "@bitwarden/key-management"; + import { BaseResponse } from "../../../models/response/base.response"; -import { KdfType } from "../../../platform/enums"; export class PreloginResponse extends BaseResponse { kdf: KdfType; diff --git a/libs/common/src/auth/services/key-connector.service.ts b/libs/common/src/auth/services/key-connector.service.ts index 111f82e6e52..1f10141c756 100644 --- a/libs/common/src/auth/services/key-connector.service.ts +++ b/libs/common/src/auth/services/key-connector.service.ts @@ -1,8 +1,14 @@ import { firstValueFrom } from "rxjs"; import { LogoutReason } from "@bitwarden/auth/common"; +import { + Argon2KdfConfig, + KdfConfig, + PBKDF2KdfConfig, + KeyService, + KdfType, +} from "@bitwarden/key-management"; -import { KeyService } from "../../../../key-management/src/abstractions/key.service"; import { ApiService } from "../../abstractions/api.service"; import { OrganizationService } from "../../admin-console/abstractions/organization/organization.service.abstraction"; import { OrganizationUserType } from "../../admin-console/enums"; @@ -10,7 +16,6 @@ import { Organization } from "../../admin-console/models/domain/organization"; import { KeysRequest } from "../../models/request/keys.request"; import { KeyGenerationService } from "../../platform/abstractions/key-generation.service"; import { LogService } from "../../platform/abstractions/log.service"; -import { KdfType } from "../../platform/enums/kdf-type.enum"; import { Utils } from "../../platform/misc/utils"; import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key"; import { @@ -25,7 +30,6 @@ import { AccountService } from "../abstractions/account.service"; import { KeyConnectorService as KeyConnectorServiceAbstraction } from "../abstractions/key-connector.service"; import { InternalMasterPasswordServiceAbstraction } from "../abstractions/master-password.service.abstraction"; import { TokenService } from "../abstractions/token.service"; -import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig } from "../models/domain/kdf-config"; import { KeyConnectorUserKeyRequest } from "../models/request/key-connector-user-key.request"; import { SetKeyConnectorKeyRequest } from "../models/request/set-key-connector-key.request"; import { IdentityTokenResponse } from "../models/response/identity-token.response"; diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts b/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts index 1538f571cfd..4aa3a632855 100644 --- a/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts +++ b/libs/common/src/auth/services/user-verification/user-verification.service.spec.ts @@ -7,8 +7,9 @@ import { UserDecryptionOptions, UserDecryptionOptionsServiceAbstraction, } from "@bitwarden/auth/common"; +import { KdfConfig, KeyService } from "@bitwarden/key-management"; -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; +import { KdfConfigService } from "../../../../../key-management/src/abstractions/kdf-config.service"; import { FakeAccountService, mockAccountServiceWith } from "../../../../spec"; import { VaultTimeoutSettingsService } from "../../../abstractions/vault-timeout/vault-timeout-settings.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; @@ -18,11 +19,9 @@ import { HashPurpose } from "../../../platform/enums"; import { Utils } from "../../../platform/misc/utils"; import { UserId } from "../../../types/guid"; import { MasterKey } from "../../../types/key"; -import { KdfConfigService } from "../../abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "../../abstractions/master-password.service.abstraction"; import { UserVerificationApiServiceAbstraction } from "../../abstractions/user-verification/user-verification-api.service.abstraction"; import { VerificationType } from "../../enums/verification-type"; -import { KdfConfig } from "../../models/domain/kdf-config"; import { MasterPasswordPolicyResponse } from "../../models/response/master-password-policy.response"; import { MasterPasswordVerification } from "../../types/verification"; diff --git a/libs/common/src/auth/services/user-verification/user-verification.service.ts b/libs/common/src/auth/services/user-verification/user-verification.service.ts index 5446558a540..5d6c6a8f5f9 100644 --- a/libs/common/src/auth/services/user-verification/user-verification.service.ts +++ b/libs/common/src/auth/services/user-verification/user-verification.service.ts @@ -1,9 +1,9 @@ import { firstValueFrom, map } from "rxjs"; import { UserDecryptionOptionsServiceAbstraction } from "@bitwarden/auth/common"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { PinServiceAbstraction } from "../../../../../auth/src/common/abstractions/pin.service.abstraction"; -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; import { VaultTimeoutSettingsService as VaultTimeoutSettingsServiceAbstraction } from "../../../abstractions/vault-timeout/vault-timeout-settings.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { LogService } from "../../../platform/abstractions/log.service"; @@ -13,7 +13,6 @@ import { KeySuffixOptions } from "../../../platform/enums/key-suffix-options.enu import { UserId } from "../../../types/guid"; import { UserKey } from "../../../types/key"; import { AccountService } from "../../abstractions/account.service"; -import { KdfConfigService } from "../../abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "../../abstractions/master-password.service.abstraction"; import { UserVerificationApiServiceAbstraction } from "../../abstractions/user-verification/user-verification-api.service.abstraction"; import { UserVerificationService as UserVerificationServiceAbstraction } from "../../abstractions/user-verification/user-verification.service.abstraction"; diff --git a/libs/common/src/models/request/kdf.request.ts b/libs/common/src/models/request/kdf.request.ts index 8f27b0ec10f..12f0306edbe 100644 --- a/libs/common/src/models/request/kdf.request.ts +++ b/libs/common/src/models/request/kdf.request.ts @@ -1,5 +1,6 @@ +import { KdfType } from "@bitwarden/key-management"; + import { PasswordRequest } from "../../auth/models/request/password.request"; -import { KdfType } from "../../platform/enums"; export class KdfRequest extends PasswordRequest { kdf: KdfType; diff --git a/libs/common/src/models/request/register.request.ts b/libs/common/src/models/request/register.request.ts index f01d89f4b22..7ea7af84c5c 100644 --- a/libs/common/src/models/request/register.request.ts +++ b/libs/common/src/models/request/register.request.ts @@ -1,5 +1,6 @@ +import { KdfType } from "@bitwarden/key-management"; + import { CaptchaProtectedRequest } from "../../auth/models/request/captcha-protected.request"; -import { KdfType } from "../../platform/enums"; import { KeysRequest } from "./keys.request"; import { ReferenceEventRequest } from "./reference-event.request"; diff --git a/libs/common/src/platform/abstractions/key-generation.service.ts b/libs/common/src/platform/abstractions/key-generation.service.ts index 5c6119919a3..8314efe3469 100644 --- a/libs/common/src/platform/abstractions/key-generation.service.ts +++ b/libs/common/src/platform/abstractions/key-generation.service.ts @@ -1,4 +1,5 @@ -import { KdfConfig } from "../../auth/models/domain/kdf-config"; +import { KdfConfig } from "@bitwarden/key-management"; + import { CsprngArray } from "../../types/csprng"; import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; diff --git a/libs/common/src/platform/enums/index.ts b/libs/common/src/platform/enums/index.ts index bac3f4ec41a..389f867e645 100644 --- a/libs/common/src/platform/enums/index.ts +++ b/libs/common/src/platform/enums/index.ts @@ -2,7 +2,6 @@ export * from "./encryption-type.enum"; export * from "./file-upload-type.enum"; export * from "./hash-purpose.enum"; export * from "./html-storage-location.enum"; -export * from "./kdf-type.enum"; export * from "./key-suffix-options.enum"; export * from "./log-level-type.enum"; export * from "./storage-location.enum"; diff --git a/libs/common/src/platform/services/key-generation.service.spec.ts b/libs/common/src/platform/services/key-generation.service.spec.ts index 4f04eebd04e..7bc547dac17 100644 --- a/libs/common/src/platform/services/key-generation.service.spec.ts +++ b/libs/common/src/platform/services/key-generation.service.spec.ts @@ -1,6 +1,7 @@ import { mock } from "jest-mock-extended"; -import { Argon2KdfConfig, PBKDF2KdfConfig } from "../../auth/models/domain/kdf-config"; +import { PBKDF2KdfConfig, Argon2KdfConfig } from "@bitwarden/key-management"; + import { CsprngArray } from "../../types/csprng"; import { CryptoFunctionService } from "../abstractions/crypto-function.service"; diff --git a/libs/common/src/platform/services/key-generation.service.ts b/libs/common/src/platform/services/key-generation.service.ts index b1c1ddfcf17..911d9d1c095 100644 --- a/libs/common/src/platform/services/key-generation.service.ts +++ b/libs/common/src/platform/services/key-generation.service.ts @@ -1,8 +1,8 @@ -import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig } from "../../auth/models/domain/kdf-config"; +import { KdfConfig, PBKDF2KdfConfig, Argon2KdfConfig, KdfType } from "@bitwarden/key-management"; + import { CsprngArray } from "../../types/csprng"; import { CryptoFunctionService } from "../abstractions/crypto-function.service"; import { KeyGenerationService as KeyGenerationServiceAbstraction } from "../abstractions/key-generation.service"; -import { KdfType } from "../enums"; import { Utils } from "../misc/utils"; import { SymmetricCryptoKey } from "../models/domain/symmetric-crypto-key"; diff --git a/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts b/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts index ff82b3aa764..de8b079621a 100644 --- a/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts +++ b/libs/common/src/platform/services/sdk/default-sdk.service.spec.ts @@ -1,13 +1,11 @@ import { mock, MockProxy } from "jest-mock-extended"; import { BehaviorSubject, firstValueFrom, of } from "rxjs"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService, PBKDF2KdfConfig } from "@bitwarden/key-management"; import { BitwardenClient } from "@bitwarden/sdk-internal"; import { ApiService } from "../../../abstractions/api.service"; import { AccountInfo, AccountService } from "../../../auth/abstractions/account.service"; -import { KdfConfigService } from "../../../auth/abstractions/kdf-config.service"; -import { PBKDF2KdfConfig } from "../../../auth/models/domain/kdf-config"; import { UserId } from "../../../types/guid"; import { UserKey } from "../../../types/key"; import { Environment, EnvironmentService } from "../../abstractions/environment.service"; diff --git a/libs/common/src/platform/services/sdk/default-sdk.service.ts b/libs/common/src/platform/services/sdk/default-sdk.service.ts index ccadfe7cca3..4506319eed1 100644 --- a/libs/common/src/platform/services/sdk/default-sdk.service.ts +++ b/libs/common/src/platform/services/sdk/default-sdk.service.ts @@ -11,7 +11,7 @@ import { catchError, } from "rxjs"; -import { KeyService } from "@bitwarden/key-management"; +import { KeyService, KdfConfigService, KdfConfig, KdfType } from "@bitwarden/key-management"; import { BitwardenClient, ClientSettings, @@ -22,8 +22,6 @@ import { import { ApiService } from "../../../abstractions/api.service"; import { EncryptedOrganizationKeyData } from "../../../admin-console/models/data/encrypted-organization-key.data"; import { AccountInfo, AccountService } from "../../../auth/abstractions/account.service"; -import { KdfConfigService } from "../../../auth/abstractions/kdf-config.service"; -import { KdfConfig } from "../../../auth/models/domain/kdf-config"; import { DeviceType } from "../../../enums/device-type.enum"; import { OrganizationId, UserId } from "../../../types/guid"; import { UserKey } from "../../../types/key"; @@ -31,7 +29,6 @@ import { Environment, EnvironmentService } from "../../abstractions/environment. import { PlatformUtilsService } from "../../abstractions/platform-utils.service"; import { SdkClientFactory } from "../../abstractions/sdk/sdk-client-factory"; import { SdkService } from "../../abstractions/sdk/sdk.service"; -import { KdfType } from "../../enums"; import { compareValues } from "../../misc/compare-values"; import { EncryptedString } from "../../models/domain/enc-string"; diff --git a/libs/common/src/tools/send/services/send.service.ts b/libs/common/src/tools/send/services/send.service.ts index 3ba1cb92e2c..aa4aa6033e1 100644 --- a/libs/common/src/tools/send/services/send.service.ts +++ b/libs/common/src/tools/send/services/send.service.ts @@ -1,7 +1,7 @@ import { Observable, concatMap, distinctUntilChanged, firstValueFrom, map } from "rxjs"; -import { KeyService } from "../../../../../key-management/src/abstractions/key.service"; -import { PBKDF2KdfConfig } from "../../../auth/models/domain/kdf-config"; +import { PBKDF2KdfConfig, KeyService } from "@bitwarden/key-management"; + import { EncryptService } from "../../../platform/abstractions/encrypt.service"; import { I18nService } from "../../../platform/abstractions/i18n.service"; import { KeyGenerationService } from "../../../platform/abstractions/key-generation.service"; diff --git a/libs/common/tsconfig.json b/libs/common/tsconfig.json index 99c58f3cf24..27d8acbd360 100644 --- a/libs/common/tsconfig.json +++ b/libs/common/tsconfig.json @@ -1,12 +1,5 @@ { "extends": "../shared/tsconfig.libs", - "include": [ - "src", - "spec", - "./custom-matchers.d.ts", - "../key-management/src/key.service.spec.ts", - "../key-management/src/key.service.ts", - "../key-management/src/abstractions/key.service.ts" - ], + "include": ["src", "spec", "./custom-matchers.d.ts", "../key-management/src/index.ts"], "exclude": ["node_modules", "dist"] } diff --git a/libs/importer/spec/bitwarden-password-protected-importer.spec.ts b/libs/importer/spec/bitwarden-password-protected-importer.spec.ts index d15aa61c8a7..008d6e25f92 100644 --- a/libs/importer/spec/bitwarden-password-protected-importer.spec.ts +++ b/libs/importer/spec/bitwarden-password-protected-importer.spec.ts @@ -4,10 +4,9 @@ import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfType, KeyService } from "@bitwarden/key-management"; import { BitwardenPasswordProtectedImporter, diff --git a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts index fa19e3c0001..446694b8d27 100644 --- a/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts +++ b/libs/importer/src/importers/bitwarden/bitwarden-password-protected-importer.ts @@ -1,17 +1,17 @@ import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; +import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; +import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; -import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; -import { EncString } from "@bitwarden/common/platform/models/domain/enc-string"; -import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key"; -import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service"; -import { KeyService } from "@bitwarden/key-management"; + KeyService, + KdfType, +} from "@bitwarden/key-management"; import { BitwardenPasswordProtectedFileFormat } from "@bitwarden/vault-export-core"; import { ImportResult } from "../../models/import-result"; diff --git a/libs/common/src/auth/abstractions/kdf-config.service.ts b/libs/key-management/src/abstractions/kdf-config.service.ts similarity index 71% rename from libs/common/src/auth/abstractions/kdf-config.service.ts rename to libs/key-management/src/abstractions/kdf-config.service.ts index f4ffe31baa4..d5f613828d4 100644 --- a/libs/common/src/auth/abstractions/kdf-config.service.ts +++ b/libs/key-management/src/abstractions/kdf-config.service.ts @@ -1,7 +1,8 @@ import { Observable } from "rxjs"; -import { UserId } from "../../types/guid"; -import { KdfConfig } from "../models/domain/kdf-config"; +import { UserId } from "@bitwarden/common/types/guid"; + +import { KdfConfig } from "../models/kdf-config"; export abstract class KdfConfigService { abstract setKdfConfig(userId: UserId, KdfConfig: KdfConfig): Promise; diff --git a/libs/key-management/src/abstractions/key.service.ts b/libs/key-management/src/abstractions/key.service.ts index 0ec3aaafdc6..d43a9aeb624 100644 --- a/libs/key-management/src/abstractions/key.service.ts +++ b/libs/key-management/src/abstractions/key.service.ts @@ -1,11 +1,11 @@ import { Observable } from "rxjs"; import { EncryptedOrganizationKeyData } from "@bitwarden/common/admin-console/models/data/encrypted-organization-key.data"; +import { KdfConfig } from "@bitwarden/key-management"; import { ProfileOrganizationResponse } from "../../../common/src/admin-console/models/response/profile-organization.response"; import { ProfileProviderOrganizationResponse } from "../../../common/src/admin-console/models/response/profile-provider-organization.response"; import { ProfileProviderResponse } from "../../../common/src/admin-console/models/response/profile-provider.response"; -import { KdfConfig } from "../../../common/src/auth/models/domain/kdf-config"; import { KeySuffixOptions, HashPurpose } from "../../../common/src/platform/enums"; import { EncryptedString, EncString } from "../../../common/src/platform/models/domain/enc-string"; import { SymmetricCryptoKey } from "../../../common/src/platform/models/domain/symmetric-crypto-key"; diff --git a/libs/common/src/platform/enums/kdf-type.enum.ts b/libs/key-management/src/enums/kdf-type.enum.ts similarity index 100% rename from libs/common/src/platform/enums/kdf-type.enum.ts rename to libs/key-management/src/enums/kdf-type.enum.ts diff --git a/libs/key-management/src/index.ts b/libs/key-management/src/index.ts index 5ad96ddeba7..a779d3a9caf 100644 --- a/libs/key-management/src/index.ts +++ b/libs/key-management/src/index.ts @@ -8,3 +8,12 @@ export * from "./biometrics/biometric.state"; export { KeyService } from "./abstractions/key.service"; export { DefaultKeyService } from "./key.service"; export { UserKeyRotationDataProvider } from "./abstractions/user-key-rotation-data-provider.abstraction"; +export { + PBKDF2KdfConfig, + Argon2KdfConfig, + KdfConfig, + DEFAULT_KDF_CONFIG, +} from "./models/kdf-config"; +export { KdfConfigService } from "./abstractions/kdf-config.service"; +export { DefaultKdfConfigService } from "./kdf-config.service"; +export { KdfType } from "./enums/kdf-type.enum"; diff --git a/libs/common/src/auth/services/kdf-config.service.spec.ts b/libs/key-management/src/kdf-config.service.spec.ts similarity index 91% rename from libs/common/src/auth/services/kdf-config.service.spec.ts rename to libs/key-management/src/kdf-config.service.spec.ts index 7f3613294e7..c9912930e2c 100644 --- a/libs/common/src/auth/services/kdf-config.service.spec.ts +++ b/libs/key-management/src/kdf-config.service.spec.ts @@ -1,12 +1,17 @@ -import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from "../../../spec"; -import { Utils } from "../../platform/misc/utils"; -import { UserId } from "../../types/guid"; -import { Argon2KdfConfig, PBKDF2KdfConfig } from "../models/domain/kdf-config"; +import { + FakeAccountService, + FakeStateProvider, + mockAccountServiceWith, +} from "@bitwarden/common/spec"; +import { UserId } from "@bitwarden/common/src/types/guid"; -import { KdfConfigService } from "./kdf-config.service"; +import { Utils } from "../../common/src/platform/misc/utils"; + +import { DefaultKdfConfigService } from "./kdf-config.service"; +import { Argon2KdfConfig, PBKDF2KdfConfig } from "./models/kdf-config"; describe("KdfConfigService", () => { - let sutKdfConfigService: KdfConfigService; + let sutKdfConfigService: DefaultKdfConfigService; let fakeStateProvider: FakeStateProvider; let fakeAccountService: FakeAccountService; @@ -17,7 +22,7 @@ describe("KdfConfigService", () => { fakeAccountService = mockAccountServiceWith(mockUserId); fakeStateProvider = new FakeStateProvider(fakeAccountService); - sutKdfConfigService = new KdfConfigService(fakeStateProvider); + sutKdfConfigService = new DefaultKdfConfigService(fakeStateProvider); }); it("setKdfConfig(): should set the KDF config", async () => { diff --git a/libs/common/src/auth/services/kdf-config.service.ts b/libs/key-management/src/kdf-config.service.ts similarity index 76% rename from libs/common/src/auth/services/kdf-config.service.ts rename to libs/key-management/src/kdf-config.service.ts index 604a186d765..59907195f04 100644 --- a/libs/common/src/auth/services/kdf-config.service.ts +++ b/libs/key-management/src/kdf-config.service.ts @@ -1,10 +1,12 @@ import { firstValueFrom, Observable } from "rxjs"; -import { KdfType } from "../../platform/enums/kdf-type.enum"; -import { KDF_CONFIG_DISK, StateProvider, UserKeyDefinition } from "../../platform/state"; -import { UserId } from "../../types/guid"; -import { KdfConfigService as KdfConfigServiceAbstraction } from "../abstractions/kdf-config.service"; -import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig } from "../models/domain/kdf-config"; +import { UserId } from "@bitwarden/common/src/types/guid"; + +import { KDF_CONFIG_DISK, StateProvider, UserKeyDefinition } from "../../common/src/platform/state"; + +import { KdfConfigService } from "./abstractions/kdf-config.service"; +import { KdfType } from "./enums/kdf-type.enum"; +import { Argon2KdfConfig, KdfConfig, PBKDF2KdfConfig } from "./models/kdf-config"; export const KDF_CONFIG = new UserKeyDefinition(KDF_CONFIG_DISK, "kdfConfig", { deserializer: (kdfConfig: KdfConfig) => { @@ -18,7 +20,7 @@ export const KDF_CONFIG = new UserKeyDefinition(KDF_CONFIG_DISK, "kdf clearOn: ["logout"], }); -export class KdfConfigService implements KdfConfigServiceAbstraction { +export class DefaultKdfConfigService implements KdfConfigService { constructor(private stateProvider: StateProvider) {} async setKdfConfig(userId: UserId, kdfConfig: KdfConfig) { if (!userId) { diff --git a/libs/key-management/src/key.service.spec.ts b/libs/key-management/src/key.service.spec.ts index 2b2c6514eb4..142a8bbeb86 100644 --- a/libs/key-management/src/key.service.spec.ts +++ b/libs/key-management/src/key.service.spec.ts @@ -1,6 +1,8 @@ import { mock } from "jest-mock-extended"; import { bufferCount, firstValueFrom, lastValueFrom, of, take, tap } from "rxjs"; +import { EncryptedOrganizationKeyData } from "@bitwarden/common/admin-console/models/data/encrypted-organization-key.data"; + import { PinServiceAbstraction } from "../../auth/src/common/abstractions"; import { awaitAsync, @@ -11,8 +13,6 @@ import { import { FakeAccountService, mockAccountServiceWith } from "../../common/spec/fake-account-service"; import { FakeActiveUserState, FakeSingleUserState } from "../../common/spec/fake-state"; import { FakeStateProvider } from "../../common/spec/fake-state-provider"; -import { EncryptedOrganizationKeyData } from "../../common/src/admin-console/models/data/encrypted-organization-key.data"; -import { KdfConfigService } from "../../common/src/auth/abstractions/kdf-config.service"; import { FakeMasterPasswordService } from "../../common/src/auth/services/master-password/fake-master-password.service"; import { CryptoFunctionService } from "../../common/src/platform/abstractions/crypto-function.service"; import { EncryptService } from "../../common/src/platform/abstractions/encrypt.service"; @@ -38,6 +38,7 @@ import { OrganizationId, UserId } from "../../common/src/types/guid"; import { UserKey, MasterKey } from "../../common/src/types/key"; import { VaultTimeoutStringType } from "../../common/src/types/vault-timeout.type"; +import { KdfConfigService } from "./abstractions/kdf-config.service"; import { UserPrivateKeyDecryptionFailedError } from "./abstractions/key.service"; import { DefaultKeyService } from "./key.service"; diff --git a/libs/key-management/src/key.service.ts b/libs/key-management/src/key.service.ts index f2ba24ef5df..ae0b6263de7 100644 --- a/libs/key-management/src/key.service.ts +++ b/libs/key-management/src/key.service.ts @@ -17,9 +17,7 @@ import { ProfileOrganizationResponse } from "../../common/src/admin-console/mode import { ProfileProviderOrganizationResponse } from "../../common/src/admin-console/models/response/profile-provider-organization.response"; import { ProfileProviderResponse } from "../../common/src/admin-console/models/response/profile-provider.response"; import { AccountService } from "../../common/src/auth/abstractions/account.service"; -import { KdfConfigService } from "../../common/src/auth/abstractions/kdf-config.service"; import { InternalMasterPasswordServiceAbstraction } from "../../common/src/auth/abstractions/master-password.service.abstraction"; -import { KdfConfig } from "../../common/src/auth/models/domain/kdf-config"; import { CryptoFunctionService } from "../../common/src/platform/abstractions/crypto-function.service"; import { EncryptService } from "../../common/src/platform/abstractions/encrypt.service"; import { KeyGenerationService } from "../../common/src/platform/abstractions/key-generation.service"; @@ -54,11 +52,13 @@ import { } from "../../common/src/types/key"; import { VaultTimeoutStringType } from "../../common/src/types/vault-timeout.type"; +import { KdfConfigService } from "./abstractions/kdf-config.service"; import { CipherDecryptionKeys, KeyService as KeyServiceAbstraction, UserPrivateKeyDecryptionFailedError, } from "./abstractions/key.service"; +import { KdfConfig } from "./models/kdf-config"; export class DefaultKeyService implements KeyServiceAbstraction { private readonly activeUserEverHadUserKey: ActiveUserState; diff --git a/libs/common/src/auth/models/domain/kdf-config.ts b/libs/key-management/src/models/kdf-config.ts similarity index 96% rename from libs/common/src/auth/models/domain/kdf-config.ts rename to libs/key-management/src/models/kdf-config.ts index 1909aa875e5..11431337a39 100644 --- a/libs/common/src/auth/models/domain/kdf-config.ts +++ b/libs/key-management/src/models/kdf-config.ts @@ -1,7 +1,7 @@ import { Jsonify } from "type-fest"; -import { KdfType } from "../../../platform/enums/kdf-type.enum"; -import { RangeWithDefault } from "../../../platform/misc/range-with-default"; +import { RangeWithDefault } from "../../../common/src/platform/misc/range-with-default"; +import { KdfType } from "../enums/kdf-type.enum"; /** * Represents a type safe KDF configuration. diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts index 76b008be620..60f0f003948 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/base-vault-export.service.ts @@ -1,12 +1,10 @@ import { PinServiceAbstraction } from "@bitwarden/auth/common"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; -import { KdfConfig } from "@bitwarden/common/auth/models/domain/kdf-config"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; +import { KdfConfig, KdfConfigService, KdfType } from "@bitwarden/key-management"; import { BitwardenCsvExportType, BitwardenPasswordProtectedFileFormat } from "../types"; export class BaseVaultExportService { diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts index d264991ae40..9d58bcbf559 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.spec.ts @@ -3,15 +3,9 @@ import { BehaviorSubject } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; -import { - DEFAULT_KDF_CONFIG, - PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; import { CipherWithIdExport } from "@bitwarden/common/models/export/cipher-with-ids.export"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; @@ -24,7 +18,13 @@ import { Login } from "@bitwarden/common/vault/models/domain/login"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; -import { KeyService } from "@bitwarden/key-management"; +import { + DEFAULT_KDF_CONFIG, + PBKDF2KdfConfig, + KdfConfigService, + KeyService, + KdfType, +} from "@bitwarden/key-management"; import { BuildTestObject, GetUniqueString } from "../../../../../../common/spec"; diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts index 04dba1299d7..529c2ff3de9 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/individual-vault-export.service.ts @@ -3,7 +3,6 @@ import { firstValueFrom, map } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { CipherWithIdExport, FolderWithIdExport } from "@bitwarden/common/models/export"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -15,7 +14,7 @@ import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { Folder } from "@bitwarden/common/vault/models/domain/folder"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { BitwardenCsvIndividualExportType, diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts index 4e23a0ed25c..2408aeb6cdf 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/org-vault-export.service.ts @@ -11,7 +11,6 @@ import { import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; import { CipherWithIdExport, CollectionWithIdExport } from "@bitwarden/common/models/export"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; @@ -22,7 +21,7 @@ import { CipherType } from "@bitwarden/common/vault/enums"; import { CipherData } from "@bitwarden/common/vault/models/data/cipher.data"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { KeyService } from "@bitwarden/key-management"; +import { KdfConfigService, KeyService } from "@bitwarden/key-management"; import { BitwardenCsvOrgExportType, diff --git a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts index 525e769957f..6bf05796070 100644 --- a/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts +++ b/libs/tools/export/vault-export/vault-export-core/src/services/vault-export.service.spec.ts @@ -3,15 +3,9 @@ import { BehaviorSubject } from "rxjs"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { AccountInfo, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; -import { KdfConfigService } from "@bitwarden/common/auth/abstractions/kdf-config.service"; -import { - DEFAULT_KDF_CONFIG, - PBKDF2KdfConfig, -} from "@bitwarden/common/auth/models/domain/kdf-config"; import { CipherWithIdExport } from "@bitwarden/common/models/export/cipher-with-ids.export"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; -import { KdfType } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { EncryptedString, EncString } from "@bitwarden/common/platform/models/domain/enc-string"; import { UserId } from "@bitwarden/common/types/guid"; @@ -24,7 +18,13 @@ import { Login } from "@bitwarden/common/vault/models/domain/login"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; import { FolderView } from "@bitwarden/common/vault/models/view/folder.view"; import { LoginView } from "@bitwarden/common/vault/models/view/login.view"; -import { KeyService } from "@bitwarden/key-management"; +import { + DEFAULT_KDF_CONFIG, + PBKDF2KdfConfig, + KdfConfigService, + KeyService, + KdfType, +} from "@bitwarden/key-management"; import { BuildTestObject, GetUniqueString } from "../../../../../../common/spec"; From acf5b1e9e6860cb1a94eb7d1b46c9ca10f7af3b6 Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Thu, 21 Nov 2024 15:54:19 +0100 Subject: [PATCH 09/16] [PM-7382] Add support for non-UUID credential (#11993) * feat: add tests for guidToRawFormat * feat: add support for parsing b64 credential ids * refactor: change interface to use Uint8Array for simplification Technically this deviates from the specification, but nobody is going to be using the authenticator directly but us so it shouldn't matter. We're gonna switch to `passkey-rs` anyways so * feat: change how the authenticator parses credential ids to support b64 --- ...fido2-authenticator.service.abstraction.ts | 2 +- .../fido2/credential-id-utils.spec.ts | 68 +++++++++++++++++++ .../services/fido2/credential-id-utils.ts | 31 +++++++++ .../fido2/fido2-authenticator.service.spec.ts | 14 ++-- .../fido2/fido2-authenticator.service.ts | 29 ++++---- .../services/fido2/guid-utils.spec.ts | 28 ++++++++ 6 files changed, 148 insertions(+), 24 deletions(-) create mode 100644 libs/common/src/platform/services/fido2/credential-id-utils.spec.ts create mode 100644 libs/common/src/platform/services/fido2/credential-id-utils.ts create mode 100644 libs/common/src/platform/services/fido2/guid-utils.spec.ts diff --git a/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts b/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts index 535248e7ecd..d878d70b56e 100644 --- a/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts +++ b/libs/common/src/platform/abstractions/fido2/fido2-authenticator.service.abstraction.ts @@ -64,7 +64,7 @@ export class Fido2AuthenticatorError extends Error { } export interface PublicKeyCredentialDescriptor { - id: BufferSource; + id: Uint8Array; transports?: ("ble" | "hybrid" | "internal" | "nfc" | "usb")[]; type: "public-key"; } diff --git a/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts b/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts new file mode 100644 index 00000000000..76e068ac01c --- /dev/null +++ b/libs/common/src/platform/services/fido2/credential-id-utils.spec.ts @@ -0,0 +1,68 @@ +import { compareCredentialIds, parseCredentialId } from "./credential-id-utils"; + +describe("credential-id-utils", () => { + describe("parseCredentialId", () => { + it("returns credentialId in binary format when given a valid UUID string", () => { + const result = parseCredentialId("08d70b74-e9f5-4522-a425-e5dcd40107e7"); + + expect(result).toEqual( + new Uint8Array([ + 0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07, + 0xe7, + ]), + ); + }); + + it("returns credentialId in binary format when given a valid Base64Url string", () => { + const result = parseCredentialId("b64.CNcLdOn1RSKkJeXc1AEH5w"); + + expect(result).toEqual( + new Uint8Array([ + 0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07, + 0xe7, + ]), + ); + }); + + it("returns undefined when given an invalid Base64 string", () => { + const result = parseCredentialId("b64.#$%&"); + + expect(result).toBeUndefined(); + }); + + it("returns undefined when given an invalid UUID string", () => { + const result = parseCredentialId("invalid"); + + expect(result).toBeUndefined(); + }); + }); + + describe("compareCredentialIds", () => { + it("returns true when the two credential IDs are equal", () => { + const a = new Uint8Array([0x01, 0x02, 0x03]); + const b = new Uint8Array([0x01, 0x02, 0x03]); + + const result = compareCredentialIds(a, b); + + expect(result).toBe(true); + }); + + it("returns false when the two credential IDs are not equal", () => { + const a = new Uint8Array([0x01, 0x02, 0x03]); + const b = new Uint8Array([0x01, 0x02, 0x04]); + + const result = compareCredentialIds(a, b); + + expect(result).toBe(false); + }); + + it("returns false when the two credential IDs have different lengths", () => { + const a = new Uint8Array([0x01, 0x02, 0x03]); + const b = new Uint8Array([0x01, 0x02, 0x03, 0x04]); + + const result = compareCredentialIds(a, b); + + expect(result).toBe(false); + }); + }); +}); diff --git a/libs/common/src/platform/services/fido2/credential-id-utils.ts b/libs/common/src/platform/services/fido2/credential-id-utils.ts new file mode 100644 index 00000000000..a548b8befd3 --- /dev/null +++ b/libs/common/src/platform/services/fido2/credential-id-utils.ts @@ -0,0 +1,31 @@ +import { Fido2Utils } from "./fido2-utils"; +import { guidToRawFormat } from "./guid-utils"; + +export function parseCredentialId(encodedCredentialId: string): Uint8Array { + try { + if (encodedCredentialId.startsWith("b64.")) { + return Fido2Utils.stringToBuffer(encodedCredentialId.slice(4)); + } + + return guidToRawFormat(encodedCredentialId); + } catch { + return undefined; + } +} + +/** + * Compares two credential IDs for equality. + */ +export function compareCredentialIds(a: Uint8Array, b: Uint8Array): boolean { + if (a.length !== b.length) { + return false; + } + + for (let i = 0; i < a.length; i++) { + if (a[i] !== b[i]) { + return false; + } + } + + return true; +} diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts index 5f15005d71c..e3f79ff9d58 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.spec.ts @@ -26,9 +26,9 @@ import { import { Utils } from "../../misc/utils"; import { CBOR } from "./cbor"; +import { parseCredentialId } from "./credential-id-utils"; import { AAGUID, Fido2AuthenticatorService } from "./fido2-authenticator.service"; import { Fido2Utils } from "./fido2-utils"; -import { guidToRawFormat } from "./guid-utils"; const RpId = "bitwarden.com"; @@ -139,7 +139,7 @@ describe("FidoAuthenticatorService", () => { params = await createParams({ excludeCredentialDescriptorList: [ { - id: guidToRawFormat(excludedCipher.login.fido2Credentials[0].credentialId), + id: parseCredentialId(excludedCipher.login.fido2Credentials[0].credentialId), type: "public-key", }, ], @@ -482,7 +482,7 @@ describe("FidoAuthenticatorService", () => { credentialId = Utils.newGuid(); params = await createParams({ allowCredentialDescriptorList: [ - { id: guidToRawFormat(credentialId), type: "public-key" }, + { id: parseCredentialId(credentialId), type: "public-key" }, ], rpId: RpId, }); @@ -546,7 +546,7 @@ describe("FidoAuthenticatorService", () => { let params: Fido2AuthenticatorGetAssertionParams; beforeEach(async () => { - credentialIds = [Utils.newGuid(), Utils.newGuid()]; + credentialIds = [Utils.newGuid(), "b64.Lb5SVTumSV6gYJpeWh3laA"]; ciphers = [ await createCipherView( { type: CipherType.Login }, @@ -559,7 +559,7 @@ describe("FidoAuthenticatorService", () => { ]; params = await createParams({ allowCredentialDescriptorList: credentialIds.map((credentialId) => ({ - id: guidToRawFormat(credentialId), + id: parseCredentialId(credentialId), type: "public-key", })), rpId: RpId, @@ -667,7 +667,7 @@ describe("FidoAuthenticatorService", () => { selectedCredentialId = credentialIds[0]; params = await createParams({ allowCredentialDescriptorList: credentialIds.map((credentialId) => ({ - id: guidToRawFormat(credentialId), + id: parseCredentialId(credentialId), type: "public-key", })), rpId: RpId, @@ -723,7 +723,7 @@ describe("FidoAuthenticatorService", () => { const flags = encAuthData.slice(32, 33); const counter = encAuthData.slice(33, 37); - expect(result.selectedCredential.id).toEqual(guidToRawFormat(selectedCredentialId)); + expect(result.selectedCredential.id).toEqual(parseCredentialId(selectedCredentialId)); expect(result.selectedCredential.userHandle).toEqual( Fido2Utils.stringToBuffer(fido2Credentials[0].userHandle), ); diff --git a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts index 8f0523769d9..e5d3685b9c2 100644 --- a/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts +++ b/libs/common/src/platform/services/fido2/fido2-authenticator.service.ts @@ -23,9 +23,10 @@ import { LogService } from "../../abstractions/log.service"; import { Utils } from "../../misc/utils"; import { CBOR } from "./cbor"; +import { compareCredentialIds, parseCredentialId } from "./credential-id-utils"; import { p1363ToDer } from "./ecdsa-utils"; import { Fido2Utils } from "./fido2-utils"; -import { guidToRawFormat, guidToStandardFormat } from "./guid-utils"; +import { guidToStandardFormat } from "./guid-utils"; // AAGUID: d548826e-79b4-db40-a3d8-11116f7e8349 export const AAGUID = new Uint8Array([ @@ -178,7 +179,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr const authData = await generateAuthData({ rpId: params.rpEntity.id, - credentialId: guidToRawFormat(credentialId), + credentialId: parseCredentialId(credentialId), counter: fido2Credential.counter, userPresence: true, userVerification: userVerified, @@ -193,7 +194,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr ); return { - credentialId: guidToRawFormat(credentialId), + credentialId: parseCredentialId(credentialId), attestationObject, authData, publicKey: pubKeyDer, @@ -313,7 +314,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr const authenticatorData = await generateAuthData({ rpId: selectedFido2Credential.rpId, - credentialId: guidToRawFormat(selectedCredentialId), + credentialId: parseCredentialId(selectedCredentialId), counter: selectedFido2Credential.counter, userPresence: true, userVerification: userVerified, @@ -328,7 +329,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr return { authenticatorData, selectedCredential: { - id: guidToRawFormat(selectedCredentialId), + id: parseCredentialId(selectedCredentialId), userHandle: Fido2Utils.stringToBuffer(selectedFido2Credential.userHandle), }, signature, @@ -412,16 +413,7 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr credentials: PublicKeyCredentialDescriptor[], rpId: string, ): Promise { - const ids: string[] = []; - - for (const credential of credentials) { - try { - ids.push(guidToStandardFormat(credential.id)); - // eslint-disable-next-line no-empty - } catch {} - } - - if (ids.length === 0) { + if (credentials.length === 0) { return []; } @@ -432,7 +424,12 @@ export class Fido2AuthenticatorService implements Fido2AuthenticatorServiceAbstr cipher.type === CipherType.Login && cipher.login.hasFido2Credentials && cipher.login.fido2Credentials[0].rpId === rpId && - ids.includes(cipher.login.fido2Credentials[0].credentialId), + credentials.some((credential) => + compareCredentialIds( + credential.id, + parseCredentialId(cipher.login.fido2Credentials[0].credentialId), + ), + ), ); } diff --git a/libs/common/src/platform/services/fido2/guid-utils.spec.ts b/libs/common/src/platform/services/fido2/guid-utils.spec.ts new file mode 100644 index 00000000000..098ea4bee75 --- /dev/null +++ b/libs/common/src/platform/services/fido2/guid-utils.spec.ts @@ -0,0 +1,28 @@ +import { guidToRawFormat } from "./guid-utils"; + +describe("guid-utils", () => { + describe("guidToRawFormat", () => { + it.each([ + [ + "00000000-0000-0000-0000-000000000000", + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, + ], + "08d70b74-e9f5-4522-a425-e5dcd40107e7", + [ + 0x08, 0xd7, 0x0b, 0x74, 0xe9, 0xf5, 0x45, 0x22, 0xa4, 0x25, 0xe5, 0xdc, 0xd4, 0x01, 0x07, + 0xe7, + ], + ], + ])("returns UUID in binary format when given a valid UUID string", (input, expected) => { + const result = guidToRawFormat(input); + + expect(result).toEqual(new Uint8Array(expected)); + }); + + it("throws an error when given an invalid UUID string", () => { + expect(() => guidToRawFormat("invalid")).toThrow(TypeError); + }); + }); +}); From 5873f0e89d0b25429369ae90ce6e3eccfe6bd28a Mon Sep 17 00:00:00 2001 From: Github Actions Date: Thu, 21 Nov 2024 16:14:06 +0000 Subject: [PATCH 10/16] Bumped client version(s) --- apps/browser/package.json | 2 +- apps/browser/src/manifest.json | 6 ++++-- apps/browser/src/manifest.v3.json | 2 +- apps/cli/package.json | 2 +- apps/desktop/package.json | 2 +- apps/desktop/src/package-lock.json | 4 ++-- apps/desktop/src/package.json | 2 +- apps/web/package.json | 2 +- package-lock.json | 8 ++++---- 9 files changed, 16 insertions(+), 14 deletions(-) diff --git a/apps/browser/package.json b/apps/browser/package.json index ed0a8d36342..53500a83d2b 100644 --- a/apps/browser/package.json +++ b/apps/browser/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/browser", - "version": "2024.11.1", + "version": "2024.11.2", "scripts": { "build": "npm run build:chrome", "build:chrome": "cross-env BROWSER=chrome MANIFEST_VERSION=3 webpack", diff --git a/apps/browser/src/manifest.json b/apps/browser/src/manifest.json index 9c2d2d610bc..e81409e6e2f 100644 --- a/apps/browser/src/manifest.json +++ b/apps/browser/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.11.1", + "version": "2024.11.2", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", @@ -171,6 +171,8 @@ "open_at_install": false, "browser_style": false }, - "storage": { "managed_schema": "managed_schema.json" }, + "storage": { + "managed_schema": "managed_schema.json" + }, "__firefox__storage": null } diff --git a/apps/browser/src/manifest.v3.json b/apps/browser/src/manifest.v3.json index fb44505ae8d..1ece5626227 100644 --- a/apps/browser/src/manifest.v3.json +++ b/apps/browser/src/manifest.v3.json @@ -3,7 +3,7 @@ "minimum_chrome_version": "102.0", "name": "__MSG_extName__", "short_name": "__MSG_appName__", - "version": "2024.11.1", + "version": "2024.11.2", "description": "__MSG_extDesc__", "default_locale": "en", "author": "Bitwarden Inc.", diff --git a/apps/cli/package.json b/apps/cli/package.json index e48507373f5..8be8f9ca34a 100644 --- a/apps/cli/package.json +++ b/apps/cli/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/cli", "description": "A secure and free password manager for all of your devices.", - "version": "2024.11.0", + "version": "2024.11.1", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/package.json b/apps/desktop/package.json index be285f2cc18..cfdd76ec21e 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@bitwarden/desktop", "description": "A secure and free password manager for all of your devices.", - "version": "2024.11.1", + "version": "2024.11.2", "keywords": [ "bitwarden", "password", diff --git a/apps/desktop/src/package-lock.json b/apps/desktop/src/package-lock.json index f47f0f6a281..85a47fa6b2f 100644 --- a/apps/desktop/src/package-lock.json +++ b/apps/desktop/src/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bitwarden/desktop", - "version": "2024.11.1", + "version": "2024.11.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bitwarden/desktop", - "version": "2024.11.1", + "version": "2024.11.2", "license": "GPL-3.0", "dependencies": { "@bitwarden/desktop-napi": "file:../desktop_native/napi", diff --git a/apps/desktop/src/package.json b/apps/desktop/src/package.json index ca700eff2c6..c23baf37acf 100644 --- a/apps/desktop/src/package.json +++ b/apps/desktop/src/package.json @@ -2,7 +2,7 @@ "name": "@bitwarden/desktop", "productName": "Bitwarden", "description": "A secure and free password manager for all of your devices.", - "version": "2024.11.1", + "version": "2024.11.2", "author": "Bitwarden Inc. (https://bitwarden.com)", "homepage": "https://bitwarden.com", "license": "GPL-3.0", diff --git a/apps/web/package.json b/apps/web/package.json index 5dd0e442f2d..02ee6babe92 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,6 +1,6 @@ { "name": "@bitwarden/web-vault", - "version": "2024.11.0", + "version": "2024.11.1", "scripts": { "build:oss": "webpack", "build:bit": "webpack -c ../../bitwarden_license/bit-web/webpack.config.js", diff --git a/package-lock.json b/package-lock.json index 3eb6b9322f6..226ceaca156 100644 --- a/package-lock.json +++ b/package-lock.json @@ -189,11 +189,11 @@ }, "apps/browser": { "name": "@bitwarden/browser", - "version": "2024.11.1" + "version": "2024.11.2" }, "apps/cli": { "name": "@bitwarden/cli", - "version": "2024.11.0", + "version": "2024.11.1", "license": "SEE LICENSE IN LICENSE.txt", "dependencies": { "@koa/multer": "3.0.2", @@ -229,7 +229,7 @@ }, "apps/desktop": { "name": "@bitwarden/desktop", - "version": "2024.11.1", + "version": "2024.11.2", "hasInstallScript": true, "license": "GPL-3.0" }, @@ -243,7 +243,7 @@ }, "apps/web": { "name": "@bitwarden/web-vault", - "version": "2024.11.0" + "version": "2024.11.1" }, "libs/admin-console": { "name": "@bitwarden/admin-console", From a9f570be06a480362e9607fd4570fb4523bac9da Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Thu, 21 Nov 2024 19:37:29 +0100 Subject: [PATCH 11/16] Fix toggle entry not displaying correctly on non-English clients (#12088) Co-authored-by: Daniel James Smith --- .../generator/components/src/password-generator.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/tools/generator/components/src/password-generator.component.ts b/libs/tools/generator/components/src/password-generator.component.ts index 715904dc984..affd162d398 100644 --- a/libs/tools/generator/components/src/password-generator.component.ts +++ b/libs/tools/generator/components/src/password-generator.component.ts @@ -249,7 +249,7 @@ export class PasswordGeneratorComponent implements OnInit, OnDestroy { private toOptions(algorithms: AlgorithmInfo[]) { const options: Option[] = algorithms.map((algorithm) => ({ value: algorithm.id, - label: this.i18nService.t(algorithm.name), + label: algorithm.name, })); return options; From 3732f1293ee66ecd085169d9deabbe9693bbcae6 Mon Sep 17 00:00:00 2001 From: Bernd Schoolmann Date: Thu, 21 Nov 2024 13:10:20 -0800 Subject: [PATCH 12/16] Fix title missing in ssh-key edit/view in web (#12081) --- apps/web/src/app/vault/individual-vault/view.component.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/web/src/app/vault/individual-vault/view.component.ts b/apps/web/src/app/vault/individual-vault/view.component.ts index d30c453a4bd..779035c972b 100644 --- a/apps/web/src/app/vault/individual-vault/view.component.ts +++ b/apps/web/src/app/vault/individual-vault/view.component.ts @@ -184,6 +184,8 @@ export class ViewComponent implements OnInit { return this.i18nService.t("viewItemType", this.i18nService.t("typeCard").toLowerCase()); case CipherType.Identity: return this.i18nService.t("viewItemType", this.i18nService.t("typeIdentity").toLowerCase()); + case CipherType.SshKey: + return this.i18nService.t("viewItemType", this.i18nService.t("typeSshKey").toLowerCase()); default: return null; } From 228817b85f08f7b3cba927e4941095f87ca2b74c Mon Sep 17 00:00:00 2001 From: Daniel James Smith <2670567+djsmith85@users.noreply.github.com> Date: Thu, 21 Nov 2024 22:16:49 +0100 Subject: [PATCH 13/16] Ensure labels on nav-buttons can be translated (#12084) - Introduce using i18n by importing JslibModule - Use i18n within markup - Ensure navButtons.labels is a key that is present in the en/messages.json Co-authored-by: Daniel James Smith --- .../src/platform/popup/layout/popup-layout.stories.ts | 4 ++++ .../popup/layout/popup-tab-navigation.component.html | 2 +- .../popup/layout/popup-tab-navigation.component.ts | 11 ++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index 5b9417a6a19..e80ac249ac1 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -313,6 +313,10 @@ export default { back: "Back", loading: "Loading", search: "Search", + vault: "Vault", + generator: "Generator", + send: "Send", + settings: "Settings", }); }, }, diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html index e53e8905e69..78b859f33b1 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.html @@ -28,7 +28,7 @@ aria-hidden="true" > - {{ button.label }} + {{ button.label | i18n }} diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts index ced3f6462e9..e01b4efd71b 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts @@ -2,13 +2,14 @@ import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; import { RouterModule } from "@angular/router"; +import { JslibModule } from "@bitwarden/angular/jslib.module"; import { LinkModule } from "@bitwarden/components"; @Component({ selector: "popup-tab-navigation", templateUrl: "popup-tab-navigation.component.html", standalone: true, - imports: [CommonModule, LinkModule, RouterModule], + imports: [CommonModule, LinkModule, RouterModule, JslibModule], host: { class: "tw-block tw-h-full tw-w-full tw-flex tw-flex-col", }, @@ -16,25 +17,25 @@ import { LinkModule } from "@bitwarden/components"; export class PopupTabNavigationComponent { navButtons = [ { - label: "Vault", + label: "vault", page: "/tabs/vault", iconKey: "lock", iconKeyActive: "lock-f", }, { - label: "Generator", + label: "generator", page: "/tabs/generator", iconKey: "generate", iconKeyActive: "generate-f", }, { - label: "Send", + label: "send", page: "/tabs/send", iconKey: "send", iconKeyActive: "send-f", }, { - label: "Settings", + label: "settings", page: "/tabs/settings", iconKey: "cog", iconKeyActive: "cog-f", From 9f99454b377044b37a9a96a7976a67a4459e0cc8 Mon Sep 17 00:00:00 2001 From: rr-bw <102181210+rr-bw@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:31:20 -0800 Subject: [PATCH 14/16] feat(auth): [PM-9693] Refresh LoginDecryptionOptionsComponent (#11782) Creates a refreshed and consolidated `LoginDecryptionOptionsComponent` for use on all visual clients, which will be used when the `UnauthenticatedExtensionUIRefresh` feature flag is on. --- apps/browser/src/_locales/en/messages.json | 15 + ...n-login-decryption-options.service.spec.ts | 64 ++++ ...ension-login-decryption-options.service.ts | 37 +++ ...ogin-decryption-options-v1.component.html} | 0 ... login-decryption-options-v1.component.ts} | 6 +- apps/browser/src/popup/app-routing.module.ts | 28 +- apps/browser/src/popup/app.module.ts | 4 +- .../src/popup/services/services.module.ts | 8 + apps/desktop/src/app/app-routing.module.ts | 26 +- ...ogin-decryption-options-v1.component.html} | 0 ... login-decryption-options-v1.component.ts} | 6 +- apps/desktop/src/auth/login/login.module.ts | 4 +- apps/desktop/src/locales/en/messages.json | 15 + apps/web/src/app/auth/core/services/index.ts | 1 + .../login-decryption-options/index.ts | 1 + ...b-login-decryption-options.service.spec.ts | 41 +++ .../web-login-decryption-options.service.ts | 33 ++ ...ogin-decryption-options-v1.component.html} | 0 ... login-decryption-options-v1.component.ts} | 6 +- apps/web/src/app/auth/login/login.module.ts | 6 +- apps/web/src/app/core/core.module.ts | 8 + apps/web/src/app/oss-routing.module.ts | 24 +- apps/web/src/locales/en/messages.json | 12 + ...-login-decryption-options-v1.component.ts} | 2 +- .../src/services/jslib-services.module.ts | 7 + libs/auth/src/angular/index.ts | 5 + ...t-login-decryption-options.service.spec.ts | 37 +++ ...efault-login-decryption-options.service.ts | 15 + .../login-decryption-options.component.html | 60 ++++ .../login-decryption-options.component.ts | 299 ++++++++++++++++++ .../login-decryption-options.service.ts | 10 + 31 files changed, 742 insertions(+), 38 deletions(-) create mode 100644 apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.spec.ts create mode 100644 apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.ts rename apps/browser/src/auth/popup/login-decryption-options/{login-decryption-options.component.html => login-decryption-options-v1.component.html} (100%) rename apps/browser/src/auth/popup/login-decryption-options/{login-decryption-options.component.ts => login-decryption-options-v1.component.ts} (80%) rename apps/desktop/src/auth/login/login-decryption-options/{login-decryption-options.component.html => login-decryption-options-v1.component.html} (100%) rename apps/desktop/src/auth/login/login-decryption-options/{login-decryption-options.component.ts => login-decryption-options-v1.component.ts} (56%) create mode 100644 apps/web/src/app/auth/core/services/login-decryption-options/index.ts create mode 100644 apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.spec.ts create mode 100644 apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.ts rename apps/web/src/app/auth/login/login-decryption-options/{login-decryption-options.component.html => login-decryption-options-v1.component.html} (100%) rename apps/web/src/app/auth/login/login-decryption-options/{login-decryption-options.component.ts => login-decryption-options-v1.component.ts} (78%) rename libs/angular/src/auth/components/{base-login-decryption-options.component.ts => base-login-decryption-options-v1.component.ts} (99%) create mode 100644 libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.spec.ts create mode 100644 libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.ts create mode 100644 libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html create mode 100644 libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts create mode 100644 libs/auth/src/angular/login-decryption-options/login-decryption-options.service.ts diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 0dc93dd0b32..5200cf81d09 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3287,9 +3287,18 @@ "opensInANewWindow": { "message": "Opens in a new window" }, + "rememberThisDeviceToMakeFutureLoginsSeamless": { + "message": "Remember this device to make future logins seamless" + }, "deviceApprovalRequired": { "message": "Device approval required. Select an approval option below:" }, + "deviceApprovalRequiredV2": { + "message": "Device approval required" + }, + "selectAnApprovalOptionBelow": { + "message": "Select an approval option below" + }, "rememberThisDevice": { "message": "Remember this device" }, @@ -3363,6 +3372,9 @@ "userEmailMissing": { "message": "User email missing" }, + "activeUserEmailNotFoundLoggingYouOut": { + "message": "Active user email not found. Logging you out." + }, "deviceTrusted": { "message": "Device trusted" }, @@ -3799,6 +3811,9 @@ "accessing": { "message": "Accessing" }, + "loggedInExclamation": { + "message": "Logged in!" + }, "passkeyNotCopied": { "message": "Passkey will not be copied" }, diff --git a/apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.spec.ts b/apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.spec.ts new file mode 100644 index 00000000000..8f3199cdfce --- /dev/null +++ b/apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.spec.ts @@ -0,0 +1,64 @@ +import { Router } from "@angular/router"; +import { MockProxy, mock } from "jest-mock-extended"; +import { BehaviorSubject } from "rxjs"; + +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { postLogoutMessageListener$ } from "../utils/post-logout-message-listener"; + +import { ExtensionLoginDecryptionOptionsService } from "./extension-login-decryption-options.service"; + +// Mock the module providing postLogoutMessageListener$ +jest.mock("../utils/post-logout-message-listener", () => { + return { + postLogoutMessageListener$: new BehaviorSubject(""), // Replace with mock subject + }; +}); + +describe("ExtensionLoginDecryptionOptionsService", () => { + let service: ExtensionLoginDecryptionOptionsService; + + let messagingService: MockProxy; + let router: MockProxy; + let postLogoutMessageSubject: BehaviorSubject; + + beforeEach(() => { + messagingService = mock(); + router = mock(); + + // Cast postLogoutMessageListener$ to BehaviorSubject for dynamic control + postLogoutMessageSubject = postLogoutMessageListener$ as BehaviorSubject; + + service = new ExtensionLoginDecryptionOptionsService(messagingService, router); + }); + + it("should instantiate the service", () => { + expect(service).not.toBeFalsy(); + }); + + describe("logOut()", () => { + it("should send a logout message", async () => { + postLogoutMessageSubject.next("switchAccountFinish"); + + await service.logOut(); + + expect(messagingService.send).toHaveBeenCalledWith("logout"); + }); + + it("should navigate to root on 'switchAccountFinish'", async () => { + postLogoutMessageSubject.next("switchAccountFinish"); + + await service.logOut(); + + expect(router.navigate).toHaveBeenCalledWith(["/"]); + }); + + it("should not navigate for 'doneLoggingOut'", async () => { + postLogoutMessageSubject.next("doneLoggingOut"); + + await service.logOut(); + + expect(router.navigate).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.ts b/apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.ts new file mode 100644 index 00000000000..ea529e277e6 --- /dev/null +++ b/apps/browser/src/auth/popup/login-decryption-options/extension-login-decryption-options.service.ts @@ -0,0 +1,37 @@ +import { Router } from "@angular/router"; +import { firstValueFrom } from "rxjs"; + +import { + DefaultLoginDecryptionOptionsService, + LoginDecryptionOptionsService, +} from "@bitwarden/auth/angular"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { postLogoutMessageListener$ } from "../utils/post-logout-message-listener"; + +export class ExtensionLoginDecryptionOptionsService + extends DefaultLoginDecryptionOptionsService + implements LoginDecryptionOptionsService +{ + constructor( + protected messagingService: MessagingService, + private router: Router, + ) { + super(messagingService); + } + + override async logOut(): Promise { + // start listening for "switchAccountFinish" or "doneLoggingOut" + const messagePromise = firstValueFrom(postLogoutMessageListener$); + + super.logOut(); + + // wait for messages + const command = await messagePromise; + + // doneLoggingOut already has a message handler that will navigate us + if (command === "switchAccountFinish") { + await this.router.navigate(["/"]); + } + } +} diff --git a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.html b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.html similarity index 100% rename from apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.html rename to apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.html diff --git a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.ts b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.ts similarity index 80% rename from apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.ts rename to apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.ts index 6231b027749..bd8f808c910 100644 --- a/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options.component.ts +++ b/apps/browser/src/auth/popup/login-decryption-options/login-decryption-options-v1.component.ts @@ -1,15 +1,15 @@ import { Component } from "@angular/core"; import { firstValueFrom } from "rxjs"; -import { BaseLoginDecryptionOptionsComponent } from "@bitwarden/angular/auth/components/base-login-decryption-options.component"; +import { BaseLoginDecryptionOptionsComponentV1 } from "@bitwarden/angular/auth/components/base-login-decryption-options-v1.component"; import { postLogoutMessageListener$ } from "../utils/post-logout-message-listener"; @Component({ selector: "browser-login-decryption-options", - templateUrl: "login-decryption-options.component.html", + templateUrl: "login-decryption-options-v1.component.html", }) -export class LoginDecryptionOptionsComponent extends BaseLoginDecryptionOptionsComponent { +export class LoginDecryptionOptionsComponentV1 extends BaseLoginDecryptionOptionsComponentV1 { override async createUser(): Promise { try { await super.createUser(); diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index ba8ab1e7aaf..5e6f38e80b0 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -21,7 +21,6 @@ import { extensionRefreshSwap } from "@bitwarden/angular/utils/extension-refresh import { AnonLayoutWrapperComponent, AnonLayoutWrapperData, - DevicesIcon, LoginComponent, LoginSecondaryContentComponent, LockIcon, @@ -37,6 +36,8 @@ import { SetPasswordJitComponent, UserLockIcon, VaultIcon, + LoginDecryptionOptionsComponent, + DevicesIcon, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -51,7 +52,7 @@ import { import { HintComponent } from "../auth/popup/hint.component"; import { HomeComponent } from "../auth/popup/home.component"; import { LockComponent } from "../auth/popup/lock.component"; -import { LoginDecryptionOptionsComponent } from "../auth/popup/login-decryption-options/login-decryption-options.component"; +import { LoginDecryptionOptionsComponentV1 } from "../auth/popup/login-decryption-options/login-decryption-options-v1.component"; import { LoginComponentV1 } from "../auth/popup/login-v1.component"; import { LoginViaAuthRequestComponentV1 } from "../auth/popup/login-via-auth-request-v1.component"; import { RegisterComponent } from "../auth/popup/register.component"; @@ -206,12 +207,6 @@ const routes: Routes = [ canActivate: [unauthGuardFn(unauthRouteOverrides)], data: { state: "2fa-options" } satisfies RouteDataProperties, }, - { - path: "login-initiated", - component: LoginDecryptionOptionsComponent, - canActivate: [tdeDecryptionRequiredGuard()], - data: { state: "login-initiated" } satisfies RouteDataProperties, - }, { path: "sso", component: SsoComponent, @@ -534,6 +529,23 @@ const routes: Routes = [ ], }, ), + ...unauthUiRefreshSwap( + LoginDecryptionOptionsComponentV1, + ExtensionAnonLayoutWrapperComponent, + { + path: "login-initiated", + canActivate: [tdeDecryptionRequiredGuard()], + data: { state: "login-initiated" } satisfies RouteDataProperties, + }, + { + path: "login-initiated", + canActivate: [tdeDecryptionRequiredGuard()], + data: { + pageIcon: DevicesIcon, + }, + children: [{ path: "", component: LoginDecryptionOptionsComponent }], + }, + ), { path: "", component: ExtensionAnonLayoutWrapperComponent, diff --git a/apps/browser/src/popup/app.module.ts b/apps/browser/src/popup/app.module.ts index d6e46de6ba0..d637f695e81 100644 --- a/apps/browser/src/popup/app.module.ts +++ b/apps/browser/src/popup/app.module.ts @@ -24,7 +24,7 @@ import { ExtensionAnonLayoutWrapperComponent } from "../auth/popup/extension-ano import { HintComponent } from "../auth/popup/hint.component"; import { HomeComponent } from "../auth/popup/home.component"; import { LockComponent } from "../auth/popup/lock.component"; -import { LoginDecryptionOptionsComponent } from "../auth/popup/login-decryption-options/login-decryption-options.component"; +import { LoginDecryptionOptionsComponentV1 } from "../auth/popup/login-decryption-options/login-decryption-options-v1.component"; import { LoginComponentV1 } from "../auth/popup/login-v1.component"; import { LoginViaAuthRequestComponentV1 } from "../auth/popup/login-via-auth-request-v1.component"; import { RegisterComponent } from "../auth/popup/register.component"; @@ -161,7 +161,7 @@ import "../platform/popup/locales"; LockComponent, LoginViaAuthRequestComponentV1, LoginComponentV1, - LoginDecryptionOptionsComponent, + LoginDecryptionOptionsComponentV1, NotificationsSettingsV1Component, AppearanceComponent, GeneratorComponent, diff --git a/apps/browser/src/popup/services/services.module.ts b/apps/browser/src/popup/services/services.module.ts index 9a1acb54ab7..b68102033bb 100644 --- a/apps/browser/src/popup/services/services.module.ts +++ b/apps/browser/src/popup/services/services.module.ts @@ -1,4 +1,5 @@ import { APP_INITIALIZER, NgModule, NgZone } from "@angular/core"; +import { Router } from "@angular/router"; import { Subject, merge, of } from "rxjs"; import { CollectionService } from "@bitwarden/admin-console/common"; @@ -22,6 +23,7 @@ import { AnonLayoutWrapperDataService, LoginComponentService, LockComponentService, + LoginDecryptionOptionsService, } from "@bitwarden/auth/angular"; import { LockService, LoginEmailService, PinServiceAbstraction } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; @@ -115,6 +117,7 @@ import { PasswordRepromptService } from "@bitwarden/vault"; import { ForegroundLockService } from "../../auth/popup/accounts/foreground-lock.service"; import { ExtensionAnonLayoutWrapperDataService } from "../../auth/popup/extension-anon-layout-wrapper/extension-anon-layout-wrapper-data.service"; import { ExtensionLoginComponentService } from "../../auth/popup/login/extension-login-component.service"; +import { ExtensionLoginDecryptionOptionsService } from "../../auth/popup/login-decryption-options/extension-login-decryption-options.service"; import { AutofillService as AutofillServiceAbstraction } from "../../autofill/services/abstractions/autofill.service"; import AutofillService from "../../autofill/services/autofill.service"; import { InlineMenuFieldQualificationService } from "../../autofill/services/inline-menu-field-qualification.service"; @@ -591,6 +594,11 @@ const safeProviders: SafeProvider[] = [ useExisting: PopupCompactModeService, deps: [], }), + safeProvider({ + provide: LoginDecryptionOptionsService, + useClass: ExtensionLoginDecryptionOptionsService, + deps: [MessagingServiceAbstraction, Router], + }), ]; @NgModule({ diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index c1e4fd18692..e61335859c4 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -18,7 +18,6 @@ import { extensionRefreshRedirect } from "@bitwarden/angular/utils/extension-ref import { AnonLayoutWrapperComponent, AnonLayoutWrapperData, - DevicesIcon, LoginComponent, LoginSecondaryContentComponent, LockIcon, @@ -34,6 +33,8 @@ import { SetPasswordJitComponent, UserLockIcon, VaultIcon, + LoginDecryptionOptionsComponent, + DevicesIcon, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -42,7 +43,7 @@ import { AccessibilityCookieComponent } from "../auth/accessibility-cookie.compo import { maxAccountsGuardFn } from "../auth/guards/max-accounts.guard"; import { HintComponent } from "../auth/hint.component"; import { LockComponent } from "../auth/lock.component"; -import { LoginDecryptionOptionsComponent } from "../auth/login/login-decryption-options/login-decryption-options.component"; +import { LoginDecryptionOptionsComponentV1 } from "../auth/login/login-decryption-options/login-decryption-options-v1.component"; import { LoginComponentV1 } from "../auth/login/login-v1.component"; import { LoginViaAuthRequestComponentV1 } from "../auth/login/login-via-auth-request-v1.component"; import { RegisterComponent } from "../auth/register.component"; @@ -95,11 +96,6 @@ const routes: Routes = [ ], }, ), - { - path: "login-initiated", - component: LoginDecryptionOptionsComponent, - canActivate: [tdeDecryptionRequiredGuard()], - }, { path: "register", component: RegisterComponent }, { path: "vault", @@ -241,6 +237,22 @@ const routes: Routes = [ ], }, ), + ...unauthUiRefreshSwap( + LoginDecryptionOptionsComponentV1, + AnonLayoutWrapperComponent, + { + path: "login-initiated", + canActivate: [tdeDecryptionRequiredGuard()], + }, + { + path: "login-initiated", + canActivate: [tdeDecryptionRequiredGuard()], + data: { + pageIcon: DevicesIcon, + }, + children: [{ path: "", component: LoginDecryptionOptionsComponent }], + }, + ), { path: "", component: AnonLayoutWrapperComponent, diff --git a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options.component.html b/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.html similarity index 100% rename from apps/desktop/src/auth/login/login-decryption-options/login-decryption-options.component.html rename to apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.html diff --git a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options.component.ts b/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.ts similarity index 56% rename from apps/desktop/src/auth/login/login-decryption-options/login-decryption-options.component.ts rename to apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.ts index f64ec977ce7..d9cc07adb7e 100644 --- a/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options.component.ts +++ b/apps/desktop/src/auth/login/login-decryption-options/login-decryption-options-v1.component.ts @@ -1,12 +1,12 @@ import { Component } from "@angular/core"; -import { BaseLoginDecryptionOptionsComponent } from "@bitwarden/angular/auth/components/base-login-decryption-options.component"; +import { BaseLoginDecryptionOptionsComponentV1 } from "@bitwarden/angular/auth/components/base-login-decryption-options-v1.component"; @Component({ selector: "desktop-login-decryption-options", - templateUrl: "login-decryption-options.component.html", + templateUrl: "login-decryption-options-v1.component.html", }) -export class LoginDecryptionOptionsComponent extends BaseLoginDecryptionOptionsComponent { +export class LoginDecryptionOptionsComponentV1 extends BaseLoginDecryptionOptionsComponentV1 { override async createUser(): Promise { try { await super.createUser(); diff --git a/apps/desktop/src/auth/login/login.module.ts b/apps/desktop/src/auth/login/login.module.ts index 20c0bc97c6c..427cbcb2069 100644 --- a/apps/desktop/src/auth/login/login.module.ts +++ b/apps/desktop/src/auth/login/login.module.ts @@ -5,7 +5,7 @@ import { EnvironmentSelectorComponent } from "@bitwarden/angular/auth/components import { SharedModule } from "../../app/shared/shared.module"; -import { LoginDecryptionOptionsComponent } from "./login-decryption-options/login-decryption-options.component"; +import { LoginDecryptionOptionsComponentV1 } from "./login-decryption-options/login-decryption-options-v1.component"; import { LoginComponentV1 } from "./login-v1.component"; import { LoginViaAuthRequestComponentV1 } from "./login-via-auth-request-v1.component"; @@ -15,7 +15,7 @@ import { LoginViaAuthRequestComponentV1 } from "./login-via-auth-request-v1.comp LoginComponentV1, LoginViaAuthRequestComponentV1, EnvironmentSelectorComponent, - LoginDecryptionOptionsComponent, + LoginDecryptionOptionsComponentV1, ], exports: [LoginComponentV1, LoginViaAuthRequestComponentV1], }) diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index e9f26d23e94..ab6fb586948 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -2832,6 +2832,9 @@ "checkForBreaches": { "message": "Check known data breaches for this password" }, + "loggedInExclamation": { + "message": "Logged in!" + }, "important": { "message": "Important:" }, @@ -2862,9 +2865,18 @@ "windowsBiometricUpdateWarningTitle": { "message": "Recommended Settings Update" }, + "rememberThisDeviceToMakeFutureLoginsSeamless": { + "message": "Remember this device to make future logins seamless" + }, "deviceApprovalRequired": { "message": "Device approval required. Select an approval option below:" }, + "deviceApprovalRequiredV2": { + "message": "Device approval required" + }, + "selectAnApprovalOptionBelow": { + "message": "Select an approval option below" + }, "rememberThisDevice": { "message": "Remember this device" }, @@ -2917,6 +2929,9 @@ "userEmailMissing": { "message": "User email missing" }, + "activeUserEmailNotFoundLoggingYouOut": { + "message": "Active user email not found. Logging you out." + }, "deviceTrusted": { "message": "Device trusted" }, diff --git a/apps/web/src/app/auth/core/services/index.ts b/apps/web/src/app/auth/core/services/index.ts index a2e674c2a95..c14292d7c6d 100644 --- a/apps/web/src/app/auth/core/services/index.ts +++ b/apps/web/src/app/auth/core/services/index.ts @@ -1,4 +1,5 @@ export * from "./login"; +export * from "./login-decryption-options"; export * from "./webauthn-login"; export * from "./set-password-jit"; export * from "./registration"; diff --git a/apps/web/src/app/auth/core/services/login-decryption-options/index.ts b/apps/web/src/app/auth/core/services/login-decryption-options/index.ts new file mode 100644 index 00000000000..f0ff30b8727 --- /dev/null +++ b/apps/web/src/app/auth/core/services/login-decryption-options/index.ts @@ -0,0 +1 @@ +export * from "./web-login-decryption-options.service"; diff --git a/apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.spec.ts b/apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.spec.ts new file mode 100644 index 00000000000..31df33a6ece --- /dev/null +++ b/apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.spec.ts @@ -0,0 +1,41 @@ +import { MockProxy, mock } from "jest-mock-extended"; + +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { RouterService } from "../../../../core/router.service"; +import { AcceptOrganizationInviteService } from "../../../organization-invite/accept-organization.service"; + +import { WebLoginDecryptionOptionsService } from "./web-login-decryption-options.service"; + +describe("WebLoginDecryptionOptionsService", () => { + let service: WebLoginDecryptionOptionsService; + + let messagingService: MockProxy; + let routerService: MockProxy; + let acceptOrganizationInviteService: MockProxy; + + beforeEach(() => { + messagingService = mock(); + routerService = mock(); + acceptOrganizationInviteService = mock(); + + service = new WebLoginDecryptionOptionsService( + messagingService, + routerService, + acceptOrganizationInviteService, + ); + }); + + it("should instantiate the service", () => { + expect(service).not.toBeFalsy(); + }); + + describe("handleCreateUserSuccess()", () => { + it("should clear the redirect URL and the org invite", async () => { + await service.handleCreateUserSuccess(); + + expect(routerService.getAndClearLoginRedirectUrl).toHaveBeenCalled(); + expect(acceptOrganizationInviteService.clearOrganizationInvitation).toHaveBeenCalled(); + }); + }); +}); diff --git a/apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.ts b/apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.ts new file mode 100644 index 00000000000..30654decdc3 --- /dev/null +++ b/apps/web/src/app/auth/core/services/login-decryption-options/web-login-decryption-options.service.ts @@ -0,0 +1,33 @@ +import { + LoginDecryptionOptionsService, + DefaultLoginDecryptionOptionsService, +} from "@bitwarden/auth/angular"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { RouterService } from "../../../../core/router.service"; +import { AcceptOrganizationInviteService } from "../../../organization-invite/accept-organization.service"; + +export class WebLoginDecryptionOptionsService + extends DefaultLoginDecryptionOptionsService + implements LoginDecryptionOptionsService +{ + constructor( + protected messagingService: MessagingService, + private routerService: RouterService, + private acceptOrganizationInviteService: AcceptOrganizationInviteService, + ) { + super(messagingService); + } + + override async handleCreateUserSuccess(): Promise { + try { + // Invites from TDE orgs go through here, but the invite is + // accepted while being enrolled in admin recovery. So we need to clear + // the redirect and stored org invite. + await this.routerService.getAndClearLoginRedirectUrl(); + await this.acceptOrganizationInviteService.clearOrganizationInvitation(); + } catch (error) { + throw new Error(error); + } + } +} diff --git a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.html b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.html similarity index 100% rename from apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.html rename to apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.html diff --git a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.ts similarity index 78% rename from apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts rename to apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.ts index 991fe8b5971..5eb72503b90 100644 --- a/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options.component.ts +++ b/apps/web/src/app/auth/login/login-decryption-options/login-decryption-options-v1.component.ts @@ -1,14 +1,14 @@ import { Component, inject } from "@angular/core"; -import { BaseLoginDecryptionOptionsComponent } from "@bitwarden/angular/auth/components/base-login-decryption-options.component"; +import { BaseLoginDecryptionOptionsComponentV1 } from "@bitwarden/angular/auth/components/base-login-decryption-options-v1.component"; import { RouterService } from "../../../core"; import { AcceptOrganizationInviteService } from "../../organization-invite/accept-organization.service"; @Component({ selector: "web-login-decryption-options", - templateUrl: "login-decryption-options.component.html", + templateUrl: "login-decryption-options-v1.component.html", }) -export class LoginDecryptionOptionsComponent extends BaseLoginDecryptionOptionsComponent { +export class LoginDecryptionOptionsComponentV1 extends BaseLoginDecryptionOptionsComponentV1 { protected routerService = inject(RouterService); protected acceptOrganizationInviteService = inject(AcceptOrganizationInviteService); diff --git a/apps/web/src/app/auth/login/login.module.ts b/apps/web/src/app/auth/login/login.module.ts index b8f39890aa1..a33a6b8a5a8 100644 --- a/apps/web/src/app/auth/login/login.module.ts +++ b/apps/web/src/app/auth/login/login.module.ts @@ -4,7 +4,7 @@ import { CheckboxModule } from "@bitwarden/components"; import { SharedModule } from "../../../app/shared"; -import { LoginDecryptionOptionsComponent } from "./login-decryption-options/login-decryption-options.component"; +import { LoginDecryptionOptionsComponentV1 } from "./login-decryption-options/login-decryption-options-v1.component"; import { LoginComponentV1 } from "./login-v1.component"; import { LoginViaAuthRequestComponentV1 } from "./login-via-auth-request-v1.component"; import { LoginViaWebAuthnComponent } from "./login-via-webauthn/login-via-webauthn.component"; @@ -14,13 +14,13 @@ import { LoginViaWebAuthnComponent } from "./login-via-webauthn/login-via-webaut declarations: [ LoginComponentV1, LoginViaAuthRequestComponentV1, - LoginDecryptionOptionsComponent, + LoginDecryptionOptionsComponentV1, LoginViaWebAuthnComponent, ], exports: [ LoginComponentV1, LoginViaAuthRequestComponentV1, - LoginDecryptionOptionsComponent, + LoginDecryptionOptionsComponentV1, LoginViaWebAuthnComponent, ], }) diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index cfca5659c38..79a7862178f 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -30,6 +30,7 @@ import { LoginComponentService, LockComponentService, SetPasswordJitService, + LoginDecryptionOptionsService, } from "@bitwarden/auth/angular"; import { InternalUserDecryptionOptionsServiceAbstraction, @@ -60,6 +61,7 @@ import { import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { SdkClientFactory } from "@bitwarden/common/platform/abstractions/sdk/sdk-client-factory"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; @@ -95,6 +97,7 @@ import { WebRegistrationFinishService, WebLoginComponentService, WebLockComponentService, + WebLoginDecryptionOptionsService, } from "../auth"; import { AcceptOrganizationInviteService } from "../auth/organization-invite/accept-organization.service"; import { HtmlStorageService } from "../core/html-storage.service"; @@ -296,6 +299,11 @@ const safeProviders: SafeProvider[] = [ useClass: LoginEmailService, deps: [AccountService, AuthService, StateProvider], }), + safeProvider({ + provide: LoginDecryptionOptionsService, + useClass: WebLoginDecryptionOptionsService, + deps: [MessagingService, RouterService, AcceptOrganizationInviteService], + }), ]; @NgModule({ diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index 20361c7edc2..6e2e97d8e06 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -33,6 +33,7 @@ import { RegistrationLockAltIcon, RegistrationExpiredLinkIcon, VaultIcon, + LoginDecryptionOptionsComponent, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -46,7 +47,7 @@ import { CreateOrganizationComponent } from "./admin-console/settings/create-org import { deepLinkGuard } from "./auth/guards/deep-link.guard"; import { HintComponent } from "./auth/hint.component"; import { LockComponent } from "./auth/lock.component"; -import { LoginDecryptionOptionsComponent } from "./auth/login/login-decryption-options/login-decryption-options.component"; +import { LoginDecryptionOptionsComponentV1 } from "./auth/login/login-decryption-options/login-decryption-options-v1.component"; import { LoginComponentV1 } from "./auth/login/login-v1.component"; import { LoginViaAuthRequestComponentV1 } from "./auth/login/login-via-auth-request-v1.component"; import { LoginViaWebAuthnComponent } from "./auth/login/login-via-webauthn/login-via-webauthn.component"; @@ -103,11 +104,6 @@ const routes: Routes = [ component: LoginViaWebAuthnComponent, data: { titleId: "logInWithPasskey" } satisfies RouteDataProperties, }, - { - path: "login-initiated", - component: LoginDecryptionOptionsComponent, - canActivate: [tdeDecryptionRequiredGuard()], - }, { path: "register", component: TrialInitiationComponent, @@ -272,6 +268,22 @@ const routes: Routes = [ ], }, ), + ...unauthUiRefreshSwap( + LoginDecryptionOptionsComponentV1, + AnonLayoutWrapperComponent, + { + path: "login-initiated", + canActivate: [tdeDecryptionRequiredGuard()], + }, + { + path: "login-initiated", + canActivate: [tdeDecryptionRequiredGuard()], + data: { + pageIcon: DevicesIcon, + }, + children: [{ path: "", component: LoginDecryptionOptionsComponent }], + }, + ), ...unauthUiRefreshSwap( AnonLayoutWrapperComponent, AnonLayoutWrapperComponent, diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index ff3f0505699..419a89056c7 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8051,9 +8051,18 @@ "loginInitiated": { "message": "Login initiated" }, + "rememberThisDeviceToMakeFutureLoginsSeamless": { + "message": "Remember this device to make future logins seamless" + }, "deviceApprovalRequired": { "message": "Device approval required. Select an approval option below:" }, + "deviceApprovalRequiredV2": { + "message": "Device approval required" + }, + "selectAnApprovalOptionBelow": { + "message": "Select an approval option below" + }, "rememberThisDevice": { "message": "Remember this device" }, @@ -8283,6 +8292,9 @@ "userEmailMissing": { "message": "User email missing" }, + "activeUserEmailNotFoundLoggingYouOut": { + "message": "Active user email not found. Logging you out." + }, "deviceTrusted": { "message": "Device trusted" }, diff --git a/libs/angular/src/auth/components/base-login-decryption-options.component.ts b/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts similarity index 99% rename from libs/angular/src/auth/components/base-login-decryption-options.component.ts rename to libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts index f674a32af8b..df99503b6d7 100644 --- a/libs/angular/src/auth/components/base-login-decryption-options.component.ts +++ b/libs/angular/src/auth/components/base-login-decryption-options-v1.component.ts @@ -63,7 +63,7 @@ type ExistingUserUntrustedDeviceData = { type Data = NewUserData | ExistingUserUntrustedDeviceData; @Directive() -export class BaseLoginDecryptionOptionsComponent implements OnInit, OnDestroy { +export class BaseLoginDecryptionOptionsComponentV1 implements OnInit, OnDestroy { private destroy$ = new Subject(); protected State = State; diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 9d1cd6e502d..0208a3cdc7a 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -16,6 +16,8 @@ import { DefaultAnonLayoutWrapperDataService, LoginComponentService, DefaultLoginComponentService, + LoginDecryptionOptionsService, + DefaultLoginDecryptionOptionsService, } from "@bitwarden/auth/angular"; import { AuthRequestServiceAbstraction, @@ -1384,6 +1386,11 @@ const safeProviders: SafeProvider[] = [ useClass: DefaultAuthRequestApiService, deps: [ApiServiceAbstraction, LogService], }), + safeProvider({ + provide: LoginDecryptionOptionsService, + useClass: DefaultLoginDecryptionOptionsService, + deps: [MessagingServiceAbstraction], + }), ]; @NgModule({ diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index 5c028065c62..16ae77e937f 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -24,6 +24,11 @@ export * from "./login/login-secondary-content.component"; export * from "./login/login-component.service"; export * from "./login/default-login-component.service"; +// login decryption options +export * from "./login-decryption-options/login-decryption-options.component"; +export * from "./login-decryption-options/login-decryption-options.service"; +export * from "./login-decryption-options/default-login-decryption-options.service"; + // login via auth request export * from "./login-via-auth-request/login-via-auth-request.component"; diff --git a/libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.spec.ts b/libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.spec.ts new file mode 100644 index 00000000000..735b7667540 --- /dev/null +++ b/libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.spec.ts @@ -0,0 +1,37 @@ +import { MockProxy, mock } from "jest-mock-extended"; + +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { DefaultLoginDecryptionOptionsService } from "./default-login-decryption-options.service"; + +describe("DefaultLoginDecryptionOptionsService", () => { + let service: DefaultLoginDecryptionOptionsService; + + let messagingService: MockProxy; + + beforeEach(() => { + messagingService = mock(); + + service = new DefaultLoginDecryptionOptionsService(messagingService); + }); + + it("should instantiate the service", () => { + expect(service).not.toBeFalsy(); + }); + + describe("handleCreateUserSuccess()", () => { + it("should return null", async () => { + const result = await service.handleCreateUserSuccess(); + + expect(result).toBeNull(); + }); + }); + + describe("logOut()", () => { + it("should send a logout message", async () => { + await service.logOut(); + + expect(messagingService.send).toHaveBeenCalledWith("logout"); + }); + }); +}); diff --git a/libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.ts b/libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.ts new file mode 100644 index 00000000000..17ea0bc9653 --- /dev/null +++ b/libs/auth/src/angular/login-decryption-options/default-login-decryption-options.service.ts @@ -0,0 +1,15 @@ +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +import { LoginDecryptionOptionsService } from "./login-decryption-options.service"; + +export class DefaultLoginDecryptionOptionsService implements LoginDecryptionOptionsService { + constructor(protected messagingService: MessagingService) {} + + handleCreateUserSuccess(): Promise { + return null; + } + + async logOut(): Promise { + this.messagingService.send("logout"); + } +} diff --git a/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html new file mode 100644 index 00000000000..cb340f646f1 --- /dev/null +++ b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.html @@ -0,0 +1,60 @@ + +
+ + {{ "loading" | i18n }} +
+
+ +
+ + + {{ "rememberThisDevice" | i18n }} + {{ "uncheckIfPublicDevice" | i18n }} + +
+ + + + + + +
+ + + +
+ {{ "or" | i18n }} +
+
+ + + + +
+
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 new file mode 100644 index 00000000000..38771f9dada --- /dev/null +++ b/libs/auth/src/angular/login-decryption-options/login-decryption-options.component.ts @@ -0,0 +1,299 @@ +import { CommonModule } from "@angular/common"; +import { Component, DestroyRef, OnInit } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; +import { FormBuilder, FormControl, ReactiveFormsModule } from "@angular/forms"; +import { Router } from "@angular/router"; +import { catchError, defer, firstValueFrom, from, map, of, switchMap, throwError } from "rxjs"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { + LoginEmailServiceAbstraction, + UserDecryptionOptions, + UserDecryptionOptionsServiceAbstraction, +} from "@bitwarden/auth/common"; +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 { 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"; +import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; +import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; +import { UserId } from "@bitwarden/common/types/guid"; +import { + AsyncActionsModule, + ButtonModule, + CheckboxModule, + FormFieldModule, + ToastService, + TypographyModule, +} from "@bitwarden/components"; +import { KeyService } from "@bitwarden/key-management"; + +import { AnonLayoutWrapperDataService } from "../anon-layout/anon-layout-wrapper-data.service"; + +import { LoginDecryptionOptionsService } from "./login-decryption-options.service"; + +enum State { + NewUser, + ExistingUserUntrustedDevice, +} + +@Component({ + standalone: true, + templateUrl: "./login-decryption-options.component.html", + imports: [ + AsyncActionsModule, + ButtonModule, + CheckboxModule, + CommonModule, + FormFieldModule, + JslibModule, + ReactiveFormsModule, + TypographyModule, + ], +}) +export class LoginDecryptionOptionsComponent implements OnInit { + private activeAccountId: UserId; + private clientType: ClientType; + private email: string; + + protected loading = false; + protected state: State; + protected State = State; + + protected formGroup = this.formBuilder.group({ + rememberDevice: [true], // Remember device means for the user to trust the device + }); + + private get rememberDeviceControl(): FormControl { + return this.formGroup.controls.rememberDevice; + } + + // New User Properties + private newUserOrgId: string; + + // Existing User Untrusted Device Properties + protected canApproveFromOtherDevice = false; + protected canRequestAdminApproval = false; + protected canApproveWithMasterPassword = false; + + constructor( + private accountService: AccountService, + private anonLayoutWrapperDataService: AnonLayoutWrapperDataService, + private apiService: ApiService, + private destroyRef: DestroyRef, + private deviceTrustService: DeviceTrustServiceAbstraction, + private formBuilder: FormBuilder, + private i18nService: I18nService, + private keyService: KeyService, + private loginDecryptionOptionsService: LoginDecryptionOptionsService, + private loginEmailService: LoginEmailServiceAbstraction, + private messagingService: MessagingService, + private organizationApiService: OrganizationApiServiceAbstraction, + private passwordResetEnrollmentService: PasswordResetEnrollmentServiceAbstraction, + private platformUtilsService: PlatformUtilsService, + private router: Router, + private ssoLoginService: SsoLoginServiceAbstraction, + private toastService: ToastService, + private userDecryptionOptionsService: UserDecryptionOptionsServiceAbstraction, + private validationService: ValidationService, + ) { + this.clientType === this.platformUtilsService.getClientType(); + } + + async ngOnInit() { + this.loading = true; + + this.activeAccountId = (await firstValueFrom(this.accountService.activeAccount$))?.id; + + this.email = await firstValueFrom( + this.accountService.activeAccount$.pipe(map((a) => a?.email)), + ); + + if (!this.email) { + await this.handleMissingEmail(); + return; + } + + this.observeAndPersistRememberDeviceValueChanges(); + await this.setRememberDeviceDefaultValueFromState(); + + try { + const userDecryptionOptions = await firstValueFrom( + this.userDecryptionOptionsService.userDecryptionOptions$, + ); + + if ( + !userDecryptionOptions?.trustedDeviceOption?.hasAdminApproval && + !userDecryptionOptions?.hasMasterPassword + ) { + /** + * We are dealing with a new account if both are true: + * - User does NOT have admin approval (i.e. has not enrolled in admin reset) + * - User does NOT have a master password + */ + await this.loadNewUserData(); + } else { + this.loadExistingUserUntrustedDeviceData(userDecryptionOptions); + } + } catch (err) { + this.validationService.showError(err); + } finally { + this.loading = false; + } + } + + private async handleMissingEmail() { + this.toastService.showToast({ + variant: "error", + title: null, + message: this.i18nService.t("activeUserEmailNotFoundLoggingYouOut"), + }); + + setTimeout(async () => { + // We can't simply redirect to `/login` because the user is authed and the unauthGuard + // will prevent navigation. We must logout the user first via messagingService, which + // redirects to `/`, which will be handled by the redirectGuard to navigate the user to `/login`. + // The timeout just gives the user a chance to see the error toast before process reload runs on logout. + await this.loginDecryptionOptionsService.logOut(); + }, 5000); + } + + private observeAndPersistRememberDeviceValueChanges() { + this.rememberDeviceControl.valueChanges + .pipe( + takeUntilDestroyed(this.destroyRef), + switchMap((value) => + defer(() => this.deviceTrustService.setShouldTrustDevice(this.activeAccountId, value)), + ), + ) + .subscribe(); + } + + private async setRememberDeviceDefaultValueFromState() { + const rememberDeviceFromState = await this.deviceTrustService.getShouldTrustDevice( + this.activeAccountId, + ); + + const rememberDevice = rememberDeviceFromState ?? true; + + this.rememberDeviceControl.setValue(rememberDevice); + } + + private async loadNewUserData() { + this.state = State.NewUser; + + this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({ + pageTitle: { + key: "loggedInExclamation", + }, + pageSubtitle: { + key: "rememberThisDeviceToMakeFutureLoginsSeamless", + }, + }); + + const autoEnrollStatus$ = defer(() => + this.ssoLoginService.getActiveUserOrganizationSsoIdentifier(), + ).pipe( + switchMap((organizationIdentifier) => { + if (organizationIdentifier == undefined) { + return throwError(() => new Error(this.i18nService.t("ssoIdentifierRequired"))); + } + + return from(this.organizationApiService.getAutoEnrollStatus(organizationIdentifier)); + }), + catchError((err: unknown) => { + this.validationService.showError(err); + return of(undefined); + }), + ); + + const autoEnrollStatus = await firstValueFrom(autoEnrollStatus$); + + this.newUserOrgId = autoEnrollStatus.id; + } + + private loadExistingUserUntrustedDeviceData(userDecryptionOptions: UserDecryptionOptions) { + this.state = State.ExistingUserUntrustedDevice; + + this.anonLayoutWrapperDataService.setAnonLayoutWrapperData({ + pageTitle: { + key: "deviceApprovalRequiredV2", + }, + pageSubtitle: { + key: "selectAnApprovalOptionBelow", + }, + }); + + this.canApproveFromOtherDevice = + userDecryptionOptions?.trustedDeviceOption?.hasLoginApprovingDevice || false; + this.canRequestAdminApproval = + userDecryptionOptions?.trustedDeviceOption?.hasAdminApproval || false; + this.canApproveWithMasterPassword = userDecryptionOptions?.hasMasterPassword || false; + } + + protected createUser = async () => { + if (this.state !== State.NewUser) { + return; + } + + try { + const { publicKey, privateKey } = await this.keyService.initAccount(); + const keysRequest = new KeysRequest(publicKey, privateKey.encryptedString); + await this.apiService.postAccountKeys(keysRequest); + + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("accountSuccessfullyCreated"), + }); + + await this.passwordResetEnrollmentService.enroll(this.newUserOrgId); + + if (this.formGroup.value.rememberDevice) { + await this.deviceTrustService.trustDevice(this.activeAccountId); + } + + await this.loginDecryptionOptionsService.handleCreateUserSuccess(); + + if (this.clientType === ClientType.Desktop) { + this.messagingService.send("redrawMenu"); + } + + await this.handleCreateUserSuccessNavigation(); + } catch (err) { + this.validationService.showError(err); + } + }; + + private async handleCreateUserSuccessNavigation() { + if (this.clientType === ClientType.Browser) { + await this.router.navigate(["/tabs/vault"]); + } else { + await this.router.navigate(["/vault"]); + } + } + + protected async approveFromOtherDevice() { + this.loginEmailService.setLoginEmail(this.email); + await this.router.navigate(["/login-with-device"]); + } + + protected async approveWithMasterPassword() { + await this.router.navigate(["/lock"], { + queryParams: { + from: "login-initiated", + }, + }); + } + + protected async requestAdminApproval() { + this.loginEmailService.setLoginEmail(this.email); + await this.router.navigate(["/admin-approval-requested"]); + } +} diff --git a/libs/auth/src/angular/login-decryption-options/login-decryption-options.service.ts b/libs/auth/src/angular/login-decryption-options/login-decryption-options.service.ts new file mode 100644 index 00000000000..d81d56d6393 --- /dev/null +++ b/libs/auth/src/angular/login-decryption-options/login-decryption-options.service.ts @@ -0,0 +1,10 @@ +export abstract class LoginDecryptionOptionsService { + /** + * Handles client-specific logic that runs after a user was successfully created + */ + abstract handleCreateUserSuccess(): Promise; + /** + * Logs the user out + */ + abstract logOut(): Promise; +} From 9e9f977eb3b2f662080b5b446fe5fca883f9001e Mon Sep 17 00:00:00 2001 From: Thomas Rittson <31796059+eliykat@users.noreply.github.com> Date: Fri, 22 Nov 2024 07:58:03 +1000 Subject: [PATCH 15/16] [PM-11360] Remove export permission for providers (#12062) * Split organization.canAccessImportExport * Fix import permission to include CanCreateNewCollections * Remove provider export permission (feature flagged) --- apps/cli/src/tools/import.command.ts | 2 +- .../organization-layout.component.html | 4 +- .../layouts/organization-layout.component.ts | 40 ++++++++----------- .../organization-settings-routing.module.ts | 32 ++++++++++++--- .../navigation-switcher.stories.ts | 24 +++++++++-- .../product-switcher.stories.ts | 24 +++++++++-- .../shared/product-switcher.service.spec.ts | 23 +++++++++-- .../organization.service.abstraction.ts | 31 +------------- .../vnext.organization.service.ts | 19 +-------- .../models/domain/organization.ts | 23 ++++++++++- libs/common/src/enums/feature-flag.enum.ts | 2 + .../src/components/import.component.ts | 15 +++---- 12 files changed, 142 insertions(+), 97 deletions(-) diff --git a/apps/cli/src/tools/import.command.ts b/apps/cli/src/tools/import.command.ts index 1cb3ac19f6b..879b2313baf 100644 --- a/apps/cli/src/tools/import.command.ts +++ b/apps/cli/src/tools/import.command.ts @@ -27,7 +27,7 @@ export class ImportCommand { ); } - if (!organization.canAccessImportExport) { + if (!organization.canAccessImport) { return Response.badRequest( "You are not authorized to import into the provided organization.", ); diff --git a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html index aaba492dff8..1e811b6c29d 100644 --- a/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html +++ b/apps/web/src/app/admin-console/organizations/layouts/organization-layout.component.html @@ -84,12 +84,12 @@ canAccessOrgAdmin(org); organization$: Observable; + canAccessExport$: Observable; showPaymentAndHistory$: Observable; hideNewOrgButton$: Observable; organizationIsUnmanaged$: Observable; isAccessIntelligenceFeatureEnabled = false; - private _destroy = new Subject(); - constructor( private route: ActivatedRoute, private organizationService: OrganizationService, @@ -71,23 +70,23 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy { FeatureFlag.AccessIntelligence, ); - this.organization$ = this.route.params - .pipe(takeUntil(this._destroy)) - .pipe(map((p) => p.organizationId)) - .pipe( - mergeMap((id) => { - return this.organizationService.organizations$ - .pipe(takeUntil(this._destroy)) - .pipe(getOrganizationById(id)); - }), - ); + this.organization$ = this.route.params.pipe( + map((p) => p.organizationId), + switchMap((id) => this.organizationService.organizations$.pipe(getById(id))), + filter((org) => org != null), + ); + + this.canAccessExport$ = combineLatest([ + this.organization$, + this.configService.getFeatureFlag$(FeatureFlag.PM11360RemoveProviderExportPermission), + ]).pipe(map(([org, removeProviderExport]) => org.canAccessExport(removeProviderExport))); this.showPaymentAndHistory$ = this.organization$.pipe( map( (org) => !this.platformUtilsService.isSelfHost() && - org?.canViewBillingHistory && - org?.canEditPaymentMethods, + org.canViewBillingHistory && + org.canEditPaymentMethods, ), ); @@ -107,11 +106,6 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy { ); } - ngOnDestroy() { - this._destroy.next(); - this._destroy.complete(); - } - canShowVaultTab(organization: Organization): boolean { return canAccessVaultTab(organization); } diff --git a/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts b/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts index 4e9180ef123..d7fad9fded2 100644 --- a/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts +++ b/apps/web/src/app/admin-console/organizations/settings/organization-settings-routing.module.ts @@ -1,8 +1,11 @@ -import { NgModule } from "@angular/core"; -import { RouterModule, Routes } from "@angular/router"; +import { inject, NgModule } from "@angular/core"; +import { CanMatchFn, RouterModule, Routes } from "@angular/router"; +import { map } from "rxjs"; import { canAccessSettingsTab } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { organizationPermissionsGuard } from "../../organizations/guards/org-permissions.guard"; import { organizationRedirectGuard } from "../../organizations/guards/org-redirect.guard"; @@ -11,6 +14,11 @@ import { PoliciesComponent } from "../../organizations/policies"; import { AccountComponent } from "./account.component"; import { TwoFactorSetupComponent } from "./two-factor-setup.component"; +const removeProviderExportPermission$: CanMatchFn = () => + inject(ConfigService) + .getFeatureFlag$(FeatureFlag.PM11360RemoveProviderExportPermission) + .pipe(map((removeProviderExport) => removeProviderExport === true)); + const routes: Routes = [ { path: "", @@ -53,18 +61,32 @@ const routes: Routes = [ path: "import", loadComponent: () => import("./org-import.component").then((mod) => mod.OrgImportComponent), - canActivate: [organizationPermissionsGuard((org) => org.canAccessImportExport)], + canActivate: [organizationPermissionsGuard((org) => org.canAccessImport)], data: { titleId: "importData", }, }, + + // Export routing is temporarily duplicated to set the flag value passed into org.canAccessExport + { + path: "export", + loadComponent: () => + import("../tools/vault-export/org-vault-export.component").then( + (mod) => mod.OrganizationVaultExportComponent, + ), + canMatch: [removeProviderExportPermission$], // if this matches, the flag is ON + canActivate: [organizationPermissionsGuard((org) => org.canAccessExport(true))], + data: { + titleId: "exportVault", + }, + }, { path: "export", loadComponent: () => import("../tools/vault-export/org-vault-export.component").then( (mod) => mod.OrganizationVaultExportComponent, ), - canActivate: [organizationPermissionsGuard((org) => org.canAccessImportExport)], + canActivate: [organizationPermissionsGuard((org) => org.canAccessExport(false))], data: { titleId: "exportVault", }, @@ -82,7 +104,7 @@ function getSettingsRoute(organization: Organization) { if (organization.canManagePolicies) { return "policies"; } - if (organization.canAccessImportExport) { + if (organization.canAccessImport) { return ["tools", "import"]; } if (organization.canManageSso) { diff --git a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts index cd1a77a9ec4..a7ff50b4264 100644 --- a/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/navigation-switcher/navigation-switcher.stories.ts @@ -152,7 +152,13 @@ export const SMAvailable: Story = { ...Template, args: { mockOrgs: [ - { id: "org-a", canManageUsers: false, canAccessSecretsManager: true, enabled: true }, + { + id: "org-a", + canManageUsers: false, + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => false, + }, ] as Organization[], mockProviders: [], }, @@ -162,7 +168,13 @@ export const SMAndACAvailable: Story = { ...Template, args: { mockOrgs: [ - { id: "org-a", canManageUsers: true, canAccessSecretsManager: true, enabled: true }, + { + id: "org-a", + canManageUsers: true, + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => false, + }, ] as Organization[], mockProviders: [], }, @@ -172,7 +184,13 @@ export const WithAllOptions: Story = { ...Template, args: { mockOrgs: [ - { id: "org-a", canManageUsers: true, canAccessSecretsManager: true, enabled: true }, + { + id: "org-a", + canManageUsers: true, + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => false, + }, ] as Organization[], mockProviders: [{ id: "provider-a" }] as Provider[], }, diff --git a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts index b9d1d394920..b53d0243f64 100644 --- a/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts +++ b/apps/web/src/app/layouts/product-switcher/product-switcher.stories.ts @@ -171,7 +171,13 @@ export const WithSM: Story = { ...Template, args: { mockOrgs: [ - { id: "org-a", canManageUsers: false, canAccessSecretsManager: true, enabled: true }, + { + id: "org-a", + canManageUsers: false, + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => false, + }, ] as Organization[], mockProviders: [], }, @@ -181,7 +187,13 @@ export const WithSMAndAC: Story = { ...Template, args: { mockOrgs: [ - { id: "org-a", canManageUsers: true, canAccessSecretsManager: true, enabled: true }, + { + id: "org-a", + canManageUsers: true, + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => false, + }, ] as Organization[], mockProviders: [], }, @@ -191,7 +203,13 @@ export const WithAllOptions: Story = { ...Template, args: { mockOrgs: [ - { id: "org-a", canManageUsers: true, canAccessSecretsManager: true, enabled: true }, + { + id: "org-a", + canManageUsers: true, + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => false, + }, ] as Organization[], mockProviders: [{ id: "provider-a" }] as Provider[], }, diff --git a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts index 07a41e7c94c..7c53cd86d3b 100644 --- a/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts +++ b/apps/web/src/app/layouts/product-switcher/shared/product-switcher.service.spec.ts @@ -110,7 +110,12 @@ describe("ProductSwitcherService", () => { it("is included in bento when there is an organization with SM", async () => { organizationService.organizations$ = of([ - { id: "1234", canAccessSecretsManager: true, enabled: true }, + { + id: "1234", + canAccessSecretsManager: true, + enabled: true, + canAccessExport: (_) => true, + }, ] as Organization[]); initiateService(); @@ -220,8 +225,20 @@ describe("ProductSwitcherService", () => { router.url = "/sm/4243"; organizationService.organizations$ = of([ - { id: "23443234", canAccessSecretsManager: true, enabled: true, name: "Org 2" }, - { id: "4243", canAccessSecretsManager: true, enabled: true, name: "Org 32" }, + { + id: "23443234", + canAccessSecretsManager: true, + enabled: true, + name: "Org 2", + canAccessExport: (_) => true, + }, + { + id: "4243", + canAccessSecretsManager: true, + enabled: true, + name: "Org 32", + canAccessExport: (_) => true, + }, ] as Organization[]); initiateService(); diff --git a/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts b/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts index a2ea6aa8861..e687c0a34a7 100644 --- a/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts +++ b/libs/common/src/admin-console/abstractions/organization/organization.service.abstraction.ts @@ -1,7 +1,5 @@ import { map, Observable } from "rxjs"; -import { I18nService } from "../../../platform/abstractions/i18n.service"; -import { Utils } from "../../../platform/misc/utils"; import { UserId } from "../../../types/guid"; import { OrganizationData } from "../../models/data/organization.data"; import { Organization } from "../../models/domain/organization"; @@ -16,7 +14,8 @@ export function canAccessSettingsTab(org: Organization): boolean { org.canManagePolicies || org.canManageSso || org.canManageScim || - org.canAccessImportExport || + org.canAccessImport || + org.canAccessExport(false) || // Feature flag value doesn't matter here, providers will have access to this group anyway org.canManageDeviceApprovals ); } @@ -56,32 +55,6 @@ export function getOrganizationById(id: string) { return map((orgs) => orgs.find((o) => o.id === id)); } -export function canAccessAdmin(i18nService: I18nService) { - return map((orgs) => - orgs.filter(canAccessOrgAdmin).sort(Utils.getSortFunction(i18nService, "name")), - ); -} - -/** - * @deprecated - * To be removed after Flexible Collections. - **/ -export function canAccessImportExport(i18nService: I18nService) { - return map((orgs) => - orgs - .filter((org) => org.canAccessImportExport) - .sort(Utils.getSortFunction(i18nService, "name")), - ); -} - -export function canAccessImport(i18nService: I18nService) { - return map((orgs) => - orgs - .filter((org) => org.canAccessImportExport || org.canCreateNewCollections) - .sort(Utils.getSortFunction(i18nService, "name")), - ); -} - /** * Returns `true` if a user is a member of an organization (rather than only being a ProviderUser) * @deprecated Use organizationService.organizations$ with a filter instead diff --git a/libs/common/src/admin-console/abstractions/organization/vnext.organization.service.ts b/libs/common/src/admin-console/abstractions/organization/vnext.organization.service.ts index 45c00e3fd4a..68c61e298ae 100644 --- a/libs/common/src/admin-console/abstractions/organization/vnext.organization.service.ts +++ b/libs/common/src/admin-console/abstractions/organization/vnext.organization.service.ts @@ -1,7 +1,5 @@ import { map, Observable } from "rxjs"; -import { I18nService } from "../../../platform/abstractions/i18n.service"; -import { Utils } from "../../../platform/misc/utils"; import { UserId } from "../../../types/guid"; import { OrganizationData } from "../../models/data/organization.data"; import { Organization } from "../../models/domain/organization"; @@ -16,7 +14,8 @@ export function canAccessSettingsTab(org: Organization): boolean { org.canManagePolicies || org.canManageSso || org.canManageScim || - org.canAccessImportExport || + org.canAccessImport || + org.canAccessExport(false) || // Feature flag value doesn't matter here, providers will have access to this group anyway org.canManageDeviceApprovals ); } @@ -56,20 +55,6 @@ export function getOrganizationById(id: string) { return map((orgs) => orgs.find((o) => o.id === id)); } -export function canAccessAdmin(i18nService: I18nService) { - return map((orgs) => - orgs.filter(canAccessOrgAdmin).sort(Utils.getSortFunction(i18nService, "name")), - ); -} - -export function canAccessImport(i18nService: I18nService) { - return map((orgs) => - orgs - .filter((org) => org.canAccessImportExport || org.canCreateNewCollections) - .sort(Utils.getSortFunction(i18nService, "name")), - ); -} - /** * Publishes an observable stream of organizations. This service is meant to * be used widely across Bitwarden as the primary way of fetching organizations. diff --git a/libs/common/src/admin-console/models/domain/organization.ts b/libs/common/src/admin-console/models/domain/organization.ts index 070617b9e5f..2ff17ca119c 100644 --- a/libs/common/src/admin-console/models/domain/organization.ts +++ b/libs/common/src/admin-console/models/domain/organization.ts @@ -168,8 +168,27 @@ export class Organization { return (this.isAdmin || this.permissions.accessEventLogs) && this.useEvents; } - get canAccessImportExport() { - return this.isAdmin || this.permissions.accessImportExport; + get canAccessImport() { + return ( + this.isProviderUser || + this.type === OrganizationUserType.Owner || + this.type === OrganizationUserType.Admin || + this.permissions.accessImportExport || + this.canCreateNewCollections // To allow users to create collections and then import into them + ); + } + + canAccessExport(removeProviderExport: boolean) { + if (!removeProviderExport && this.isProviderUser) { + return true; + } + + return ( + this.isMember && + (this.type === OrganizationUserType.Owner || + this.type === OrganizationUserType.Admin || + this.permissions.accessImportExport) + ); } get canAccessReports() { diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index ec5a8e47d73..6dafe8fc7fe 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -40,6 +40,7 @@ export enum FeatureFlag { NewDeviceVerificationTemporaryDismiss = "new-device-temporary-dismiss", NewDeviceVerificationPermanentDismiss = "new-device-permanent-dismiss", DisableFreeFamiliesSponsorship = "PM-12274-disable-free-families-sponsorship", + PM11360RemoveProviderExportPermission = "pm-11360-remove-provider-export-permission", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -90,6 +91,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.NewDeviceVerificationTemporaryDismiss]: FALSE, [FeatureFlag.NewDeviceVerificationPermanentDismiss]: FALSE, [FeatureFlag.DisableFreeFamiliesSponsorship]: FALSE, + [FeatureFlag.PM11360RemoveProviderExportPermission]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; diff --git a/libs/importer/src/components/import.component.ts b/libs/importer/src/components/import.component.ts index 1ffe2728b05..1ab300fc378 100644 --- a/libs/importer/src/components/import.component.ts +++ b/libs/importer/src/components/import.component.ts @@ -21,10 +21,7 @@ import { JslibModule } from "@bitwarden/angular/jslib.module"; import { safeProvider, SafeProvider } from "@bitwarden/angular/platform/utils/safe-provider"; import { PinServiceAbstraction } from "@bitwarden/auth/common"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; -import { - canAccessImport, - OrganizationService, -} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; +import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; @@ -226,7 +223,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { this.setImportOptions(); await this.initializeOrganizations(); - if (this.organizationId && (await this.canAccessImportExport(this.organizationId))) { + if (this.organizationId && (await this.canAccessImport(this.organizationId))) { this.handleOrganizationImportInit(); } else { this.handleImportInit(); @@ -289,7 +286,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { private async initializeOrganizations() { this.organizations$ = concat( this.organizationService.memberOrganizations$.pipe( - canAccessImport(this.i18nService), + map((orgs) => orgs.filter((org) => org.canAccessImport)), map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))), ), ); @@ -375,7 +372,7 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { importContents, this.organizationId, this.formGroup.controls.targetSelector.value, - (await this.canAccessImportExport(this.organizationId)) && this.isFromAC, + (await this.canAccessImport(this.organizationId)) && this.isFromAC, ); //No errors, display success message @@ -395,11 +392,11 @@ export class ImportComponent implements OnInit, OnDestroy, AfterViewInit { } } - private async canAccessImportExport(organizationId?: string): Promise { + private async canAccessImport(organizationId?: string): Promise { if (!organizationId) { return false; } - return (await this.organizationService.get(this.organizationId))?.canAccessImportExport; + return (await this.organizationService.get(this.organizationId))?.canAccessImport; } getFormatInstructionTitle() { From e6c68b7138a7db42fe93434e96f99eac5fba7652 Mon Sep 17 00:00:00 2001 From: Addison Beck Date: Thu, 21 Nov 2024 22:58:21 -0500 Subject: [PATCH 16/16] Remove `LimitCollectionCreationDeletionSplit` feature flag (#11258) * Remove references to feature flag * Remove feature flag enum --- .../settings/account.component.html | 31 +++------ .../settings/account.component.ts | 67 +++---------------- apps/web/src/locales/en/messages.json | 3 - .../models/data/organization.data.spec.ts | 2 - .../models/data/organization.data.ts | 4 -- .../models/domain/organization.ts | 6 +- ...on-collection-management-update.request.ts | 2 - .../models/response/organization.response.ts | 6 -- .../response/profile-organization.response.ts | 6 -- libs/common/src/enums/feature-flag.enum.ts | 2 - 10 files changed, 21 insertions(+), 108 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/settings/account.component.html b/apps/web/src/app/admin-console/organizations/settings/account.component.html index d1a1a091929..b3fac56c0bb 100644 --- a/apps/web/src/app/admin-console/organizations/settings/account.component.html +++ b/apps/web/src/app/admin-console/organizations/settings/account.component.html @@ -52,11 +52,7 @@

{{ "collectionManagement" | i18n }}

{{ "collectionManagementDesc" | i18n }}

@@ -64,24 +60,15 @@ {{ "allowAdminAccessToAllCollectionItemsDesc" | i18n }} - - - {{ "limitCollectionCreationDesc" | i18n }} - - - - {{ "limitCollectionDeletionDesc" | i18n }} - - - - - - {{ "limitCollectionCreationDeletionDesc" | i18n }} - - - + + {{ "limitCollectionCreationDesc" | i18n }} + + + + {{ "limitCollectionDeletionDesc" | i18n }} + +