Does subscribed stanza trigger a callback? - strophe

Is there a way to get a callback from a subscribed type stanza ? There's an XML response from server but Strophe does not trigger any callback.
This is what I'm sending:
<body rid='576795248' xmlns='http://jabber.org/protocol/httpbind' sid='e3552b8d'><presence to='user2#localhost' type='subscribed' xmlns='jabber:client' id='2:sendIQ'/></body>
And I'm getting:
<body xmlns='http://jabber.org/protocol/httpbind'><iq xmlns="jabber:client" type="set" id="842-543" to="user1#localhost"><query xmlns="jabber:iq:roster"><item jid="test2#localhost" subscription="both"/></query></iq></body>
As you can see, the server is correctly sending a response, but Strophe does not trigger any callback.
Thanks.

add a handler: addHandler(func, Strophe.NS.ROSTER, 'iq')

Related

How to get MAM message ID of sent messages?

I am using eJabberd server (MAM enabled) with client library Strophe.js. Client app is storing fixed amount of the messages in local storage.
All the messages, that I receive from the server include elements <archived/> and <stanza-id/>, which provide server-side generated IDs:
<message
xmlns="jabber:client" to="aaa#example.net/8667085700924567016834" from="aaa#example.net">
<result
xmlns="urn:xmpp:mam:2" id="1520510373346685">
<forwarded
xmlns="urn:xmpp:forward:0">
<message
xmlns="jabber:client" xml:lang="en" to="bbb#example.net" from="aaa#example.net/60965696931000870402419" type="chat">
<archived
xmlns="urn:xmpp:mam:tmp" by="aaa#example.net" id="1520510373346685"/>
<stanza-id
xmlns="urn:xmpp:sid:0" by="aaa#example.net" id="1520510373346685"/>
<body>asdf</body>
</message>
<delay
xmlns="urn:xmpp:delay" from="example.net" stamp="2018-03-08T11:59:33.346685Z"/>
</forwarded>
</result>
</message>
I use these IDs to get fixed amount of messages on each MAM call (using RSM paging - before/after/max attributes). For example:
params = {
"before": "1520510373346685",
"max": 10,
onMessage: <some handler>,
onComplete: <some handler>,
}
this.connection.mam.query(Strophe.getBareJidFromJid(this.myJid), params);
This gets me 10 messages before the message with stanza-id 1520510373346685.
However, the messages I send inherently do not have this ID, until I send them and retrieve from MAM.
I did not find any examples on getting the currently sent message ID from the server, and the Strophe does not provide any callbacks after the message was sent from the client and received by the server.
So, the question - is there any way to get the server-generated message ID (stanza-id/archived) for the currently sent message?
Maybe my own approach is wrong - should I generate my own IDs and add it to each message from the client?
There is currently no mechanism specified besides querying the archive. One prominent idea within the XMPP community to solve this in the future is to reflect the send carbon back to the original sender, which would include a stanza-id element with the ID assigned by the archive.

Openfire returns error 500 when retrieving privacy lists

I'm using converse.js and trying to work with privacy lists. I'm trying to send this IQ:
<body rid="2993056535" xmlns="http://jabber.org/protocol/httpbind" sid="578oe88nm1">
<iq from="alex3#ofb2" type="set" id="active1" xmlns="jabber:client">
<query xmlns="jabber:iq:privacy"/>
</iq>
</body>
This is what server returns me:
<body xmlns="http://jabber.org/protocol/httpbind" ack="2993056535">
<iq xmlns="jabber:client" type="error" id="active1" to="alex3#ofb2/converse.js-90734653">
<query xmlns="jabber:iq:privacy"/>
<error code="500" type="wait">
<internal-server-error xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
</error>
</iq>
</body>
In the server logs I see this exception:
2016.02.19 12:49:00 org.jivesoftware.openfire.handler.IQHandler - Internal server error
java.lang.NullPointerException
at org.jivesoftware.openfire.handler.IQPrivacyHandler.handleIQ(IQPrivacyHandler.java:120)
at org.jivesoftware.openfire.handler.IQHandler.process(IQHandler.java:66)
at org.jivesoftware.openfire.IQRouter.handle(IQRouter.java:372)
at org.jivesoftware.openfire.IQRouter.route(IQRouter.java:115)
at org.jivesoftware.openfire.spi.PacketRouterImpl.route(PacketRouterImpl.java:78)
at org.jivesoftware.openfire.SessionPacketRouter.route(SessionPacketRouter.java:108)
at org.jivesoftware.openfire.SessionPacketRouter.route(SessionPacketRouter.java:67)
at org.jivesoftware.openfire.http.HttpSession.sendPendingPackets(HttpSession.java:639)
at org.jivesoftware.openfire.http.HttpSession$HttpPacketSender.run(HttpSession.java:1270)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
What's wrong?
The stacktrace points to these lines:
// Privacy list handling (create/edit/delete)
Element list = child.element("list");
String listName = list.attributeValue("name");
That is, it looks for a child element <list>, and crashes when it can't find it.
So why does it look for that? It turns out that this is the branch it takes if the IQ has type set (and neither a <default> nor <active> child element). However, as described in XEP-0016, to get the names of existing privacy lists you need to send an IQ with type get instead. Your request should look like this instead:
<iq from='romeo#example.net/orchard' type='get' id='getlist1'>
<query xmlns='jabber:iq:privacy'/>
</iq>

