From a6aef345d5da80dcd212233544de6411e95ec756 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 11 Jun 2018 11:43:10 -0400 Subject: [PATCH] two-step login pages --- src/app/accounts/login.component.html | 6 +- .../two-factor-options.component.html | 46 ++--- .../accounts/two-factor-options.component.ts | 6 - src/app/accounts/two-factor.component.html | 169 +++++++----------- src/app/accounts/two-factor.component.ts | 37 ++-- src/app/app.module.ts | 1 + src/images/two-factor/{authapp.png => 0.png} | Bin src/images/two-factor/{gmail.png => 1.png} | Bin src/images/two-factor/{duo.png => 2.png} | Bin src/images/two-factor/{yubico.png => 3.png} | Bin src/images/two-factor/{fido.png => 4.png} | Bin src/images/two-factor/6.png | Bin 0 -> 1211 bytes src/images/{two-factor => }/u2fkey.jpg | Bin src/images/{two-factor => }/yubikey.jpg | Bin src/locales/en/messages.json | 90 ++++++++++ src/scss/styles.scss | 10 +- src/services/htmlStorage.service.ts | 19 +- 17 files changed, 233 insertions(+), 151 deletions(-) rename src/images/two-factor/{authapp.png => 0.png} (100%) rename src/images/two-factor/{gmail.png => 1.png} (100%) rename src/images/two-factor/{duo.png => 2.png} (100%) rename src/images/two-factor/{yubico.png => 3.png} (100%) rename src/images/two-factor/{fido.png => 4.png} (100%) create mode 100644 src/images/two-factor/6.png rename src/images/{two-factor => }/u2fkey.jpg (100%) rename src/images/{two-factor => }/yubikey.jpg (100%) diff --git a/src/app/accounts/login.component.html b/src/app/accounts/login.component.html index 4454989b19..afac3587ba 100644 --- a/src/app/accounts/login.component.html +++ b/src/app/accounts/login.component.html @@ -18,6 +18,9 @@ + + {{'getMasterPasswordHint' | i18n}} +
@@ -32,9 +35,6 @@
-
- {{'getMasterPasswordHint' | i18n}} -
diff --git a/src/app/accounts/two-factor-options.component.html b/src/app/accounts/two-factor-options.component.html index d2bbd3112a..abbced4fac 100644 --- a/src/app/accounts/two-factor-options.component.html +++ b/src/app/accounts/two-factor-options.component.html @@ -1,24 +1,26 @@ -
- -
- {{'twoStepOptions' | i18n}} -
-
-
- -
-
- - {{p.name}} - {{p.description}} - - - {{'recoveryCodeTitle' | i18n}} - {{'recoveryCodeDesc' | i18n}} - + diff --git a/src/app/accounts/two-factor-options.component.ts b/src/app/accounts/two-factor-options.component.ts index 779d4813c1..6ab0be4faa 100644 --- a/src/app/accounts/two-factor-options.component.ts +++ b/src/app/accounts/two-factor-options.component.ts @@ -22,10 +22,4 @@ export class TwoFactorOptionsComponent extends BaseTwoFactorOptionsComponent { i18nService: I18nService, platformUtilsService: PlatformUtilsService) { super(authService, router, analytics, toasterService, i18nService, platformUtilsService, window); } - - choose(p: any) { - super.choose(p); - this.authService.selectedTwoFactorProviderType = p.type; - this.router.navigate(['2fa']); - } } diff --git a/src/app/accounts/two-factor.component.html b/src/app/accounts/two-factor.component.html index 404f865e8e..b7f4725d35 100644 --- a/src/app/accounts/two-factor.component.html +++ b/src/app/accounts/two-factor.component.html @@ -1,108 +1,73 @@ -
-
- -
- {{title}} -
-
- -
-
- - -
- - {{'enterVerificationCodeApp' | i18n}} - - - {{'enterVerificationCodeEmail' | i18n : twoFactorEmail}} - -
-
-
-
- - -
-
- - -
-
-
-
- -
-

