Explorar el Código

Adds advertisement of XEP-0115 capabilities to MUC presence.

j8
paweldomas hace 11 años
padre
commit
8c64d3192b

+ 1
- 0
config.js Ver fichero

@@ -11,6 +11,7 @@ var config = {
11 11
 //  useIPv6: true, // ipv6 support. use at your own risk
12 12
     useNicks: false,
13 13
     bosh: '//jitsi-meet.example.com/http-bind', // FIXME: use xep-0156 for that
14
+    clientNode: 'http://jitsi.org/jitsimeet', // The name of client node advertised in XEP-0115 'c' stanza
14 15
     desktopSharing: 'ext', // Desktop sharing method. Can be set to 'ext', 'webrtc' or false to disable.
15 16
     chromeExtensionId: 'diibjkoicjeejcmhdnailmkgecihlobk', // Id of desktop streamer Chrome extension
16 17
     desktopSharingSources: ['screen', 'window'],

+ 202
- 0
debian/patches/missing-source/libs/strophe/sha1.js Ver fichero

@@ -0,0 +1,202 @@
1
+/*
2
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
3
+ * in FIPS PUB 180-1
4
+ * Version 2.1a Copyright Paul Johnston 2000 - 2002.
5
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
6
+ * Distributed under the BSD License
7
+ * See http://pajhome.org.uk/crypt/md5 for details.
8
+ */
9
+
10
+/*
11
+ * Configurable variables. You may need to tweak these to be compatible with
12
+ * the server-side, but the defaults work in most cases.
13
+ */
14
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
15
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
16
+var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */
17
+
18
+/*
19
+ * These are the functions you'll usually want to call
20
+ * They take string arguments and return either hex or base-64 encoded strings
21
+ */
22
+function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
23
+function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
24
+function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
25
+function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
26
+function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
27
+function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
28
+
29
+/*
30
+ * Perform a simple self-test to see if the VM is working
31
+ */
32
+function sha1_vm_test()
33
+{
34
+  return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
35
+}
36
+
37
+/*
38
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
39
+ */
40
+function core_sha1(x, len)
41
+{
42
+  /* append padding */
43
+  x[len >> 5] |= 0x80 << (24 - len % 32);
44
+  x[((len + 64 >> 9) << 4) + 15] = len;
45
+
46
+  var w = Array(80);
47
+  var a =  1732584193;
48
+  var b = -271733879;
49
+  var c = -1732584194;
50
+  var d =  271733878;
51
+  var e = -1009589776;
52
+
53
+  for(var i = 0; i < x.length; i += 16)
54
+  {
55
+    var olda = a;
56
+    var oldb = b;
57
+    var oldc = c;
58
+    var oldd = d;
59
+    var olde = e;
60
+
61
+    for(var j = 0; j < 80; j++)
62
+    {
63
+      if(j < 16) w[j] = x[i + j];
64
+      else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
65
+      var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
66
+                       safe_add(safe_add(e, w[j]), sha1_kt(j)));
67
+      e = d;
68
+      d = c;
69
+      c = rol(b, 30);
70
+      b = a;
71
+      a = t;
72
+    }
73
+
74
+    a = safe_add(a, olda);
75
+    b = safe_add(b, oldb);
76
+    c = safe_add(c, oldc);
77
+    d = safe_add(d, oldd);
78
+    e = safe_add(e, olde);
79
+  }
80
+  return Array(a, b, c, d, e);
81
+
82
+}
83
+
84
+/*
85
+ * Perform the appropriate triplet combination function for the current
86
+ * iteration
87
+ */
88
+function sha1_ft(t, b, c, d)
89
+{
90
+  if(t < 20) return (b & c) | ((~b) & d);
91
+  if(t < 40) return b ^ c ^ d;
92
+  if(t < 60) return (b & c) | (b & d) | (c & d);
93
+  return b ^ c ^ d;
94
+}
95
+
96
+/*
97
+ * Determine the appropriate additive constant for the current iteration
98
+ */
99
+function sha1_kt(t)
100
+{
101
+  return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
102
+         (t < 60) ? -1894007588 : -899497514;
103
+}
104
+
105
+/*
106
+ * Calculate the HMAC-SHA1 of a key and some data
107
+ */
108
+function core_hmac_sha1(key, data)
109
+{
110
+  var bkey = str2binb(key);
111
+  if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
112
+
113
+  var ipad = Array(16), opad = Array(16);
114
+  for(var i = 0; i < 16; i++)
115
+  {
116
+    ipad[i] = bkey[i] ^ 0x36363636;
117
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
118
+  }
119
+
120
+  var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
121
+  return core_sha1(opad.concat(hash), 512 + 160);
122
+}
123
+
124
+/*
125
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
126
+ * to work around bugs in some JS interpreters.
127
+ */
128
+function safe_add(x, y)
129
+{
130
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
131
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
132
+  return (msw << 16) | (lsw & 0xFFFF);
133
+}
134
+
135
+/*
136
+ * Bitwise rotate a 32-bit number to the left.
137
+ */
138
+function rol(num, cnt)
139
+{
140
+  return (num << cnt) | (num >>> (32 - cnt));
141
+}
142
+
143
+/*
144
+ * Convert an 8-bit or 16-bit string to an array of big-endian words
145
+ * In 8-bit function, characters >255 have their hi-byte silently ignored.
146
+ */
147
+function str2binb(str)
148
+{
149
+  var bin = Array();
150
+  var mask = (1 << chrsz) - 1;
151
+  for(var i = 0; i < str.length * chrsz; i += chrsz)
152
+    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
153
+  return bin;
154
+}
155
+
156
+/*
157
+ * Convert an array of big-endian words to a string
158
+ */
159
+function binb2str(bin)
160
+{
161
+  var str = "";
162
+  var mask = (1 << chrsz) - 1;
163
+  for(var i = 0; i < bin.length * 32; i += chrsz)
164
+    str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
165
+  return str;
166
+}
167
+
168
+/*
169
+ * Convert an array of big-endian words to a hex string.
170
+ */
171
+function binb2hex(binarray)
172
+{
173
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
174
+  var str = "";
175
+  for(var i = 0; i < binarray.length * 4; i++)
176
+  {
177
+    str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
178
+           hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8  )) & 0xF);
179
+  }
180
+  return str;
181
+}
182
+
183
+/*
184
+ * Convert an array of big-endian words to a base-64 string
185
+ */
186
+function binb2b64(binarray)
187
+{
188
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
189
+  var str = "";
190
+  for(var i = 0; i < binarray.length * 4; i += 3)
191
+  {
192
+    var triplet = (((binarray[i   >> 2] >> 8 * (3 -  i   %4)) & 0xFF) << 16)
193
+                | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
194
+                |  ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
195
+    for(var j = 0; j < 4; j++)
196
+    {
197
+      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
198
+      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
199
+    }
200
+  }
201
+  return str;
202
+}