candy/strophe -- using prebind (.attach) results in tight idle loop?

I'm using Candy.js (v1.7.1) and Openfire v3.9.3. Running the sample index.html included in the Candy package, I have no issues using direct authentication (browser prompts for jid/pwd). However, if I change the sample to use Candy.Core.attach (nearly a pass-thru to Strophe.Connection.attach) after performing a server side prebind (uisng MatriX), I seem to get stuck in some sort of idle loop that blasts empty messages to the XMPP server 3x a second.
Any ideas what is causing this looping and why the demo Candy UI doesn't appear when I use Candy.Core.attach?
Modified sample...
$(document).ready(function() {
var httpbindUrl = 'http://xmpp.mydomain.net:7070/http-bind/';
var chatRoom = 'testroom#conference.mydomain.net';
// These values come from a REST call to our services that perform
// the prebind authentication (using MatriX, obviously)
var jid = 'someuser#mydomain.net/MatriX';
var sid = 'b95ffa4'; // must be a string despite what candy's doc say
var rid = 1983626985;
Candy.init(httpbindUrl, {
core: {
debug: true,
autojoin: [chatRoom]
},
view: { assets: './res/' }
});
Candy.Core.attach(jid, sid, rid); // this seems to cause some sort of looping to occur
// Candy.Core.connect('someuser#mydomain.net', 'password'); // <-- this works as expected
});
The browser's console log displays...
POST http://xmpp.mydomain.net:7070/http-bind/ [HTTP/1.1 200 OK 895ms]
POST http://xmpp.mydomain.net:7070/http-bind/ [HTTP/1.1 200 OK 491ms]
POST http://xmpp.mydomain.net:7070/http-bind/ [HTTP/1.1 200 OK 483ms]
"RECV: <body xmlns='http://jabber.org/protocol/httpbind' ack='1983626985'/>" candy.bundle.js:159
"LIBS:<1>: no requests during idle cycle, sending blank request" libs.bundle.js:1192
"LIBS:<0>: request id 4.0 posting" libs.bundle.js:1192
"LIBS:<0>: request id 4.0 state changed to 1" libs.bundle.js:1192
"SENT: <body rid='1983626986' xmlns='http://jabber.org/protocol/httpbind' sid='b95ffa4'/>" candy.bundle.js:159
POST http://xmpp.mydomain.net:7070/http-bind/ [HTTP/1.1 200 OK 436ms]
"LIBS:<0>: request id 4.1 state changed to 2" libs.bundle.js:1192
"LIBS:<0>: request id 4.1 state changed to 3" libs.bundle.js:1192
"LIBS:<0>: request id 4.1 state changed to 4" libs.bundle.js:1192
"LIBS:<0>: removing request" libs.bundle.js:1192
"LIBS:<0>: _throttledRequestHandler called with 0 requests" libs.bundle.js:1192
"LIBS:<0>: request id 4 should now be removed" libs.bundle.js:1192
"LIBS:<0>: request id 4.1 got 200" libs.bundle.js:1192
"LIBS:<1>: _dataRecv called" libs.bundle.js:1192
"RECV: <body xmlns='http://jabber.org/protocol/httpbind' ack='1983626986'/>" candy.bundle.js:159
"LIBS:<1>: no requests during idle cycle, sending blank request" libs.bundle.js:1192
"LIBS:<0>: request id 5.0 posting" libs.bundle.js:1192
"LIBS:<0>: request id 5.0 state changed to 1" libs.bundle.js:1192
"SENT: <body rid='1983626987' xmlns='http://jabber.org/protocol/httpbind' sid='b95ffa4'/>" candy.bundle.js:159
...continues in a similar pattern until I close the browser window.
NOTE: Entries prepended with "LIBS:" are from strophe's low-level logging (level, msg). It should also be noted that the candy demo wraps strophe.js into a larger bundle called libs.bundle.js.
Normally when you connect to a BOSH connection manager you have the ability to set the wait attribute on your first stanza (session creation request).
XEP-0124 Session Creation Response
Default value used by Strophe and Candy is 60. Can you confirm the value which MatriX is using when establishing your BOSH session?
Ex:
<body content='text/xml; charset=utf-8'
from='user#example.com'
hold='1'
rid='1573741820'
to='example.com'
route='xmpp:example.com:9999'
wait='60'
xml:lang='en'
xmpp:version='1.0'
xmlns='http://jabber.org/protocol/httpbind'
xmlns:xmpp='urn:xmpp:xbosh'/>
It seems Openfire v3.9.3 BOSH implementation is 'quirky'. MatriX developers were able to work around the issue. As of MatriX v1.6.0.1 the scenario is resolved.

