From 91ce6527c093e9ad05cf7d665aeb50f4667c931b Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Tue, 25 Aug 2020 09:49:24 -0500 Subject: [PATCH 1/8] Added set password flow to browser based SSO --- .../accounts/set-password.component.html | 124 ++++++++++++++++++ src/popup/accounts/set-password.component.ts | 60 +++++++++ src/popup/app-routing.module.ts | 6 + src/popup/app.module.ts | 2 + src/popup/services/services.module.ts | 13 +- 5 files changed, 196 insertions(+), 9 deletions(-) create mode 100644 src/popup/accounts/set-password.component.html create mode 100644 src/popup/accounts/set-password.component.ts diff --git a/src/popup/accounts/set-password.component.html b/src/popup/accounts/set-password.component.html new file mode 100644 index 0000000000..9f291a527b --- /dev/null +++ b/src/popup/accounts/set-password.component.html @@ -0,0 +1,124 @@ +
+
+ +
+ {{'appName' | 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..959263d77f 100644 --- a/src/popup/app-routing.module.ts +++ b/src/popup/app-routing.module.ts @@ -39,6 +39,7 @@ import { GroupingsComponent } from './vault/groupings.component'; import { PasswordHistoryComponent } from './vault/password-history.component'; import { ShareComponent } from './vault/share.component'; import { ViewComponent } from './vault/view.component'; +import { SetPasswordComponent } from './accounts/set-password.component'; const routes: Routes = [ { @@ -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..f6ec79ae06 100644 --- a/src/popup/app.module.ts +++ b/src/popup/app.module.ts @@ -45,6 +45,7 @@ import { GroupingsComponent } from './vault/groupings.component'; import { PasswordHistoryComponent } from './vault/password-history.component'; import { ShareComponent } from './vault/share.component'; import { ViewComponent } from './vault/view.component'; +import { SetPasswordComponent } from './accounts/set-password.component'; import { A11yTitleDirective } from 'jslib/angular/directives/a11y-title.directive'; import { ApiActionDirective } from 'jslib/angular/directives/api-action.directive'; @@ -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..d5e032ba93 100644 --- a/src/popup/services/services.module.ts +++ b/src/popup/services/services.module.ts @@ -21,7 +21,7 @@ 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 { CryptoFunctionService as CryptoFunctionServiceAbstraction } 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 +41,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'; @@ -50,6 +49,7 @@ import { AuthService } from 'jslib/services/auth.service'; import { ConstantsService } from 'jslib/services/constants.service'; import { SearchService } from 'jslib/services/search.service'; import { StateService } from 'jslib/services/state.service'; +import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service'; import { Analytics } from 'jslib/misc/analytics'; @@ -72,7 +72,7 @@ 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, +export const cryptoFunctionService = new WebCryptoFunctionService(window, getBgService('platformUtilsService')()); export function initFactory(i18nService: I18nService, storageService: StorageService, @@ -125,7 +125,7 @@ export function initFactory(i18nService: I18nService, storageService: StorageSer { provide: AuthServiceAbstraction, useValue: authService }, { provide: StateServiceAbstraction, useValue: stateService }, { provide: SearchServiceAbstraction, useValue: searchService }, - { provide: CryptoFunctionService, useValue: cryptoFunctionService }, + { provide: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService }, { provide: AuditService, useFactory: getBgService('auditService'), deps: [] }, { provide: CipherService, useFactory: getBgService('cipherService'), deps: [] }, { provide: FolderService, useFactory: getBgService('folderService'), deps: [] }, @@ -135,11 +135,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: [] }, { From 033d02d3ec620337d15e4d9e495e00a33122be1e Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Tue, 25 Aug 2020 10:19:39 -0500 Subject: [PATCH 2/8] Linter Issues / JSLib Update --- src/content/sso.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/content/sso.ts b/src/content/sso.ts index cc936d91ab..99be142ff3 100644 --- a/src/content/sso.ts +++ b/src/content/sso.ts @@ -1,8 +1,8 @@ -window.addEventListener("message", function(event) { - if (event.source != window) +window.addEventListener('message', (event) => { + if (event.source !== window) return; - if (event.data.command && (event.data.command == "authResult")) { + if (event.data.command && (event.data.command === 'authResult')) { chrome.runtime.sendMessage({ command: event.data.command, code: event.data.code, From f594401fbb2da7f815b3228ff24989ad44f928f3 Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Tue, 25 Aug 2020 10:35:13 -0500 Subject: [PATCH 3/8] Upgrading JSlib.. I think? --- jslib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jslib b/jslib index 5d874d07b3..e55528e617 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 5d874d07b35a23dc6d54f1f435d88d2ddd815e33 +Subproject commit e55528e61737635e7f8970b913bcc3f10bede85d From b65d6582be5a72c9bbc52f5b77c64fa323241fcc Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Tue, 25 Aug 2020 11:08:35 -0500 Subject: [PATCH 4/8] Fixed ordering. Removed commented out code. --- .../accounts/set-password.component.html | 21 +------------------ src/popup/app-routing.module.ts | 2 +- src/popup/app.module.ts | 2 +- 3 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/popup/accounts/set-password.component.html b/src/popup/accounts/set-password.component.html index 9f291a527b..f47d3d8884 100644 --- a/src/popup/accounts/set-password.component.html +++ b/src/popup/accounts/set-password.component.html @@ -102,23 +102,4 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/src/popup/app-routing.module.ts b/src/popup/app-routing.module.ts index 959263d77f..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'; @@ -39,7 +40,6 @@ import { GroupingsComponent } from './vault/groupings.component'; import { PasswordHistoryComponent } from './vault/password-history.component'; import { ShareComponent } from './vault/share.component'; import { ViewComponent } from './vault/view.component'; -import { SetPasswordComponent } from './accounts/set-password.component'; const routes: Routes = [ { diff --git a/src/popup/app.module.ts b/src/popup/app.module.ts index f6ec79ae06..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'; @@ -45,7 +46,6 @@ import { GroupingsComponent } from './vault/groupings.component'; import { PasswordHistoryComponent } from './vault/password-history.component'; import { ShareComponent } from './vault/share.component'; import { ViewComponent } from './vault/view.component'; -import { SetPasswordComponent } from './accounts/set-password.component'; import { A11yTitleDirective } from 'jslib/angular/directives/a11y-title.directive'; import { ApiActionDirective } from 'jslib/angular/directives/api-action.directive'; From e7dc93b71590f19548697b795ed8821bacc3501a Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Tue, 25 Aug 2020 14:03:47 -0500 Subject: [PATCH 5/8] Verbiage changes --- src/_locales/en/messages.json | 4 +++- src/popup/accounts/login.component.html | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index 12d9466742..e5eb024330 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1308,5 +1308,7 @@ }, "autoFillSuccess": { "message": "Auto-filled Item" - } + }, + "setMasterPassword": { + "message": "Set Master Password" } diff --git a/src/popup/accounts/login.component.html b/src/popup/accounts/login.component.html index 6c9c222d99..e2c02b26b1 100644 --- a/src/popup/accounts/login.component.html +++ b/src/popup/accounts/login.component.html @@ -4,11 +4,11 @@ {{'cancel' | i18n}}
- {{'appName' | i18n}} + {{'setMasterPassword' | i18n}}
From 136f75f389e4bb3fb9e60911f958a9c3384801cf Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Fri, 28 Aug 2020 11:00:51 -0500 Subject: [PATCH 6/8] Added localization strings --- src/_locales/en/messages.json | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index e5eb024330..c5667b7b13 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1311,4 +1311,47 @@ }, "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." + } } From 7c4ef9d8fc763a2176028fed84052a34477a8eda Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Fri, 28 Aug 2020 11:52:24 -0500 Subject: [PATCH 7/8] Modified correct file for feedback --- src/popup/accounts/login.component.html | 4 ++-- src/popup/accounts/set-password.component.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/popup/accounts/login.component.html b/src/popup/accounts/login.component.html index e2c02b26b1..6c9c222d99 100644 --- a/src/popup/accounts/login.component.html +++ b/src/popup/accounts/login.component.html @@ -4,11 +4,11 @@ {{'cancel' | i18n}}
- {{'setMasterPassword' | i18n}} + {{'appName' | i18n}}
diff --git a/src/popup/accounts/set-password.component.html b/src/popup/accounts/set-password.component.html index f47d3d8884..91fd86250b 100644 --- a/src/popup/accounts/set-password.component.html +++ b/src/popup/accounts/set-password.component.html @@ -4,11 +4,11 @@ {{'cancel' | i18n}}
- {{'appName' | i18n}} + {{'setMasterPassword' | i18n}}
From fad4f9ef5e6df352c753542320cfafd602c96ab1 Mon Sep 17 00:00:00 2001 From: Matt Smith Date: Fri, 28 Aug 2020 13:40:21 -0500 Subject: [PATCH 8/8] Removed duplicate Crypto Function Service. --- src/popup/services/services.module.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/popup/services/services.module.ts b/src/popup/services/services.module.ts index d5e032ba93..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 as CryptoFunctionServiceAbstraction } 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'; @@ -49,7 +48,6 @@ import { AuthService } from 'jslib/services/auth.service'; import { ConstantsService } from 'jslib/services/constants.service'; import { SearchService } from 'jslib/services/search.service'; import { StateService } from 'jslib/services/state.service'; -import { WebCryptoFunctionService } from 'jslib/services/webCryptoFunction.service'; import { Analytics } from 'jslib/misc/analytics'; @@ -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 = 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: CryptoFunctionServiceAbstraction, useValue: cryptoFunctionService }, { provide: AuditService, useFactory: getBgService('auditService'), deps: [] }, { provide: CipherService, useFactory: getBgService('cipherService'), deps: [] }, { provide: FolderService, useFactory: getBgService('folderService'), deps: [] },