From 5098153fdeecb55e37035091eee5c871ac93efac Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 8 Jun 2018 17:08:19 -0400 Subject: [PATCH] layouts and messaging --- jslib | 2 +- src/app/app-routing.module.ts | 35 ++++-- src/app/app.component.ts | 117 +++++++++++++++++- src/app/app.module.ts | 11 ++ src/app/layouts/footer.component.html | 13 ++ src/app/layouts/footer.component.ts | 9 ++ .../layouts/frontend-layout.component.html | 2 + src/app/layouts/frontend-layout.component.ts | 9 ++ src/app/layouts/navbar.component.html | 33 +++++ src/app/layouts/navbar.component.ts | 17 +++ .../organization-layout.component.html | 3 + .../layouts/organization-layout.component.ts | 9 ++ src/app/layouts/user-layout.component.html | 3 + src/app/layouts/user-layout.component.ts | 9 ++ src/app/services.module.ts | 4 +- src/app/vault/vault.component.html | 42 ------- src/services/broadcasterMessaging.service.ts | 12 ++ src/services/webMessaging.service.ts | 7 -- 18 files changed, 274 insertions(+), 63 deletions(-) create mode 100644 src/app/layouts/footer.component.html create mode 100644 src/app/layouts/footer.component.ts create mode 100644 src/app/layouts/frontend-layout.component.html create mode 100644 src/app/layouts/frontend-layout.component.ts create mode 100644 src/app/layouts/navbar.component.html create mode 100644 src/app/layouts/navbar.component.ts create mode 100644 src/app/layouts/organization-layout.component.html create mode 100644 src/app/layouts/organization-layout.component.ts create mode 100644 src/app/layouts/user-layout.component.html create mode 100644 src/app/layouts/user-layout.component.ts create mode 100644 src/services/broadcasterMessaging.service.ts delete mode 100644 src/services/webMessaging.service.ts diff --git a/jslib b/jslib index 4c083eeb92..fe3a878542 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit 4c083eeb92d599bd8b85fb88ec5d435079b79395 +Subproject commit fe3a8785422a8866dbcb91d31db6d3fd2aa2daaa diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 80970051b7..b7f8923f84 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -4,6 +4,10 @@ import { Routes, } from '@angular/router'; +import { FrontendLayoutComponent } from './layouts/frontend-layout.component'; +import { OrganizationLayoutComponent } from './layouts/organization-layout.component'; +import { UserLayoutComponent } from './layouts/user-layout.component'; + import { HintComponent } from './accounts/hint.component'; import { LoginComponent } from './accounts/login.component'; import { RegisterComponent } from './accounts/register.component'; @@ -12,15 +16,32 @@ import { TwoFactorComponent } from './accounts/two-factor.component'; import { VaultComponent } from './vault/vault.component'; const routes: Routes = [ - { path: '', redirectTo: '/vault', pathMatch: 'full' }, - { path: 'login', component: LoginComponent }, - { path: '2fa', component: TwoFactorComponent }, - { path: 'register', component: RegisterComponent }, - { path: 'hint', component: HintComponent }, { - path: 'vault', - component: VaultComponent, + path: '', + component: UserLayoutComponent, + children: [ + { path: '', redirectTo: 'vault', pathMatch: 'full' }, + { path: 'vault', component: VaultComponent }, + ], }, + { + path: '', + component: FrontendLayoutComponent, + children: [ + { path: 'login', component: LoginComponent }, + { path: '2fa', component: TwoFactorComponent }, + { path: 'register', component: RegisterComponent }, + { path: 'hint', component: HintComponent }, + ], + }, + { + path: 'organization/:organizationId', + component: OrganizationLayoutComponent, + children: [ + { path: 'vault', component: VaultComponent }, + ], + }, + { path: '**', redirectTo: '' }, ]; @NgModule({ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 66bdaca1b0..b806a07ef8 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,19 +1,45 @@ import { ToasterConfig, ToasterContainerComponent, + ToasterService, } from 'angular2-toaster'; -import { Angulartics2GoogleAnalytics } from 'angulartics2/ga'; +import { Angulartics2 } from 'angulartics2'; import { Component, + NgZone, + OnDestroy, + OnInit, } from '@angular/core'; import { Router } from '@angular/router'; +import { BroadcasterService } from 'jslib/angular/services/broadcaster.service'; + +import { StorageService } from 'jslib/abstractions/storage.service'; + +import { AuthService } from 'jslib/abstractions/auth.service'; +import { CipherService } from 'jslib/abstractions/cipher.service'; +import { CollectionService } from 'jslib/abstractions/collection.service'; +import { CryptoService } from 'jslib/abstractions/crypto.service'; +import { FolderService } from 'jslib/abstractions/folder.service'; +import { I18nService } from 'jslib/abstractions/i18n.service'; +import { LockService } from 'jslib/abstractions/lock.service'; +import { PasswordGenerationService } from 'jslib/abstractions/passwordGeneration.service'; +import { PlatformUtilsService } from 'jslib/abstractions/platformUtils.service'; +import { SettingsService } from 'jslib/abstractions/settings.service'; +import { SyncService } from 'jslib/abstractions/sync.service'; +import { TokenService } from 'jslib/abstractions/token.service'; +import { UserService } from 'jslib/abstractions/user.service'; + +import { ConstantsService } from 'jslib/services/constants.service'; + +const BroadcasterSubscriptionId = 'AppComponent'; + @Component({ selector: 'app-root', templateUrl: 'app.component.html', }) -export class AppComponent { +export class AppComponent implements OnDestroy, OnInit { toasterConfig: ToasterConfig = new ToasterConfig({ showCloseButton: true, mouseoverTimerStop: true, @@ -22,7 +48,90 @@ export class AppComponent { positionClass: 'toast-bottom-right', }); - constructor() { - // + private lastActivity: number = null; + + constructor(private broadcasterService: BroadcasterService, private userService: UserService, + private tokenService: TokenService, private folderService: FolderService, + private settingsService: SettingsService, private syncService: SyncService, + private passwordGenerationService: PasswordGenerationService, private cipherService: CipherService, + private authService: AuthService, private router: Router, private analytics: Angulartics2, + private toasterService: ToasterService, private i18nService: I18nService, + private platformUtilsService: PlatformUtilsService, private ngZone: NgZone, + private lockService: LockService, private storageService: StorageService, + private cryptoService: CryptoService, private collectionService: CollectionService) { } + + ngOnInit() { + this.ngZone.runOutsideAngular(() => { + window.onmousemove = () => this.recordActivity(); + window.onmousedown = () => this.recordActivity(); + window.ontouchstart = () => this.recordActivity(); + window.onclick = () => this.recordActivity(); + window.onscroll = () => this.recordActivity(); + window.onkeypress = () => this.recordActivity(); + }); + + this.broadcasterService.subscribe(BroadcasterSubscriptionId, async (message: any) => { + this.ngZone.run(async () => { + switch (message.command) { + case 'loggedIn': + case 'unlocked': + case 'loggedOut': + break; + case 'logout': + this.logOut(!!message.expired); + break; + case 'lockVault': + //await this.lockService.lock(); + break; + case 'locked': + //this.router.navigate(['lock']); + break; + case 'syncStarted': + break; + case 'syncCompleted': + break; + default: + } + }); + }); + } + + ngOnDestroy() { + this.broadcasterService.unsubscribe(BroadcasterSubscriptionId); + } + + private async logOut(expired: boolean) { + const userId = await this.userService.getUserId(); + + await Promise.all([ + this.syncService.setLastSync(new Date(0)), + this.tokenService.clearToken(), + this.cryptoService.clearKeys(), + this.userService.clear(), + this.settingsService.clear(userId), + this.cipherService.clear(userId), + this.folderService.clear(userId), + this.collectionService.clear(userId), + this.passwordGenerationService.clear(), + ]); + + this.authService.logOut(async () => { + this.analytics.eventTrack.next({ action: 'Logged Out' }); + if (expired) { + this.toasterService.popAsync('warning', this.i18nService.t('loggedOut'), + this.i18nService.t('loginExpired')); + } + this.router.navigate(['login']); + }); + } + + private async recordActivity() { + const now = (new Date()).getTime(); + if (this.lastActivity != null && now - this.lastActivity < 250) { + return; + } + + this.lastActivity = now; + this.storageService.save(ConstantsService.lastActiveKey, now); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 61d24feac5..c2932a377a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -16,6 +16,12 @@ import { ServicesModule } from './services.module'; import { AppComponent } from './app.component'; import { ModalComponent } from './modal.component'; +import { FooterComponent } from './layouts/footer.component'; +import { FrontendLayoutComponent } from './layouts/frontend-layout.component'; +import { NavbarComponent } from './layouts/navbar.component'; +import { OrganizationLayoutComponent } from './layouts/organization-layout.component'; +import { UserLayoutComponent } from './layouts/user-layout.component'; + import { HintComponent } from './accounts/hint.component'; import { LoginComponent } from './accounts/login.component'; import { RegisterComponent } from './accounts/register.component'; @@ -69,6 +75,8 @@ import { Folder } from 'jslib/models/domain'; CiphersComponent, FallbackSrcDirective, FolderAddEditComponent, + FooterComponent, + FrontendLayoutComponent, GroupingsComponent, HintComponent, IconComponent, @@ -76,12 +84,15 @@ import { Folder } from 'jslib/models/domain'; InputVerbatimDirective, LoginComponent, ModalComponent, + NavbarComponent, + OrganizationLayoutComponent, RegisterComponent, SearchCiphersPipe, StopClickDirective, StopPropDirective, TwoFactorComponent, TwoFactorOptionsComponent, + UserLayoutComponent, VaultComponent, ], entryComponents: [ diff --git a/src/app/layouts/footer.component.html b/src/app/layouts/footer.component.html new file mode 100644 index 0000000000..116376c426 --- /dev/null +++ b/src/app/layouts/footer.component.html @@ -0,0 +1,13 @@ + diff --git a/src/app/layouts/footer.component.ts b/src/app/layouts/footer.component.ts new file mode 100644 index 0000000000..225beb1a4d --- /dev/null +++ b/src/app/layouts/footer.component.ts @@ -0,0 +1,9 @@ +import { + Component, +} from '@angular/core'; + +@Component({ + selector: 'app-footer', + templateUrl: 'footer.component.html', +}) +export class FooterComponent { } diff --git a/src/app/layouts/frontend-layout.component.html b/src/app/layouts/frontend-layout.component.html new file mode 100644 index 0000000000..4cca73f7a2 --- /dev/null +++ b/src/app/layouts/frontend-layout.component.html @@ -0,0 +1,2 @@ + + diff --git a/src/app/layouts/frontend-layout.component.ts b/src/app/layouts/frontend-layout.component.ts new file mode 100644 index 0000000000..737f5ab955 --- /dev/null +++ b/src/app/layouts/frontend-layout.component.ts @@ -0,0 +1,9 @@ +import { + Component, +} from '@angular/core'; + +@Component({ + selector: 'app-frontend-layout', + templateUrl: 'frontend-layout.component.html', +}) +export class FrontendLayoutComponent { } diff --git a/src/app/layouts/navbar.component.html b/src/app/layouts/navbar.component.html new file mode 100644 index 0000000000..e202ed3e28 --- /dev/null +++ b/src/app/layouts/navbar.component.html @@ -0,0 +1,33 @@ + diff --git a/src/app/layouts/navbar.component.ts b/src/app/layouts/navbar.component.ts new file mode 100644 index 0000000000..5579bb057d --- /dev/null +++ b/src/app/layouts/navbar.component.ts @@ -0,0 +1,17 @@ +import { + Component, +} from '@angular/core'; + +import { MessagingService } from 'jslib/abstractions/messaging.service'; + +@Component({ + selector: 'app-navbar', + templateUrl: 'navbar.component.html', +}) +export class NavbarComponent { + constructor(private messagingService: MessagingService) { } + + logOut() { + this.messagingService.send('logout'); + } +} diff --git a/src/app/layouts/organization-layout.component.html b/src/app/layouts/organization-layout.component.html new file mode 100644 index 0000000000..28dca81162 --- /dev/null +++ b/src/app/layouts/organization-layout.component.html @@ -0,0 +1,3 @@ + + + diff --git a/src/app/layouts/organization-layout.component.ts b/src/app/layouts/organization-layout.component.ts new file mode 100644 index 0000000000..df0e885707 --- /dev/null +++ b/src/app/layouts/organization-layout.component.ts @@ -0,0 +1,9 @@ +import { + Component, +} from '@angular/core'; + +@Component({ + selector: 'app-organization-layout', + templateUrl: 'organization-layout.component.html', +}) +export class OrganizationLayoutComponent { } diff --git a/src/app/layouts/user-layout.component.html b/src/app/layouts/user-layout.component.html new file mode 100644 index 0000000000..28dca81162 --- /dev/null +++ b/src/app/layouts/user-layout.component.html @@ -0,0 +1,3 @@ + + + diff --git a/src/app/layouts/user-layout.component.ts b/src/app/layouts/user-layout.component.ts new file mode 100644 index 0000000000..5cf669719d --- /dev/null +++ b/src/app/layouts/user-layout.component.ts @@ -0,0 +1,9 @@ +import { + Component, +} from '@angular/core'; + +@Component({ + selector: 'app-user-layout', + templateUrl: 'user-layout.component.html', +}) +export class UserLayoutComponent { } diff --git a/src/app/services.module.ts b/src/app/services.module.ts index 69a315a3f0..295813c641 100644 --- a/src/app/services.module.ts +++ b/src/app/services.module.ts @@ -5,8 +5,8 @@ import { import { ToasterModule } from 'angular2-toaster'; +import { BroadcasterMessagingService } from '../services/broadcasterMessaging.service'; import { I18nService } from '../services/i18n.service'; -import { WebMessagingService } from '../services/webMessaging.service'; import { WebPlatformUtilsService } from '../services/webPlatformUtils.service'; import { WebStorageService } from '../services/webStorage.service'; @@ -68,7 +68,7 @@ import { UserService as UserServiceAbstraction } from 'jslib/abstractions/user.s const i18nService = new I18nService(window.navigator.language, 'locales'); const stateService = new StateService(); const broadcasterService = new BroadcasterService(); -const messagingService = new WebMessagingService(); +const messagingService = new BroadcasterMessagingService(broadcasterService); const platformUtilsService = new WebPlatformUtilsService(messagingService, i18nService); const storageService: StorageServiceAbstraction = new WebStorageService(); const cryptoFunctionService: CryptoFunctionServiceAbstraction = new WebCryptoFunctionService(window, diff --git a/src/app/vault/vault.component.html b/src/app/vault/vault.component.html index 8b9cd1ea92..99d224b8c6 100644 --- a/src/app/vault/vault.component.html +++ b/src/app/vault/vault.component.html @@ -1,32 +1,3 @@ -
@@ -93,19 +64,6 @@
- diff --git a/src/services/broadcasterMessaging.service.ts b/src/services/broadcasterMessaging.service.ts new file mode 100644 index 0000000000..ffb501c194 --- /dev/null +++ b/src/services/broadcasterMessaging.service.ts @@ -0,0 +1,12 @@ +import { MessagingService } from 'jslib/abstractions/messaging.service'; + +import { BroadcasterService } from 'jslib/angular/services/broadcaster.service'; + +export class BroadcasterMessagingService implements MessagingService { + constructor(private broadcasterService: BroadcasterService) { } + + send(subscriber: string, arg: any = {}) { + const message = Object.assign({}, { command: subscriber }, arg); + this.broadcasterService.send(message); + } +} diff --git a/src/services/webMessaging.service.ts b/src/services/webMessaging.service.ts deleted file mode 100644 index 07571ae288..0000000000 --- a/src/services/webMessaging.service.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { MessagingService } from 'jslib/abstractions/messaging.service'; - -export class WebMessagingService implements MessagingService { - send(subscriber: string, arg: any = {}) { - // - } -}