diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 4bd656a282..a29a42a07a 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -13,6 +13,9 @@ "loginOrCreateNewAccount": { "message": "Log in or create a new account to access your secure vault." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "createAccount": { "message": "Create account" }, @@ -68,6 +71,12 @@ "masterPassHint": { "message": "Master password hint (optional)" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "tab": { "message": "Tab" }, diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts index bb9d038378..57195564c7 100644 --- a/apps/browser/src/popup/app-routing.module.ts +++ b/apps/browser/src/popup/app-routing.module.ts @@ -16,6 +16,7 @@ import { RegistrationStartComponent, RegistrationStartSecondaryComponent, RegistrationStartSecondaryComponentData, + SetPasswordJitComponent, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -409,6 +410,15 @@ const routes: Routes = [ }, ], }, + { + path: "set-password-jit", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification)], + component: SetPasswordJitComponent, + data: { + pageTitle: "joinOrganization", + pageSubtitle: "finishJoiningThisOrganizationBySettingAMasterPassword", + } satisfies AnonLayoutWrapperData, + }, ], }, { diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index 0e3f10345a..a93299e45a 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -16,6 +16,7 @@ import { RegistrationStartComponent, RegistrationStartSecondaryComponent, RegistrationStartSecondaryComponentData, + SetPasswordJitComponent, } from "@bitwarden/auth/angular"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; @@ -149,6 +150,15 @@ const routes: Routes = [ }, ], }, + { + path: "set-password-jit", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification)], + component: SetPasswordJitComponent, + data: { + pageTitle: "joinOrganization", + pageSubtitle: "finishJoiningThisOrganizationBySettingAMasterPassword", + } satisfies AnonLayoutWrapperData, + }, ], }, ]; diff --git a/apps/desktop/src/app/services/desktop-set-password-jit.service.ts b/apps/desktop/src/app/services/desktop-set-password-jit.service.ts new file mode 100644 index 0000000000..f6ea3d0ce8 --- /dev/null +++ b/apps/desktop/src/app/services/desktop-set-password-jit.service.ts @@ -0,0 +1,21 @@ +import { inject } from "@angular/core"; + +import { + DefaultSetPasswordJitService, + SetPasswordCredentials, + SetPasswordJitService, +} from "@bitwarden/auth/angular"; +import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; + +export class DesktopSetPasswordJitService + extends DefaultSetPasswordJitService + implements SetPasswordJitService +{ + messagingService = inject(MessagingService); + + override async setPassword(credentials: SetPasswordCredentials) { + await super.setPassword(credentials); + + this.messagingService.send("redrawMenu"); + } +} diff --git a/apps/desktop/src/app/services/services.module.ts b/apps/desktop/src/app/services/services.module.ts index c0b4bf4eb1..85bfbc09f6 100644 --- a/apps/desktop/src/app/services/services.module.ts +++ b/apps/desktop/src/app/services/services.module.ts @@ -18,16 +18,30 @@ import { CLIENT_TYPE, } from "@bitwarden/angular/services/injection-tokens"; import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module"; +import { SetPasswordJitService } from "@bitwarden/auth/angular"; +import { + InternalUserDecryptionOptionsServiceAbstraction, + PinServiceAbstraction, +} from "@bitwarden/auth/common"; +import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service"; +import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; +import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service"; import { PolicyService as PolicyServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService as AccountServiceAbstraction } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService as AuthServiceAbstraction } from "@bitwarden/common/auth/abstractions/auth.service"; -import { KdfConfigService as KdfConfigServiceAbstraction } from "@bitwarden/common/auth/abstractions/kdf-config.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 { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; import { ClientType } from "@bitwarden/common/enums"; import { CryptoFunctionService as CryptoFunctionServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto-function.service"; -import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service"; +import { + CryptoService, + CryptoService as CryptoServiceAbstraction, +} from "@bitwarden/common/platform/abstractions/crypto.service"; import { EncryptService } from "@bitwarden/common/platform/abstractions/encrypt.service"; import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service"; import { I18nService as I18nServiceAbstraction } from "@bitwarden/common/platform/abstractions/i18n.service"; @@ -56,7 +70,6 @@ import { CipherService as CipherServiceAbstraction } from "@bitwarden/common/vau import { DialogService } from "@bitwarden/components"; import { PasswordGenerationServiceAbstraction } from "@bitwarden/generator-legacy"; -import { PinServiceAbstraction } from "../../../../../libs/auth/src/common/abstractions"; import { DesktopAutofillSettingsService } from "../../autofill/services/desktop-autofill-settings.service"; import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; import { ElectronCryptoService } from "../../platform/services/electron-crypto.service"; @@ -77,6 +90,7 @@ import { NativeMessagingService } from "../../services/native-messaging.service" import { SearchBarService } from "../layout/search/search-bar.service"; import { DesktopFileDownloadService } from "./desktop-file-download.service"; +import { DesktopSetPasswordJitService } from "./desktop-set-password-jit.service"; import { InitService } from "./init.service"; import { NativeMessagingManifestService } from "./native-messaging-manifest.service"; import { RendererCryptoFunctionService } from "./renderer-crypto-function.service"; @@ -254,6 +268,20 @@ const safeProviders: SafeProvider[] = [ provide: CLIENT_TYPE, useValue: ClientType.Desktop, }), + safeProvider({ + provide: SetPasswordJitService, + useClass: DesktopSetPasswordJitService, + deps: [ + ApiService, + CryptoService, + I18nServiceAbstraction, + KdfConfigService, + InternalMasterPasswordServiceAbstraction, + OrganizationApiServiceAbstraction, + OrganizationUserService, + InternalUserDecryptionOptionsServiceAbstraction, + ], + }), ]; @NgModule({ diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json index 7b7dc28b31..868367cf18 100644 --- a/apps/desktop/src/locales/en/messages.json +++ b/apps/desktop/src/locales/en/messages.json @@ -551,6 +551,12 @@ "masterPassHintLabel": { "message": "Master password hint" }, + "joinOrganization": { + "message": "Join organization" + }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "settings": { "message": "Settings" }, @@ -2093,6 +2099,9 @@ "vaultTimeoutTooLarge": { "message": "Your vault timeout exceeds the restrictions set by your organization." }, + "inviteAccepted": { + "message": "Invitation accepted" + }, "resetPasswordPolicyAutoEnroll": { "message": "Automatic enrollment" }, diff --git a/apps/web/src/app/auth/core/services/index.ts b/apps/web/src/app/auth/core/services/index.ts index 6a28efcbaa..c85f0f3204 100644 --- a/apps/web/src/app/auth/core/services/index.ts +++ b/apps/web/src/app/auth/core/services/index.ts @@ -1,2 +1,3 @@ export * from "./webauthn-login"; +export * from "./set-password-jit"; export * from "./registration"; 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 999e603ef6..007165a1bc 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 @@ -145,6 +145,7 @@ describe("DefaultRegistrationFinishService", () => { passwordInputResult = { masterKey: masterKey, masterKeyHash: "masterKeyHash", + localMasterKeyHash: "localMasterKeyHash", kdfConfig: DEFAULT_KDF_CONFIG, hint: "hint", }; diff --git a/apps/web/src/app/auth/core/services/set-password-jit/index.ts b/apps/web/src/app/auth/core/services/set-password-jit/index.ts new file mode 100644 index 0000000000..fc119fd964 --- /dev/null +++ b/apps/web/src/app/auth/core/services/set-password-jit/index.ts @@ -0,0 +1 @@ +export * from "./web-set-password-jit.service"; diff --git a/apps/web/src/app/auth/core/services/set-password-jit/web-set-password-jit.service.ts b/apps/web/src/app/auth/core/services/set-password-jit/web-set-password-jit.service.ts new file mode 100644 index 0000000000..62175f1256 --- /dev/null +++ b/apps/web/src/app/auth/core/services/set-password-jit/web-set-password-jit.service.ts @@ -0,0 +1,27 @@ +import { inject } from "@angular/core"; + +import { + DefaultSetPasswordJitService, + SetPasswordCredentials, + SetPasswordJitService, +} from "@bitwarden/auth/angular"; + +import { RouterService } from "../../../../core/router.service"; +import { AcceptOrganizationInviteService } from "../../../organization-invite/accept-organization.service"; + +export class WebSetPasswordJitService + extends DefaultSetPasswordJitService + implements SetPasswordJitService +{ + routerService = inject(RouterService); + acceptOrganizationInviteService = inject(AcceptOrganizationInviteService); + + override async setPassword(credentials: SetPasswordCredentials) { + await super.setPassword(credentials); + + // SSO JIT accepts org invites when setting their MP, meaning + // we can clear the deep linked url for accepting it. + await this.routerService.getAndClearLoginRedirectUrl(); + await this.acceptOrganizationInviteService.clearOrganizationInvitation(); + } +} diff --git a/apps/web/src/app/core/core.module.ts b/apps/web/src/app/core/core.module.ts index 93a5a9c00a..45cfa8a355 100644 --- a/apps/web/src/app/core/core.module.ts +++ b/apps/web/src/app/core/core.module.ts @@ -17,11 +17,20 @@ import { } from "@bitwarden/angular/services/injection-tokens"; import { JslibServicesModule } from "@bitwarden/angular/services/jslib-services.module"; import { ModalService as ModalServiceAbstraction } from "@bitwarden/angular/services/modal.service"; -import { RegistrationFinishService as RegistrationFinishServiceAbstraction } from "@bitwarden/auth/angular"; +import { + SetPasswordJitService, + RegistrationFinishService as RegistrationFinishServiceAbstraction, +} from "@bitwarden/auth/angular"; +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 { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service"; 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 { AccountApiService as AccountApiServiceAbstraction } from "@bitwarden/common/auth/abstractions/account-api.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 { ClientType } from "@bitwarden/common/enums"; import { CryptoService as CryptoServiceAbstraction } from "@bitwarden/common/platform/abstractions/crypto.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -48,7 +57,7 @@ import { import { VaultTimeout, VaultTimeoutStringType } from "@bitwarden/common/types/vault-timeout.type"; import { PolicyListService } from "../admin-console/core/policy-list.service"; -import { WebRegistrationFinishService } from "../auth"; +import { WebSetPasswordJitService, WebRegistrationFinishService } from "../auth"; import { AcceptOrganizationInviteService } from "../auth/organization-invite/accept-organization.service"; import { HtmlStorageService } from "../core/html-storage.service"; import { I18nService } from "../core/i18n.service"; @@ -184,6 +193,20 @@ const safeProviders: SafeProvider[] = [ PolicyService, ], }), + safeProvider({ + provide: SetPasswordJitService, + useClass: WebSetPasswordJitService, + deps: [ + ApiService, + CryptoServiceAbstraction, + I18nServiceAbstraction, + KdfConfigService, + InternalMasterPasswordServiceAbstraction, + OrganizationApiServiceAbstraction, + OrganizationUserService, + InternalUserDecryptionOptionsServiceAbstraction, + ], + }), ]; @NgModule({ diff --git a/apps/web/src/app/oss-routing.module.ts b/apps/web/src/app/oss-routing.module.ts index a4172ad03e..6b382756f9 100644 --- a/apps/web/src/app/oss-routing.module.ts +++ b/apps/web/src/app/oss-routing.module.ts @@ -17,6 +17,7 @@ import { RegistrationStartComponent, RegistrationStartSecondaryComponent, RegistrationStartSecondaryComponentData, + SetPasswordJitComponent, LockIcon, RegistrationLinkExpiredComponent, } from "@bitwarden/auth/angular"; @@ -206,6 +207,15 @@ const routes: Routes = [ }, ], }, + { + path: "set-password-jit", + canActivate: [canAccessFeature(FeatureFlag.EmailVerification)], + component: SetPasswordJitComponent, + data: { + pageTitle: "joinOrganization", + pageSubtitle: "finishJoiningThisOrganizationBySettingAMasterPassword", + } satisfies AnonLayoutWrapperData, + }, { path: "signup-link-expired", canActivate: [canAccessFeature(FeatureFlag.EmailVerification), unauthGuardFn()], diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 6c16d8569f..04121c7894 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -3471,6 +3471,9 @@ "joinOrganizationDesc": { "message": "You've been invited to join the organization listed above. To accept the invitation, you need to log in or create a new Bitwarden account." }, + "finishJoiningThisOrganizationBySettingAMasterPassword": { + "message": "Finish joining this organization by setting a master password." + }, "inviteAccepted": { "message": "Invitation accepted" }, diff --git a/libs/angular/src/auth/components/sso.component.ts b/libs/angular/src/auth/components/sso.component.ts index 2c6f7b29cb..42119be360 100644 --- a/libs/angular/src/auth/components/sso.component.ts +++ b/libs/angular/src/auth/components/sso.component.ts @@ -17,6 +17,7 @@ import { SsoLoginServiceAbstraction } from "@bitwarden/common/auth/abstractions/ import { AuthResult } from "@bitwarden/common/auth/models/domain/auth-result"; import { ForceSetPasswordReason } from "@bitwarden/common/auth/models/domain/force-set-password-reason"; import { SsoPreValidateResponse } from "@bitwarden/common/auth/models/response/sso-pre-validate.response"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { CryptoFunctionService } from "@bitwarden/common/platform/abstractions/crypto-function.service"; import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; @@ -319,6 +320,14 @@ export class SsoComponent { } private async handleChangePasswordRequired(orgIdentifier: string) { + const emailVerification = await this.configService.getFeatureFlag( + FeatureFlag.EmailVerification, + ); + + if (emailVerification) { + this.changePasswordRoute = "set-password-jit"; + } + await this.navigateViaCallbackOrRoute( this.onSuccessfulLoginChangePasswordNavigate, [this.changePasswordRoute], diff --git a/libs/angular/src/services/jslib-services.module.ts b/libs/angular/src/services/jslib-services.module.ts index 56b2e956cd..3294e59751 100644 --- a/libs/angular/src/services/jslib-services.module.ts +++ b/libs/angular/src/services/jslib-services.module.ts @@ -2,6 +2,8 @@ import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core"; import { Subject } from "rxjs"; import { + SetPasswordJitService, + DefaultSetPasswordJitService, RegistrationFinishService as RegistrationFinishServiceAbstraction, DefaultRegistrationFinishService, } from "@bitwarden/auth/angular"; @@ -1265,6 +1267,20 @@ const safeProviders: SafeProvider[] = [ useClass: StripeService, deps: [LogService], }), + safeProvider({ + provide: SetPasswordJitService, + useClass: DefaultSetPasswordJitService, + deps: [ + ApiServiceAbstraction, + CryptoServiceAbstraction, + I18nServiceAbstraction, + KdfConfigServiceAbstraction, + InternalMasterPasswordServiceAbstraction, + OrganizationApiServiceAbstraction, + OrganizationUserService, + InternalUserDecryptionOptionsServiceAbstraction, + ], + }), safeProvider({ provide: RegisterRouteService, useClass: RegisterRouteService, diff --git a/libs/auth/src/angular/index.ts b/libs/auth/src/angular/index.ts index b594477243..f455f42eef 100644 --- a/libs/auth/src/angular/index.ts +++ b/libs/auth/src/angular/index.ts @@ -5,13 +5,26 @@ // icons export * from "./icons"; +// anon layout export * from "./anon-layout/anon-layout.component"; export * from "./anon-layout/anon-layout-wrapper.component"; + +// fingerprint dialog export * from "./fingerprint-dialog/fingerprint-dialog.component"; -export * from "./input-password/input-password.component"; + +// password callout export * from "./password-callout/password-callout.component"; export * from "./vault-timeout-input/vault-timeout-input.component"; +// input password +export * from "./input-password/input-password.component"; +export * from "./input-password/password-input-result"; + +// set password (JIT user) +export * from "./set-password-jit/set-password-jit.component"; +export * from "./set-password-jit/set-password-jit.service.abstraction"; +export * from "./set-password-jit/default-set-password-jit.service"; + // user verification export * from "./user-verification/user-verification-dialog.component"; export * from "./user-verification/user-verification-dialog.types"; @@ -25,6 +38,3 @@ export * from "./registration/registration-start/registration-start-secondary.co export * from "./registration/registration-env-selector/registration-env-selector.component"; export * from "./registration/registration-finish/registration-finish.service"; export * from "./registration/registration-finish/default-registration-finish.service"; - -// input password -export * from "./input-password/password-input-result"; diff --git a/libs/auth/src/angular/input-password/input-password.component.html b/libs/auth/src/angular/input-password/input-password.component.html index 42d67a77c9..54c832fbd6 100644 --- a/libs/auth/src/angular/input-password/input-password.component.html +++ b/libs/auth/src/angular/input-password/input-password.component.html @@ -23,7 +23,7 @@ {{ "important" | i18n }} {{ "masterPassImportant" | i18n }} - {{ minPasswordMsg }}. + {{ minPasswordLengthMsg }}. 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 7b5651492e..0fa5d0ac41 100644 --- a/libs/auth/src/angular/input-password/input-password.component.ts +++ b/libs/auth/src/angular/input-password/input-password.component.ts @@ -1,4 +1,4 @@ -import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; +import { Component, EventEmitter, Input, Output } from "@angular/core"; import { ReactiveFormsModule, FormBuilder, Validators } from "@angular/forms"; import { JslibModule } from "@bitwarden/angular/jslib.module"; @@ -12,6 +12,7 @@ import { MasterPasswordPolicyOptions } from "@bitwarden/common/admin-console/mod import { DEFAULT_KDF_CONFIG } from "@bitwarden/common/auth/models/domain/kdf-config"; import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { HashPurpose } from "@bitwarden/common/platform/enums"; import { Utils } from "@bitwarden/common/platform/misc/utils"; import { AsyncActionsModule, @@ -48,17 +49,16 @@ import { PasswordInputResult } from "./password-input-result"; JslibModule, ], }) -export class InputPasswordComponent implements OnInit { +export class InputPasswordComponent { @Output() onPasswordFormSubmit = new EventEmitter(); @Input({ required: true }) email: string; - @Input() protected buttonText: string; + @Input() buttonText: string; @Input() masterPasswordPolicyOptions: MasterPasswordPolicyOptions | null = null; @Input() loading: boolean = false; private minHintLength = 0; protected maxHintLength = 50; - protected minPasswordLength = Utils.minimumPasswordLength; protected minPasswordMsg = ""; protected passwordStrengthScore: PasswordStrengthScore; @@ -103,17 +103,14 @@ export class InputPasswordComponent implements OnInit { private toastService: ToastService, ) {} - async ngOnInit() { + get minPasswordLengthMsg() { if ( this.masterPasswordPolicyOptions != null && this.masterPasswordPolicyOptions.minLength > 0 ) { - this.minPasswordMsg = this.i18nService.t( - "characterMinimum", - this.masterPasswordPolicyOptions.minLength, - ); + return this.i18nService.t("characterMinimum", this.masterPasswordPolicyOptions.minLength); } else { - this.minPasswordMsg = this.i18nService.t("characterMinimum", this.minPasswordLength); + return this.i18nService.t("characterMinimum", this.minPasswordLength); } } @@ -181,9 +178,16 @@ export class InputPasswordComponent implements OnInit { const masterKeyHash = await this.cryptoService.hashMasterKey(password, masterKey); + const localMasterKeyHash = await this.cryptoService.hashMasterKey( + password, + masterKey, + HashPurpose.LocalAuthorization, + ); + this.onPasswordFormSubmit.emit({ masterKey, masterKeyHash, + localMasterKeyHash, kdfConfig, hint: this.formGroup.controls.hint.value, }); 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 0a74b88a2e..ce9f0b7386 100644 --- a/libs/auth/src/angular/input-password/password-input-result.ts +++ b/libs/auth/src/angular/input-password/password-input-result.ts @@ -4,6 +4,7 @@ import { MasterKey } from "@bitwarden/common/types/key"; export interface PasswordInputResult { masterKey: MasterKey; masterKeyHash: string; + localMasterKeyHash: string; kdfConfig: PBKDF2KdfConfig; hint: string; } diff --git a/libs/auth/src/angular/password-callout/password-callout.component.html b/libs/auth/src/angular/password-callout/password-callout.component.html index f8a73ab623..589d2a2045 100644 --- a/libs/auth/src/angular/password-callout/password-callout.component.html +++ b/libs/auth/src/angular/password-callout/password-callout.component.html @@ -1,7 +1,7 @@ {{ message | i18n }} -