xmpp.chapril.org-conversejs/src/plugins/omemo/device.js

69 lines
2.1 KiB
JavaScript

import log from '@converse/headless/log';
import { IQError } from './errors.js';
import { Model } from '@converse/skeletor/src/model.js';
import { UNDECIDED } from './consts.js';
import { _converse, api, converse } from '@converse/headless/core';
import { parseBundle } from './utils.js';
const { Strophe, sizzle, u, $iq } = converse.env;
/**
* @class
* @namespace _converse.Device
* @memberOf _converse
*/
const Device = Model.extend({
defaults: {
'trusted': UNDECIDED,
'active': true
},
getRandomPreKey () {
// XXX: assumes that the bundle has already been fetched
const bundle = this.get('bundle');
return bundle.prekeys[u.getRandomInt(bundle.prekeys.length)];
},
async fetchBundleFromServer () {
const stanza = $iq({
'type': 'get',
'from': _converse.bare_jid,
'to': this.get('jid')
}).c('pubsub', { 'xmlns': Strophe.NS.PUBSUB })
.c('items', { 'node': `${Strophe.NS.OMEMO_BUNDLES}:${this.get('id')}` });
let iq;
try {
iq = await api.sendIQ(stanza);
} catch (iq) {
log.error(`Could not fetch bundle for device ${this.get('id')} from ${this.get('jid')}`);
log.error(iq);
return null;
}
if (iq.querySelector('error')) {
throw new IQError('Could not fetch bundle', iq);
}
const publish_el = sizzle(`items[node="${Strophe.NS.OMEMO_BUNDLES}:${this.get('id')}"]`, iq).pop();
const bundle_el = sizzle(`bundle[xmlns="${Strophe.NS.OMEMO}"]`, publish_el).pop();
const bundle = parseBundle(bundle_el);
this.save('bundle', bundle);
return bundle;
},
/**
* Fetch and save the bundle information associated with
* this device, if the information is not cached already.
* @method _converse.Device#getBundle
*/
getBundle () {
if (this.get('bundle')) {
return Promise.resolve(this.get('bundle'), this);
} else {
return this.fetchBundleFromServer();
}
}
});
export default Device;