xmppify 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +1 -0
  7. data/app/assets/javascripts/xmpp/index.js +0 -0
  8. data/app/assets/javascripts/xmpp/scripts/checkplayer.js +12 -0
  9. data/app/assets/javascripts/xmpp/scripts/crossdomain.xml +7 -0
  10. data/app/assets/javascripts/xmpp/scripts/flXHR.js +2 -0
  11. data/app/assets/javascripts/xmpp/scripts/flXHR.swf +0 -0
  12. data/app/assets/javascripts/xmpp/scripts/flXHR.vbs +44 -0
  13. data/app/assets/javascripts/xmpp/scripts/flensed.js +12 -0
  14. data/app/assets/javascripts/xmpp/scripts/strophe.flxhr.js +31 -0
  15. data/app/assets/javascripts/xmpp/scripts/strophe.js +3538 -0
  16. data/app/assets/javascripts/xmpp/scripts/swfobject.js +5 -0
  17. data/app/assets/javascripts/xmpp/scripts/updateplayer.swf +0 -0
  18. data/app/assets/javascripts/xmpp/scripts/xmpp.js.coffee +386 -0
  19. data/app/assets/javascripts/xmpp/strophejs-plugins/LICENSE.txt +19 -0
  20. data/app/assets/javascripts/xmpp/strophejs-plugins/README.markdown +95 -0
  21. data/app/assets/javascripts/xmpp/strophejs-plugins/archive/README.markdown +14 -0
  22. data/app/assets/javascripts/xmpp/strophejs-plugins/archive/iso8601_support.js +32 -0
  23. data/app/assets/javascripts/xmpp/strophejs-plugins/archive/strophe.archive.js +88 -0
  24. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/README.markdown +53 -0
  25. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/sha1.js +202 -0
  26. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.coffee +153 -0
  27. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.js +88 -0
  28. data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.caps.jsonly.js +240 -0
  29. data/app/assets/javascripts/xmpp/strophejs-plugins/chatstates/strophe.chatstates.js +80 -0
  30. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/README.markdown +47 -0
  31. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/GetUrlComamndSpec.js +66 -0
  32. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/strophe.cmds.spec.coffee +145 -0
  33. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/support/jasmine.json +16 -0
  34. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.coffee +265 -0
  35. data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.js +403 -0
  36. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/README.markdown +82 -0
  37. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/spec/strophe.x.coffee +715 -0
  38. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.coffee +443 -0
  39. data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.js +854 -0
  40. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/.gitignore +1 -0
  41. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/README.markdown +0 -0
  42. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/convert.js +13 -0
  43. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/jasmine.json +11 -0
  44. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/lib/strophe.disco.js +137 -0
  45. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/public/javascript/strophe.disco.js +137 -0
  46. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/01_querying_information.xml +6 -0
  47. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/02_result_set_for_information_request.xml +22 -0
  48. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/03_target_entity_does_not_exist.xml +10 -0
  49. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/04_service_unavailable.xml +11 -0
  50. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/09_querying_specific_jid_and_node_combination.xml +7 -0
  51. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/10_jid_and_node_result.xml +12 -0
  52. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/11_requesting_all_items.xml +6 -0
  53. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/12_result_set_for_all_items.xml +23 -0
  54. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/13_empty_result_set.xml +7 -0
  55. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/17_service_returns_nodes.xml +16 -0
  56. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/18_requesting_further_nodes.xml +7 -0
  57. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/24_jid_and_node_error.xml +11 -0
  58. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/DiscoNodeSpec.js +50 -0
  59. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/SpecHelper.js +51 -0
  60. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/Stanzas.js +0 -0
  61. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.helper.js +54 -0
  62. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.js +0 -0
  63. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/support/jasmine.json +13 -0
  64. data/app/assets/javascripts/xmpp/strophejs-plugins/disco/strophe.disco.js +232 -0
  65. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/public/javascript/jquery.epic.js +61 -0
  66. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/SpecHelper.js +9 -0
  67. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/jquery.epic.js +39 -0
  68. data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/support/jasmine.json +22 -0
  69. data/app/assets/javascripts/xmpp/strophejs-plugins/iexdomain/iexdomain.js +36 -0
  70. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/README.markdown +117 -0
  71. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/buster.js +23 -0
  72. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.coffee +64 -0
  73. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.js +92 -0
  74. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/browserSetup.coffee +1 -0
  75. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/jid.spec.coffee +96 -0
  76. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/strophe.joap.spec.coffee +461 -0
  77. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.coffee +304 -0
  78. data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.js +522 -0
  79. data/app/assets/javascripts/xmpp/strophejs-plugins/mam/LICENSE.txt +19 -0
  80. data/app/assets/javascripts/xmpp/strophejs-plugins/mam/README.markdown +52 -0
  81. data/app/assets/javascripts/xmpp/strophejs-plugins/mam/strophe.mam.js +62 -0
  82. data/app/assets/javascripts/xmpp/strophejs-plugins/muc/LICENSE.txt +20 -0
  83. data/app/assets/javascripts/xmpp/strophejs-plugins/muc/strophe.muc.js +1003 -0
  84. data/app/assets/javascripts/xmpp/strophejs-plugins/ping/README.markdown +28 -0
  85. data/app/assets/javascripts/xmpp/strophejs-plugins/ping/strophe.ping.js +68 -0
  86. data/app/assets/javascripts/xmpp/strophejs-plugins/private/README.markdown +16 -0
  87. data/app/assets/javascripts/xmpp/strophejs-plugins/private/strophe.private.js +192 -0
  88. data/app/assets/javascripts/xmpp/strophejs-plugins/pubsub/strophe.pubsub.js +555 -0
  89. data/app/assets/javascripts/xmpp/strophejs-plugins/receipts/strophe.receipts.js +155 -0
  90. data/app/assets/javascripts/xmpp/strophejs-plugins/register/README.markdown +44 -0
  91. data/app/assets/javascripts/xmpp/strophejs-plugins/register/strophe.register.js +431 -0
  92. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/public/javascript/strophe.roster.js +40 -0
  93. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/strophe.roster.spec.js +65 -0
  94. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/support/jasmine.json +15 -0
  95. data/app/assets/javascripts/xmpp/strophejs-plugins/roster/strophe.roster.js +438 -0
  96. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/.gitignore +6 -0
  97. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/README.md +113 -0
  98. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/buster.js +11 -0
  99. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/lib/strophe.js +4198 -0
  100. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.helper.js +38 -0
  101. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.js +262 -0
  102. data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/strophe.rpc.js +464 -0
  103. data/app/assets/javascripts/xmpp/strophejs-plugins/rsm/strophe.rsm.js +52 -0
  104. data/app/assets/javascripts/xmpp/strophejs-plugins/serverdate/strophe.serverdate.js +58 -0
  105. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/index.html +17 -0
  106. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/strophevcard.js +0 -0
  107. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.coffee +44 -0
  108. data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.js +66 -0
  109. data/app/assets/stylesheets/xmpp/index.css +0 -0
  110. data/app/controllers/omniauth_callbacks_controller.rb +15 -0
  111. data/app/controllers/ruby_bosh.rb +221 -0
  112. data/app/models/identity.rb +3 -0
  113. data/app/models/user.rb +40 -0
  114. data/bin/rails +8 -0
  115. data/db/migrate/20140329065635_create_users.rb +10 -0
  116. data/db/migrate/20140329070238_create_identities.rb +11 -0
  117. data/lib/xmppify/version.rb +3 -0
  118. data/lib/xmppify.rb +6 -0
  119. data/xmppify.gemspec +23 -0
  120. metadata +197 -0
