diff --git a/jslib b/jslib index 5d874d07b3..e55528e617 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 5d874d07b35a23dc6d54f1f435d88d2ddd815e33 +Subproject commit e55528e61737635e7f8970b913bcc3f10bede85d diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 12d9466742..c5667b7b13 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1308,5 +1308,50 @@ }, "autoFillSuccess": { "message": "Auto-filled Item" + }, + "setMasterPassword": { + "message": "Set Master Password" + }, + "masterPasswordPolicyInEffect": { + "message": "One or more organization policies require your master password to meet the following requirements:" + }, + "policyInEffectMinComplexity": { + "message": "Minimum complexity score of $SCORE$", + "placeholders": { + "score": { + "content": "$1", + "example": "4" + } + } + }, + "policyInEffectMinLength": { + "message": "Minimum length of $LENGTH$", + "placeholders": { + "length": { + "content": "$1", + "example": "14" + } + } + }, + "policyInEffectUppercase": { + "message": "Contain one or more uppercase characters" + }, + "policyInEffectLowercase": { + "message": "Contain one or more lowercase characters" + }, + "policyInEffectNumbers": { + "message": "Contain one or more numbers" + }, + "policyInEffectSpecial": { + "message": "Contain one or more of the following special characters $CHARS$", + "placeholders": { + "chars": { + "content": "$1", + "example": "!@#$%^&*" + } + } + }, + "masterPasswordPolicyRequirementsNotMet": { + "message": "Your new master password does not meet the policy requirements." } } diff --git a/src/popup/accounts/set-password.component.html b/src/popup/accounts/set-password.component.html new file mode 100644 index 0000000000..91fd86250b --- /dev/null +++ b/src/popup/accounts/set-password.component.html @@ -0,0 +1,105 @@ +
+
+ +
+ {{'setMasterPassword' | i18n}} +
+
+ +
+
+ +
+ {{'ssoCompleteRegistration' | i18n}} + + {{'masterPasswordPolicyInEffect' | i18n}} +
    +
  • + {{'policyInEffectMinComplexity' | i18n : getPasswordScoreAlertDisplay()}} +
  • +
  • + {{'policyInEffectMinLength' | i18n : enforcedPolicyOptions?.minLength.toString()}} +
  • +
  • {{'policyInEffectUppercase' | i18n}}
  • +
  • {{'policyInEffectLowercase' | i18n}}
  • +
  • {{'policyInEffectNumbers' | i18n}}
  • +
  • {{'policyInEffectSpecial' | i18n : '!@#$%^&*'}} +
  • +
+
+
+
+
+
+
+
+ + +
+
+ + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ + +
+
+ + + +
+
+
+
+
+
+
+
+ + +
+
+ +
+
+
\ No newline at end of file diff --git a/src/popup/accounts/set-password.component.ts b/src/popup/accounts/set-password.component.ts new file mode 100644 index 0000000000..ee0da49e57 --- /dev/null +++ b/src/popup/accounts/set-password.component.ts @@ -0,0 +1,60 @@ +import { Component } from '@angular/core'; + +import { Router } from '@angular/router'; + +import { ApiService } from 'jslib/abstractions/api.service'; +import { CryptoService } from 'jslib/abstractions/crypto.service'; +import { I18nService } from 'jslib/abstractions/i18n.service'; +import { MessagingService } from 'jslib/abstractions/messaging.service'; +import { PasswordGenerationService } from 'jslib/abstractions/passwordGeneration.service'; +import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; +import { PolicyService } from 'jslib/abstractions/policy.service'; +import { UserService } from 'jslib/abstractions/user.service'; + +import { + SetPasswordComponent as BaseSetPasswordComponent, +} from 'jslib/angular/components/set-password.component'; + +@Component({ + selector: 'app-set-password', + templateUrl: 'set-password.component.html', +}) +export class SetPasswordComponent extends BaseSetPasswordComponent { + constructor(apiService: ApiService, i18nService: I18nService, + cryptoService: CryptoService, messagingService: MessagingService, + userService: UserService, passwordGenerationService: PasswordGenerationService, + platformUtilsService: PlatformUtilsService, policyService: PolicyService, router: Router) { + super(i18nService, cryptoService, messagingService, userService, passwordGenerationService, + platformUtilsService, policyService, router, apiService); + } + + get masterPasswordScoreWidth() { + return this.masterPasswordScore == null ? 0 : (this.masterPasswordScore + 1) * 20; + } + + get masterPasswordScoreColor() { + switch (this.masterPasswordScore) { + case 4: + return 'success'; + case 3: + return 'primary'; + case 2: + return 'warning'; + default: + return 'danger'; + } + } + + get masterPasswordScoreText() { + switch (this.masterPasswordScore) { + case 4: + return this.i18nService.t('strong'); + case 3: + return this.i18nService.t('good'); + case 2: + return this.i18nService.t('weak'); + default: + return this.masterPasswordScore != null ? this.i18nService.t('weak') : null; + } + } +} \ No newline at end of file diff --git a/src/popup/app-routing.module.ts b/src/popup/app-routing.module.ts index ca3c4b37b8..5c3ea8dbba 100644 --- a/src/popup/app-routing.module.ts +++ b/src/popup/app-routing.module.ts @@ -16,6 +16,7 @@ import { HomeComponent } from './accounts/home.component'; import { LockComponent } from './accounts/lock.component'; import { LoginComponent } from './accounts/login.component'; import { RegisterComponent } from './accounts/register.component'; +import { SetPasswordComponent } from './accounts/set-password.component'; import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component'; import { TwoFactorComponent } from './accounts/two-factor.component'; import { SsoComponent } from './accounts/sso.component'; @@ -86,6 +87,11 @@ const routes: Routes = [ canActivate: [LaunchGuardService], data: { state: 'sso' }, }, + { + path: 'set-password', + component: SetPasswordComponent, + data: { state: 'set-password' }, + }, { path: 'register', component: RegisterComponent, diff --git a/src/popup/app.module.ts b/src/popup/app.module.ts index 7fce0b27d7..e3f7b54c01 100644 --- a/src/popup/app.module.ts +++ b/src/popup/app.module.ts @@ -21,6 +21,7 @@ import { HomeComponent } from './accounts/home.component'; import { LockComponent } from './accounts/lock.component'; import { LoginComponent } from './accounts/login.component'; import { RegisterComponent } from './accounts/register.component'; +import { SetPasswordComponent } from './accounts/set-password.component'; import { TwoFactorOptionsComponent } from './accounts/two-factor-options.component'; import { TwoFactorComponent } from './accounts/two-factor.component'; import { SsoComponent } from './accounts/sso.component'; @@ -209,6 +210,7 @@ registerLocaleData(localeZhTw, 'zh-TW'); TwoFactorComponent, SsoComponent, ViewComponent, + SetPasswordComponent ], entryComponents: [], providers: [ diff --git a/src/popup/services/services.module.ts b/src/popup/services/services.module.ts index 785aba0675..dc5605e06f 100644 --- a/src/popup/services/services.module.ts +++ b/src/popup/services/services.module.ts @@ -21,7 +21,6 @@ import { AuthService as AuthServiceAbstraction } from 'jslib/abstractions/auth.s import { CipherService } from 'jslib/abstractions/cipher.service'; import { CollectionService } from 'jslib/abstractions/collection.service'; import { CryptoService } from 'jslib/abstractions/crypto.service'; -import { CryptoFunctionService } from 'jslib/abstractions/cryptoFunction.service'; import { EnvironmentService } from 'jslib/abstractions/environment.service'; import { EventService } from 'jslib/abstractions/event.service'; import { ExportService } from 'jslib/abstractions/export.service'; @@ -41,7 +40,6 @@ import { TokenService } from 'jslib/abstractions/token.service'; import { TotpService } from 'jslib/abstractions/totp.service'; import { UserService } from 'jslib/abstractions/user.service'; import { VaultTimeoutService } from 'jslib/abstractions/vaultTimeout.service'; -import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service'; import { AutofillService } from '../../services/abstractions/autofill.service'; import BrowserMessagingService from '../../services/browserMessaging.service'; @@ -72,8 +70,6 @@ export const authService = new AuthService(getBgService('cryptoSe messagingService, getBgService('vaultTimeoutService')(), null); export const searchService = new PopupSearchService(getBgService('searchService')(), getBgService('cipherService')(), getBgService('platformUtilsService')()); -export const cryptoFunctionService: CryptoFunctionService = new WebCryptoFunctionService(window, - getBgService('platformUtilsService')()); export function initFactory(i18nService: I18nService, storageService: StorageService, popupUtilsService: PopupUtilsService): Function { @@ -125,7 +121,6 @@ export function initFactory(i18nService: I18nService, storageService: StorageSer { provide: AuthServiceAbstraction, useValue: authService }, { provide: StateServiceAbstraction, useValue: stateService }, { provide: SearchServiceAbstraction, useValue: searchService }, - { provide: CryptoFunctionService, useValue: cryptoFunctionService }, { provide: AuditService, useFactory: getBgService('auditService'), deps: [] }, { provide: CipherService, useFactory: getBgService('cipherService'), deps: [] }, { provide: FolderService, useFactory: getBgService('folderService'), deps: [] }, @@ -135,11 +130,6 @@ export function initFactory(i18nService: I18nService, storageService: StorageSer { provide: TokenService, useFactory: getBgService('tokenService'), deps: [] }, { provide: I18nService, useFactory: getBgService('i18nService'), deps: [] }, { provide: CryptoService, useFactory: getBgService('cryptoService'), deps: [] }, - { - provide: CryptoFunctionService, - useFactory: getBgService('cryptoFunctionService'), - deps: [], - }, { provide: EventService, useFactory: getBgService('eventService'), deps: [] }, { provide: PolicyService, useFactory: getBgService('policyService'), deps: [] }, {