diff --git a/jslib b/jslib index a67ea2422f..c0fd5f71f8 160000 --- a/jslib +++ b/jslib @@ -1 +1 @@ -Subproject commit a67ea2422f082c6b884a3c7187e17a318048f7f5 +Subproject commit c0fd5f71f8e2cf36165c565b4967ac0e379f166f diff --git a/package-lock.json b/package-lock.json index 47aecd38c8..1987c8a8e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,9 +103,17 @@ } }, "@aspnet/signalr": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.2.tgz", - "integrity": "sha512-sXleqUCCbodCOqUA8MjLSvtAgDTvDhEq6j3JyAq/w4RMJhpZ+dXK9+6xEMbzag2hisq5e/8vDC82JYutkcOISQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@aspnet/signalr/-/signalr-1.0.3.tgz", + "integrity": "sha512-8nPSarp4k+oP2M6P7tw2FZMXOMR86wH9GPb/4wiqA18c4Ds88SUmE0pSpnNQPDOoWGMj6y9F2Xz5JyoynCPXWQ==" + }, + "@aspnet/signalr-protocol-msgpack": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@aspnet/signalr-protocol-msgpack/-/signalr-protocol-msgpack-1.0.3.tgz", + "integrity": "sha512-R5CRpxXGICi0Tgbd86uA8bC75Rm0y7Yp6oD87INfKxsav/m/xbz33rkGOI1OZIfsc/J6/WU5z0Bqpc2QgYfaJQ==", + "requires": { + "msgpack5": "^4.0.2" + } }, "@ngtools/webpack": { "version": "1.10.2", @@ -6786,6 +6794,28 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "msgpack5": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/msgpack5/-/msgpack5-4.2.0.tgz", + "integrity": "sha512-tQkRlwO4f3/E8Kq5qm6PcVw+J+K4+U/XNqeD9Ebo1qVsrjkcKb2FfmdtuuIslw42CGT+K3ZVKAvKfSPp3QRplQ==", + "requires": { + "bl": "^2.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.3.6", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bl": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.0.1.tgz", + "integrity": "sha512-FrMgLukB9jujvJ92p5TA0hcKIHtInVXXhxD7qgAuV7k0cbPt9USZmOYnhDXH6IsnGeIUglX42TSBV7Gn4q5sbQ==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + } + } + }, "multipipe": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", diff --git a/package.json b/package.json index 3eda35bc7f..affc52694a 100644 --- a/package.json +++ b/package.json @@ -238,7 +238,8 @@ "@angular/platform-browser-dynamic": "5.2.0", "@angular/router": "5.2.0", "@angular/upgrade": "5.2.0", - "@aspnet/signalr": "1.0.2", + "@aspnet/signalr": "1.0.3", + "@aspnet/signalr-protocol-msgpack": "1.0.3", "angular2-toaster": "4.0.2", "angulartics2": "5.0.1", "core-js": "2.4.1", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9fb1915ed5..0cf4d96fab 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -44,6 +44,7 @@ import { UserService } from 'jslib/abstractions/user.service'; import { ConstantsService } from 'jslib/services/constants.service'; const BroadcasterSubscriptionId = 'AppComponent'; +const IdleTimeout = 60000 * 10; // 10 minutes @Component({ selector: 'app-root', @@ -69,6 +70,8 @@ export class AppComponent implements OnInit { private lastActivity: number = null; private modal: ModalComponent = null; + private idleTimer: number = null; + private isIdle = false; constructor(private angulartics2GoogleAnalytics: Angulartics2GoogleAnalytics, private broadcasterService: BroadcasterService, private userService: UserService, @@ -104,10 +107,8 @@ export class AppComponent implements OnInit { switch (message.command) { case 'loggedIn': case 'loggedOut': - this.notificationsService.updateConnection(); - this.updateAppMenu(); - break; case 'unlocked': + this.notificationsService.updateConnection(); this.updateAppMenu(); break; case 'logout': @@ -118,6 +119,7 @@ export class AppComponent implements OnInit { break; case 'locked': this.router.navigate(['lock']); + this.notificationsService.updateConnection(); this.updateAppMenu(); break; case 'syncStarted': @@ -185,6 +187,30 @@ export class AppComponent implements OnInit { this.lastActivity = now; this.storageService.save(ConstantsService.lastActiveKey, now); + + // Idle states + if (this.isIdle) { + this.isIdle = false; + this.idleStateChanged(); + } + if (this.idleTimer != null) { + window.clearTimeout(this.idleTimer); + this.idleTimer = null; + } + this.idleTimer = window.setTimeout(() => { + if (!this.isIdle) { + this.isIdle = true; + this.idleStateChanged(); + } + }, IdleTimeout); + } + + private idleStateChanged() { + if (this.isIdle) { + this.notificationsService.disconnectFromInactivity(); + } else { + this.notificationsService.reconnectFromActivity(); + } } private openModal(type: Type, ref: ViewContainerRef) { @@ -194,7 +220,7 @@ export class AppComponent implements OnInit { const factory = this.componentFactoryResolver.resolveComponentFactory(ModalComponent); this.modal = ref.createComponent(factory).instance; - const childComponent = this.modal.show(type, ref); + this.modal.show(type, ref); this.modal.onClosed.subscribe(() => { this.modal = null; diff --git a/src/app/services.module.ts b/src/app/services.module.ts index 852d216b78..9b7eec1238 100644 --- a/src/app/services.module.ts +++ b/src/app/services.module.ts @@ -112,8 +112,8 @@ const authService = new AuthService(cryptoService, apiService, userService, tokenService, appIdService, i18nService, platformUtilsService, messagingService); const exportService = new ExportService(folderService, cipherService, apiService); const auditService = new AuditService(cryptoFunctionService, apiService); -const notificationsService = new NotificationsService(userService, tokenService, syncService, appIdService, - apiService); +const notificationsService = new NotificationsService(userService, syncService, appIdService, + apiService, cryptoService); const environmentService = new EnvironmentService(apiService, storageService, notificationsService); const analytics = new Analytics(window, () => isDev(), platformUtilsService, storageService, appIdService);