+ 240
- 0
debian/patches/missing-source/libs/strophe/strophe.caps.jsonly.js Ver fichero

@@ -0,0 +1,240 @@
1
+/**
2
+ * Entity Capabilities (XEP-0115)
3
+ *
4
+ * Depends on disco plugin.
5
+ *
6
+ * See: http://xmpp.org/extensions/xep-0115.html
7
+ *
8
+ * Authors:
9
+ *   - Michael Weibel <michael.weibel@gmail.com>
10
+ *
11
+ * Copyright:
12
+ *   - Michael Weibel <michael.weibel@gmail.com>
13
+ */
14
+
15
+ Strophe.addConnectionPlugin('caps', {
16
+	/** Constant: HASH
17
+	 * Hash used
18
+	 *
19
+	 * Currently only sha-1 is supported.
20
+	 */
21
+	HASH: 'sha-1',
22
+	/** Variable: node
23
+	 * Client which is being used.
24
+	 *
25
+	 * Can be overwritten as soon as Strophe has been initialized.
26
+	 */
27
+	node: 'http://strophe.im/strophejs/',
28
+	/** PrivateVariable: _ver
29
+	 * Own generated version string
30
+	 */
31
+	_ver: '',
32
+	/** PrivateVariable: _connection
33
+	 * Strophe connection
34
+	 */
35
+	_connection: null,
36
+	/** PrivateVariable: _knownCapabilities
37
+	 * A hashtable containing version-strings and their capabilities, serialized
38
+	 * as string.
39
+	 *
40
+	 * TODO: Maybe those caps shouldn't be serialized.
41
+	 */
42
+	_knownCapabilities: {},
43
+	/** PrivateVariable: _jidVerIndex
44
+	 * A hashtable containing jids and their versions for better lookup of capabilities.
45
+	 */
46
+	_jidVerIndex: {},
47
+
48
+	/** Function: init
49
+	 * Initialize plugin:
50
+	 *   - Add caps namespace
51
+	 *   - Add caps feature to disco plugin
52
+	 *   - Add handler for caps stanzas
53
+	 *
54
+	 * Parameters:
55
+	 *   (Strophe.Connection) conn - Strophe connection
56
+	 */
57
+	init: function(conn) {
58
+		this._connection = conn;
59
+
60
+		Strophe.addNamespace('CAPS', 'http://jabber.org/protocol/caps');
61
+
62
+		if (!this._connection.disco) {
63
+			throw "Caps plugin requires the disco plugin to be installed.";
64
+		}
65
+
66
+		this._connection.disco.addFeature(Strophe.NS.CAPS);
67
+		this._connection.addHandler(this._delegateCapabilities.bind(this), Strophe.NS.CAPS);
68
+	},
69
+
70
+	/** Function: generateCapsAttrs
71
+	 * Returns the attributes for generating the "c"-stanza containing the own version
72
+	 *
73
+	 * Returns:
74
+	 *   (Object) - attributes
75
+	 */
76
+	generateCapsAttrs: function() {
77
+		return {
78
+			'xmlns': Strophe.NS.CAPS,
79
+			'hash': this.HASH,
80
+			'node': this.node,
81
+			'ver': this.generateVer()
82
+		};
83
+	},
84
+
85
+	/** Function: generateVer
86
+	 * Returns the base64 encoded version string (encoded itself with sha1)
87
+	 *
88
+	 * Returns:
89
+	 *   (String) - version
90
+	 */
91
+	generateVer: function() {
92
+		if (this._ver !== "") {
93
+			return this._ver;
94
+		}
95
+
96
+		var ver = "",
97
+			identities = this._connection.disco._identities.sort(this._sortIdentities),
98
+			identitiesLen = identities.length,
99
+			features = this._connection.disco._features.sort(),
100
+			featuresLen = features.length;
101
+		for(var i = 0; i < identitiesLen; i++) {
102
+			var curIdent = identities[i];
103
+			ver += curIdent.category + "/" + curIdent.type + "/" + curIdent.lang + "/" + curIdent.name + "<";
104
+		}
105
+		for(var i = 0; i < featuresLen; i++) {
106
+			ver += features[i] + '<';
107
+		}
108
+
109
+		this._ver = b64_sha1(ver);
110
+		return this._ver;
111
+	},
112
+
113
+	/** Function: getCapabilitiesByJid
114
+	 * Returns serialized capabilities of a jid (if available).
115
+	 * Otherwise null.
116
+	 *
117
+	 * Parameters:
118
+	 *   (String) jid - Jabber id
119
+	 *
120
+	 * Returns:
121
+	 *   (String|null) - capabilities, serialized; or null when not available.
122
+	 */
123
+	getCapabilitiesByJid: function(jid) {
124
+		if (this._jidVerIndex[jid]) {
125
+			return this._knownCapabilities[this._jidVerIndex[jid]];
126
+		}
127
+		return null;
128
+	},
129
+
130
+	/** PrivateFunction: _delegateCapabilities
131
+	 * Checks if the version has already been saved.
132
+	 * If yes: do nothing.
133
+	 * If no: Request capabilities
134
+	 *
135
+	 * Parameters:
136
+	 *   (Strophe.Builder) stanza - Stanza
137
+	 *
138
+	 * Returns:
139
+	 *   (Boolean)
140
+	 */
141
+	_delegateCapabilities: function(stanza) {
142
+		var from = stanza.getAttribute('from'),
143
+			c = stanza.querySelector('c'),
144
+			ver = c.getAttribute('ver'),
145
+			node = c.getAttribute('node');
146
+		if (!this._knownCapabilities[ver]) {
147
+			return this._requestCapabilities(from, node, ver);
148
+		} else {
149
+			this._jidVerIndex[from] = ver;
150
+		}
151
+		if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) {
152
+			this._jidVerIndex[from] = ver;
153
+		}
154
+		return true;
155
+	},
156
+
157
+	/** PrivateFunction: _requestCapabilities
158
+	 * Requests capabilities from the one which sent the caps-info stanza.
159
+	 * This is done using disco info.
160
+	 *
161
+	 * Additionally, it registers a handler for handling the reply.
162
+	 *
163
+	 * Parameters:
164
+	 *   (String) to - Destination jid
165
+	 *   (String) node - Node attribute of the caps-stanza
166
+	 *   (String) ver - Version of the caps-stanza
167
+	 *
168
+	 * Returns:
169
+	 *   (Boolean) - true
170
+	 */
171
+	_requestCapabilities: function(to, node, ver) {
172
+		if (to !== this._connection.jid) {
173
+			var id = this._connection.disco.info(to, node + '#' + ver);
174
+			this._connection.addHandler(this._handleDiscoInfoReply.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'result', id, to);
175
+		}
176
+		return true;
177
+	},
178
+
179
+	/** PrivateFunction: _handleDiscoInfoReply
180
+	 * Parses the disco info reply and adds the version & it's capabilities to the _knownCapabilities variable.
181
+	 * Additionally, it adds the jid & the version to the _jidVerIndex variable for a better lookup.
182
+	 *
183
+	 * Parameters:
184
+	 *   (Strophe.Builder) stanza - Disco info stanza
185
+	 *
186
+	 * Returns:
187
+	 *   (Boolean) - false, to automatically remove the handler.
188
+	 */
189
+	_handleDiscoInfoReply: function(stanza) {
190
+		var query = stanza.querySelector('query'),
191
+			node = query.getAttribute('node').split('#'),
192
+			ver = node[1],
193
+			from = stanza.getAttribute('from');
194
+		if (!this._knownCapabilities[ver]) {
195
+			var childNodes = query.childNodes,
196
+				childNodesLen = childNodes.length;
197
+			this._knownCapabilities[ver] = [];
198
+			for(var i = 0; i < childNodesLen; i++) {
199
+				var node = childNodes[i];
200
+				this._knownCapabilities[ver].push({name: node.nodeName, attributes: node.attributes});
201
+			}
202
+			this._jidVerIndex[from] = ver;
203
+		} else if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) {
204
+			this._jidVerIndex[from] = ver;
205
+		}
206
+		return false;
207
+	},
208
+
209
+	/** PrivateFunction: _sortIdentities
210
+	 * Sorts two identities according the sorting requirements in XEP-0115.
211
+	 *
212
+	 * Parameters:
213
+	 *   (Object) a - Identity a
214
+	 *   (Object) b - Identity b
215
+	 *
216
+	 * Returns:
217
+	 *   (Integer) - 1, 0 or -1; according to which one's greater.
218
+	 */
219
+	_sortIdentities: function(a, b) {
220
+		if (a.category > b.category) {
221
+			return 1;
222
+		}
223
+		if (a.category < b.category) {
224
+			return -1;
225
+		}
226
+		if (a.type > b.type) {
227
+			return 1;
228
+		}
229
+		if (a.type < b.type) {
230
+			return -1;
231
+		}
232
+		if (a.lang > b.lang) {
233
+			return 1;
234
+		}
235
+		if (a.lang < b.lang) {
236
+			return -1;
237
+		}
238
+		return 0;
239
+	}
240
+ });

