UNPKG

@pazznetwork/ngx-chat

Version:

[![Build status](https://api.travis-ci.com/pazznetwork/ngx-chat.svg?branch=master)](https://travis-ci.com/pazznetwork/ngx-chat) [![Coverage](https://coveralls.io/repos/github/pazznetwork/ngx-chat/badge.svg?branch=master)](https://coveralls.io/github/pazzn

115 lines 19.5 kB
import { xml } from '@xmpp/client'; import { BehaviorSubject } from 'rxjs'; import { first } from 'rxjs/operators'; import { AbstractStanzaBuilder } from '../abstract-stanza-builder'; import { AbstractXmppPlugin } from './abstract-xmpp-plugin'; class QueryStanzaBuilder extends AbstractStanzaBuilder { constructor(xmlns, to) { super(); this.xmlns = xmlns; this.to = to; } toStanza() { return xml('iq', { type: 'get', ...(this.to ? { to: this.to } : {}), }, xml('query', { xmlns: this.xmlns })); } } /** * see XEP-0030 Service Discovery */ export class ServiceDiscoveryPlugin extends AbstractXmppPlugin { constructor(chatAdapter) { super(); this.chatAdapter = chatAdapter; this.servicesInitialized$ = new BehaviorSubject(false); this.hostedServices = []; this.resourceCache = new Map(); } async onBeforeOnline() { await this.discoverServices(this.chatAdapter.chatConnectionService.userJid.domain); this.servicesInitialized$.next(true); } onOffline() { this.servicesInitialized$.next(false); this.hostedServices = []; this.resourceCache.clear(); } supportsFeature(jid, searchedFeature) { return new Promise((resolve, reject) => { this.servicesInitialized$.pipe(first(value => !!value)).subscribe(async () => { try { const service = this.resourceCache.get(jid) || await this.discoverServiceInformation(jid); if (!service) { reject(new Error('no service found for jid ' + jid)); } resolve(service.features.includes(searchedFeature)); } catch (e) { reject(e); } }); }); } findService(category, type) { return new Promise((resolve, reject) => { this.servicesInitialized$.pipe(first(value => !!value)).subscribe(() => { const results = this.hostedServices.filter(service => service.identitiesAttrs.filter(identityAttrs => identityAttrs.category === category && identityAttrs.type === type).length > 0); if (results.length === 0) { reject(new Error(`no service matching category ${category} and type ${type} found!`)); } else if (results.length > 1) { reject(new Error(`multiple services matching category ${category} and type ${type} found! ${JSON.stringify(results)}`)); } else { return resolve(results[0]); } }); }); } async discoverServices(mainDomain) { const serviceListResponse = await this.chatAdapter.chatConnectionService.sendIq(new QueryStanzaBuilder(ServiceDiscoveryPlugin.DISCO_ITEMS, this.chatAdapter.chatConnectionService.userJid.domain).toStanza()); const serviceDomains = new Set(serviceListResponse .getChild('query') .getChildren('item') .map((itemNode) => itemNode.attrs.jid)); serviceDomains.add(mainDomain); const discoveredServices = await Promise.all([...serviceDomains.keys()] .map((serviceDomain) => this.discoverServiceInformation(serviceDomain))); this.hostedServices.push(...discoveredServices); } async discoverServiceInformation(serviceDomain) { const serviceInformationResponse = await this.chatAdapter.chatConnectionService.sendIq(new QueryStanzaBuilder(ServiceDiscoveryPlugin.DISCO_INFO, serviceDomain).toStanza()); const queryNode = serviceInformationResponse.getChild('query'); const features = queryNode.getChildren('feature').map((featureNode) => featureNode.attrs.var); const identitiesAttrs = queryNode .getChildren('identity') .filter((identityNode) => identityNode.attrs) .map((identityNode) => identityNode.attrs); const serviceInformation = { identitiesAttrs: this.isIdentitiesAttrs(identitiesAttrs) ? identitiesAttrs : [], features, jid: serviceInformationResponse.attrs.from, }; this.resourceCache.set(serviceInformationResponse.attrs.from, serviceInformation); return serviceInformation; } isIdentitiesAttrs(elements) { return elements.every((element) => { const keys = Object.keys(element); const mustHave = keys.includes('category') && keys.includes('type'); if (keys.length === 2) { return mustHave; } else if (keys.length === 3) { return mustHave && keys.includes('name'); } return false; }); } } ServiceDiscoveryPlugin.DISCO_INFO = 'http://jabber.org/protocol/disco#info'; ServiceDiscoveryPlugin.DISCO_ITEMS = 'http://jabber.org/protocol/disco#items'; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS1kaXNjb3ZlcnkucGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hZGFwdGVycy94bXBwL3BsdWdpbnMvc2VydmljZS1kaXNjb3ZlcnkucGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFbkMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUQsTUFBTSxrQkFBbUIsU0FBUSxxQkFBcUI7SUFFbEQsWUFBb0IsS0FBYSxFQUFVLEVBQVc7UUFDbEQsS0FBSyxFQUFFLENBQUM7UUFEUSxVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQVUsT0FBRSxHQUFGLEVBQUUsQ0FBUztJQUV0RCxDQUFDO0lBRUQsUUFBUTtRQUNKLE9BQU8sR0FBRyxDQUFDLElBQUksRUFDWDtZQUNJLElBQUksRUFBRSxLQUFLO1lBQ1gsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ3BDLEVBQ0QsR0FBRyxDQUFDLE9BQU8sRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFDLENBQUMsQ0FDcEMsQ0FBQztJQUNOLENBQUM7Q0FFSjtBQWNEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGtCQUFrQjtJQVMxRCxZQUE2QixXQUE0QjtRQUNyRCxLQUFLLEVBQUUsQ0FBQztRQURpQixn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QUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwRSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUNuQixPQUFPLFFBQVEsQ0FBQzthQUNuQjtpQkFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUMxQixPQUFPLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQzVDO1lBQ0QsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOztBQXRIc0IsaUNBQVUsR0FBRyx1Q0FBdUMsQ0FBQztBQUNyRCxrQ0FBVyxHQUFHLHdDQUF3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeG1sIH0gZnJvbSAnQHhtcHAvY2xpZW50JztcbmltcG9ydCB7IEVsZW1lbnQgfSBmcm9tICdsdHgnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaXJzdCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFic3RyYWN0U3RhbnphQnVpbGRlciB9IGZyb20gJy4uL2Fic3RyYWN0LXN0YW56YS1idWlsZGVyJztcbmltcG9ydCB7IFhtcHBDaGF0QWRhcHRlciB9IGZyb20gJy4uL3htcHAtY2hhdC1hZGFwdGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQWJzdHJhY3RYbXBwUGx1Z2luIH0gZnJvbSAnLi9hYnN0cmFjdC14bXBwLXBsdWdpbic7XG5cbmNsYXNzIFF1ZXJ5U3RhbnphQnVpbGRlciBleHRlbmRzIEFic3RyYWN0U3RhbnphQnVpbGRlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHhtbG5zOiBzdHJpbmcsIHByaXZhdGUgdG8/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICB0b1N0YW56YSgpIHtcbiAgICAgICAgcmV0dXJuIHhtbCgnaXEnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdnZXQnLFxuICAgICAgICAgICAgICAgIC4uLih0aGlzLnRvID8ge3RvOiB0aGlzLnRvfSA6IHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB4bWwoJ3F1ZXJ5Jywge3htbG5zOiB0aGlzLnhtbG5zfSksXG4gICAgICAgICk7XG4gICAgfVxuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSWRlbnRpdHlBdHRycyB7XG4gICAgY2F0ZWdvcnk6IHN0cmluZztcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgbmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlIHtcbiAgICBqaWQ6IHN0cmluZztcbiAgICBpZGVudGl0aWVzQXR0cnM6IElkZW50aXR5QXR0cnNbXTtcbiAgICBmZWF0dXJlczogc3RyaW5nW107XG59XG5cbi8qKlxuICogc2VlIFhFUC0wMDMwIFNlcnZpY2UgRGlzY292ZXJ5XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlRGlzY292ZXJ5UGx1Z2luIGV4dGVuZHMgQWJzdHJhY3RYbXBwUGx1Z2luIHtcblxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRElTQ09fSU5GTyA9ICdodHRwOi8vamFiYmVyLm9yZy9wcm90b2NvbC9kaXNjbyNpbmZvJztcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERJU0NPX0lURU1TID0gJ2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2Rpc2NvI2l0ZW1zJztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZXNJbml0aWFsaXplZCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcbiAgICBwcml2YXRlIGhvc3RlZFNlcnZpY2VzOiBTZXJ2aWNlW10gPSBbXTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgU2VydmljZT4oKTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY2hhdEFkYXB0ZXI6IFhtcHBDaGF0QWRhcHRlcikge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uQmVmb3JlT25saW5lKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmRpc2NvdmVyU2VydmljZXModGhpcy5jaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2UudXNlckppZC5kb21haW4pO1xuICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLm5leHQodHJ1ZSk7XG4gICAgfVxuXG4gICAgb25PZmZsaW5lKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLm5leHQoZmFsc2UpO1xuICAgICAgICB0aGlzLmhvc3RlZFNlcnZpY2VzID0gW107XG4gICAgICAgIHRoaXMucmVzb3VyY2VDYWNoZS5jbGVhcigpO1xuICAgIH1cblxuICAgIHN1cHBvcnRzRmVhdHVyZShqaWQ6IHN0cmluZywgc2VhcmNoZWRGZWF0dXJlOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLnBpcGUoZmlyc3QodmFsdWUgPT4gISF2YWx1ZSkpLnN1YnNjcmliZShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VydmljZSA9IHRoaXMucmVzb3VyY2VDYWNoZS5nZXQoamlkKSB8fCBhd2FpdCB0aGlzLmRpc2NvdmVyU2VydmljZUluZm9ybWF0aW9uKGppZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VydmljZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignbm8gc2VydmljZSBmb3VuZCBmb3IgamlkICcgKyBqaWQpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHNlcnZpY2UuZmVhdHVyZXMuaW5jbHVkZXMoc2VhcmNoZWRGZWF0dXJlKSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICBmaW5kU2VydmljZShjYXRlZ29yeTogc3RyaW5nLCB0eXBlOiBzdHJpbmcpOiBQcm9taXNlPFNlcnZpY2U+IHtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLnBpcGUoZmlyc3QodmFsdWUgPT4gISF2YWx1ZSkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IHRoaXMuaG9zdGVkU2VydmljZXMuZmlsdGVyKHNlcnZpY2UgPT5cbiAgICAgICAgICAgICAgICAgICAgc2VydmljZS5pZGVudGl0aWVzQXR0cnMuZmlsdGVyKGlkZW50aXR5QXR0cnMgPT4gaWRlbnRpdHlBdHRycy5jYXRlZ29yeSA9PT0gY2F0ZWdvcnlcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIGlkZW50aXR5QXR0cnMudHlwZSA9PT0gdHlwZSkubGVuZ3RoID4gMCxcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYG5vIHNlcnZpY2UgbWF0Y2hpbmcgY2F0ZWdvcnkgJHtjYXRlZ29yeX0gYW5kIHR5cGUgJHt0eXBlfSBmb3VuZCFgKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgbXVsdGlwbGUgc2VydmljZXMgbWF0Y2hpbmcgY2F0ZWdvcnkgJHtjYXRlZ29yeX0gYW5kIHR5cGUgJHt0eXBlfSBmb3VuZCEgJHtKU09OLnN0cmluZ2lmeShyZXN1bHRzKX1gKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0c1swXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGRpc2NvdmVyU2VydmljZXMobWFpbkRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VMaXN0UmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNoYXRBZGFwdGVyLmNoYXRDb25uZWN0aW9uU2VydmljZS5zZW5kSXEoXG4gICAgICAgICAgICBuZXcgUXVlcnlTdGFuemFCdWlsZGVyKFxuICAgICAgICAgICAgICAgIFNlcnZpY2VEaXNjb3ZlcnlQbHVnaW4uRElTQ09fSVRFTVMsIHRoaXMuY2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnVzZXJKaWQuZG9tYWluKS50b1N0YW56YSgpLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHNlcnZpY2VEb21haW5zID0gbmV3IFNldChcbiAgICAgICAgICAgIHNlcnZpY2VMaXN0UmVzcG9uc2VcbiAgICAgICAgICAgICAgICAuZ2V0Q2hpbGQoJ3F1ZXJ5JylcbiAgICAgICAgICAgICAgICAuZ2V0Q2hpbGRyZW4oJ2l0ZW0nKVxuICAgICAgICAgICAgICAgIC5tYXAoKGl0ZW1Ob2RlOiBFbGVtZW50KSA9PiBpdGVtTm9kZS5hdHRycy5qaWQgYXMgc3RyaW5nKSxcbiAgICAgICAgKTtcbiAgICAgICAgc2VydmljZURvbWFpbnMuYWRkKG1haW5Eb21haW4pO1xuXG4gICAgICAgIGNvbnN0IGRpc2NvdmVyZWRTZXJ2aWNlczogU2VydmljZVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBbLi4uc2VydmljZURvbWFpbnMua2V5cygpXVxuICAgICAgICAgICAgICAgIC5tYXAoKHNlcnZpY2VEb21haW4pID0+IHRoaXMuZGlzY292ZXJTZXJ2aWNlSW5mb3JtYXRpb24oc2VydmljZURvbWFpbikpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmhvc3RlZFNlcnZpY2VzLnB1c2goLi4uZGlzY292ZXJlZFNlcnZpY2VzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGRpc2NvdmVyU2VydmljZUluZm9ybWF0aW9uKHNlcnZpY2VEb21haW46IHN0cmluZyk6IFByb21pc2U8U2VydmljZT4ge1xuICAgICAgICBjb25zdCBzZXJ2aWNlSW5mb3JtYXRpb25SZXNwb25zZSA9IGF3YWl0IHRoaXMuY2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmRJcShcbiAgICAgICAgICAgIG5ldyBRdWVyeVN0YW56YUJ1aWxkZXIoU2VydmljZURpc2NvdmVyeVBsdWdpbi5ESVNDT19JTkZPLCBzZXJ2aWNlRG9tYWluKS50b1N0YW56YSgpLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHF1ZXJ5Tm9kZSA9IHNlcnZpY2VJbmZvcm1hdGlvblJlc3BvbnNlLmdldENoaWxkKCdxdWVyeScpO1xuICAgICAgICBjb25zdCBmZWF0dXJlcyA9IHF1ZXJ5Tm9kZS5nZXRDaGlsZHJlbignZmVhdHVyZScpLm1hcCgoZmVhdHVyZU5vZGU6IEVsZW1lbnQpID0+IGZlYXR1cmVOb2RlLmF0dHJzLnZhcik7XG4gICAgICAgIGNvbnN0IGlkZW50aXRpZXNBdHRycyA9IHF1ZXJ5Tm9kZVxuICAgICAgICAgICAgLmdldENoaWxkcmVuKCdpZGVudGl0eScpXG4gICAgICAgICAgICAuZmlsdGVyKChpZGVudGl0eU5vZGU6IEVsZW1lbnQpID0+IGlkZW50aXR5Tm9kZS5hdHRycylcbiAgICAgICAgICAgIC5tYXAoKGlkZW50aXR5Tm9kZTogRWxlbWVudCkgPT4gaWRlbnRpdHlOb2RlLmF0dHJzKTtcblxuICAgICAgICBjb25zdCBzZXJ2aWNlSW5mb3JtYXRpb246IFNlcnZpY2UgPSB7XG4gICAgICAgICAgICBpZGVudGl0aWVzQXR0cnM6IHRoaXMuaXNJZGVudGl0aWVzQXR0cnMoaWRlbnRpdGllc0F0dHJzKSA/IGlkZW50aXRpZXNBdHRycyA6IFtdLFxuICAgICAgICAgICAgZmVhdHVyZXMsXG4gICAgICAgICAgICBqaWQ6IHNlcnZpY2VJbmZvcm1hdGlvblJlc3BvbnNlLmF0dHJzLmZyb20sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucmVzb3VyY2VDYWNoZS5zZXQoc2VydmljZUluZm9ybWF0aW9uUmVzcG9uc2UuYXR0cnMuZnJvbSwgc2VydmljZUluZm9ybWF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHNlcnZpY2VJbmZvcm1hdGlvbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzSWRlbnRpdGllc0F0dHJzKGVsZW1lbnRzOiB7IFthdHRyTmFtZTogc3RyaW5nXTogYW55IH1bXSk6IGVsZW1lbnRzIGlzIElkZW50aXR5QXR0cnNbXSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50cy5ldmVyeSgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgbXVzdEhhdmUgPSBrZXlzLmluY2x1ZGVzKCdjYXRlZ29yeScpICYmIGtleXMuaW5jbHVkZXMoJ3R5cGUnKTtcbiAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtdXN0SGF2ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5cy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbXVzdEhhdmUgJiYga2V5cy5pbmNsdWRlcygnbmFtZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iXX0=