2018-05-05 20:28:41 +02:00
|
|
|
// Converse.js
|
2016-03-16 12:16:32 +01:00
|
|
|
// http://conversejs.org
|
|
|
|
//
|
2018-05-25 16:25:02 +02:00
|
|
|
// Copyright (c) 2013-2018, the Converse.js developers
|
2016-03-16 12:16:32 +01:00
|
|
|
// Licensed under the Mozilla Public License (MPLv2)
|
|
|
|
|
|
|
|
(function (root, factory) {
|
2018-05-24 21:09:33 +02:00
|
|
|
define(["converse-core", "crypto", "templates/vcard.html"], factory);
|
2018-05-08 17:48:37 +02:00
|
|
|
}(this, function (converse, CryptoJS, tpl_vcard) {
|
2016-03-16 12:16:32 +01:00
|
|
|
"use strict";
|
2018-05-08 17:48:37 +02:00
|
|
|
const { Backbone, Promise, Strophe, SHA1, _, $iq, $build, b64_sha1, moment, sizzle } = converse.env;
|
2018-02-23 22:15:04 +01:00
|
|
|
const u = converse.env.utils;
|
2017-12-02 18:00:18 +01:00
|
|
|
|
|
|
|
|
2016-12-20 11:42:20 +01:00
|
|
|
converse.plugins.add('converse-vcard', {
|
2016-03-16 12:16:32 +01:00
|
|
|
|
2017-07-10 17:46:22 +02:00
|
|
|
initialize () {
|
2016-03-16 12:16:32 +01:00
|
|
|
/* The initialize function gets called as soon as the plugin is
|
|
|
|
* loaded by converse.js's plugin machinery.
|
|
|
|
*/
|
2017-07-10 17:46:22 +02:00
|
|
|
const { _converse } = this;
|
2016-03-16 12:16:32 +01:00
|
|
|
|
2018-05-15 09:47:52 +02:00
|
|
|
_converse.VCard = Backbone.Model.extend({
|
|
|
|
defaults: {
|
|
|
|
'image': _converse.DEFAULT_IMAGE,
|
|
|
|
'image_type': _converse.DEFAULT_IMAGE_TYPE
|
|
|
|
},
|
|
|
|
|
|
|
|
set (key, val, options) {
|
|
|
|
// Override Backbone.Model.prototype.set to make sure that the
|
|
|
|
// default `image` and `image_type` values are maintained.
|
|
|
|
let attrs;
|
|
|
|
if (typeof key === 'object') {
|
|
|
|
attrs = key;
|
|
|
|
options = val;
|
|
|
|
} else {
|
|
|
|
(attrs = {})[key] = val;
|
|
|
|
}
|
|
|
|
if (_.has(attrs, 'image') && !attrs['image']) {
|
|
|
|
attrs['image'] = _converse.DEFAULT_IMAGE;
|
|
|
|
attrs['image_type'] = _converse.DEFAULT_IMAGE_TYPE;
|
|
|
|
return Backbone.Model.prototype.set.call(this, attrs, options);
|
|
|
|
} else {
|
|
|
|
return Backbone.Model.prototype.set.apply(this, arguments);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2018-05-03 18:34:28 +02:00
|
|
|
_converse.VCards = Backbone.Collection.extend({
|
2018-05-15 09:47:52 +02:00
|
|
|
model: _converse.VCard,
|
2018-05-03 18:34:28 +02:00
|
|
|
|
|
|
|
initialize () {
|
2018-05-04 22:50:41 +02:00
|
|
|
this.on('add', (vcard) => _converse.api.vcard.update(vcard));
|
2018-05-03 18:34:28 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2018-05-08 17:48:37 +02:00
|
|
|
function onVCardData (_converse, jid, iq, callback) {
|
|
|
|
const vcard = iq.querySelector('vCard');
|
|
|
|
let result = {};
|
|
|
|
if (!_.isNull(vcard)) {
|
|
|
|
result = {
|
|
|
|
'stanza': iq,
|
|
|
|
'fullname': _.get(vcard.querySelector('FN'), 'textContent'),
|
|
|
|
'nickname': _.get(vcard.querySelector('NICKNAME'), 'textContent'),
|
|
|
|
'image': _.get(vcard.querySelector('PHOTO BINVAL'), 'textContent'),
|
|
|
|
'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
|
|
|
|
'url': _.get(vcard.querySelector('URL'), 'textContent'),
|
|
|
|
'role': _.get(vcard.querySelector('ROLE'), 'textContent'),
|
2018-05-25 16:25:02 +02:00
|
|
|
'email': _.get(vcard.querySelector('EMAIL USERID'), 'textContent'),
|
|
|
|
'vcard_updated': moment().format(),
|
|
|
|
'vcard_error': undefined
|
2018-05-08 17:48:37 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
if (result.image) {
|
|
|
|
const word_array_from_b64 = CryptoJS.enc.Base64.parse(result['image']);
|
2018-05-17 11:25:05 +02:00
|
|
|
result['image_hash'] = CryptoJS.SHA1(word_array_from_b64).toString()
|
2018-05-08 17:48:37 +02:00
|
|
|
}
|
|
|
|
if (callback) {
|
|
|
|
callback(result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onVCardError (_converse, jid, iq, errback) {
|
|
|
|
if (errback) {
|
2018-05-25 16:25:02 +02:00
|
|
|
errback({
|
|
|
|
'stanza': iq,
|
|
|
|
'jid': jid,
|
|
|
|
'vcard_error': moment().format()
|
|
|
|
});
|
2018-05-08 17:48:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function createStanza (type, jid, vcard_el) {
|
|
|
|
const iq = $iq(jid ? {'type': type, 'to': jid} : {'type': type});
|
|
|
|
if (!vcard_el) {
|
|
|
|
iq.c("vCard", {'xmlns': Strophe.NS.VCARD});
|
|
|
|
} else {
|
|
|
|
iq.cnode(vcard_el);
|
|
|
|
}
|
|
|
|
return iq;
|
|
|
|
}
|
|
|
|
|
|
|
|
function setVCard (data) {
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const vcard_el = Strophe.xmlHtmlNode(tpl_vcard(data)).firstElementChild;
|
2018-05-15 09:47:52 +02:00
|
|
|
_converse.connection.sendIQ(createStanza("set", data.jid, vcard_el), resolve, reject);
|
2018-05-08 17:48:37 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function getVCard (_converse, jid) {
|
|
|
|
/* Request the VCard of another user. Returns a promise.
|
|
|
|
*
|
|
|
|
* Parameters:
|
|
|
|
* (String) jid - The Jabber ID of the user whose VCard
|
|
|
|
* is being requested.
|
|
|
|
*/
|
|
|
|
jid = Strophe.getBareJidFromJid(jid) === _converse.bare_jid ? null : jid;
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
_converse.connection.sendIQ(
|
|
|
|
createStanza("get", jid),
|
|
|
|
_.partial(onVCardData, _converse, jid, _, resolve),
|
|
|
|
_.partial(onVCardError, _converse, jid, _, resolve),
|
|
|
|
5000
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-07-21 12:41:16 +02:00
|
|
|
/* Event handlers */
|
2018-05-03 18:34:28 +02:00
|
|
|
_converse.initVCardCollection = function () {
|
|
|
|
_converse.vcards = new _converse.VCards();
|
2018-05-22 16:44:58 +02:00
|
|
|
_converse.vcards.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1(`converse.vcards`));
|
2018-05-03 18:34:28 +02:00
|
|
|
_converse.vcards.fetch();
|
|
|
|
}
|
2018-06-07 14:24:59 +02:00
|
|
|
_converse.api.listen.on('sessionInitialized', _converse.initVCardCollection);
|
2018-05-03 18:34:28 +02:00
|
|
|
|
|
|
|
|
2017-07-21 12:41:16 +02:00
|
|
|
_converse.on('addClientFeatures', () => {
|
2018-05-11 13:31:48 +02:00
|
|
|
_converse.api.disco.own.features.add(Strophe.NS.VCARD);
|
2017-07-21 12:41:16 +02:00
|
|
|
});
|
|
|
|
|
2017-12-02 18:00:18 +01:00
|
|
|
_.extend(_converse.api, {
|
|
|
|
'vcard': {
|
2018-05-08 17:48:37 +02:00
|
|
|
'set': setVCard,
|
|
|
|
|
2018-05-01 11:33:32 +02:00
|
|
|
'get' (model, force) {
|
|
|
|
if (_.isString(model)) {
|
|
|
|
return getVCard(_converse, model);
|
2018-05-25 16:25:02 +02:00
|
|
|
} else if (force ||
|
|
|
|
!model.get('vcard_updated') ||
|
|
|
|
!moment(model.get('vcard_error')).isSame(new Date(), "day")) {
|
|
|
|
|
2018-05-25 15:55:34 +02:00
|
|
|
const jid = model.get('jid');
|
2018-05-01 11:33:32 +02:00
|
|
|
if (!jid) {
|
|
|
|
throw new Error("No JID to get vcard for!");
|
|
|
|
}
|
|
|
|
return getVCard(_converse, jid);
|
|
|
|
} else {
|
2018-05-01 14:51:18 +02:00
|
|
|
return Promise.resolve({});
|
2018-05-01 11:33:32 +02:00
|
|
|
}
|
2018-05-01 14:51:18 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
'update' (model, force) {
|
2018-05-01 18:18:02 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
this.get(model, force).then((vcard) => {
|
2018-05-25 16:25:02 +02:00
|
|
|
delete vcard['stanza']
|
|
|
|
model.save(vcard);
|
2018-05-01 18:18:02 +02:00
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
2017-12-02 18:00:18 +01:00
|
|
|
}
|
2016-03-16 12:16:32 +01:00
|
|
|
}
|
2017-07-21 12:41:16 +02:00
|
|
|
});
|
2016-03-16 12:16:32 +01:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}));
|