+ 232
- 0
debian/patches/missing-source/libs/strophe/strophe.disco.js Ver fichero

@@ -0,0 +1,232 @@
1
+/*
2
+  Copyright 2010, François de Metz <francois@2metz.fr>
3
+*/
4
+
5
+/**
6
+ * Disco Strophe Plugin
7
+ * Implement http://xmpp.org/extensions/xep-0030.html
8
+ * TODO: manage node hierarchies, and node on info request
9
+ */
10
+Strophe.addConnectionPlugin('disco',
11
+{
12
+    _connection: null,
13
+    _identities : [],
14
+    _features : [],
15
+    _items : [],
16
+    /** Function: init
17
+     * Plugin init
18
+     *
19
+     * Parameters:
20
+     *   (Strophe.Connection) conn - Strophe connection
21
+     */
22
+    init: function(conn)
23
+    {
24
+    this._connection = conn;
25
+        this._identities = [];
26
+        this._features   = [];
27
+        this._items      = [];
28
+        // disco info
29
+        conn.addHandler(this._onDiscoInfo.bind(this), Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
30
+        // disco items
31
+        conn.addHandler(this._onDiscoItems.bind(this), Strophe.NS.DISCO_ITEMS, 'iq', 'get', null, null);
32
+    },
33
+    /** Function: addIdentity
34
+     * See http://xmpp.org/registrar/disco-categories.html
35
+     * Parameters:
36
+     *   (String) category - category of identity (like client, automation, etc ...)
37
+     *   (String) type - type of identity (like pc, web, bot , etc ...)
38
+     *   (String) name - name of identity in natural language
39
+     *   (String) lang - lang of name parameter
40
+     *
41
+     * Returns:
42
+     *   Boolean
43
+     */
44
+    addIdentity: function(category, type, name, lang)
45
+    {
46
+        for (var i=0; i<this._identities.length; i++)
47
+        {
48
+            if (this._identities[i].category == category &&
49
+                this._identities[i].type == type &&
50
+                this._identities[i].name == name &&
51
+                this._identities[i].lang == lang)
52
+            {
53
+                return false;
54
+            }
55
+        }
56
+        this._identities.push({category: category, type: type, name: name, lang: lang});
57
+        return true;
58
+    },
59
+    /** Function: addFeature
60
+     *
61
+     * Parameters:
62
+     *   (String) var_name - feature name (like jabber:iq:version)
63
+     *
64
+     * Returns:
65
+     *   boolean
66
+     */
67
+    addFeature: function(var_name)
68
+    {
69
+        for (var i=0; i<this._features.length; i++)
70
+        {
71
+             if (this._features[i] == var_name)
72
+                 return false;
73
+        }
74
+        this._features.push(var_name);
75
+        return true;
76
+    },
77
+    /** Function: removeFeature
78
+     *
79
+     * Parameters:
80
+     *   (String) var_name - feature name (like jabber:iq:version)
81
+     *
82
+     * Returns:
83
+     *   boolean
84
+     */
85
+    removeFeature: function(var_name)
86
+    {
87
+        for (var i=0; i<this._features.length; i++)
88
+        {
89
+             if (this._features[i] === var_name){
90
+                 this._features.splice(i,1)
91
+                 return true;
92
+             }
93
+        }
94
+        return false;
95
+    },
96
+    /** Function: addItem
97
+     *
98
+     * Parameters:
99
+     *   (String) jid
100
+     *   (String) name
101
+     *   (String) node
102
+     *   (Function) call_back
103
+     *
104
+     * Returns:
105
+     *   boolean
106
+     */
107
+    addItem: function(jid, name, node, call_back)
108
+    {
109
+        if (node && !call_back)
110
+            return false;
111
+        this._items.push({jid: jid, name: name, node: node, call_back: call_back});
112
+        return true;
113
+    },
114
+    /** Function: info
115
+     * Info query
116
+     *
117
+     * Parameters:
118
+     *   (Function) call_back
119
+     *   (String) jid
120
+     *   (String) node
121
+     */
122
+    info: function(jid, node, success, error, timeout)
123
+    {
124
+        var attrs = {xmlns: Strophe.NS.DISCO_INFO};
125
+        if (node)
126
+            attrs.node = node;
127
+
128
+        var info = $iq({from:this._connection.jid,
129
+                         to:jid, type:'get'}).c('query', attrs);
130
+        this._connection.sendIQ(info, success, error, timeout);
131
+    },
132
+    /** Function: items
133
+     * Items query
134
+     *
135
+     * Parameters:
136
+     *   (Function) call_back
137
+     *   (String) jid
138
+     *   (String) node
139
+     */
140
+    items: function(jid, node, success, error, timeout)
141
+    {
142
+        var attrs = {xmlns: Strophe.NS.DISCO_ITEMS};
143
+        if (node)
144
+            attrs.node = node;
145
+
146
+        var items = $iq({from:this._connection.jid,
147
+                         to:jid, type:'get'}).c('query', attrs);
148
+        this._connection.sendIQ(items, success, error, timeout);
149
+    },
150
+
151
+    /** PrivateFunction: _buildIQResult
152
+     */
153
+    _buildIQResult: function(stanza, query_attrs)
154
+    {
155
+        var id   =  stanza.getAttribute('id');
156
+        var from = stanza.getAttribute('from');
157
+        var iqresult = $iq({type: 'result', id: id});
158
+
159
+        if (from !== null) {
160
+            iqresult.attrs({to: from});
161
+        }
162
+
163
+        return iqresult.c('query', query_attrs);
164
+    },
165
+
166
+    /** PrivateFunction: _onDiscoInfo
167
+     * Called when receive info request
168
+     */
169
+    _onDiscoInfo: function(stanza)
170
+    {
171
+        var node = stanza.getElementsByTagName('query')[0].getAttribute('node');
172
+        var attrs = {xmlns: Strophe.NS.DISCO_INFO};
173
+        if (node)
174
+        {
175
+            attrs.node = node;
176
+        }
177
+        var iqresult = this._buildIQResult(stanza, attrs);
178
+        for (var i=0; i<this._identities.length; i++)
179
+        {
180
+            var attrs = {category: this._identities[i].category,
181
+                         type    : this._identities[i].type};
182
+            if (this._identities[i].name)
183
+                attrs.name = this._identities[i].name;
184
+            if (this._identities[i].lang)
185
+                attrs['xml:lang'] = this._identities[i].lang;
186
+            iqresult.c('identity', attrs).up();
187
+        }
188
+        for (var i=0; i<this._features.length; i++)
189
+        {
190
+            iqresult.c('feature', {'var':this._features[i]}).up();
191
+        }
192
+        this._connection.send(iqresult.tree());
193
+        return true;
194
+    },
195
+    /** PrivateFunction: _onDiscoItems
196
+     * Called when receive items request
197
+     */
198
+    _onDiscoItems: function(stanza)
199
+    {
200
+        var query_attrs = {xmlns: Strophe.NS.DISCO_ITEMS};
201
+        var node = stanza.getElementsByTagName('query')[0].getAttribute('node');
202
+        if (node)
203
+        {
204
+            query_attrs.node = node;
205
+            var items = [];
206
+            for (var i = 0; i < this._items.length; i++)
207
+            {
208
+                if (this._items[i].node == node)
209
+                {
210
+                    items = this._items[i].call_back(stanza);
211
+                    break;
212
+                }
213
+            }
214
+        }
215
+        else
216
+        {
217
+            var items = this._items;
218
+        }
219
+        var iqresult = this._buildIQResult(stanza, query_attrs);
220
+        for (var i = 0; i < items.length; i++)
221
+        {
222
+            var attrs = {jid:  items[i].jid};
223
+            if (items[i].name)
224
+                attrs.name = items[i].name;
225
+            if (items[i].node)
226
+                attrs.node = items[i].node;
227
+            iqresult.c('item', attrs).up();
228
+        }
229
+        this._connection.send(iqresult.tree());
230
+        return true;
231
+    }
232
+});

+ 2
- 0
index.html Ver fichero

@@ -13,6 +13,8 @@
13 13
     <script src="simulcast.js?v=1"></script><!-- simulcast handling -->
14 14
     <script src="libs/strophe/strophe.jingle.adapter.js?v=1"></script><!-- strophe.jingle bundles -->
15 15
     <script src="libs/strophe/strophe.min.js?v=1"></script>
16
+    <script src="libs/strophe/strophe.disco.min.js?v=1"></script>
17
+    <script src="libs/strophe/strophe.caps.jsonly.min.js?v=1"></script>
16 18
     <script src="libs/strophe/strophe.jingle.js?v=1"></script>
17 19
     <script src="libs/strophe/strophe.jingle.sdp.js?v=2"></script>
18 20
     <script src="libs/strophe/strophe.jingle.sdp.util.js?v=1"></script>

+ 1
- 0
libs/strophe/strophe.caps.jsonly.min.js Ver fichero

@@ -0,0 +1 @@
1
+Strophe.addConnectionPlugin("caps",{HASH:"sha-1",node:"http://strophe.im/strophejs/",_ver:"",_connection:null,_knownCapabilities:{},_jidVerIndex:{},init:function(conn){this._connection=conn;Strophe.addNamespace("CAPS","http://jabber.org/protocol/caps");if(!this._connection.disco){throw"Caps plugin requires the disco plugin to be installed."}this._connection.disco.addFeature(Strophe.NS.CAPS);this._connection.addHandler(this._delegateCapabilities.bind(this),Strophe.NS.CAPS)},generateCapsAttrs:function(){return{xmlns:Strophe.NS.CAPS,hash:this.HASH,node:this.node,ver:this.generateVer()}},generateVer:function(){if(this._ver!==""){return this._ver}var ver="",identities=this._connection.disco._identities.sort(this._sortIdentities),identitiesLen=identities.length,features=this._connection.disco._features.sort(),featuresLen=features.length;for(var i=0;i<identitiesLen;i++){var curIdent=identities[i];ver+=curIdent.category+"/"+curIdent.type+"/"+curIdent.lang+"/"+curIdent.name+"<"}for(var i=0;i<featuresLen;i++){ver+=features[i]+"<"}this._ver=b64_sha1(ver);return this._ver},getCapabilitiesByJid:function(jid){if(this._jidVerIndex[jid]){return this._knownCapabilities[this._jidVerIndex[jid]]}return null},_delegateCapabilities:function(stanza){var from=stanza.getAttribute("from"),c=stanza.querySelector("c"),ver=c.getAttribute("ver"),node=c.getAttribute("node");if(!this._knownCapabilities[ver]){return this._requestCapabilities(from,node,ver)}else{this._jidVerIndex[from]=ver}if(!this._jidVerIndex[from]||!this._jidVerIndex[from]!==ver){this._jidVerIndex[from]=ver}return true},_requestCapabilities:function(to,node,ver){if(to!==this._connection.jid){var id=this._connection.disco.info(to,node+"#"+ver);this._connection.addHandler(this._handleDiscoInfoReply.bind(this),Strophe.NS.DISCO_INFO,"iq","result",id,to)}return true},_handleDiscoInfoReply:function(stanza){var query=stanza.querySelector("query"),node=query.getAttribute("node").split("#"),ver=node[1],from=stanza.getAttribute("from");if(!this._knownCapabilities[ver]){var childNodes=query.childNodes,childNodesLen=childNodes.length;this._knownCapabilities[ver]=[];for(var i=0;i<childNodesLen;i++){var node=childNodes[i];this._knownCapabilities[ver].push({name:node.nodeName,attributes:node.attributes})}this._jidVerIndex[from]=ver}else{if(!this._jidVerIndex[from]||!this._jidVerIndex[from]!==ver){this._jidVerIndex[from]=ver}}return false},_sortIdentities:function(a,b){if(a.category>b.category){return 1}if(a.category<b.category){return -1}if(a.type>b.type){return 1}if(a.type<b.type){return -1}if(a.lang>b.lang){return 1}if(a.lang<b.lang){return -1}return 0}});

+ 1
- 0
libs/strophe/strophe.disco.min.js Ver fichero

@@ -0,0 +1 @@
1
+Strophe.addConnectionPlugin("disco",{_connection:null,_identities:[],_features:[],_items:[],init:function(conn){this._connection=conn;this._identities=[];this._features=[];this._items=[];conn.addHandler(this._onDiscoInfo.bind(this),Strophe.NS.DISCO_INFO,"iq","get",null,null);conn.addHandler(this._onDiscoItems.bind(this),Strophe.NS.DISCO_ITEMS,"iq","get",null,null)},addIdentity:function(category,type,name,lang){for(var i=0;i<this._identities.length;i++){if(this._identities[i].category==category&&this._identities[i].type==type&&this._identities[i].name==name&&this._identities[i].lang==lang){return false}}this._identities.push({category:category,type:type,name:name,lang:lang});return true},addFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]==var_name){return false}}this._features.push(var_name);return true},removeFeature:function(var_name){for(var i=0;i<this._features.length;i++){if(this._features[i]===var_name){this._features.splice(i,1);return true}}return false},addItem:function(jid,name,node,call_back){if(node&&!call_back){return false}this._items.push({jid:jid,name:name,node:node,call_back:call_back});return true},info:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var info=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(info,success,error,timeout)},items:function(jid,node,success,error,timeout){var attrs={xmlns:Strophe.NS.DISCO_ITEMS};if(node){attrs.node=node}var items=$iq({from:this._connection.jid,to:jid,type:"get"}).c("query",attrs);this._connection.sendIQ(items,success,error,timeout)},_buildIQResult:function(stanza,query_attrs){var id=stanza.getAttribute("id");var from=stanza.getAttribute("from");var iqresult=$iq({type:"result",id:id});if(from!==null){iqresult.attrs({to:from})}return iqresult.c("query",query_attrs)},_onDiscoInfo:function(stanza){var node=stanza.getElementsByTagName("query")[0].getAttribute("node");var attrs={xmlns:Strophe.NS.DISCO_INFO};if(node){attrs.node=node}var iqresult=this._buildIQResult(stanza,attrs);for(var i=0;i<this._identities.length;i++){var attrs={category:this._identities[i].category,type:this._identities[i].type};if(this._identities[i].name){attrs.name=this._identities[i].name}if(this._identities[i].lang){attrs["xml:lang"]=this._identities[i].lang}iqresult.c("identity",attrs).up()}for(var i=0;i<this._features.length;i++){iqresult.c("feature",{"var":this._features[i]}).up()}this._connection.send(iqresult.tree());return true},_onDiscoItems:function(stanza){var query_attrs={xmlns:Strophe.NS.DISCO_ITEMS};var node=stanza.getElementsByTagName("query")[0].getAttribute("node");if(node){query_attrs.node=node;var items=[];for(var i=0;i<this._items.length;i++){if(this._items[i].node==node){items=this._items[i].call_back(stanza);break}}}else{var items=this._items}var iqresult=this._buildIQResult(stanza,query_attrs);for(var i=0;i<items.length;i++){var attrs={jid:items[i].jid};if(items[i].name){attrs.name=items[i].name}if(items[i].node){attrs.node=items[i].node}iqresult.c("item",attrs).up()}this._connection.send(iqresult.tree());return true}});

+ 6
- 0
muc.js Ver fichero

@@ -291,6 +291,12 @@ Strophe.addConnectionPlugin('emuc', {
291 291
 
292 292
         pres.up();
293 293
 
294
+        // Send XEP-0115 'c' stanza that contains our capabilities info
295
+        if (connection.caps) {
296
+            connection.caps.node = config.clientNode;
297
+            pres.c('c', connection.caps.generateCapsAttrs()).up();
298
+        }
299
+
294 300
         if(this.presMap['bridgeIsDown']) {
295 301
             pres.c('bridgeIsDown').up();
296 302
         }

Loading…
Cancelar
Guardar