@pazznetwork/ngx-chat
Version:
[](https://travis-ci.com/pazznetwork/ngx-chat) [](https://coveralls.io/github/pazzn
53 lines • 10.5 kB
JavaScript
import { xml } from '@xmpp/client';
import { BehaviorSubject, of } from 'rxjs';
import { catchError, first, mergeMap, map, timeout } from 'rxjs/operators';
import { AbstractXmppPlugin } from './abstract-xmpp-plugin';
/**
* Request time of entities via XEP-0202.
*/
export class EntityTimePlugin extends AbstractXmppPlugin {
constructor(xmppChatAdapter, serviceDiscoveryPlugin, logService) {
super();
this.xmppChatAdapter = xmppChatAdapter;
this.serviceDiscoveryPlugin = serviceDiscoveryPlugin;
this.logService = logService;
this.serverSupportsTime$ = new BehaviorSubject('unknown');
this.serverTime$ = new BehaviorSubject(null);
}
async onBeforeOnline() {
const serverSupportsTimeRequest = await this.serviceDiscoveryPlugin.supportsFeature(this.xmppChatAdapter.chatConnectionService.userJid.domain, 'urn:xmpp:time');
if (serverSupportsTimeRequest) {
const sharedUtcTimeStamp = await this.requestTime(this.xmppChatAdapter.chatConnectionService.userJid.domain);
this.serverTime$.next(sharedUtcTimeStamp);
this.serverSupportsTime$.next(true);
}
else {
this.serverSupportsTime$.next(false);
}
}
onOffline() {
this.serverSupportsTime$.next('unknown');
this.serverTime$.next(null);
}
/**
* Returns a non-client-specific timestamp if server supports XEP-0202. Fallback to local timestamp in case of missing support.
*/
async getNow() {
const calculateNowViaServerTime$ = this.serverTime$.pipe(map(reference => this.calculateNow(reference)), first());
return await this.serverSupportsTime$.pipe(timeout(5000), first(supportsServerTime => supportsServerTime !== 'unknown'), mergeMap(supportsServerTime => supportsServerTime ? calculateNowViaServerTime$ : of(Date.now())), catchError(() => of(Date.now()))).toPromise();
}
calculateNow(reference) {
return reference.utcTimestamp + (performance.now() - reference.localReference);
}
async requestTime(jid) {
const response = await this.xmppChatAdapter.chatConnectionService.sendIq(xml('iq', { type: 'get', to: jid }, xml('time', { xmlns: 'urn:xmpp:time' })));
const utcString = response.getChild('time', 'urn:xmpp:time')?.getChildText('utc');
if (!utcString) {
const message = 'invalid time response';
this.logService.error(message, response.toString());
throw new Error(message);
}
return { utcTimestamp: Date.parse(utcString), localReference: performance.now() };
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXRpbWUucGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hZGFwdGVycy94bXBwL3BsdWdpbnMvZW50aXR5LXRpbWUucGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbkMsT0FBTyxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUczRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQVc1RDs7R0FFRztBQUNILE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxrQkFBa0I7SUFLcEQsWUFDWSxlQUFnQyxFQUNoQyxzQkFBOEMsRUFDOUMsVUFBc0I7UUFFOUIsS0FBSyxFQUFFLENBQUM7UUFKQSxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsMkJBQXNCLEdBQXRCLHNCQUFzQixDQUF3QjtRQUM5QyxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBTjFCLHdCQUFtQixHQUFHLElBQUksZUFBZSxDQUFzQixTQUFTLENBQUMsQ0FBQztRQUMxRSxnQkFBVyxHQUFHLElBQUksZUFBZSxDQUF1QixJQUFJLENBQUMsQ0FBQztJQVF0RSxDQUFDO0lBRUQsS0FBSyxDQUFDLGNBQWM7UUFDaEIsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxlQUFlLENBQy9FLElBQUksQ0FBQyxlQUFlLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFDekQsZUFBZSxDQUNsQixDQUFDO1FBQ0YsSUFBSSx5QkFBeUIsRUFBRTtZQUMzQixNQUFNLGtCQUFrQixHQUFHLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3RyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1lBQzFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7U0FDdkM7YUFBTTtZQUNILElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDeEM7SUFDTCxDQUFDO0lBRUQsU0FBUztRQUNMLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLE1BQU07UUFDUixNQUFNLDBCQUEwQixHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2xILE9BQU8sTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUN0QyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQ2IsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsS0FBSyxTQUFTLENBQUMsRUFDN0QsUUFBUSxDQUFDLGtCQUFrQixDQUFDLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsMEJBQTBCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUNoRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQ25DLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbEIsQ0FBQztJQUVPLFlBQVksQ0FBQyxTQUF3QjtRQUN6QyxPQUFPLFNBQVMsQ0FBQyxZQUFZLEdBQUcsQ0FBQyxXQUFXLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFRCxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQVc7UUFDekIsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FDcEUsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBQyxFQUM1QixHQUFHLENBQUMsTUFBTSxFQUFFLEVBQUMsS0FBSyxFQUFFLGVBQWUsRUFBQyxDQUFDLENBQ3hDLENBQ0osQ0FBQztRQUNGLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLGVBQWUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsRixJQUFJLENBQUMsU0FBUyxFQUFFO1lBQ1osTUFBTSxPQUFPLEdBQUcsdUJBQXVCLENBQUM7WUFDeEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1lBQ3BELE1BQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDNUI7UUFDRCxPQUFPLEVBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsY0FBYyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUUsRUFBQyxDQUFDO0lBQ3BGLENBQUM7Q0FFSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHhtbCB9IGZyb20gJ0B4bXBwL2NsaWVudCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaXJzdCwgbWVyZ2VNYXAsIG1hcCwgdGltZW91dCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IExvZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9sb2cuc2VydmljZSc7XG5pbXBvcnQgeyBYbXBwQ2hhdEFkYXB0ZXIgfSBmcm9tICcuLi94bXBwLWNoYXQtYWRhcHRlci5zZXJ2aWNlJztcbmltcG9ydCB7IEFic3RyYWN0WG1wcFBsdWdpbiB9IGZyb20gJy4vYWJzdHJhY3QteG1wcC1wbHVnaW4nO1xuaW1wb3J0IHsgU2VydmljZURpc2NvdmVyeVBsdWdpbiB9IGZyb20gJy4vc2VydmljZS1kaXNjb3ZlcnkucGx1Z2luJztcblxuZXhwb3J0IGludGVyZmFjZSBUaW1lUmVmZXJlbmNlIHtcbiAgICB1dGNUaW1lc3RhbXA6IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBXaGVuIHdhcyB1dGNUaW1lc3RhbXAgc2VlbiBsb2NhbGx5IGFjY29yZGluZyB0byBwZXJmb3JtYW5jZS5ub3coKS5cbiAgICAgKi9cbiAgICBsb2NhbFJlZmVyZW5jZTogbnVtYmVyO1xufVxuXG4vKipcbiAqIFJlcXVlc3QgdGltZSBvZiBlbnRpdGllcyB2aWEgWEVQLTAyMDIuXG4gKi9cbmV4cG9ydCBjbGFzcyBFbnRpdHlUaW1lUGx1Z2luIGV4dGVuZHMgQWJzdHJhY3RYbXBwUGx1Z2luIHtcblxuICAgIHByaXZhdGUgc2VydmVyU3VwcG9ydHNUaW1lJCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbiB8ICd1bmtub3duJz4oJ3Vua25vd24nKTtcbiAgICBwcml2YXRlIHNlcnZlclRpbWUkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxUaW1lUmVmZXJlbmNlIHwgbnVsbD4obnVsbCk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSB4bXBwQ2hhdEFkYXB0ZXI6IFhtcHBDaGF0QWRhcHRlcixcbiAgICAgICAgcHJpdmF0ZSBzZXJ2aWNlRGlzY292ZXJ5UGx1Z2luOiBTZXJ2aWNlRGlzY292ZXJ5UGx1Z2luLFxuICAgICAgICBwcml2YXRlIGxvZ1NlcnZpY2U6IExvZ1NlcnZpY2UsXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25CZWZvcmVPbmxpbmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHNlcnZlclN1cHBvcnRzVGltZVJlcXVlc3QgPSBhd2FpdCB0aGlzLnNlcnZpY2VEaXNjb3ZlcnlQbHVnaW4uc3VwcG9ydHNGZWF0dXJlKFxuICAgICAgICAgICAgdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnVzZXJKaWQuZG9tYWluLFxuICAgICAgICAgICAgJ3Vybjp4bXBwOnRpbWUnLFxuICAgICAgICApO1xuICAgICAgICBpZiAoc2VydmVyU3VwcG9ydHNUaW1lUmVxdWVzdCkge1xuICAgICAgICAgICAgY29uc3Qgc2hhcmVkVXRjVGltZVN0YW1wID0gYXdhaXQgdGhpcy5yZXF1ZXN0VGltZSh0aGlzLnhtcHBDaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2UudXNlckppZC5kb21haW4pO1xuICAgICAgICAgICAgdGhpcy5zZXJ2ZXJUaW1lJC5uZXh0KHNoYXJlZFV0Y1RpbWVTdGFtcCk7XG4gICAgICAgICAgICB0aGlzLnNlcnZlclN1cHBvcnRzVGltZSQubmV4dCh0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VydmVyU3VwcG9ydHNUaW1lJC5uZXh0KGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uT2ZmbGluZSgpIHtcbiAgICAgICAgdGhpcy5zZXJ2ZXJTdXBwb3J0c1RpbWUkLm5leHQoJ3Vua25vd24nKTtcbiAgICAgICAgdGhpcy5zZXJ2ZXJUaW1lJC5uZXh0KG51bGwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgYSBub24tY2xpZW50LXNwZWNpZmljIHRpbWVzdGFtcCBpZiBzZXJ2ZXIgc3VwcG9ydHMgWEVQLTAyMDIuIEZhbGxiYWNrIHRvIGxvY2FsIHRpbWVzdGFtcCBpbiBjYXNlIG9mIG1pc3Npbmcgc3VwcG9ydC5cbiAgICAgKi9cbiAgICBhc3luYyBnZXROb3coKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICAgICAgY29uc3QgY2FsY3VsYXRlTm93VmlhU2VydmVyVGltZSQgPSB0aGlzLnNlcnZlclRpbWUkLnBpcGUobWFwKHJlZmVyZW5jZSA9PiB0aGlzLmNhbGN1bGF0ZU5vdyhyZWZlcmVuY2UpKSwgZmlyc3QoKSk7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlcnZlclN1cHBvcnRzVGltZSQucGlwZShcbiAgICAgICAgICAgIHRpbWVvdXQoNTAwMCksXG4gICAgICAgICAgICBmaXJzdChzdXBwb3J0c1NlcnZlclRpbWUgPT4gc3VwcG9ydHNTZXJ2ZXJUaW1lICE9PSAndW5rbm93bicpLFxuICAgICAgICAgICAgbWVyZ2VNYXAoc3VwcG9ydHNTZXJ2ZXJUaW1lID0+IHN1cHBvcnRzU2VydmVyVGltZSA/IGNhbGN1bGF0ZU5vd1ZpYVNlcnZlclRpbWUkIDogb2YoRGF0ZS5ub3coKSkpLFxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihEYXRlLm5vdygpKSksXG4gICAgICAgICkudG9Qcm9taXNlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjYWxjdWxhdGVOb3cocmVmZXJlbmNlOiBUaW1lUmVmZXJlbmNlKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHJlZmVyZW5jZS51dGNUaW1lc3RhbXAgKyAocGVyZm9ybWFuY2Uubm93KCkgLSByZWZlcmVuY2UubG9jYWxSZWZlcmVuY2UpO1xuICAgIH1cblxuICAgIGFzeW5jIHJlcXVlc3RUaW1lKGppZDogc3RyaW5nKTogUHJvbWlzZTxUaW1lUmVmZXJlbmNlPiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmRJcShcbiAgICAgICAgICAgIHhtbCgnaXEnLCB7dHlwZTogJ2dldCcsIHRvOiBqaWR9LFxuICAgICAgICAgICAgICAgIHhtbCgndGltZScsIHt4bWxuczogJ3Vybjp4bXBwOnRpbWUnfSksXG4gICAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCB1dGNTdHJpbmcgPSByZXNwb25zZS5nZXRDaGlsZCgndGltZScsICd1cm46eG1wcDp0aW1lJyk/LmdldENoaWxkVGV4dCgndXRjJyk7XG4gICAgICAgIGlmICghdXRjU3RyaW5nKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gJ2ludmFsaWQgdGltZSByZXNwb25zZSc7XG4gICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2UuZXJyb3IobWVzc2FnZSwgcmVzcG9uc2UudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHt1dGNUaW1lc3RhbXA6IERhdGUucGFyc2UodXRjU3RyaW5nKSwgbG9jYWxSZWZlcmVuY2U6IHBlcmZvcm1hbmNlLm5vdygpfTtcbiAgICB9XG5cbn1cbiJdfQ==