xml-not-well-formed error in when I try to bind resource in XMPP over Bosh

1 Problem: I am getting xml not well formed error, when I try to bind resource in XMPP over Bosh.
What I tried: I went to xmpp.org to look for proper xml stanza for binding resource(http://xmpp.org/extensions/xep-0206.html#preconditions-sasl), but it seems similar.
Possible answer: I havn't restarted the stream after authentication, can that be the cause of this error?
2 problem: I tried to restart the stream by using the packet(http://xmpp.org/extensions/xep-0206.html#preconditions-sasl) but I got 400 in response code? Any body has any idea why I got that?
Possible answer: I didn't get xmpp:restartLogic attribute in response to initial packet? Can that be the reason for getting 400 error(May be Ejabbered server doesn't support restart)?
Doubt: Anyone got any idea on how to enable restartlogic in Ejabberd or is it enabled by default?
My Log is as follow:
Stanza to read is = body xmlns='http://jabber.org/protocol/httpbind' sid='8d96d01bb87f526e78b0f0b620dd1c94edd172ee' wait='30' requests='2' inactivity='30' maxpause='120' polling='2' ver='1.8' from='someserver.com' secure='true' authid='2817580747' xmlns:xmpp='urn:xmpp:xbosh' xmlns:stream='http://etherx.jabber.org/streams' xmpp:version='1.0'
Stanza to read is = stream:features xmlns:stream='http://etherx.jabber.org/streams'
Stanza to read is = mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'
Stanza to read is = mechanism
Stanza to read is = c xmlns='http://jabber.org/protocol/caps' hash='sha-1' node='http://www.process-one.net/en/ejabberd/' ver='U5DC02T7iwEqfov5b3KpIVgA5+I='/
Stanza to read is = register xmlns='http://jabber.org/features/iq-register'/
Session creation response received: body secure=true requests=2 inactivity=30 authid=2817580747 sid=8d96d01bb87f526e78b0f0b620dd1c94edd172ee polling=2 xmlns=http://jabber.org/protocol/httpbind wait=30 xmpp=urn:xmpp:xbosh ver=1.8 version=1.0 from=someserver.com stream=http://etherx.jabber.org/streams maxpause=120 ==
features stream=http://etherx.jabber.org/streams ==
mechanisms xmlns=urn:ietf:params:xml:ns:xmpp-sasl ==
mechanism == PLAIN
mechanism == DIGEST-MD5
mechanism == SCRAM-SHA-1
c ver=U5DC02T7iwEqfov5b3KpIVgA5+I= node=http://www.process-one.net/en/ejabberd/ hash=sha-1 xmlns=http://jabber.org/protocol/caps ==
register xmlns=http://jabber.org/features/iq-register ==
Authenticating: body secure=true requests=2 inactivity=30 authid=2817580747 sid=8d96d01bb87f526e78b0f0b620dd1c94edd172ee polling=2 xmlns=http://jabber.org/protocol/httpbind wait=30 xmpp=urn:xmpp:xbosh ver=1.8 version=1.0 from=someserver.com stream=http://etherx.jabber.org/streams maxpause=120 ==
features stream=http://etherx.jabber.org/streams ==
mechanisms xmlns=urn:ietf:params:xml:ns:xmpp-sasl ==
mechanism == PLAIN
mechanism == DIGEST-MD5
mechanism == SCRAM-SHA-1
c ver=U5DC02T7iwEqfov5b3KpIVgA5+I= node=http://www.process-one.net/en/ejabberd/ hash=sha-1 xmlns=http://jabber.org/protocol/caps ==
register xmlns=http://jabber.org/features/iq-register ==
Using plain authorization
writtenToAir [0]: AE1haGlAdGVzdC5yYXBpZHNvZnR0ZWNobm9sb2d5LmNvbQBtYWhp
Starting PLAIN authorization
Stanza to read is = body xmlns='http://jabber.org/protocol/httpbind'
Stanza to read is = success xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/
writtenToAir [0]: Resource
Binding resource
Stanza to read is = body type='terminate' condition='remote-stream-error' xmlns='http://jabber.org/protocol/httpbind' xmlns:stream='http://etherx.jabber.org/streams'
Stanza to read is = stream:error
Stanza to read is = xml-not-well-formed xmlns='urn:ietf:params:xml:ns:xmpp-streams'/

Openfire prebind + robbiehanson/XMPPFramework using BOSH not working

We're trying to implement XMPP over BOSH for our product. The Strophe.js javascript library works fine for our needs on the WWW site. We request a prebind, it's delivered and then we use Strophe's 'attach' method to start our session - then we're able to update presence and send/receive messages. On the iOS side of things, we're using the robbiehanson XMPPFramework which includes a BOSH transport, but there's no attach method. Below is some of my grief with trying to get this to work.
I prebind, get my sid/jid/rid, then set the internal logic inside the bosh transport and other files to say that we're already connected. Then if I try to update presence, including the given SID, I send:
BOSH: SEND[1248340729] = < body xmlns="http://jabber.org/protocol/httpbind" sid="568a3ae9" ack="1248340728" rid="1248340729">< presence>< /presence>< /body>
but don't get any reply atall. That's the last of it. If I try to update presence without specifying SID, I send:
BOSH: SEND[1064338700] = < body xmlns="http://jabber.org/protocol/httpbind" ack="1064338699" rid="1064338700">< presence>< /presence>< /body>
and get back:
BOSH: RECD[1342811427] = < body xmlns="http://jabber.org/protocol/httpbind" xmlns:stream="http://etherx.jabber.org/streams" authid="9ef0ccdb" sid="9ef0ccdb" secure="true" requests="2" inactivity="300" polling="5" wait="60">< stream:features>< mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"> < mechanism>PLAIN< /mechanism>< /mechanisms>< compression xmlns="http://jabber.org/features/compress">< method>zlib< /method>< /compression>< bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/>< session xmlns="urn:ietf:params:xml:ns:xmpp-session"/>< /stream:features>< /body>
which looks like a connection affirmation, or a connection challenge stanza expecting me to respond with the PLAIN information - but this has already been established with the prebind. If it is a connection affirmation, then the next lines don't make sense. If using the SID provided by the connection string above, as if it's an affirmation (I'm not sure), these are the next lines:
BOSH: SEND[1342811427] = < body xmlns="http://jabber.org/protocol/httpbind" sid="9ef0ccdb" rid="1342811428">< iq type="set">< bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">< resource>api< /resource>< /bind>< /iq>< /body>
BOSH: RECD[1342811427] = < body xmlns='http://jabber.org/protocol/httpbind'>< iq xmlns="jabber:client" type="error" to="chat.*.com/9ef0ccdb">< bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">< resource>api< /resource>< /bind>< error code="401" type="auth">< not-authorized xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>< /error>< /iq>< /body>
I'm not authorized. Now if I try using the SID that was negotiated during prebind, the last two lines are different:
BOSH: SEND[1172064714] = < body xmlns="http://jabber.org/protocol/httpbind" sid="27e3745b" rid="1172064715">< iq type="set">< resource>api< /resource>< /bind>< /iq>< /body>
BOSH: RECD[1172064714] = < body xmlns="http://jabber.org/protocol/httpbind">< /body>
an empty response. Then if I try updating my presence again, it gives me a literal 404 page saying there's an invalid SID. When I was using the SID provided by openfire, if I re-tried the presence update, it would just keep on giving me 401 not authorized.
Any help would be greatly appreciated.