@@ -0,0 +1,438 @@
1
+ /*
2
+ Copyright 2010, François de Metz <francois@2metz.fr>
3
+ */
4
+ /**
5
+ * Roster Plugin
6
+ * Allow easily roster management
7
+ *
8
+ * Features
9
+ * * Get roster from server
10
+ * * handle presence
11
+ * * handle roster iq
12
+ * * subscribe/unsubscribe
13
+ * * authorize/unauthorize
14
+ * * roster versioning (xep 237)
15
+ */
16
+ Strophe.addConnectionPlugin('roster',
17
+ {
18
+ _connection: null,
19
+
20
+ _callbacks : [],
21
+ /** Property: items
22
+ * Roster items
23
+ * [
24
+ * {
25
+ * name : "",
26
+ * jid : "",
27
+ * subscription : "",
28
+ * ask : "",
29
+ * groups : ["", ""],
30
+ * resources : {
31
+ * myresource : {
32
+ * show : "",
33
+ * status : "",
34
+ * priority : ""
35
+ * }
36
+ * }
37
+ * }
38
+ * ]
39
+ */
40
+ items : [],
41
+ /** Property: ver
42
+ * current roster revision
43
+ * always null if server doesn't support xep 237
44
+ */
45
+ ver : null,
46
+ /** Function: init
47
+ * Plugin init
48
+ *
49
+ * Parameters:
50
+ * (Strophe.Connection) conn - Strophe connection
51
+ */
52
+ init: function(conn)
53
+ {
54
+ this._connection = conn;
55
+ this.items = [];
56
+ // Override the connect and attach methods to always add presence and roster handlers.
57
+ // They are removed when the connection disconnects, so must be added on connection.
58
+ var oldCallback, roster = this, _connect = conn.connect, _attach = conn.attach;
59
+ var newCallback = function(status)
60
+ {
61
+ if (status == Strophe.Status.ATTACHED || status == Strophe.Status.CONNECTED)
62
+ {
63
+ try
64
+ {
65
+ // Presence subscription
66
+ conn.addHandler(roster._onReceivePresence.bind(roster), null, 'presence', null, null, null);
67
+ conn.addHandler(roster._onReceiveIQ.bind(roster), Strophe.NS.ROSTER, 'iq', "set", null, null);
68
+ }
69
+ catch (e)
70
+ {
71
+ Strophe.error(e);
72
+ }
73
+ }
74
+ if (oldCallback !== null)
75
+ oldCallback.apply(this, arguments);
76
+ };
77
+ conn.connect = function(jid, pass, callback, wait, hold)
78
+ {
79
+ oldCallback = callback;
80
+ if (typeof arguments[0] == "undefined")
81
+ arguments[0] = null;
82
+ if (typeof arguments[1] == "undefined")
83
+ arguments[1] = null;
84
+ arguments[2] = newCallback;
85
+ _connect.apply(conn, arguments);
86
+ };
87
+ conn.attach = function(jid, sid, rid, callback, wait, hold, wind)
88
+ {
89
+ oldCallback = callback;
90
+ if (typeof arguments[0] == "undefined")
91
+ arguments[0] = null;
92
+ if (typeof arguments[1] == "undefined")
93
+ arguments[1] = null;
94
+ if (typeof arguments[2] == "undefined")
95
+ arguments[2] = null;
96
+ arguments[3] = newCallback;
97
+ _attach.apply(conn, arguments);
98
+ };
99
+
100
+ Strophe.addNamespace('ROSTER_VER', 'urn:xmpp:features:rosterver');
101
+ },
102
+ /** Function: supportVersioning
103
+ * return true if roster versioning is enabled on server
104
+ */
105
+ supportVersioning: function()
106
+ {
107
+ return (this._connection.features && this._connection.features.getElementsByTagName('ver').length > 0);
108
+ },
109
+ /** Function: get
110
+ * Get Roster on server
111
+ *
112
+ * Parameters:
113
+ * (Function) userCallback - callback on roster result
114
+ * (String) ver - current rev of roster
115
+ * (only used if roster versioning is enabled)
116
+ * (Array) items - initial items of ver
117
+ * (only used if roster versioning is enabled)
118
+ * In browser context you can use sessionStorage
119
+ * to store your roster in json (JSON.stringify())
120
+ */
121
+ get: function(userCallback, ver, items)
122
+ {
123
+ var attrs = {xmlns: Strophe.NS.ROSTER};
124
+ this.items = [];
125
+ if (this.supportVersioning())
126
+ {
127
+ // empty rev because i want an rev attribute in the result
128
+ attrs.ver = ver || '';
129
+ this.items = items || [];
130
+ }
131
+ var iq = $iq({type: 'get', 'id' : this._connection.getUniqueId('roster')}).c('query', attrs);
132
+ return this._connection.sendIQ(iq,
133
+ this._onReceiveRosterSuccess.bind(this, userCallback),
134
+ this._onReceiveRosterError.bind(this, userCallback));
135
+ },
136
+ /** Function: registerCallback
137
+ * register callback on roster (presence and iq)
138
+ *
139
+ * Parameters:
140
+ * (Function) call_back
141
+ */
142
+ registerCallback: function(call_back)
143
+ {
144
+ this._callbacks.push(call_back);
145
+ },
146
+ /** Function: findItem
147
+ * Find item by JID
148
+ *
149
+ * Parameters:
150
+ * (String) jid
151
+ */
152
+ findItem : function(jid)
153
+ {
154
+ for (var i = 0; i < this.items.length; i++)
155
+ {
156
+ if (this.items[i] && this.items[i].jid == jid)
157
+ {
158
+ return this.items[i];
159
+ }
160
+ }
161
+ return false;
162
+ },
163
+ /** Function: removeItem
164
+ * Remove item by JID
165
+ *
166
+ * Parameters:
167
+ * (String) jid
168
+ */
169
+ removeItem : function(jid)
170
+ {
171
+ for (var i = 0; i < this.items.length; i++)
172
+ {
173
+ if (this.items[i] && this.items[i].jid == jid)
174
+ {
175
+ this.items.splice(i, 1);
176
+ return true;
177
+ }
178
+ }
179
+ return false;
180
+ },
181
+ /** Function: subscribe
182
+ * Subscribe presence
183
+ *
184
+ * Parameters:
185
+ * (String) jid
186
+ * (String) message
187
+ */
188
+ subscribe: function(jid, message)
189
+ {
190
+ var pres = $pres({to: jid, type: "subscribe"});
191
+ if (message && message != "")
192
+ pres.c("status").t(message);
193
+ this._connection.send(pres);
194
+ },
195
+ /** Function: unsubscribe
196
+ * Unsubscribe presence
197
+ *
198
+ * Parameters:
199
+ * (String) jid
200
+ * (String) message
201
+ */
202
+ unsubscribe: function(jid, message)
203
+ {
204
+ var pres = $pres({to: jid, type: "unsubscribe"});
205
+ if (message && message != "")
206
+ pres.c("status").t(message);
207
+ this._connection.send(pres);
208
+ },
209
+ /** Function: authorize
210
+ * Authorize presence subscription
211
+ *
212
+ * Parameters:
213
+ * (String) jid
214
+ * (String) message
215
+ */
216
+ authorize: function(jid, message)
217
+ {
218
+ var pres = $pres({to: jid, type: "subscribed"});
219
+ if (message && message != "")
220
+ pres.c("status").t(message);
221
+ this._connection.send(pres);
222
+ },
223
+ /** Function: unauthorize
224
+ * Unauthorize presence subscription
225
+ *
226
+ * Parameters:
227
+ * (String) jid
228
+ * (String) message
229
+ */
230
+ unauthorize: function(jid, message)
231
+ {
232
+ var pres = $pres({to: jid, type: "unsubscribed"});
233
+ if (message && message != "")
234
+ pres.c("status").t(message);
235
+ this._connection.send(pres);
236
+ },
237
+ /** Function: add
238
+ * Add roster item
239
+ *
240
+ * Parameters:
241
+ * (String) jid - item jid
242
+ * (String) name - name
243
+ * (Array) groups
244
+ * (Function) call_back
245
+ */
246
+ add: function(jid, name, groups, call_back)
247
+ {
248
+ var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: jid,
249
+ name: name});
250
+ for (var i = 0; i < groups.length; i++)
251
+ {
252
+ iq.c('group').t(groups[i]).up();
253
+ }
254
+ this._connection.sendIQ(iq, call_back, call_back);
255
+ },
256
+ /** Function: update
257
+ * Update roster item
258
+ *
259
+ * Parameters:
260
+ * (String) jid - item jid
261
+ * (String) name - name
262
+ * (Array) groups
263
+ * (Function) call_back
264
+ */
265
+ update: function(jid, name, groups, call_back)
266
+ {
267
+ var item = this.findItem(jid);
268
+ if (!item)
269
+ {
270
+ throw "item not found";
271
+ }
272
+ var newName = name || item.name;
273
+ var newGroups = groups || item.groups;
274
+ var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
275
+ name: newName});
276
+ for (var i = 0; i < newGroups.length; i++)
277
+ {
278
+ iq.c('group').t(newGroups[i]).up();
279
+ }
280
+ return this._connection.sendIQ(iq, call_back, call_back);
281
+ },
282
+ /** Function: remove
283
+ * Remove roster item
284
+ *
285
+ * Parameters:
286
+ * (String) jid - item jid
287
+ * (Function) call_back
288
+ */
289
+ remove: function(jid, call_back)
290
+ {
291
+ var item = this.findItem(jid);
292
+ if (!item)
293
+ {
294
+ throw "item not found";
295
+ }
296
+ var iq = $iq({type: 'set'}).c('query', {xmlns: Strophe.NS.ROSTER}).c('item', {jid: item.jid,
297
+ subscription: "remove"});
298
+ this._connection.sendIQ(iq, call_back, call_back);
299
+ },
300
+ /** PrivateFunction: _onReceiveRosterSuccess
301
+ *
302
+ */
303
+ _onReceiveRosterSuccess: function(userCallback, stanza)
304
+ {
305
+ this._updateItems(stanza);
306
+ userCallback(this.items);
307
+ },
308
+ /** PrivateFunction: _onReceiveRosterError
309
+ *
310
+ */
311
+ _onReceiveRosterError: function(userCallback, stanza)
312
+ {
313
+ userCallback(this.items);
314
+ },
315
+ /** PrivateFunction: _onReceivePresence
316
+ * Handle presence
317
+ */
318
+ _onReceivePresence : function(presence)
319
+ {
320
+ // TODO: from is optional
321
+ var jid = presence.getAttribute('from');
322
+ var from = Strophe.getBareJidFromJid(jid);
323
+ var item = this.findItem(from);
324
+ // not in roster
325
+ if (!item)
326
+ {
327
+ return true;
328
+ }
329
+ var type = presence.getAttribute('type');
330
+ if (type == 'unavailable')
331
+ {
332
+ delete item.resources[Strophe.getResourceFromJid(jid)];
333
+ }
334
+ else if (!type)
335
+ {
336
+ // TODO: add timestamp
337
+ item.resources[Strophe.getResourceFromJid(jid)] = {
338
+ show : (presence.getElementsByTagName('show').length != 0) ? Strophe.getText(presence.getElementsByTagName('show')[0]) : "",
339
+ status : (presence.getElementsByTagName('status').length != 0) ? Strophe.getText(presence.getElementsByTagName('status')[0]) : "",
340
+ priority : (presence.getElementsByTagName('priority').length != 0) ? Strophe.getText(presence.getElementsByTagName('priority')[0]) : ""
341
+ };
342
+ }
343
+ else
344
+ {
345
+ // Stanza is not a presence notification. (It's probably a subscription type stanza.)
346
+ return true;
347
+ }
348
+ this._call_backs(this.items, item);
349
+ return true;
350
+ },
351
+ /** PrivateFunction: _call_backs
352
+ *
353
+ */
354
+ _call_backs : function(items, item)
355
+ {
356
+ for (var i = 0; i < this._callbacks.length; i++) // [].forEach my love ...
357
+ {
358
+ this._callbacks[i](items, item);
359
+ }
360
+ },
361
+ /** PrivateFunction: _onReceiveIQ
362
+ * Handle roster push.
363
+ */
364
+ _onReceiveIQ : function(iq)
365
+ {
366
+ var id = iq.getAttribute('id');
367
+ var from = iq.getAttribute('from');
368
+ // Receiving client MUST ignore stanza unless it has no from or from = user's JID.
369
+ if (from && from != "" && from != this._connection.jid && from != Strophe.getBareJidFromJid(this._connection.jid))
370
+ return true;
371
+ var iqresult = $iq({type: 'result', id: id, from: this._connection.jid});
372
+ this._connection.send(iqresult);
373
+ this._updateItems(iq);
374
+ return true;
375
+ },
376
+ /** PrivateFunction: _updateItems
377
+ * Update items from iq
378
+ */
379
+ _updateItems : function(iq)
380
+ {
381
+ var query = iq.getElementsByTagName('query');
382
+ if (query.length != 0)
383
+ {
384
+ this.ver = query.item(0).getAttribute('ver');
385
+ var self = this;
386
+ Strophe.forEachChild(query.item(0), 'item',
387
+ function (item)
388
+ {
389
+ self._updateItem(item);
390
+ }
391
+ );
392
+ }
393
+ this._call_backs(this.items);
394
+ },
395
+ /** PrivateFunction: _updateItem
396
+ * Update internal representation of roster item
397
+ */
398
+ _updateItem : function(item)
399
+ {
400
+ var jid = item.getAttribute("jid");
401
+ var name = item.getAttribute("name");
402
+ var subscription = item.getAttribute("subscription");
403
+ var ask = item.getAttribute("ask");
404
+ var groups = [];
405
+ Strophe.forEachChild(item, 'group',
406
+ function(group)
407
+ {
408
+ groups.push(Strophe.getText(group));
409
+ }
410
+ );
411
+
412
+ if (subscription == "remove")
413
+ {
414
+ this.removeItem(jid);
415
+ return;
416
+ }
417
+
418
+ var item = this.findItem(jid);
419
+ if (!item)
420
+ {
421
+ this.items.push({
422
+ name : name,
423
+ jid : jid,
424
+ subscription : subscription,
425
+ ask : ask,
426
+ groups : groups,
427
+ resources : {}
428
+ });
429
+ }
430
+ else
431
+ {
432
+ item.name = name;
433
+ item.subscription = subscription;
434
+ item.ask = ask;
435
+ item.groups = groups;
436
+ }
437
+ }
438
+ });
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+
3
+ .monitor
4
+
5
+ node_modules
6
+ npm-debug.log
@@ -0,0 +1,113 @@
1
+ # Jabber-RPC Module
2
+
3
+ A strophe plugin for Jabber-RPC extension ([XEP-0009](http://xmpp.org/extensions/xep-0009.html)).
4
+
5
+ See the XEP abstract :
6
+
7
+ > This specification defines an XMPP protocol extension for transporting XML-RPC encoded requests and responses between two XMPP entities. The protocol supports all syntax and semantics of XML-RPC except that it uses XMPP instead of HTTP as the underlying transport.
8
+
9
+ This plugin does not aim at managing your flow of RPC. It is a simple helper to send and handle remote requests between two XMPP nodes.
10
+
11
+ ## Usage
12
+
13
+ Just link the rpc plugin below the strophe library in your HTML head section:
14
+
15
+ ``` html
16
+ <head>
17
+ <!-- ... -->
18
+ <script type="text/javascript" src="strophe.min.js"></script>
19
+ <script type="text/javascript" src="strophe.rpc.js"></script>
20
+ <!-- ... -->
21
+ </head>
22
+ ```
23
+
24
+ It's preferable to also use the service discovery plugin to respond correctly to `disco#info` requests. You can [download it](https://github.com/metajack/strophejs-plugins/tree/master/disco) and add it as follow :
25
+
26
+ ``` html
27
+ <head>
28
+ <!-- ... -->
29
+ <script type="text/javascript" src="strophe.min.js"></script>
30
+ <script type="text/javascript" src="strophe.disco.js"></script>
31
+ <script type="text/javascript" src="strophe.rpc.js"></script>
32
+ <!-- ... -->
33
+ </head>
34
+ ```
35
+
36
+ ## API
37
+
38
+ The plugin prototype is accessible from the `connection.rpc` variable
39
+
40
+ ### Send an RPC
41
+
42
+ There are four functions to send RPC :
43
+
44
+ - `sendRequest(id, to, method, params)`
45
+ - `method` is the string name of the method to call
46
+ - `params` is an array of parameters to send
47
+ - `sendResponse(id, to, result)`
48
+ - `result` is the object to send as the result of the request
49
+ - `sendError(id, to, code, message)`
50
+ - `code` is the number of the error
51
+ - `message` is the message describing the error
52
+ - `sendXMLElement(id, to, xml)`
53
+ - `xml` is the XML Element that will be sent (whether it is properly formed or not)
54
+
55
+ The parameters `id` and `to` are respectively the id of the request and the the jid of the recipient.
56
+
57
+ ### Handle incoming RPCs
58
+
59
+ It is possible to handle incoming RPCs using the functions :
60
+
61
+ - `addRequestHandler`
62
+ - `addResponseHandler`
63
+ - `addXMLHandler`
64
+
65
+ The handlers you pass to these functions take different parameters :
66
+
67
+ ```javascript
68
+ var responseHandler = function(id, from, result, error) {
69
+ // error is a boolean
70
+ // it is true if the response was an error message
71
+ if (error === true) { ... }
72
+ else { ... }
73
+ }
74
+ connection.rpc.addResponseHandler(responseHandler);
75
+
76
+ var requestHandler = function(id, from, method, parameters) { ... }
77
+ connection.rpc.addRequestHandler(requestHandler);
78
+
79
+ var xmlHandler = function(xml) { ... }
80
+ connection.rpc.addXMLHandler(xmlHandler)
81
+ ```
82
+
83
+ Note that the parser of this module won't throw any exception. However `result`, `method` and `parameters` will be set as `null` if the incoming message is not XML-RPC compliant.
84
+
85
+ ### Whitelist
86
+
87
+ By default, this plugin will accept RPC from everyone. However, it is possible to use a whitelist of JID to filter incoming RPCs.
88
+
89
+ Use the function `addJidToWhiteList` to accept JIDs. Note that it is possible to use a wildcard for the node or the domain.
90
+
91
+ Examples :
92
+
93
+ ```javascript
94
+ connection.rpc.addJidToWhiteList("me@jabber.org");
95
+ connection.rpc.addJidToWhiteList(["*@jabber.org", "me@*"]);
96
+ connection.rpc.addJidToWhiteList("*@*");
97
+ ```
98
+
99
+ ## Tests & specs
100
+
101
+ I use the node module `buster` for the tests. Install it and use it as follow :
102
+
103
+ ```bash
104
+ $ npm install buster
105
+ $ buster server
106
+ ```
107
+
108
+ Open a browser and navigate to `http://localhost:1111` and capture the browser.
109
+ Then you can run the tests:
110
+
111
+ ```
112
+ $ buster test --browser
113
+ ```
@@ -0,0 +1,11 @@
1
+ var config = module.exports;
2
+
3
+ config["rpc"] = {
4
+ environment: "browser",
5
+ specs: ["spec/*.spec.js"],
6
+ sources: ["strophe.rpc.js"],
7
+ libs: [
8
+ "lib/strophe.js",
9
+ "spec/strophe.rpc.spec.helper.js"
10
+ ]
11
+ };