mirror of
https://github.com/bitwarden/browser
synced 2025-12-16 16:23:44 +00:00
notification service
This commit is contained in:
72
package-lock.json
generated
72
package-lock.json
generated
@@ -84,6 +84,11 @@
|
|||||||
"tslib": "^1.7.1"
|
"tslib": "^1.7.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@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=="
|
||||||
|
},
|
||||||
"@types/form-data": {
|
"@types/form-data": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz",
|
||||||
@@ -1937,9 +1942,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "2.0.5",
|
"version": "2.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-2.0.7.tgz",
|
||||||
"integrity": "sha512-NbWsgAvcxxQrDNaLA2L5adZTKWO6mZwC57uSPQiZiFjpO0K6uVNCjFyRbLnhq8AWq2tmcuzs6mFpIzQXmvlnUQ==",
|
"integrity": "sha512-MRrDE6mrp+ZrIBpZM27pxbO2yEDKYfkmc6Ll79BtedMNEZsY4+oblupeDJL6RM6meUIp82KMo63W7fP65Tb89Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/node": "^8.0.24",
|
"@types/node": "^8.0.24",
|
||||||
@@ -1948,9 +1953,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "8.10.24",
|
"version": "8.10.26",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.24.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.26.tgz",
|
||||||
"integrity": "sha512-5YaBKa6oFuWy7ptIFMATyftIcpZTZtvgrzPThEbs+kl4Uu41oUxiRunG0k32QZjD6MXMELls//ry/epNxc11aQ==",
|
"integrity": "sha512-opk6bLLErLSwyVVJeSH5Ek7ZWOBSsN0JrvXTNVGLXLAXKB9xlTYajrplR44xVyMrmbut94H6uJ9jqzM/12jxkA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3301,12 +3306,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"har-validator": {
|
"har-validator": {
|
||||||
"version": "5.0.3",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
|
||||||
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
|
"integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ajv": "^5.1.0",
|
"ajv": "^5.3.0",
|
||||||
"har-schema": "^2.0.0"
|
"har-schema": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5358,9 +5363,9 @@
|
|||||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||||
},
|
},
|
||||||
"oauth-sign": {
|
"oauth-sign": {
|
||||||
"version": "0.8.2",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
|
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||||
"integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
|
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
@@ -5878,6 +5883,12 @@
|
|||||||
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"psl": {
|
||||||
|
"version": "1.1.29",
|
||||||
|
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
|
||||||
|
"integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"pstree.remy": {
|
"pstree.remy": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
|
||||||
@@ -6214,31 +6225,31 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"request": {
|
"request": {
|
||||||
"version": "2.87.0",
|
"version": "2.88.0",
|
||||||
"resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
|
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||||
"integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
|
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"aws-sign2": "~0.7.0",
|
"aws-sign2": "~0.7.0",
|
||||||
"aws4": "^1.6.0",
|
"aws4": "^1.8.0",
|
||||||
"caseless": "~0.12.0",
|
"caseless": "~0.12.0",
|
||||||
"combined-stream": "~1.0.5",
|
"combined-stream": "~1.0.6",
|
||||||
"extend": "~3.0.1",
|
"extend": "~3.0.2",
|
||||||
"forever-agent": "~0.6.1",
|
"forever-agent": "~0.6.1",
|
||||||
"form-data": "~2.3.1",
|
"form-data": "~2.3.2",
|
||||||
"har-validator": "~5.0.3",
|
"har-validator": "~5.1.0",
|
||||||
"http-signature": "~1.2.0",
|
"http-signature": "~1.2.0",
|
||||||
"is-typedarray": "~1.0.0",
|
"is-typedarray": "~1.0.0",
|
||||||
"isstream": "~0.1.2",
|
"isstream": "~0.1.2",
|
||||||
"json-stringify-safe": "~5.0.1",
|
"json-stringify-safe": "~5.0.1",
|
||||||
"mime-types": "~2.1.17",
|
"mime-types": "~2.1.19",
|
||||||
"oauth-sign": "~0.8.2",
|
"oauth-sign": "~0.9.0",
|
||||||
"performance-now": "^2.1.0",
|
"performance-now": "^2.1.0",
|
||||||
"qs": "~6.5.1",
|
"qs": "~6.5.2",
|
||||||
"safe-buffer": "^5.1.1",
|
"safe-buffer": "^5.1.2",
|
||||||
"tough-cookie": "~2.3.3",
|
"tough-cookie": "~2.4.3",
|
||||||
"tunnel-agent": "^0.6.0",
|
"tunnel-agent": "^0.6.0",
|
||||||
"uuid": "^3.1.0"
|
"uuid": "^3.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"requires-port": {
|
"requires-port": {
|
||||||
@@ -7293,11 +7304,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "2.3.4",
|
"version": "2.4.3",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||||
"integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
|
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"psl": "^1.1.24",
|
||||||
"punycode": "^1.4.1"
|
"punycode": "^1.4.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
"@types/papaparse": "4.1.31",
|
"@types/papaparse": "4.1.31",
|
||||||
"@types/webcrypto": "0.0.28",
|
"@types/webcrypto": "0.0.28",
|
||||||
"concurrently": "3.5.1",
|
"concurrently": "3.5.1",
|
||||||
"electron": "2.0.5",
|
"electron": "2.0.7",
|
||||||
"jasmine": "^3.1.0",
|
"jasmine": "^3.1.0",
|
||||||
"jasmine-core": "^2.8.0",
|
"jasmine-core": "^2.8.0",
|
||||||
"jasmine-spec-reporter": "^4.2.1",
|
"jasmine-spec-reporter": "^4.2.1",
|
||||||
@@ -67,6 +67,7 @@
|
|||||||
"@angular/platform-browser-dynamic": "5.2.0",
|
"@angular/platform-browser-dynamic": "5.2.0",
|
||||||
"@angular/router": "5.2.0",
|
"@angular/router": "5.2.0",
|
||||||
"@angular/upgrade": "5.2.0",
|
"@angular/upgrade": "5.2.0",
|
||||||
|
"@aspnet/signalr": "1.0.2",
|
||||||
"angular2-toaster": "4.0.2",
|
"angular2-toaster": "4.0.2",
|
||||||
"angulartics2": "5.0.1",
|
"angulartics2": "5.0.1",
|
||||||
"core-js": "2.4.1",
|
"core-js": "2.4.1",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ export abstract class EnvironmentService {
|
|||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
identityUrl: string;
|
identityUrl: string;
|
||||||
iconsUrl: string;
|
iconsUrl: string;
|
||||||
|
notificationsUrl: string;
|
||||||
|
|
||||||
getWebVaultUrl: () => string;
|
getWebVaultUrl: () => string;
|
||||||
setUrlsFromStorage: () => Promise<void>;
|
setUrlsFromStorage: () => Promise<void>;
|
||||||
|
|||||||
6
src/abstractions/notifications.service.ts
Normal file
6
src/abstractions/notifications.service.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { EnvironmentService } from './environment.service';
|
||||||
|
|
||||||
|
export abstract class NotificationsService {
|
||||||
|
init: (environmentService: EnvironmentService) => Promise<void>;
|
||||||
|
updateConnection: () => Promise<void>;
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ export class EnvironmentComponent {
|
|||||||
identityUrl: string;
|
identityUrl: string;
|
||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
webVaultUrl: string;
|
webVaultUrl: string;
|
||||||
|
notificationsUrl: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
showCustom = false;
|
showCustom = false;
|
||||||
|
|
||||||
@@ -26,6 +27,7 @@ export class EnvironmentComponent {
|
|||||||
this.apiUrl = environmentService.apiUrl || '';
|
this.apiUrl = environmentService.apiUrl || '';
|
||||||
this.identityUrl = environmentService.identityUrl || '';
|
this.identityUrl = environmentService.identityUrl || '';
|
||||||
this.iconsUrl = environmentService.iconsUrl || '';
|
this.iconsUrl = environmentService.iconsUrl || '';
|
||||||
|
this.notificationsUrl = environmentService.notificationsUrl || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async submit() {
|
async submit() {
|
||||||
@@ -35,6 +37,7 @@ export class EnvironmentComponent {
|
|||||||
identity: this.identityUrl,
|
identity: this.identityUrl,
|
||||||
webVault: this.webVaultUrl,
|
webVault: this.webVaultUrl,
|
||||||
icons: this.iconsUrl,
|
icons: this.iconsUrl,
|
||||||
|
notifications: this.notificationsUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
// re-set urls since service can change them, ex: prefixing https://
|
// re-set urls since service can change them, ex: prefixing https://
|
||||||
@@ -43,6 +46,7 @@ export class EnvironmentComponent {
|
|||||||
this.identityUrl = resUrls.identity;
|
this.identityUrl = resUrls.identity;
|
||||||
this.webVaultUrl = resUrls.webVault;
|
this.webVaultUrl = resUrls.webVault;
|
||||||
this.iconsUrl = resUrls.icons;
|
this.iconsUrl = resUrls.icons;
|
||||||
|
this.notificationsUrl = resUrls.notifications;
|
||||||
|
|
||||||
this.analytics.eventTrack.next({ action: 'Set Environment URLs' });
|
this.analytics.eventTrack.next({ action: 'Set Environment URLs' });
|
||||||
this.toasterService.popAsync('success', null, this.i18nService.t('environmentSaved'));
|
this.toasterService.popAsync('success', null, this.i18nService.t('environmentSaved'));
|
||||||
|
|||||||
14
src/enums/notificationType.ts
Normal file
14
src/enums/notificationType.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export enum NotificationType {
|
||||||
|
SyncCipherUpdate = 0,
|
||||||
|
SyncCipherCreate = 1,
|
||||||
|
SyncLoginDelete = 2,
|
||||||
|
SyncFolderDelete = 3,
|
||||||
|
SyncCiphers = 4,
|
||||||
|
|
||||||
|
SyncVault = 5,
|
||||||
|
SyncOrgKeys = 6,
|
||||||
|
SyncFolderCreate = 7,
|
||||||
|
SyncFolderUpdate = 8,
|
||||||
|
SyncCipherDelete = 9,
|
||||||
|
SyncSettings = 10,
|
||||||
|
}
|
||||||
71
src/models/response/notificationResponse.ts
Normal file
71
src/models/response/notificationResponse.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { NotificationType } from '../../enums/notificationType';
|
||||||
|
|
||||||
|
export class NotificationResponse {
|
||||||
|
contextId: string;
|
||||||
|
type: NotificationType;
|
||||||
|
payload: any;
|
||||||
|
|
||||||
|
constructor(response: any) {
|
||||||
|
this.contextId = response.contextId || response.ContextId;
|
||||||
|
this.type = response.type != null ? response.type : response.Type;
|
||||||
|
|
||||||
|
const payload = response.payload || response.Payload;
|
||||||
|
switch (this.type) {
|
||||||
|
case NotificationType.SyncCipherCreate:
|
||||||
|
case NotificationType.SyncCipherDelete:
|
||||||
|
case NotificationType.SyncCipherUpdate:
|
||||||
|
case NotificationType.SyncLoginDelete:
|
||||||
|
this.payload = new SyncCipherNotification(payload);
|
||||||
|
break;
|
||||||
|
case NotificationType.SyncFolderCreate:
|
||||||
|
case NotificationType.SyncFolderDelete:
|
||||||
|
case NotificationType.SyncFolderUpdate:
|
||||||
|
this.payload = new SyncFolderNotification(payload);
|
||||||
|
break;
|
||||||
|
case NotificationType.SyncVault:
|
||||||
|
case NotificationType.SyncCiphers:
|
||||||
|
case NotificationType.SyncOrgKeys:
|
||||||
|
case NotificationType.SyncSettings:
|
||||||
|
this.payload = new SyncUserNotification(payload);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SyncCipherNotification {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
organizationId: string;
|
||||||
|
revisionDate: Date;
|
||||||
|
|
||||||
|
constructor(response: any) {
|
||||||
|
this.id = response.Id;
|
||||||
|
this.userId = response.UserId;
|
||||||
|
this.organizationId = response.OrganizationId;
|
||||||
|
this.revisionDate = new Date(response.RevisionDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SyncFolderNotification {
|
||||||
|
id: string;
|
||||||
|
userId: string;
|
||||||
|
revisionDate: Date;
|
||||||
|
|
||||||
|
constructor(response: any) {
|
||||||
|
this.id = response.Id;
|
||||||
|
this.userId = response.UserId;
|
||||||
|
this.revisionDate = new Date(response.RevisionDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class SyncUserNotification {
|
||||||
|
userId: string;
|
||||||
|
date: Date;
|
||||||
|
|
||||||
|
constructor(response: any) {
|
||||||
|
this.userId = response.UserId;
|
||||||
|
this.date = new Date(response.Date);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
identityUrl: string;
|
identityUrl: string;
|
||||||
iconsUrl: string;
|
iconsUrl: string;
|
||||||
|
notificationsUrl: string;
|
||||||
|
|
||||||
constructor(private apiService: ApiService, private storageService: StorageService) {}
|
constructor(private apiService: ApiService, private storageService: StorageService) {}
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||||||
api: null,
|
api: null,
|
||||||
identity: null,
|
identity: null,
|
||||||
icons: null,
|
icons: null,
|
||||||
|
notifications: null,
|
||||||
webVault: null,
|
webVault: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -46,6 +48,7 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||||||
this.apiUrl = envUrls.api = urls.api;
|
this.apiUrl = envUrls.api = urls.api;
|
||||||
this.identityUrl = envUrls.identity = urls.identity;
|
this.identityUrl = envUrls.identity = urls.identity;
|
||||||
this.iconsUrl = urls.icons;
|
this.iconsUrl = urls.icons;
|
||||||
|
this.notificationsUrl = urls.notifications;
|
||||||
await this.apiService.setUrls(envUrls);
|
await this.apiService.setUrls(envUrls);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +58,7 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||||||
urls.api = this.formatUrl(urls.api);
|
urls.api = this.formatUrl(urls.api);
|
||||||
urls.identity = this.formatUrl(urls.identity);
|
urls.identity = this.formatUrl(urls.identity);
|
||||||
urls.icons = this.formatUrl(urls.icons);
|
urls.icons = this.formatUrl(urls.icons);
|
||||||
|
urls.notifications = this.formatUrl(urls.notifications);
|
||||||
|
|
||||||
await this.storageService.save(ConstantsService.environmentUrlsKey, {
|
await this.storageService.save(ConstantsService.environmentUrlsKey, {
|
||||||
base: urls.base,
|
base: urls.base,
|
||||||
@@ -62,6 +66,7 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||||||
identity: urls.identity,
|
identity: urls.identity,
|
||||||
webVault: urls.webVault,
|
webVault: urls.webVault,
|
||||||
icons: urls.icons,
|
icons: urls.icons,
|
||||||
|
notifications: urls.notifications,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.baseUrl = urls.base;
|
this.baseUrl = urls.base;
|
||||||
@@ -69,6 +74,7 @@ export class EnvironmentService implements EnvironmentServiceAbstraction {
|
|||||||
this.apiUrl = urls.api;
|
this.apiUrl = urls.api;
|
||||||
this.identityUrl = urls.identity;
|
this.identityUrl = urls.identity;
|
||||||
this.iconsUrl = urls.icons;
|
this.iconsUrl = urls.icons;
|
||||||
|
this.notificationsUrl = urls.notifications;
|
||||||
|
|
||||||
const envUrls = new EnvironmentUrls();
|
const envUrls = new EnvironmentUrls();
|
||||||
if (this.baseUrl) {
|
if (this.baseUrl) {
|
||||||
|
|||||||
90
src/services/notifications.service.ts
Normal file
90
src/services/notifications.service.ts
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import * as signalR from '@aspnet/signalr';
|
||||||
|
|
||||||
|
import { NotificationType } from '../enums/notificationType';
|
||||||
|
|
||||||
|
import { CipherService } from '../abstractions/cipher.service';
|
||||||
|
import { CollectionService } from '../abstractions/collection.service';
|
||||||
|
import { EnvironmentService } from '../abstractions/environment.service';
|
||||||
|
import { FolderService } from '../abstractions/folder.service';
|
||||||
|
import { NotificationsService as NotificationsServiceAbstraction } from '../abstractions/notifications.service';
|
||||||
|
import { SettingsService } from '../abstractions/settings.service';
|
||||||
|
import { SyncService } from '../abstractions/sync.service';
|
||||||
|
import { TokenService } from '../abstractions/token.service';
|
||||||
|
import { UserService } from '../abstractions/user.service';
|
||||||
|
|
||||||
|
import { NotificationResponse } from '../models/response/notificationResponse';
|
||||||
|
|
||||||
|
export class NotificationsService implements NotificationsServiceAbstraction {
|
||||||
|
private signalrConnection: signalR.HubConnection;
|
||||||
|
|
||||||
|
constructor(private userService: UserService, private tokenService: TokenService,
|
||||||
|
private syncService: SyncService) { }
|
||||||
|
|
||||||
|
async init(environmentService: EnvironmentService): Promise<void> {
|
||||||
|
let url = 'https://notifications.bitwarden.com';
|
||||||
|
if (environmentService.notificationsUrl != null) {
|
||||||
|
url = environmentService.notificationsUrl;
|
||||||
|
} else if (environmentService.baseUrl != null) {
|
||||||
|
url = environmentService.baseUrl + '/notifications';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.signalrConnection != null) {
|
||||||
|
await this.signalrConnection.stop();
|
||||||
|
this.signalrConnection = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.signalrConnection = new signalR.HubConnectionBuilder()
|
||||||
|
.withUrl(url + '/hub', {
|
||||||
|
accessTokenFactory: () => this.tokenService.getToken(),
|
||||||
|
})
|
||||||
|
.configureLogging(signalR.LogLevel.Information)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
this.signalrConnection.on('ReceiveMessage', async (data: any) => {
|
||||||
|
await this.processNotification(new NotificationResponse(data));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateConnection(): Promise<void> {
|
||||||
|
try {
|
||||||
|
if (await this.userService.isAuthenticated()) {
|
||||||
|
await this.signalrConnection.start();
|
||||||
|
} else {
|
||||||
|
await this.signalrConnection.stop();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// tslint:disable-next-line
|
||||||
|
console.error(e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async processNotification(notification: NotificationResponse) {
|
||||||
|
if (notification == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (notification.type) {
|
||||||
|
case NotificationType.SyncCipherCreate:
|
||||||
|
case NotificationType.SyncCipherDelete:
|
||||||
|
case NotificationType.SyncCipherUpdate:
|
||||||
|
case NotificationType.SyncLoginDelete:
|
||||||
|
this.syncService.fullSync(false);
|
||||||
|
break;
|
||||||
|
case NotificationType.SyncFolderCreate:
|
||||||
|
case NotificationType.SyncFolderDelete:
|
||||||
|
case NotificationType.SyncFolderUpdate:
|
||||||
|
this.syncService.fullSync(false);
|
||||||
|
break;
|
||||||
|
case NotificationType.SyncVault:
|
||||||
|
case NotificationType.SyncCiphers:
|
||||||
|
case NotificationType.SyncOrgKeys:
|
||||||
|
case NotificationType.SyncSettings:
|
||||||
|
this.syncService.fullSync(false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user