From aed5db0a8ce9659a640d97ba714357984c779b26 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 21 Jun 2018 17:14:36 -0400 Subject: [PATCH] deauth sessions --- src/app/app.module.ts | 3 ++ src/app/settings/account.component.html | 2 + src/app/settings/account.component.ts | 28 +++++++++++- .../deauthorize-sessions.component.html | 29 ++++++++++++ .../deauthorize-sessions.component.ts | 45 +++++++++++++++++++ src/locales/en/messages.json | 9 ++++ 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/app/settings/deauthorize-sessions.component.html create mode 100644 src/app/settings/deauthorize-sessions.component.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index e267ac9324..6f816ba96c 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -34,6 +34,7 @@ import { TwoFactorComponent } from './accounts/two-factor.component'; import { AccountComponent } from './settings/account.component'; import { ChangeEmailComponent } from './settings/change-email.component'; import { ChangePasswordComponent } from './settings/change-password.component'; +import { DeauthorizeSessionsComponent } from './settings/deauthorize-sessions.component'; import { ProfileComponent } from './settings/profile.component'; import { SettingsComponent } from './settings/settings.component'; @@ -102,6 +103,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe'; ChangePasswordComponent, CiphersComponent, CollectionsComponent, + DeauthorizeSessionsComponent, ExportComponent, FallbackSrcDirective, FolderAddEditComponent, @@ -142,6 +144,7 @@ import { SearchCiphersPipe } from 'jslib/angular/pipes/search-ciphers.pipe'; BulkMoveComponent, BulkShareComponent, CollectionsComponent, + DeauthorizeSessionsComponent, FolderAddEditComponent, ModalComponent, PasswordGeneratorHistoryComponent, diff --git a/src/app/settings/account.component.html b/src/app/settings/account.component.html index 0c3e28a4b3..7747e90ae7 100644 --- a/src/app/settings/account.component.html +++ b/src/app/settings/account.component.html @@ -17,3 +17,5 @@ + + diff --git a/src/app/settings/account.component.ts b/src/app/settings/account.component.ts index 6f03312d2e..c6b4427164 100644 --- a/src/app/settings/account.component.ts +++ b/src/app/settings/account.component.ts @@ -1,12 +1,36 @@ -import { Component } from '@angular/core'; +import { + Component, + ComponentFactoryResolver, + ViewChild, + ViewContainerRef, +} from '@angular/core'; + +import { ModalComponent } from '../modal.component'; +import { DeauthorizeSessionsComponent } from './deauthorize-sessions.component'; @Component({ selector: 'app-account', templateUrl: 'account.component.html', }) export class AccountComponent { - deauthorizeSessions() { + @ViewChild('deauthorizeSessionsTemplate', { read: ViewContainerRef }) deauthModalRef: ViewContainerRef; + private modal: ModalComponent = null; + + constructor(private componentFactoryResolver: ComponentFactoryResolver) { } + + deauthorizeSessions() { + if (this.modal != null) { + this.modal.close(); + } + + const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); + this.modal = this.deauthModalRef.createComponent(factory).instance; + this.modal.show(DeauthorizeSessionsComponent, this.deauthModalRef); + + this.modal.onClosed.subscribe(async () => { + this.modal = null; + }); } purgeVault() { diff --git a/src/app/settings/deauthorize-sessions.component.html b/src/app/settings/deauthorize-sessions.component.html new file mode 100644 index 0000000000..556a7ee0ad --- /dev/null +++ b/src/app/settings/deauthorize-sessions.component.html @@ -0,0 +1,29 @@ + diff --git a/src/app/settings/deauthorize-sessions.component.ts b/src/app/settings/deauthorize-sessions.component.ts new file mode 100644 index 0000000000..21b55b2ae1 --- /dev/null +++ b/src/app/settings/deauthorize-sessions.component.ts @@ -0,0 +1,45 @@ +import { + Component, +} from '@angular/core'; + +import { ToasterService } from 'angular2-toaster'; +import { Angulartics2 } from 'angulartics2'; + +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 { PasswordVerificationRequest } from 'jslib/models/request/passwordVerificationRequest'; + +@Component({ + selector: 'app-deauthorize-sessions', + templateUrl: 'deauthorize-sessions.component.html', +}) +export class DeauthorizeSessionsComponent { + masterPassword: string; + formPromise: Promise; + + constructor(private apiService: ApiService, private i18nService: I18nService, + private analytics: Angulartics2, private toasterService: ToasterService, + private cryptoService: CryptoService, private messagingService: MessagingService) { } + + async submit() { + if (this.masterPassword == null || this.masterPassword === '') { + this.toasterService.popAsync('error', this.i18nService.t('errorOccurred'), + this.i18nService.t('masterPassRequired')); + return; + } + + const request = new PasswordVerificationRequest(); + request.masterPasswordHash = await this.cryptoService.hashPassword(this.masterPassword, null); + try { + this.formPromise = this.apiService.postSecurityStamp(request); + await this.formPromise; + this.analytics.eventTrack.next({ action: 'Deauthorized Sessions' }); + this.toasterService.popAsync('success', this.i18nService.t('sessionsDeauthorized'), + this.i18nService.t('logBackIn')); + this.messagingService.send('logout'); + } catch { } + } +} diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json index c118046316..e74fc871cd 100644 --- a/src/locales/en/messages.json +++ b/src/locales/en/messages.json @@ -818,6 +818,15 @@ "deauthorizeSessions": { "message": "Deauthorize Sessions" }, + "deauthorizeSessionsDesc": { + "message": "Concerned your account is logged in on another device? Proceed below to deauthorize all computers or devices that you have previously used. This security step is recommended if you previously used a public PC or accidentally saved your password on a device that isn't yours. This step will also clear all previously remembered two-step login sessions." + }, + "deauthorizeSessionsWarning": { + "message": "Proceeding will also log you out of your current session, requiring you to log back in. You will also be prompted for two-step login again, if enabled. Active sessions on other devices may continue to remain active for up to one hour." + }, + "sessionsDeauthorized": { + "message": "All Sessions Deauthorized" + }, "purgeVault": { "message": "Purge Vault" },