Commit ebcf7098 authored by JC Brand's avatar JC Brand

New dist files

parent 4e67b420
......@@ -10760,7 +10760,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
// Converse.js
// https://conversejs.org
//
// Copyright (c) 2012-2018, the Converse.js developers
// Copyright (c) 2013-2018, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) {
define('converse-core',["sizzle", "es6-promise", "lodash.noconflict", "lodash.fp", "polyfill", "i18n", "utils", "moment", "strophe", "pluggable", "backbone.noconflict", "backbone.nativeview", "backbone.browserStorage"], factory);
......@@ -11427,6 +11427,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
_converse.session.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
_converse.session.fetch();
_converse.emit('sessionInitialized');
};
this.clearSession = function () {
......@@ -13086,15 +13088,15 @@ define("emojione", (function (global) {
initialize: function initialize() {
this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
this.dataforms = new Backbone.Collection();
this.dataforms.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.dataforms-{this.get('jid')}"));
this.dataforms.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.dataforms-{this.get('jid')}"));
this.features = new Backbone.Collection();
this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.on('add', this.onFeatureAdded, this);
this.identities = new Backbone.Collection();
this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.identities-".concat(this.get('jid'))));
this.identities.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.identities-".concat(this.get('jid'))));
this.fetchFeatures();
this.items = new _converse.DiscoEntities();
this.items.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.disco-items-".concat(this.get('jid'))));
this.items.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.disco-items-".concat(this.get('jid'))));
this.items.fetch();
},
getIdentity: function getIdentity(category, type) {
......@@ -13275,13 +13277,33 @@ define("emojione", (function (global) {
return this;
}
function initStreamFeatures() {
_converse.stream_features = new Backbone.Collection();
_converse.stream_features.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.stream-features-".concat(_converse.bare_jid)));
_converse.stream_features.fetch({
success: function success(collection) {
if (collection.length === 0 && _converse.connection.features) {
_.forEach(_converse.connection.features.childNodes, function (feature) {
_converse.stream_features.create({
'name': feature.nodeName,
'xmlns': feature.getAttribute('xmlns')
});
});
}
}
});
_converse.emit('streamFeaturesAdded');
}
function initializeDisco() {
addClientFeatures();
_converse.connection.addHandler(onDiscoInfoRequest, Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
_converse.disco_entities = new _converse.DiscoEntities();
_converse.disco_entities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.disco-entities-".concat(_converse.bare_jid)));
_converse.disco_entities.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.disco-entities-".concat(_converse.bare_jid)));
_converse.disco_entities.fetchEntities().then(function (collection) {
if (collection.length === 0 || !collection.get(_converse.domain)) {
......@@ -13296,6 +13318,8 @@ define("emojione", (function (global) {
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
_converse.api.listen.on('sessionInitialized', initStreamFeatures);
_converse.api.listen.on('reconnected', initializeDisco);
_converse.api.listen.on('connected', initializeDisco);
......@@ -13376,6 +13400,19 @@ define("emojione", (function (global) {
* @namespace
*/
'disco': {
'stream': {
'getFeature': function getFeature(name, xmlns) {
if (_.isNil(name) || _.isNil(xmlns)) {
throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature");
}
return _converse.stream_features.findWhere({
'name': name,
'xmlns': xmlns
});
}
},
/**
* The "own" grouping
* @namespace
......@@ -15890,19 +15927,24 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.on('change:image_hash', this.onAvatarChanged, this);
},
onAvatarChanged: function onAvatarChanged() {
var vcard = _converse.vcards.findWhere({
'jid': this.get('from')
});
var hash = this.get('image_hash');
var vcards = [];
if (!vcard) {
return;
if (this.get('jid')) {
vcards.push(this.updateVCard(_converse.vcards.findWhere({
'jid': this.get('jid')
})));
}
var hash = this.get('image_hash');
vcards.push(this.updateVCard(_converse.vcards.findWhere({
'jid': this.get('from')
})));
if (hash && vcard.get('image_hash') !== hash) {
_converse.api.vcard.update(vcard);
}
_.forEach(_.filter(vcards, undefined), function (vcard) {
if (hash && vcard.get('image_hash') !== hash) {
_converse.api.vcard.update(vcard);
}
});
},
getDisplayName: function getDisplayName() {
return this.get('nick') || this.get('jid');
......@@ -15950,6 +15992,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'jid': removed_jid
});
if (!occupant) {
return;
}
if (occupant.get('show') === 'offline') {
occupant.destroy();
}
......@@ -25093,7 +25139,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
// Converse.js
// http://conversejs.org
//
// Copyright (c) 2012-2018, the Converse.js developers
// Copyright (c) 2013-2018, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) {
define('converse-vcard',["converse-core", "crypto", "tpl!vcard"], factory);
......@@ -25166,7 +25212,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
'url': _.get(vcard.querySelector('URL'), 'textContent'),
'role': _.get(vcard.querySelector('ROLE'), 'textContent'),
'email': _.get(vcard.querySelector('EMAIL USERID'), 'textContent')
'email': _.get(vcard.querySelector('EMAIL USERID'), 'textContent'),
'vcard_updated': moment().format(),
'vcard_error': undefined
};
}
......@@ -25184,7 +25232,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
if (errback) {
errback({
'stanza': iq,
'jid': jid
'jid': jid,
'vcard_error': moment().format()
});
}
}
......@@ -25250,8 +25299,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'get': function get(model, force) {
if (_.isString(model)) {
return getVCard(_converse, model);
} else if (!model.get('vcard_updated') || force) {
var jid = model.get('jid') || model.get('muc_jid');
} else if (force || !model.get('vcard_updated') || !moment(model.get('vcard_error')).isSame(new Date(), "day")) {
var jid = model.get('jid');
if (!jid) {
throw new Error("No JID to get vcard for!");
......@@ -25267,9 +25316,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return new Promise(function (resolve, reject) {
_this.get(model, force).then(function (vcard) {
model.save(_.extend(_.pick(vcard, ['fullname', 'nickname', 'email', 'url', 'role', 'image_type', 'image', 'image_hash']), {
'vcard_updated': moment().format()
}));
delete vcard['stanza'];
model.save(vcard);
resolve();
});
});
......@@ -31439,6 +31487,13 @@ return __p
_converse.roster = new _converse.RosterContacts();
_converse.roster.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(`converse.contacts-${_converse.bare_jid}`));
_converse.roster.data = new Backbone.Model();
const id = b64_sha1(`converse-roster-model-${_converse.bare_jid}`);
_converse.roster.data.id = id;
_converse.roster.data.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
_converse.roster.data.fetch();
_converse.rostergroups = new _converse.RosterGroups();
_converse.rostergroups.browserStorage = new Backbone.BrowserStorage[_converse.storage](
b64_sha1(`converse.roster.groups${_converse.bare_jid}`));
......@@ -31721,28 +31776,28 @@ return __p
onConnected () {
/* Called as soon as the connection has been established
* (either after initial login, or after reconnection).
*
* Use the opportunity to register stanza handlers.
*/
* (either after initial login, or after reconnection).
*
* Use the opportunity to register stanza handlers.
*/
this.registerRosterHandler();
this.registerRosterXHandler();
},
registerRosterHandler () {
/* Register a handler for roster IQ "set" stanzas, which update
* roster contacts.
*/
_converse.connection.addHandler(
_converse.roster.onRosterPush.bind(_converse.roster),
Strophe.NS.ROSTER, 'iq', "set"
);
* roster contacts.
*/
_converse.connection.addHandler((iq) => {
_converse.roster.onRosterPush(iq);
return true;
}, Strophe.NS.ROSTER, 'iq', "set");
},
registerRosterXHandler () {
/* Register a handler for RosterX message stanzas, which are
* used to suggest roster contacts to a user.
*/
* used to suggest roster contacts to a user.
*/
let t = 0;
_converse.connection.addHandler(
function (msg) {
......@@ -31766,12 +31821,14 @@ return __p
* Returns a promise which resolves once the contacts have been
* fetched.
*/
const that = this;
return new Promise((resolve, reject) => {
this.fetch({
'add': true,
'silent': true,
success (collection) {
if (collection.length === 0) {
if (collection.length === 0 ||
(that.rosterVersioningSupported() && !_converse.session.get('roster_fetched'))) {
_converse.send_initial_presence = true;
_converse.roster.fetchFromServer().then(resolve).catch(reject);
} else {
......@@ -31897,30 +31954,44 @@ return __p
onRosterPush (iq) {
/* Handle roster updates from the XMPP server.
* See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push
*
* Parameters:
* (XMLElement) IQ - The IQ stanza received from the XMPP server.
*/
* See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push
*
* Parameters:
* (XMLElement) IQ - The IQ stanza received from the XMPP server.
*/
const id = iq.getAttribute('id');
const from = iq.getAttribute('from');
if (from && from !== "" && Strophe.getBareJidFromJid(from) !== _converse.bare_jid) {
// Receiving client MUST ignore stanza unless it has no from or from = user's bare JID.
// XXX: Some naughty servers apparently send from a full
// JID so we need to explicitly compare bare jids here.
// https://github.com/jcbrand/converse.js/issues/493
_converse.connection.send(
$iq({type: 'error', id, from: _converse.connection.jid})
.c('error', {'type': 'cancel'})
.c('service-unavailable', {'xmlns': Strophe.NS.ROSTER })
);
return true;
if (from && from !== _converse.connection.jid) {
// https://tools.ietf.org/html/rfc6121#page-15
//
// A receiving client MUST ignore the stanza unless it has no 'from'
// attribute (i.e., implicitly from the bare JID of the user's
// account) or it has a 'from' attribute whose value matches the
// user's bare JID <user@domainpart>.
return;
}
_converse.connection.send($iq({type: 'result', id, from: _converse.connection.jid}));
const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
_.each(items, this.updateContact.bind(this));
const query = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"]`, iq).pop();
this.data.save('version', query.getAttribute('ver'));
const items = sizzle(`item`, query);
if (items.length > 1) {
_converse.log(iq, Strophe.LogLevel.ERROR);
throw new Error('Roster push query may not contain more than one "item" element.');
}
if (items.length === 0) {
_converse.log(iq, Strophe.LogLevel.WARN);
_converse.log('Received a roster push stanza without an "item" element.', Strophe.LogLevel.WARN);
return;
}
this.updateContact(items.pop());
_converse.emit('rosterPush', iq);
return true;
return;
},
rosterVersioningSupported () {
return _converse.api.disco.stream.getFeature('ver', 'urn:xmpp:features:rosterver') && this.data.get('version');
},
fetchFromServer () {
......@@ -31930,7 +32001,9 @@ return __p
'type': 'get',
'id': _converse.connection.getUniqueId('roster')
}).c('query', {xmlns: Strophe.NS.ROSTER});
if (this.rosterVersioningSupported()) {
iq.attrs({'ver': this.data.get('version')});
}
const callback = _.flow(this.onReceivedFromServer.bind(this), resolve);
const errback = function (iq) {
const errmsg = "Error while trying to fetch roster from the server";
......@@ -31943,17 +32016,22 @@ return __p
onReceivedFromServer (iq) {
/* An IQ stanza containing the roster has been received from
* the XMPP server.
*/
const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
_.each(items, this.updateContact.bind(this));
* the XMPP server.
*/
const query = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"]`, iq).pop();
if (query) {
const items = sizzle(`item`, query);
_.each(items, (item) => this.updateContact(item));
this.data.save('version', query.getAttribute('ver'));
_converse.session.save('roster_fetched', true);
}
_converse.emit('roster', iq);
},
updateContact (item) {
/* Update or create RosterContact models based on items
* received in the IQ from the server.
*/
* received in the IQ from the server.
*/
const jid = item.getAttribute('jid');
if (this.isSelf(jid)) { return; }
......@@ -32610,6 +32610,8 @@ if (!root.atob) {
define('strophe-sha1', [],function () {
return factory();
});
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
// Browser globals
root.SHA1 = factory();
......@@ -32804,6 +32806,8 @@ return {
define('strophe-md5',[], function () {
return factory();
});
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
// Browser globals
root.MD5 = factory();
......@@ -33006,6 +33010,8 @@ return {
define('strophe-utils',[], function () {
return factory();
});
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
// Browser globals
root.stropheUtils = factory();
......@@ -33094,6 +33100,12 @@ return {
], function () {
return factory.apply(this, arguments);
});
} else if (typeof exports === 'object') {
module.exports = factory(
require('./sha1'),
require('./md5'),
require('./utils')
);
} else {
// Browser globals
var o = factory(root.SHA1, root.MD5, root.stropheUtils);
......@@ -33168,7 +33180,7 @@ function $pres(attrs) { return new Strophe.Builder("presence", attrs); }
*/
Strophe = {
/** Constant: VERSION */
VERSION: "1.2.14",
VERSION: "1.2.15",
/** Constants: XMPP Namespace Constants
* Common namespace constants from the XMPP RFCs and XEPs.
......@@ -33306,6 +33318,14 @@ Strophe = {
CONNTIMEOUT: 10
},
ErrorCondition: {
BAD_FORMAT: "bad-format",
CONFLICT: "conflict",
MISSING_JID_NODE: "x-strophe-bad-non-anon-jid",
NO_AUTH_MECH: "no-auth-mech",
UNKNOWN_REASON: "unknown",
},
/** Constants: Log Level Constants
* Logging level indicators.
*
......@@ -33882,7 +33902,7 @@ Strophe = {
*
* This function is called whenever the Strophe library calls any
* of the logging functions. The default implementation of this
* function does nothing. If client code wishes to handle the logging
* function logs only fatal errors. If client code wishes to handle the logging
* messages, it should override this with
* > Strophe.log = function (level, msg) {
* > (user code here)
......@@ -33906,11 +33926,13 @@ Strophe = {
* be one of the values in Strophe.LogLevel.
* (String) msg - The log message.
*/
/* jshint ignore:start */
log: function (level, msg) {
return;
if (level === this.LogLevel.FATAL &&
typeof window.console === 'object' &&
typeof window.console.error === 'function') {
window.console.error(msg);
}
},
/* jshint ignore:end */
/** Function: debug
* Log a message at the Strophe.LogLevel.DEBUG level.
......@@ -34576,10 +34598,11 @@ Strophe.TimedHandler.prototype = {
* If nothing is specified, then the following mechanisms (and their
* priorities) are registered:
*
* OAUTHBEARER - 60
* SCRAM-SHA1 - 50
* DIGEST-MD5 - 40
* PLAIN - 30
* SCRAM-SHA1 - 70
* DIGEST-MD5 - 60
* PLAIN - 50
* OAUTH-BEARER - 40
* OAUTH-2 - 30
* ANONYMOUS - 20
* EXTERNAL - 10
*
......@@ -35460,6 +35483,7 @@ Strophe.Connection.prototype = {
Strophe.SASLExternal,
Strophe.SASLMD5,
Strophe.SASLOAuthBearer,
Strophe.SASLXOAuth2,
Strophe.SASLPlain,
Strophe.SASLSHA1
];
......@@ -35526,8 +35550,9 @@ Strophe.Connection.prototype = {
* (Integer) status - the new connection status, one of the values
* in Strophe.Status
* (String) condition - the error condition or null
* (XMLElement) elem - The triggering stanza.
*/
_changeConnectStatus: function (status, condition) {
_changeConnectStatus: function (status, condition, elem) {
// notify all plugins listening for status changes
for (var k in Strophe._connectionPlugins) {
if (Strophe._connectionPlugins.hasOwnProperty(k)) {
......@@ -35546,7 +35571,7 @@ Strophe.Connection.prototype = {
// notify the user's callback
if (this.connect_callback) {
try {
this.connect_callback(status, condition);
this.connect_callback(status, condition, elem);
} catch (e) {
Strophe._handleError(e);
Strophe.error(
......@@ -35662,7 +35687,10 @@ Strophe.Connection.prototype = {
}
this._changeConnectStatus(Strophe.Status.CONNFAIL, cond);
} else {
this._changeConnectStatus(Strophe.Status.CONNFAIL, "unknown");
this._changeConnectStatus(
Strophe.Status.CONNFAIL,
Strophe.ErrorCondition.UNKOWN_REASON
);
}
this._doDisconnect(cond);
return;
......@@ -35702,6 +35730,26 @@ Strophe.Connection.prototype = {
*/
mechanisms: {},
/** PrivateFunction: _no_auth_received
*
* Called on stream start/restart when no stream:features
* has been received or when no viable authentication mechanism is offered.
*
* Sends a blank poll request.
*/
_no_auth_received: function (_callback) {
var error_msg = "Server did not offer a supported authentication mechanism";
Strophe.error(error_msg);
this._changeConnectStatus(
Strophe.Status.CONNFAIL,
Strophe.ErrorCondition.NO_AUTH_MECH
);
if (_callback) {
_callback.call(this);
}
this._doDisconnect();
},
/** PrivateFunction: _connect_cb
* _Private_ handler for initial connection request.
*
......@@ -35715,7 +35763,7 @@ Strophe.Connection.prototype = {
* Parameters:
* (Strophe.Request) req - The current request.
* (Function) _callback - low level (xmpp) connect callback function.
* Useful for plugins with their own xmpp connect callback (when their)
* Useful for plugins with their own xmpp connect callback (when they
* want to do something special).
*/
_connect_cb: function (req, _callback, raw) {
......@@ -35727,8 +35775,11 @@ Strophe.Connection.prototype = {
bodyWrap = this._proto._reqToData(req);
} catch (e) {
if (e !== "badformat") { throw e; }
this._changeConnectStatus(Strophe.Status.CONNFAIL, 'bad-format');
this._doDisconnect('bad-format');
this._changeConnectStatus(
Strophe.Status.CONNFAIL,
Strophe.ErrorCondition.BAD_FORMAT
);
this._doDisconnect(Strophe.ErrorCondition.BAD_FORMAT);
}
if (!bodyWrap) { return; }
......@@ -35761,7 +35812,7 @@ Strophe.Connection.prototype = {
bodyWrap.getElementsByTagName("features").length > 0;
}
if (!hasFeatures) {
this._proto._no_auth_received(_callback);
this._no_auth_received(_callback);
return;
}
......@@ -35777,7 +35828,7 @@ Strophe.Connection.prototype = {
if (bodyWrap.getElementsByTagName("auth").length === 0) {
// There are no matching SASL mechanisms and also no legacy
// auth available.
this._proto._no_auth_received(_callback);
this._no_auth_received(_callback);
return;
}
}
......@@ -35873,9 +35924,9 @@ Strophe.Connection.prototype = {
// client connections
this._changeConnectStatus(
Strophe.Status.CONNFAIL,
'x-strophe-bad-non-anon-jid'
Strophe.ErrorCondition.MISSING_JID_NODE
);
this.disconnect('x-strophe-bad-non-anon-jid');
this.disconnect(Strophe.ErrorCondition.MISSING_JID_NODE);
} else {
// Fall back to legacy authentication
this._changeConnectStatus(Strophe.Status.AUTHENTICATING, null);
......@@ -36093,9 +36144,9 @@ Strophe.Connection.prototype = {
Strophe.info("SASL binding failed.");
var conflict = elem.getElementsByTagName("conflict"), condition;
if (conflict.length > 0) {
condition = 'conflict';
condition = Strophe.ErrorCondition.CONFLICT;
}
this._changeConnectStatus(Strophe.Status.AUTHFAIL, condition);
this._changeConnectStatus(Strophe.Status.AUTHFAIL, condition, elem);
return false;
}
......@@ -36122,7 +36173,7 @@ Strophe.Connection.prototype = {
}
} else {
Strophe.info("SASL binding failed.");
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null);
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);
return false;
}
},
......@@ -36145,7 +36196,7 @@ Strophe.Connection.prototype = {
this._changeConnectStatus(Strophe.Status.CONNECTED, null);
} else if (elem.getAttribute("type") === "error") {
Strophe.info("Session creation failed.");
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null);
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);
return false;
}
return false;
......@@ -36174,7 +36225,7 @@ Strophe.Connection.prototype = {
if(this._sasl_mechanism)
this._sasl_mechanism.onFailure();
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null);
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);
return false;
},
/* jshint unused:true */
......@@ -36196,7 +36247,7 @@ Strophe.Connection.prototype = {
this.authenticated = true;
this._changeConnectStatus(Strophe.Status.CONNECTED, null);
} else if (elem.getAttribute("type") === "error") {
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null);
this._changeConnectStatus(Strophe.Status.AUTHFAIL, null, elem);
this.disconnect('authentication failed');
}
return false;
......@@ -36453,6 +36504,7 @@ Strophe.SASLMechanism.prototype = {
* Strophe.SASLSHA1 - SASL SCRAM-SHA1 authentication
* Strophe.SASLOAuthBearer - SASL OAuth Bearer authentication
* Strophe.SASLExternal - SASL EXTERNAL authentication
* Strophe.SASLXOAuth2 - SASL X-OAuth2 authentication
*/
// Building SASL callbacks
......@@ -36472,7 +36524,7 @@ Strophe.SASLAnonymous.prototype.test = function(connection) {
* SASL PLAIN authentication.
*/
Strophe.SASLPlain = function() {};
Strophe.SASLPlain.prototype = new Strophe.SASLMechanism("PLAIN", true, 30);
Strophe.SASLPlain.prototype = new Strophe.SASLMechanism("PLAIN", true, 50);
Strophe.SASLPlain.prototype.test = function(connection) {
return connection.authcid !== null;
......@@ -36492,7 +36544,7 @@ Strophe.SASLPlain.prototype.onChallenge = function(connection) {
* SASL SCRAM SHA 1 authentication.
*/
Strophe.SASLSHA1 = function() {};
Strophe.SASLSHA1.prototype = new Strophe.SASLMechanism("SCRAM-SHA-1", true, 50);
Strophe.SASLSHA1.prototype = new Strophe.SASLMechanism("SCRAM-SHA-1", true, 70);
Strophe.SASLSHA1.prototype.test = function(connection) {
return connection.authcid !== null;
......@@ -36576,7 +36628,7 @@ Strophe.SASLSHA1.prototype.onChallenge = function(connection, challenge, test_cn
* SASL DIGEST MD5 authentication.
*/
Strophe.SASLMD5 = function() {};
Strophe.SASLMD5.prototype = new Strophe.SASLMechanism("DIGEST-MD5", false, 40);
Strophe.SASLMD5.prototype = new Strophe.SASLMechanism("DIGEST-MD5", false, 60);
Strophe.SASLMD5.prototype.test = function(connection) {
return connection.authcid !== null;
......@@ -36659,7 +36711,7 @@ Strophe.SASLMD5.prototype.onChallenge = function(connection, challenge, test_cno
* SASL OAuth Bearer authentication.
*/
Strophe.SASLOAuthBearer = function() {};
Strophe.SASLOAuthBearer.prototype = new Strophe.SASLMechanism("OAUTHBEARER", true, 60);
Strophe.SASLOAuthBearer.prototype = new Strophe.SASLMechanism("OAUTHBEARER", true, 40);
Strophe.SASLOAuthBearer.prototype.test = function(connection) {
return connection.pass !== null;
......@@ -36703,6 +36755,29 @@ Strophe.SASLExternal.prototype.onChallenge = function(connection) {
return connection.authcid === connection.authzid ? '' : connection.authzid;
};
/** PrivateConstructor: SASLXOAuth2
* SASL X-OAuth2 authentication.
*/
Strophe.SASLXOAuth2 = function () { };
Strophe.SASLXOAuth2.prototype = new Strophe.SASLMechanism("X-OAUTH2", true, 30);
Strophe.SASLXOAuth2.prototype.test = function (connection) {
return connection.pass !== null;
};
Strophe.SASLXOAuth2.prototype.onChallenge = function (connection) {
var auth_str = '\u0000';
if (connection.authcid !== null) {
auth_str = auth_str + connection.authzid;
}
auth_str = auth_str + "\u0000";
auth_str = auth_str + connection.pass;
return utils.utf16to8(auth_str);
};
return {
'Strophe': Strophe,
'$build': $build,
......@@ -36736,6 +36811,10 @@ return {
core.$build
);
});
} else if (typeof exports === 'object') {
var core = require('./core');
module.exports = factory(core.Strophe, core.$build);
} else {
// Browser globals
return factory(Strophe, $build);
......@@ -36813,11 +36892,17 @@ Strophe.Request.prototype = {
throw "parsererror";
}
} else if (this.xhr.responseText) {
Strophe.error("invalid response received");
Strophe.error("responseText: " + this.xhr.responseText);
throw "badformat";
// In React Native, we may get responseText but no responseXML. We can try to parse it manually.
Strophe.debug("Got responseText but no responseXML; attempting to parse it with DOMParser...");
node = new DOMParser().parseFromString(this.xhr.responseText, 'application/xml').documentElement;
if (!node) {
throw new Error('Parsing produced null node');
} else if (node.querySelector('parsererror')) {
Strophe.error("invalid response received: " + node.querySelector('parsererror').textContent);
Strophe.error("responseText: " + this.xhr.responseText);
throw "badformat";
}
}
return node;
},
......@@ -36883,6 +36968,8 @@ Strophe.Bosh = function(connection) {
this.errors = 0;
this.inactivity = null;
this.lastResponseHeaders = null;
this._requests = [];
};
......@@ -37190,26 +37277,6 @@ Strophe.Bosh.prototype = {
}
},
/** PrivateFunction: _no_auth_received
*
* Called on stream start/restart when no stream:features
* has been received and sends a blank poll request.
*/
_no_auth_received: function (_callback) {
if (_callback) {
_callback = _callback.bind(this._conn);
} else {
_callback = this._conn._connect_cb.bind(this._conn);
}
var body = this._buildBody();
this._requests.push(
new Strophe.Request(body.tree(),
this._onRequestStateChange.bind(
this, _callback.bind(this._conn)),
body.tree().getAttribute("rid")));
this._throttledRequestHandler();
},
/** PrivateFunction: _onDisconnectTimeout
* _Private_ timeout handler for handling non-graceful disconnection.
*
......@@ -37350,6 +37417,7 @@ Strophe.Bosh.prototype = {
return;
}
var reqStatus = this._getRequestStatus(req);
this.lastResponseHeaders = req.xhr.getAllResponseHeaders();
if (this.disconnecting && reqStatus >= 400) {
this._hitError(reqStatus);
this._callProtocolErrorHandlers(req);
......@@ -37674,6 +37742,10 @@ return Strophe;
core.$build
);
});
} else if (typeof exports === 'object') {
var core = require('./core');
module.exports = factory(core.Strophe, core.$build);
} else {
// Browser globals
return factory(Strophe, $build);
......@@ -37948,7 +38020,7 @@ Strophe.Websocket.prototype = {
this._conn.send(pres);
}
var close = $build("close", { "xmlns": Strophe.NS.FRAMING });
this._conn.xmlOutput(close);
this._conn.xmlOutput(close.tree());
var closeString = Strophe.serialize(close);
this._conn.rawOutput(closeString);
try {
......@@ -37986,6 +38058,7 @@ Strophe.Websocket.prototype = {
*/
_closeSocket: function () {
if (this.socket) { try {
this.socket.onerror = null;
this.socket.close();
} catch (e) {} }
this.socket = null;
......@@ -38026,24 +38099,6 @@ Strophe.Websocket.prototype = {
}
},
/** PrivateFunction: _no_auth_received
*
* Called on stream start/restart when no stream:features
* has been received.
*/
_no_auth_received: function (_callback) {
Strophe.error("Server did not send any auth methods");
this._conn._changeConnectStatus(
Strophe.Status.CONNFAIL,
"Server did not send any auth methods"
);
if (_callback) {
_callback = _callback.bind(this._conn);
_callback();
}
this._conn._doDisconnect();
},
/** PrivateFunction: _onDisconnectTimeout
* _Private_ timeout handler for handling non-graceful disconnection.
*
......@@ -38219,6 +38274,11 @@ return Strophe;
], function (wrapper) {
return wrapper;
});
} else if (typeof exports === 'object') {
var core = require('./core');
require('./bosh');
require('./websocket');
module.exports = core;
}
})(this);
......@@ -43335,7 +43395,7 @@ return Backbone.BrowserStorage;
// Converse.js
// https://conversejs.org
//
// Copyright (c) 2012-2018, the Converse.js developers
// Copyright (c) 2013-2018, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) {
define('converse-core',["sizzle", "es6-promise", "lodash.noconflict", "lodash.fp", "polyfill", "i18n", "utils", "moment", "strophe", "pluggable", "backbone.noconflict", "backbone.nativeview", "backbone.browserStorage"], factory);
......@@ -44002,6 +44062,8 @@ return Backbone.BrowserStorage;
_converse.session.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
_converse.session.fetch();
_converse.emit('sessionInitialized');
};
this.clearSession = function () {
......@@ -45661,15 +45723,15 @@ define("emojione", (function (global) {
initialize: function initialize() {
this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
this.dataforms = new Backbone.Collection();
this.dataforms.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.dataforms-{this.get('jid')}"));
this.dataforms.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.dataforms-{this.get('jid')}"));
this.features = new Backbone.Collection();
this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.features-".concat(this.get('jid'))));
this.features.on('add', this.onFeatureAdded, this);
this.identities = new Backbone.Collection();
this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.identities-".concat(this.get('jid'))));
this.identities.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.identities-".concat(this.get('jid'))));
this.fetchFeatures();
this.items = new _converse.DiscoEntities();
this.items.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.disco-items-".concat(this.get('jid'))));
this.items.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.disco-items-".concat(this.get('jid'))));
this.items.fetch();
},
getIdentity: function getIdentity(category, type) {
......@@ -45850,13 +45912,33 @@ define("emojione", (function (global) {
return this;
}
function initStreamFeatures() {
_converse.stream_features = new Backbone.Collection();
_converse.stream_features.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.stream-features-".concat(_converse.bare_jid)));
_converse.stream_features.fetch({
success: function success(collection) {
if (collection.length === 0 && _converse.connection.features) {
_.forEach(_converse.connection.features.childNodes, function (feature) {
_converse.stream_features.create({
'name': feature.nodeName,
'xmlns': feature.getAttribute('xmlns')
});
});
}
}
});
_converse.emit('streamFeaturesAdded');
}
function initializeDisco() {
addClientFeatures();
_converse.connection.addHandler(onDiscoInfoRequest, Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
_converse.disco_entities = new _converse.DiscoEntities();
_converse.disco_entities.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.disco-entities-".concat(_converse.bare_jid)));
_converse.disco_entities.browserStorage = new Backbone.BrowserStorage.session(b64_sha1("converse.disco-entities-".concat(_converse.bare_jid)));
_converse.disco_entities.fetchEntities().then(function (collection) {
if (collection.length === 0 || !collection.get(_converse.domain)) {
......@@ -45871,6 +45953,8 @@ define("emojione", (function (global) {
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
_converse.api.listen.on('sessionInitialized', initStreamFeatures);
_converse.api.listen.on('reconnected', initializeDisco);
_converse.api.listen.on('connected', initializeDisco);
......@@ -45951,6 +46035,19 @@ define("emojione", (function (global) {
* @namespace
*/
'disco': {
'stream': {
'getFeature': function getFeature(name, xmlns) {
if (_.isNil(name) || _.isNil(xmlns)) {
throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature");
}
return _converse.stream_features.findWhere({
'name': name,
'xmlns': xmlns
});
}
},
/**
* The "own" grouping
* @namespace
......@@ -48627,19 +48724,24 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
this.on('change:image_hash', this.onAvatarChanged, this);
},
onAvatarChanged: function onAvatarChanged() {
var vcard = _converse.vcards.findWhere({
'jid': this.get('from')
});
var hash = this.get('image_hash');
var vcards = [];
if (!vcard) {
return;
if (this.get('jid')) {
vcards.push(this.updateVCard(_converse.vcards.findWhere({
'jid': this.get('jid')
})));
}
var hash = this.get('image_hash');
vcards.push(this.updateVCard(_converse.vcards.findWhere({
'jid': this.get('from')
})));
if (hash && vcard.get('image_hash') !== hash) {
_converse.api.vcard.update(vcard);
}
_.forEach(_.filter(vcards, undefined), function (vcard) {
if (hash && vcard.get('image_hash') !== hash) {
_converse.api.vcard.update(vcard);
}
});
},
getDisplayName: function getDisplayName() {
return this.get('nick') || this.get('jid');
......@@ -48687,6 +48789,10 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'jid': removed_jid
});
if (!occupant) {
return;
}
if (occupant.get('show') === 'offline') {
occupant.destroy();
}
......@@ -60751,7 +60857,7 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
// Converse.js
// http://conversejs.org
//
// Copyright (c) 2012-2018, the Converse.js developers
// Copyright (c) 2013-2018, the Converse.js developers
// Licensed under the Mozilla Public License (MPLv2)
(function (root, factory) {
define('converse-vcard',["converse-core", "crypto", "tpl!vcard"], factory);
......@@ -60824,7 +60930,9 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'image_type': _.get(vcard.querySelector('PHOTO TYPE'), 'textContent'),
'url': _.get(vcard.querySelector('URL'), 'textContent'),
'role': _.get(vcard.querySelector('ROLE'), 'textContent'),
'email': _.get(vcard.querySelector('EMAIL USERID'), 'textContent')
'email': _.get(vcard.querySelector('EMAIL USERID'), 'textContent'),
'vcard_updated': moment().format(),
'vcard_error': undefined
};
}
......@@ -60842,7 +60950,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
if (errback) {
errback({
'stanza': iq,
'jid': jid
'jid': jid,
'vcard_error': moment().format()
});
}
}
......@@ -60908,8 +61017,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
'get': function get(model, force) {
if (_.isString(model)) {
return getVCard(_converse, model);
} else if (!model.get('vcard_updated') || force) {
var jid = model.get('jid') || model.get('muc_jid');
} else if (force || !model.get('vcard_updated') || !moment(model.get('vcard_error')).isSame(new Date(), "day")) {
var jid = model.get('jid');
if (!jid) {
throw new Error("No JID to get vcard for!");
......@@ -60925,9 +61034,8 @@ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterat
return new Promise(function (resolve, reject) {
_this.get(model, force).then(function (vcard) {
model.save(_.extend(_.pick(vcard, ['fullname', 'nickname', 'email', 'url', 'role', 'image_type', 'image', 'image_hash']), {
'vcard_updated': moment().format()
}));
delete vcard['stanza'];
model.save(vcard);
resolve();
});
});
......@@ -72046,6 +72154,13 @@ return __p
*/
_converse.roster = new _converse.RosterContacts();
_converse.roster.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.contacts-".concat(_converse.bare_jid)));
_converse.roster.data = new Backbone.Model();
var id = b64_sha1("converse-roster-model-".concat(_converse.bare_jid));
_converse.roster.data.id = id;
_converse.roster.data.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
_converse.roster.data.fetch();
_converse.rostergroups = new _converse.RosterGroups();
_converse.rostergroups.browserStorage = new Backbone.BrowserStorage[_converse.storage](b64_sha1("converse.roster.groups".concat(_converse.bare_jid)));
......@@ -72350,23 +72465,27 @@ return __p
},
onConnected: function onConnected() {
/* Called as soon as the connection has been established
* (either after initial login, or after reconnection).
*
* Use the opportunity to register stanza handlers.
*/
* (either after initial login, or after reconnection).
*
* Use the opportunity to register stanza handlers.
*/
this.registerRosterHandler();
this.registerRosterXHandler();
},
registerRosterHandler: function registerRosterHandler() {
/* Register a handler for roster IQ "set" stanzas, which update
* roster contacts.
*/
_converse.connection.addHandler(_converse.roster.onRosterPush.bind(_converse.roster), Strophe.NS.ROSTER, 'iq', "set");
* roster contacts.
*/
_converse.connection.addHandler(function (iq) {
_converse.roster.onRosterPush(iq);
return true;
}, Strophe.NS.ROSTER, 'iq', "set");
},
registerRosterXHandler: function registerRosterXHandler() {
/* Register a handler for RosterX message stanzas, which are
* used to suggest roster contacts to a user.
*/
* used to suggest roster contacts to a user.
*/
var t = 0;
_converse.connection.addHandler(function (msg) {
......@@ -72389,12 +72508,13 @@ return __p
* Returns a promise which resolves once the contacts have been
* fetched.
*/
var that = this;
return new Promise(function (resolve, reject) {
_this2.fetch({
'add': true,
'silent': true,
success: function success(collection) {
if (collection.length === 0) {
if (collection.length === 0 || that.rosterVersioningSupported() && !_converse.session.get('roster_fetched')) {
_converse.send_initial_presence = true;
_converse.roster.fetchFromServer().then(resolve).catch(reject);
......@@ -72536,30 +72656,22 @@ return __p
},
onRosterPush: function onRosterPush(iq) {
/* Handle roster updates from the XMPP server.
* See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push
*
* Parameters:
* (XMLElement) IQ - The IQ stanza received from the XMPP server.
*/
* See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push
*
* Parameters:
* (XMLElement) IQ - The IQ stanza received from the XMPP server.
*/
var id = iq.getAttribute('id');
var from = iq.getAttribute('from');
if (from && from !== "" && Strophe.getBareJidFromJid(from) !== _converse.bare_jid) {
// Receiving client MUST ignore stanza unless it has no from or from = user's bare JID.
// XXX: Some naughty servers apparently send from a full
// JID so we need to explicitly compare bare jids here.
// https://github.com/jcbrand/converse.js/issues/493
_converse.connection.send($iq({
type: 'error',
id: id,
from: _converse.connection.jid
}).c('error', {
'type': 'cancel'
}).c('service-unavailable', {
'xmlns': Strophe.NS.ROSTER
}));
return true;
if (from && from !== _converse.connection.jid) {
// https://tools.ietf.org/html/rfc6121#page-15
//
// A receiving client MUST ignore the stanza unless it has no 'from'
// attribute (i.e., implicitly from the bare JID of the user's
// account) or it has a 'from' attribute whose value matches the
// user's bare JID <user@domainpart>.
return;
}
_converse.connection.send($iq({
......@@ -72568,13 +72680,32 @@ return __p
from: _converse.connection.jid
}));
var items = sizzle("query[xmlns=\"".concat(Strophe.NS.ROSTER, "\"] item"), iq);
var query = sizzle("query[xmlns=\"".concat(Strophe.NS.ROSTER, "\"]"), iq).pop();
this.data.save('version', query.getAttribute('ver'));
var items = sizzle("item", query);
if (items.length > 1) {
_converse.log(iq, Strophe.LogLevel.ERROR);
throw new Error('Roster push query may not contain more than one "item" element.');
}
if (items.length === 0) {
_converse.log(iq, Strophe.LogLevel.WARN);
_converse.log('Received a roster push stanza without an "item" element.', Strophe.LogLevel.WARN);
return;
}
_.each(items, this.updateContact.bind(this));
this.updateContact(items.pop());
_converse.emit('rosterPush', iq);
return true;
return;
},
rosterVersioningSupported: function rosterVersioningSupported() {
return _converse.api.disco.stream.getFeature('ver', 'urn:xmpp:features:rosterver') && this.data.get('version');
},
fetchFromServer: function fetchFromServer() {
var _this4 = this;
......@@ -72588,6 +72719,12 @@ return __p
xmlns: Strophe.NS.ROSTER
});
if (_this4.rosterVersioningSupported()) {
iq.attrs({
'ver': _this4.data.get('version')
});
}
var callback = _.flow(_this4.onReceivedFromServer.bind(_this4), resolve);
var errback = function errback(iq) {
......@@ -72602,19 +72739,31 @@ return __p
});
},
onReceivedFromServer: function onReceivedFromServer(iq) {
var _this5 = this;
/* An IQ stanza containing the roster has been received from
* the XMPP server.
*/
var items = sizzle("query[xmlns=\"".concat(Strophe.NS.ROSTER, "\"] item"), iq);
* the XMPP server.
*/
var query = sizzle("query[xmlns=\"".concat(Strophe.NS.ROSTER, "\"]"), iq).pop();
if (query) {
var items = sizzle("item", query);
_.each(items, function (item) {
return _this5.updateContact(item);
});
this.data.save('version', query.getAttribute('ver'));
_.each(items, this.updateContact.bind(this));
_converse.session.save('roster_fetched', true);
}
_converse.emit('roster', iq);
},
updateContact: function updateContact(item) {
/* Update or create RosterContact models based on items
* received in the IQ from the server.
*/
* received in the IQ from the server.
*/
var jid = item.getAttribute('jid');
if (this.isSelf(jid)) {
......@@ -72795,7 +72944,7 @@ return __p
_converse.RosterGroups = Backbone.Collection.extend({
model: _converse.RosterGroup,
fetchRosterGroups: function fetchRosterGroups() {
var _this5 = this;
var _this6 = this;
/* Fetches all the roster groups from sessionStorage.
*
......@@ -72803,7 +72952,7 @@ return __p
* returned.
*/
return new Promise(function (resolve, reject) {
_this5.fetch({
_this6.fetch({
silent: true,
// We need to first have all groups before
// we can start positioning them, so we set
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment