UNPKG

converse.js

Version:
75 lines (67 loc) 2.55 kB
import { Model } from "@converse/skeletor"; import { _converse, api, converse, log, u } from "@converse/headless"; import { IQError } from "shared/errors.js"; import { UNDECIDED } from "./consts.js"; import { parseBundle } from "./utils.js"; const { Strophe, sizzle, stx } = converse.env; class Device extends Model { defaults() { return { trusted: UNDECIDED, active: true, }; } /** * @returns {import('./types').PreKey} */ getRandomPreKey() { // XXX: assumes that the bundle has already been fetched const bundle = this.get("bundle"); return bundle.prekeys[u.getRandomInt(bundle.prekeys.length)]; } /** * Fetch the device's OMEMO bundle from the server. * A bundle is a collection of publicly accessible data that can * be used to build a session with a device, namely its public IdentityKey, * a signed PreKey with corresponding signature, and a list of (single use) PreKeys. * @returns {Promise<import('./types').Bundle>} */ async fetchBundleFromServer() { const bare_jid = _converse.session.get("bare_jid"); const stanza = stx` <iq type="get" from="${bare_jid}" to="${this.get("jid")}" xmlns="jabber:client"> <pubsub xmlns="${Strophe.NS.PUBSUB}"> <items node="${Strophe.NS.OMEMO_BUNDLES}:${this.get("id")}"/> </pubsub> </iq>`; 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. * @returns {Promise<import('./types').Bundle>} */ getBundle() { if (this.get("bundle")) { return Promise.resolve(this.get("bundle")); } else { return this.fetchBundleFromServer(); } } } export default Device;