diff --git a/jslib b/jslib index ed6978baff..7bf00b4fb3 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit ed6978baff5b129341bd46cc90a6155c1bcc5124 +Subproject commit 7bf00b4fb37d85d8ffe7aa3248bd72f304297331 diff --git a/src/app/accounts/change-password.component.html b/src/app/accounts/change-password.component.html index 460120a49d..42d3484c87 100644 --- a/src/app/accounts/change-password.component.html +++ b/src/app/accounts/change-password.component.html @@ -1,45 +1,81 @@ -
-

{{'setMasterPassword' | i18n}}

-
-{{'ssoCompleteRegistration' | i18n}} - - {{'masterPasswordPolicyInEffect' | i18n}} - - -
-
-
-
- - - -
-
-
-
- - +
+
+

{{'setMasterPassword' | i18n}}

+
+
+ {{'ssoCompleteRegistration' | i18n}} +
+ + {{'masterPasswordPolicyInEffect' | i18n}} +
    +
  • + {{'policyInEffectMinComplexity' | i18n : getPasswordScoreAlertDisplay()}} +
  • +
  • + {{'policyInEffectMinLength' | i18n : enforcedPolicyOptions?.minLength.toString()}} +
  • +
  • + {{'policyInEffectUppercase' | i18n}}
  • +
  • + {{'policyInEffectLowercase' | i18n}}
  • +
  • + {{'policyInEffectNumbers' | i18n}}
  • +
  • + {{'policyInEffectSpecial' | i18n : '!@#$%^&*'}}
  • +
+
+ +
+
+ + + +
+
+ + +
+
+ {{'masterPassDesc' | i18n}} +
+
+ +
+ + +
+
+
+ + + {{'masterPassHintDesc' | i18n}} +
+
+
+ + +
+
- diff --git a/src/app/accounts/change-password.component.ts b/src/app/accounts/change-password.component.ts index 84e55c6998..9e8acc5831 100644 --- a/src/app/accounts/change-password.component.ts +++ b/src/app/accounts/change-password.component.ts @@ -19,19 +19,25 @@ import { UserService } from 'jslib/abstractions/user.service'; import { CipherString } from 'jslib/models/domain/cipherString'; import { SymmetricCryptoKey } from 'jslib/models/domain/symmetricCryptoKey'; +import { KeysRequest } from 'jslib/models/request/keysRequest'; import { SetPasswordRequest } from 'jslib/models/request/setPasswordRequest'; import { ChangePasswordComponent as BaseChangePasswordComponent, } from 'jslib/angular/components/change-password.component'; +import { KdfType } from 'jslib/enums/kdfType'; + @Component({ selector: 'app-accounts-change-password', templateUrl: 'change-password.component.html', }) export class ChangePasswordComponent extends BaseChangePasswordComponent { + showPassword: boolean = false; + hint: string = ''; + onSuccessfulChangePassword: () => Promise; - successRoute = 'lock'; + successRoute = 'vault'; constructor(apiService: ApiService, i18nService: I18nService, cryptoService: CryptoService, messagingService: MessagingService, @@ -43,16 +49,36 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent { platformUtilsService, folderService, cipherService, syncService, policyService, router); } - async performSubmitActions(newMasterPasswordHash: string, newKey: SymmetricCryptoKey, - newEncKey: [SymmetricCryptoKey, CipherString]) { - const setRequest = new SetPasswordRequest(); - setRequest.newMasterPasswordHash = newMasterPasswordHash; - setRequest.key = newEncKey[1].encryptedString; + async setupSubmitActions() { + this.kdf = KdfType.PBKDF2_SHA256; + const useLowerKdf = this.platformUtilsService.isEdge() || this.platformUtilsService.isIE(); + this.kdfIterations = useLowerKdf ? 10000 : 100000; + return true; + } + + async performSubmitActions(masterPasswordHash: string, key: SymmetricCryptoKey, + encKey: [SymmetricCryptoKey, CipherString]) { + const request = new SetPasswordRequest(); + request.masterPasswordHash = masterPasswordHash; + request.key = encKey[1].encryptedString; + request.masterPasswordHint = this.hint; + request.kdf = this.kdf; + request.kdfIterations = this.kdfIterations; + + const keys = await this.cryptoService.makeKeyPair(encKey[0]); + request.keys = new KeysRequest(keys[0], keys[1].encryptedString); try { - this.formPromise = this.apiService.setPassword(setRequest); + this.formPromise = this.apiService.setPassword(request); await this.formPromise; + await this.userService.setInformation(await this.userService.getUserId(), await this.userService.getEmail(), + this.kdf, this.kdfIterations); + await this.cryptoService.setKey(key); + await this.cryptoService.setKeyHash(masterPasswordHash); + await this.cryptoService.setEncKey(encKey[1].encryptedString); + await this.cryptoService.setEncPrivateKey(keys[1].encryptedString); + if (this.onSuccessfulChangePassword != null) { this.onSuccessfulChangePassword(); } else { @@ -62,4 +88,10 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent { this.platformUtilsService.showToast('error', null, this.i18nService.t('errorOccurred')); } } + + togglePassword(confirmField: boolean) { + this.platformUtilsService.eventTrack('Toggled Master Password on Set Password'); + this.showPassword = !this.showPassword; + document.getElementById(confirmField ? 'masterPasswordRetype' : 'masterPassword').focus(); + } } diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 9053805b52..9a376fc305 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -108,7 +108,6 @@ const routes: Routes = [ }, { path: 'change-password', component: ChangePasswordComponent, - canActivate: [UnauthGuardService], data: { titleId: 'setMasterPassword' }, }, { diff --git a/src/app/settings/change-password.component.html b/src/app/settings/change-password.component.html index 518662c925..81dc2c9db6 100644 --- a/src/app/settings/change-password.component.html +++ b/src/app/settings/change-password.component.html @@ -28,18 +28,18 @@
- - {{'newMasterPass' | i18n}} +
- - {{'confirmNewMasterPass' | i18n}} +
diff --git a/src/app/settings/change-password.component.ts b/src/app/settings/change-password.component.ts index 5997481282..d6355d2dbf 100644 --- a/src/app/settings/change-password.component.ts +++ b/src/app/settings/change-password.component.ts @@ -79,6 +79,16 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent { } } + async submit() { + const hasEncKey = await this.cryptoService.hasEncKey(); + if (!hasEncKey) { + this.platformUtilsService.showToast('error', null, this.i18nService.t('updateKey')); + return; + } + + await super.submit(); + } + async setupSubmitActions() { if (this.currentMasterPassword == null || this.currentMasterPassword === '') { this.platformUtilsService.showToast('error', this.i18nService.t('errorOccurred'), @@ -90,7 +100,7 @@ export class ChangePasswordComponent extends BaseChangePasswordComponent { await this.syncService.fullSync(true); } - super.setupSubmitActions(); + return super.setupSubmitActions(); } async performSubmitActions(newMasterPasswordHash: string, newKey: SymmetricCryptoKey, diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index cb11c4ae09..60229fb6e8 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -3168,7 +3168,7 @@ "message": "Set Master Password" }, "ssoCompleteRegistration": { - "message": "In order to complete logging in with SSO, please set a master password below. Make sure to choose a strong password/passphrase and comply with all applied organizational policies." + "message": "In order to complete logging in with SSO, please set a master password to access and protect your vault." }, "identifier": { "message": "Identifier"