{{'insertYubiKey' | i18n}}

- -
-
-
-
- - -
-
- - -
-
-
-
- -
- -
-

{{'insertU2f' | i18n}}

- -
-
-
-
-
- - -
-
-
-
- +
+
+

{{title}}

+
+
+ +

{{'enterVerificationCodeApp' | i18n}}

+

+ {{'enterVerificationCodeEmail' | i18n : twoFactorEmail}} +

+
+ + + + + {{'sendVerificationCodeEmailAgain' | i18n}} + + +
+
+ +

{{'insertYubiKey' | i18n}}

+ +
+ + +
+
+ +

+ +

+ +

{{'insertU2f' | i18n}}

+ +
+
+ -
-
{{'twoStepNewWindowMessage' | i18n}}
-
-
-
- - +
+ +
+ +
+ + +
+ +

{{'noTwoStepProviders' | i18n}}

+

{{'noTwoStepProviders2' | i18n}}

+
+
+
+ + + {{'cancel' | i18n}} + +
+
- -
-

{{'noTwoStepProviders' | i18n}}

-

{{'noTwoStepProviders2' | i18n}}

- - +
- + diff --git a/src/app/accounts/two-factor.component.ts b/src/app/accounts/two-factor.component.ts index 3155e52d5c..932a9dd775 100644 --- a/src/app/accounts/two-factor.component.ts +++ b/src/app/accounts/two-factor.component.ts @@ -1,9 +1,8 @@ import { - ChangeDetectorRef, Component, - NgZone, - OnDestroy, - OnInit, + ComponentFactoryResolver, + ViewChild, + ViewContainerRef, } from '@angular/core'; import { Router } from '@angular/router'; @@ -11,6 +10,10 @@ import { Router } from '@angular/router'; import { ToasterService } from 'angular2-toaster'; import { Angulartics2 } from 'angulartics2'; +import { TwoFactorOptionsComponent } from './two-factor-options.component'; + +import { ModalComponent } from '../modal.component'; + import { TwoFactorProviderType } from 'jslib/enums/twoFactorProviderType'; import { ApiService } from 'jslib/abstractions/api.service'; @@ -20,31 +23,37 @@ import { I18nService } from 'jslib/abstractions/i18n.service'; import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; import { SyncService } from 'jslib/abstractions/sync.service'; -import { BroadcasterService } from 'jslib/angular/services/broadcaster.service'; - import { TwoFactorComponent as BaseTwoFactorComponent } from 'jslib/angular/components/two-factor.component'; -const BroadcasterSubscriptionId = 'TwoFactorComponent'; - @Component({ selector: 'app-two-factor', templateUrl: 'two-factor.component.html', }) export class TwoFactorComponent extends BaseTwoFactorComponent { - showNewWindowMessage = false; + @ViewChild('twoFactorOptions', { read: ViewContainerRef }) twoFactorOptionsModal: ViewContainerRef; constructor(authService: AuthService, router: Router, analytics: Angulartics2, toasterService: ToasterService, i18nService: I18nService, apiService: ApiService, - platformUtilsService: PlatformUtilsService, syncService: SyncService, - environmentService: EnvironmentService, private ngZone: NgZone, - private broadcasterService: BroadcasterService, private changeDetectorRef: ChangeDetectorRef) { + platformUtilsService: PlatformUtilsService, private syncService: SyncService, + environmentService: EnvironmentService, private componentFactoryResolver: ComponentFactoryResolver) { super(authService, router, analytics, toasterService, i18nService, apiService, platformUtilsService, window, environmentService); - this.successRoute = '/vault'; } anotherMethod() { - this.router.navigate(['2fa-options']); + const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); + const modal = this.twoFactorOptionsModal.createComponent(factory).instance; + const childComponent = modal.show(TwoFactorOptionsComponent, + this.twoFactorOptionsModal); + + childComponent.onProviderSelected.subscribe(async (provider: TwoFactorProviderType) => { + modal.close(); + this.selectedProviderType = provider; + await this.init(); + }); + childComponent.onRecoverSelected.subscribe(() => { + modal.close(); + }); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 0124db3882..7ca4e450a0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -113,6 +113,7 @@ import { Folder } from 'jslib/models/domain'; AttachmentsComponent, FolderAddEditComponent, ModalComponent, + TwoFactorOptionsComponent, ], providers: [], bootstrap: [AppComponent], diff --git a/src/images/two-factor/authapp.png b/src/images/two-factor/0.png similarity index 100% rename from src/images/two-factor/authapp.png rename to src/images/two-factor/0.png diff --git a/src/images/two-factor/gmail.png b/src/images/two-factor/1.png similarity index 100% rename from src/images/two-factor/gmail.png rename to src/images/two-factor/1.png diff --git a/src/images/two-factor/duo.png b/src/images/two-factor/2.png similarity index 100% rename from src/images/two-factor/duo.png rename to src/images/two-factor/2.png diff --git a/src/images/two-factor/yubico.png b/src/images/two-factor/3.png similarity index 100% rename from src/images/two-factor/yubico.png rename to src/images/two-factor/3.png diff --git a/src/images/two-factor/fido.png b/src/images/two-factor/4.png similarity index 100% rename from src/images/two-factor/fido.png rename to src/images/two-factor/4.png diff --git a/src/images/two-factor/6.png b/src/images/two-factor/6.png new file mode 100644 index 0000000000000000000000000000000000000000..ab2e43403614fdae987a9f34b5c7c80f7a0599cd GIT binary patch literal 1211 zcmV;s1VsCZP)%tn11b)cMr&h>9Z! zqKKearD~K`BZ~9TI#Wu;p;hXDB*uIFf9`+q5R%;C+O!F7NG5NB{Cmb2|{b3iEUsr5Tm;$;&uhR z2fc2G2CIo6P80k_e=OA>3pwGwef0zL1Gpuq6#TzyWbho?>mx__+N( z+VEYxp&$@NXd@pcF;v_=8 zKa-nV#d;|v2BXw_XnM&1;JHhkxLJD0E8oirdtT$Ver>VbGhr|y_yTy;`LDdA+J&=s z)R^%g=_&Xde5~*lcEq@08M`?OZ^$!fCyhf^k-pw^Hd{Ir~yZyf3{RxgoK#*hd+?FBUvs44}p_L$Da;4jAH6=O+nm{UqwO>AjDnK6?Ue_p+&`vL5c;ymrC<9f6;HrR?aO zMs~hKO||F>#(_~T^=|;3mASpu{c{zhHpA;rie3_h^p*#B=Snpil-CuO&bl;J@1DIE ZU;w~$(key: string): Promise { let json: string = null; - if (this.localStorageKeys.has(key)) { + if (this.isLocalStorage(key)) { json = window.localStorage.getItem(key); } else { json = window.sessionStorage.getItem(key); @@ -26,7 +27,7 @@ export class HtmlStorageService implements StorageService { } const json = JSON.stringify(obj); - if (this.localStorageKeys.has(key)) { + if (this.isLocalStorage(key)) { window.localStorage.setItem(key, json); } else { window.sessionStorage.setItem(key, json); @@ -35,11 +36,23 @@ export class HtmlStorageService implements StorageService { } remove(key: string): Promise { - if (this.localStorageKeys.has(key)) { + if (this.isLocalStorage(key)) { window.localStorage.removeItem(key); } else { window.sessionStorage.removeItem(key); } return Promise.resolve(); } + + private isLocalStorage(key: string): boolean { + if (this.localStorageKeys.has(key)) { + return true; + } + for (const swKey of this.localStorageStartsWithKeys) { + if (key.startsWith(swKey)) { + return true; + } + } + return false; + } }