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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/xmpp/index.js +0 -0
- data/app/assets/javascripts/xmpp/scripts/checkplayer.js +12 -0
- data/app/assets/javascripts/xmpp/scripts/crossdomain.xml +7 -0
- data/app/assets/javascripts/xmpp/scripts/flXHR.js +2 -0
- data/app/assets/javascripts/xmpp/scripts/flXHR.swf +0 -0
- data/app/assets/javascripts/xmpp/scripts/flXHR.vbs +44 -0
- data/app/assets/javascripts/xmpp/scripts/flensed.js +12 -0
- data/app/assets/javascripts/xmpp/scripts/strophe.flxhr.js +31 -0
- data/app/assets/javascripts/xmpp/scripts/strophe.js +3538 -0
- data/app/assets/javascripts/xmpp/scripts/swfobject.js +5 -0
- data/app/assets/javascripts/xmpp/scripts/updateplayer.swf +0 -0
- data/app/assets/javascripts/xmpp/scripts/xmpp.js.coffee +386 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/LICENSE.txt +19 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/README.markdown +95 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/archive/README.markdown +14 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/archive/iso8601_support.js +32 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/archive/strophe.archive.js +88 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/README.markdown +53 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/sha1.js +202 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.coffee +153 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.CAPS.js +88 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/caps/strophe.caps.jsonly.js +240 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/chatstates/strophe.chatstates.js +80 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/README.markdown +47 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/GetUrlComamndSpec.js +66 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/strophe.cmds.spec.coffee +145 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/spec/support/jasmine.json +16 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.coffee +265 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/cmds/src/strophe.cmds.js +403 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/README.markdown +82 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/spec/strophe.x.coffee +715 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.coffee +443 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/dataforms/src/strophe.x.js +854 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/.gitignore +1 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/README.markdown +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/convert.js +13 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/jasmine.json +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/lib/strophe.disco.js +137 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/public/javascript/strophe.disco.js +137 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/01_querying_information.xml +6 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/02_result_set_for_information_request.xml +22 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/03_target_entity_does_not_exist.xml +10 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/04_service_unavailable.xml +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/09_querying_specific_jid_and_node_combination.xml +7 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/10_jid_and_node_result.xml +12 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/11_requesting_all_items.xml +6 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/12_result_set_for_all_items.xml +23 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/13_empty_result_set.xml +7 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/17_service_returns_nodes.xml +16 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/18_requesting_further_nodes.xml +7 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/24_jid_and_node_error.xml +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/DiscoNodeSpec.js +50 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/SpecHelper.js +51 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/Stanzas.js +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.helper.js +54 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/strophe.disco.spec.js +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/spec/support/jasmine.json +13 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/disco/strophe.disco.js +232 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/public/javascript/jquery.epic.js +61 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/SpecHelper.js +9 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/jquery.epic.js +39 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/epic/spec/support/jasmine.json +22 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/iexdomain/iexdomain.js +36 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/README.markdown +117 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/buster.js +23 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.coffee +64 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/jid.js +92 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/browserSetup.coffee +1 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/jid.spec.coffee +96 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/spec/strophe.joap.spec.coffee +461 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.coffee +304 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/joap/strophe.joap.js +522 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/mam/LICENSE.txt +19 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/mam/README.markdown +52 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/mam/strophe.mam.js +62 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/muc/LICENSE.txt +20 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/muc/strophe.muc.js +1003 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/ping/README.markdown +28 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/ping/strophe.ping.js +68 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/private/README.markdown +16 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/private/strophe.private.js +192 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/pubsub/strophe.pubsub.js +555 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/receipts/strophe.receipts.js +155 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/register/README.markdown +44 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/register/strophe.register.js +431 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/public/javascript/strophe.roster.js +40 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/strophe.roster.spec.js +65 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/spec/support/jasmine.json +15 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/roster/strophe.roster.js +438 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/.gitignore +6 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/README.md +113 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/buster.js +11 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/lib/strophe.js +4198 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.helper.js +38 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/spec/strophe.rpc.spec.js +262 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rpc/strophe.rpc.js +464 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/rsm/strophe.rsm.js +52 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/serverdate/strophe.serverdate.js +58 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/index.html +17 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/examples/strophevcard.js +0 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.coffee +44 -0
- data/app/assets/javascripts/xmpp/strophejs-plugins/vcard/strophe.vcard.js +66 -0
- data/app/assets/stylesheets/xmpp/index.css +0 -0
- data/app/controllers/omniauth_callbacks_controller.rb +15 -0
- data/app/controllers/ruby_bosh.rb +221 -0
- data/app/models/identity.rb +3 -0
- data/app/models/user.rb +40 -0
- data/bin/rails +8 -0
- data/db/migrate/20140329065635_create_users.rb +10 -0
- data/db/migrate/20140329070238_create_identities.rb +11 -0
- data/lib/xmppify/version.rb +3 -0
- data/lib/xmppify.rb +6 -0
- data/xmppify.gemspec +23 -0
- 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,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
|
+
```
|