ejabberd BOSH search brings nothing - xmpp

We're trying to switch from Openfire to ejabberd XMPP server.
I have ejabberd installed with default options on my local Windows 10 workstation.
I set
mod_vcard:
search: true
I registered a couple of users using ejabberd ReST API. I also set some vcard values for those users (my understanding is that vcard entries are necessary for ejabberd search to work, correct?)
Using Postman, I can confirm that there are vcards for user "testfouoles":
POST http://localhost:5281/api/get_vcard
Body:
{
"host": "planetrisk.com",
"user": "testfouoles",
"name": "FN"
}
Response:
{
"content": "Test UnclassifiedFouoLes"
}
Besides FN, EMAIL, NICKNAME, and NICK vcards are set. vcards seems to be case-sensitive, so I set both small lettters and capital letters variants, because I'm not sure which variants are used by search. I also set vcard2 values for N FAMILY and N GIVEN.
For Openfire, we were using CandyJs with a custom Search plugin. For now we continue to use it with ejabberd.
For test purposes, I set
mod_vcard:
search: true
allow_return_all: true
This way, search operations with empty input fields return all users who added some information to their vCard (according to ejabberd docs).
Our CandyJS Search plugin issues the following POST request to ejabberd BOSH listener:
Request URL:http://localhost:5443/bosh?b=101
Request Method:POST
Status Code:200 OK
Remote Address:127.0.0.1:5443
...
Request Payload
<body rid='55271928' xmlns='http://jabber.org/protocol/httpbind' sid='5633a7a6184041b173970798227fddadea5e8742'>
<iq type='set' id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x xmlns='jabber:x:data' type='submit'>
<field var='first'><value/></field>
<field var='last'><value/></field>
<field var='nick'><value/></field>
<field var='email'><value/></field>
<field var='fn'><value/></field>
</x>
</query>
</iq>
</body>
And ejabberd responds with vcard data of the only registered user (besides the requesting user):
<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xml:lang='en' to='army.dudeFOUO(at)everbridge.mil#planetrisk.com/planetrisk_Candy_b4a02de8' from='vjud.planetrisk.com' type='result' id='search2' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x type='result' xmlns='jabber:x:data'>
<title>Search Results for vjud.planetrisk.com</title>
<reported>
<field var='jid' type='text-single' label='Jabber ID'/>
<field var='fn' type='text-single' label='Full Name'/>
<field var='first' type='text-single' label='Name'/>
<field var='middle' type='text-single' label='Middle Name'/>
<field var='last' type='text-single' label='Family Name'/>
<field var='nick' type='text-single' label='Nickname'/>
<field var='bday' type='text-single' label='Birthday'/>
<field var='ctry' type='text-single' label='Country'/>
<field var='locality' type='text-single' label='City'/>
<field var='email' type='text-single' label='Email'/>
<field var='orgname' type='text-single' label='Organization Name'/>
<field var='orgunit' type='text-single' label='Organization Unit'/>
</reported>
<item>
<field var='jid'><value>testfouoles#planetrisk.com</value></field>
<field var='fn'><value>Test UnclassifiedFouoLes</value></field>
<field var='last'><value>UnclassifiedFouoLes</value></field>
<field var='first'><value>Test</value></field>
<field var='middle'><value/></field>
<field var='nick'><value>testfouoles</value></field>
<field var='bday'><value/></field>
<field var='ctry'><value/></field>
<field var='locality'><value/></field>
<field var='email'><value>testfouoles#planetrisk.com</value></field>
<field var='orgname'><value/></field>
<field var='orgunit'><value/></field>
</item>
</x>
</query>
</iq>
</body>
Everything works fine so far. Now, if I submit a search request with non-empty search criteria, regardless of having allow_return_all: true or false, search does not find anything:
Request Payload
<body rid='839156118' xmlns='http://jabber.org/protocol/httpbind' sid='39d0d2e120960757f97eeb15488ba6820b509bf7'>
<iq type='set' id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x xmlns='jabber:x:data' type='submit'>
<field var='first'><value>UnclassifiedFouoLes</value></field>
<field var='last'><value>UnclassifiedFouoLes</value></field>
<field var='nick'><value>UnclassifiedFouoLes</value></field>
<field var='email'><value>UnclassifiedFouoLes</value></field>
<field var='fn'><value>UnclassifiedFouoLes</value></field>
</x>
</query>
</iq>
</body>
Here I tried to search for "UnclassifiedFouoLes" which is the correct value of N FAMILY. I tried to search for correct email, nick, etc - nothing works. ejabberd returns an empty result.
<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xml:lang='en' to='army.dudeFOUO(at)everbridge.mil#planetrisk.com/planetrisk_Candy_0d46391c' from='vjud.planetrisk.com' type='result' id='search2' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x type='result' xmlns='jabber:x:data'>
<title>Search Results for vjud.planetrisk.com</title>
<reported>
<field var='jid' type='text-single' label='Jabber ID'/>
<field var='fn' type='text-single' label='Full Name'/>
<field var='first' type='text-single' label='Name'/>
<field var='middle' type='text-single' label='Middle Name'/>
<field var='last' type='text-single' label='Family Name'/>
<field var='nick' type='text-single' label='Nickname'/>
<field var='bday' type='text-single' label='Birthday'/>
<field var='ctry' type='text-single' label='Country'/>
<field var='locality' type='text-single' label='City'/>
<field var='email' type='text-single' label='Email'/>
<field var='orgname' type='text-single' label='Organization Name'/>
<field var='orgunit' type='text-single' label='Organization Unit'/>
</reported>
</x>
</query>
</iq>
</body>
So, why doesn't ejabberd find users by correctly supplied (?) search terms which matches vcard values? What am I doing wrong?
I'm stuck. I cannot find any additional ejabberd documentation on Jabber Search. I don't understand how standard vcard field names correspond to standard Jabber Search field names (or maybe Data Forms field names?).
The same CandyJS Search plugin issues very similar request to Openfire XMPP server and gets results. The only difference is that Openfire requires some non-standard additions to search request payload to specify in which fields to search in:
<field var='Username'><value>1</value></field>
<field var='Name'><value>1</value></field>
<field var='Email'><value>1</value></field>
And Openfire returns results with an additional
<field var="FORM_TYPE" type="hidden"/>
clause. Does it give any clue?
I'm stuck and really appreciate pointing me to the right direction.
Update:
Actually, here is the first question:
When we send the following search request to XMPP server
<body rid='839156118' xmlns='http://jabber.org/protocol/httpbind'
sid='39d0d2e120960757f97eeb15488ba6820b509bf7'>
<iq type='set'id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x xmlns='jabber:x:data' type='submit'>
<field var='first'><value>UnclassifiedFouoLes</value></field>
<field var='last'><value>UnclassifiedFouoLes</value></field>
<field var='nick'><value>UnclassifiedFouoLes</value></field>
<field var='email'><value>UnclassifiedFouoLes</value></field>
<field var='fn'><value>UnclassifiedFouoLes</value></field>
</x>
</query>
</iq>
</body>
Are search conditions combined by "OR" or by "AND"?
Do we search for a user who has any of field values ('first', 'last', 'nick', email', 'fn') equal to 'UnclassifiedFouoLes' or all the fields equal?
Update 2:
I'm trying to send a simple request (one without <x xmlns='jabber:x:data' type='submit'>) from Postman to ejabberd:
<body rid='1106091871' xmlns='jabber.org/protocol/httpbind' sid='2afabe5b07c316685e25a2d407617a534ca6b2bb'>
<iq type='set' id='search2' to='vjud.planetrisk.com' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'><last>UnclassifiedFouoLes</last></query>
</iq>
</body>
The result is always empty - it doesn't return any items. And there is a user with "last" vCard = "UnclassifiedFouoLes".
Why is it? Is "from" clause in request required?
Two existing clients can see each other and communicate in chat. But when I login as client1, grab sid and rid, insert them into Postman post, result is empty like
<body xmlns='http://jabber.org/protocol/httpbind' sid='67c6c7ee389a99e3491bbeab9ab198766ffa5ca8' rid='1287825358'>
<iq xmlns='jabber:client' type='set' id='search2' to='vjud.planetrisk.com'>
<query xmlns='jabber:iq:search'>
<last>UnclassifiedFouoLes</last>
</query>
</iq>
</body>

Simple type of search (one without <x xmlns="jabber:x:data" type="submit">) somehow returned error.
For extended search, it turned out, I was not sending
<field type="hidden" var="FORM_TYPE"><value>jabber:iq:search</value></field>
clause. That omission was working fine against Openfire, ejabberd requires it.
Still, Openfire Search plugin provides convenience and efficiency which I didn't find in ejabberd: it allows a chat client to display one search box and then to search for the value user typed in several fields (search OR functionality). On a client side, you need to send search request like
<body rid='273260412' xmlns='http://jabber.org/protocol/httpbind' sid='961w8ipmo2'>
<iq type='set' id='search2' to='yourSearchDomain.com' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x xmlns='jabber:x:data' type='submit'>
<field var='search'><value>your_search_term</value></field>
<field var='Username'><value>1</value></field>
<field var='Name'><value>1</value></field>
<field var='Email'><value>1</value></field>
</x>
</query>
</iq>
</body>
Openfire Search plugin would interpret this request as a command to perform three search requests: to find users with Username which matches your_search_term, then to find users with Name matching, and with Email matching. All three search results would be combined using logical OR.
Client only needs to send one Http search request to Openfire to search for your_search_term in three fields. With ejabberd, client would need to send three Http requests...
It would be nice to implement similar functionality in ejabberd module...

Related

I couldn't get all messages with some user with its JID

I made custom Iq for Request to Openfire server:
<iq id="7c0b34f5-d78e-48bf-819d-a357cb1f6b9e-5" type="set">
<query xmlns="urn:xmpp:mam:2" queryid="7c0b34f5-d78e-48bf-819d-a357cb1f6b9e-5" before="2022-04-29T12:00:00+00:00">
<x xmlns="jabber:x:data" type="submit">
<field var="FORM_TYPE">
<value>urn:xmpp:mam:2</value>
</field><field var="with">
<value>boki#desktop-eub4fkr</value>
</field>
</x>
</query>
</iq>
Response is only with counted messages, not with body text. Response:
<iq type="result" id="7c0b34f5-d78e-48bf-819d-a357cb1f6b9e-5" from="jid...." to="jid.../resource">
<fin xmlns="urn:xmpp:mam:2" queryid="7c0b34f5-d78e-48bf-819d-a357cb1f6b9e-5" complete="true">
<set xmlns="http://jabber.org/protocol/rsm">
<first>1</first>
<last>58</last>
<count>9</count>
</set>
</fin>
</iq>
I installed Monitoring Service Plugin to Openfire server. I tried with put start, end, after and before tag, but always the same result. I really don't know why... Any suggestion would be helpful

QuickFix - Tag not defined for this message - Celer tech

I've seen this questioned asked before here
and have applied the suggested solution but am still coming up with
Tag not defined for this message
I'm sending this message :
toapp : 8=FIX.4.4|9=151|35=V|34=2|49=Test|52=20180731-14:35:54.947|56=UAT-Test|55=EUR/USD|63=SP|115=Username|167=FOR|207=XCEL|262=1|263=1|264=0|265=0|461=SPOT|10=074|
and getting this back
toadmin : 8=FIX.4.4|9=134|35=3|34=3|49=Test|52=20180731-14:35:54.982|56=UAT-Test|45=2|58=Tag not defined for this message type|371=264|372=W|373=2|10=090|
The entry in the data dictionary for marketdatarequest is :
<message name="MarketDataRequest" msgtype="V" msgcat="app">
<field name="MDReqID" required="Y"/>
<field name="SubscriptionRequestType" required="Y"/>
<field name="MarketDepth" required="Y"/>
<field name="Symbol" required="Y"/>
<field name="SecurityType" required="Y"/>
<field name="MDUpdateType" required="Y"/>
<field name="CFICode" required="Y"/>
<field name="SettlType" required="Y"/>
<field name="OnBehalfOfCompID" required="N"/>
<field name="SecurityExchange" required="Y"/>
</message>
...
<field number="264" name="MarketDepth" type="INT"/>
All the other FIX implementations I've come across also have NoMDEntryTypes and NoRelatedSym groups which this does not which is strange but this is what the spec requires.
Also am I correct in saying that if I send an toapp message and get the toadmin message back with no fromapp/fromadmin message, does that mean quickfix intercepted the message as incorrectly formed and never sent it?
The rejection is not for your market data request. I can tell this from tag 372=W in the rejection:
FIX 4.4 : RefMsgType <372> field
The MsgType <35> (35) of the FIX message being referenced.
Source
MsgType W refers to a market data snapshot.
From the information you've given, I can infer that you send a MarketDataRequest (35=V) which presumably works successfully. The server you're connecting to replies with a snapshot (35=W) and your FIX engine then automatically responds to them with a rejection, because their snapshot includes tag 264 which are you not expecting.

XMPP 0059/0313 Archive message - paging backwards through result set

I have gotten the last 10 messages from archive, and trying to get the 10 before that on request and so on.
On the XMPP doc. it said i set the before with my UID??
http://xmpp.org/extensions/xep-0059.html#backwards
<iq type='set' from='stpeter#jabber.org/roundabout' to='users.jabber.org' id='back1'>
<query xmlns='jabber:iq:search'>
<nick>Pete</nick>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>10</max>
<before>peter#pixyland.org</before>
</set>
</query>
</iq>
or this?? http://xmpp.org/extensions/xep-0313.html#query-paging
with some ID in the after tag? I am very confused, can anyone give me some pointer, thanks!
<iq type='set' id='q29303'>
<query xmlns='urn:xmpp:mam:1'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'><value>urn:xmpp:mam:1</value></field>>
<field var='start'><value>2010-08-07T00:00:00Z</value></field>
</x>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>10</max>
<after>09af3-cc343-b409f</after>
</set>
</query>
</iq>
I tried putting in before with my UID and it didnt work <before>peter#server.org</before>
ANd i have an error <error code='400' type='modify'><bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq></body>
I am using strophe.js mam plugin and rsm plugin
When you receive first page limited by RSM with max=10, you will receive first and last UIDs:
<iq type='result' id='q29302'>
<fin xmlns='urn:xmpp:mam:1'>
<set xmlns='http://jabber.org/protocol/rsm'>
<first index='0'>28482-98726-73623</first>
<last>09af3-cc343-b409f</last>
<count>10</count>
</set>
</fin>
</iq>
These are UIDs of messages, which you can use in before and after subsequent queries.

ejabberd bookmarks replacing previous bookmarks

I'm using ejabberd as a chat server. When I send the request
(example from http://xmpp.org/extensions/xep-0048.html#storage-pubsub-upload)
<iq from='juliet#capulet.lit/balcony' type='set' id='pip1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='storage:bookmarks'>
<item id='current'>
<storage xmlns='storage:bookmarks'>
<conference name='The Play&apos;s the Thing'
autojoin='true'
jid='theplay#conference.shakespeare.lit'>
<nick>JC</nick>
</conference>
</storage>
</item>
</publish>
<publish-options>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#publish-options</value>
</field>
<field var='pubsub#persist_items'>
<value>true</value>
</field>
<field var='pubsub#access_model'>
<value>whitelist</value>
</field>
</x>
</publish-options>
</pubsub>
</iq>
PubSub configuration:
mod_pubsub:
db_type: odbc
access_createnode: pubsub_createnode
## reduces resource comsumption, but XEP incompliant
ignore_pep_from_offline: true
## XEP compliant, but increases resource comsumption
## ignore_pep_from_offline: false
last_item_cache: false
plugins:
- "flat"
- "hometree"
- "pep" # pep requires mod_caps
It works fine. But if I send a similar request to store a different chat room it replaces this one. Even if I change the item "id". Any ideas on how to store multiple conferences?
The Bookmarks specification is leveraging Personal Eventing Protocol. The assumption we made for PEP in ejabberd with default configuration is the the number of kept items on those special PubSub nodes is '1'.
You can check this by sending the following node configuration request:
<iq type='get'
id='config1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
<configure node='storage:bookmarks'/>
</pubsub>
</iq>
You will see that the reply shows that max number of items is '1':
<iq from="mremond#localhost" type="result" to="mremond#localhost/MacBook-Pro-de-Mickael" id="config1">
<pubsub xmlns="http://jabber.org/protocol/pubsub#owner">
<configure node="storage:bookmarks">
<x xmlns="jabber:x:data" type="form">
...
<field type="text-single" label="Max # of items to persist" var="pubsub#max_items">
<value>1</value>
</field>
...
</x>
</configure>
</pubsub>
</iq>
It means indeed that you are expected to have only one bookmark set. However, it does not prevent you from storing several bookmarks in the same set, as follow:
<iq type='set' id='pip1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='storage:bookmarks'>
<item id='current'>
<storage xmlns='storage:bookmarks'>
<conference name='Bookmark1'
autojoin='false'
jid='room1#conference.shakespeare.lit'>
<nick>Mynick1</nick>
</conference>
<conference name='Bookmark2'
autojoin='true'
jid='room2#conference.shakespeare.lit'>
<nick>Mynick2</nick>
</conference>
</storage>
</item>
</publish>
<publish-options>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
<value>http://jabber.org/protocol/pubsub#publish-options</value>
</field>
<field var='pubsub#persist_items'>
<value>true</value>
</field>
<field var='pubsub#access_model'>
<value>whitelist</value>
</field>
</x>
</publish-options>
</pubsub>
</iq>
ejabberd will reply with success:
<iq from="mremond#localhost" type="result" to="mremond#localhost/MacBook-Pro-de-Mickael" id="pip1">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<publish node="storage:bookmarks">
<item id="current"/>
</publish>
</pubsub>
</iq>
You can then query your bookmark and check that you have two bookmarks in that bookmark set:
<iq type='get' id='retrieve1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<items node='storage:bookmarks'/>
</pubsub>
</iq>
and response is:
<iq from="mremond#localhost" type="result" to="mremond#localhost/MacBook-Pro-de-Mickael" id="retrieve1">
<pubsub xmlns="http://jabber.org/protocol/pubsub">
<items node="storage:bookmarks">
<item id="current">
<storage xmlns="storage:bookmarks">
<conference name="Bookmark1" autojoin="false" jid="room1#conference.shakespeare.lit">
<nick>Mynick1</nick>
</conference>
<conference name="Bookmark2" autojoin="true" jid="room2#conference.shakespeare.lit">
<nick>Mynick2</nick>
</conference>
</storage>
</item>
</items>
</pubsub>
</iq>
You can store several bookmarks in the same set. Just upload all of them at once. So, to update the bookmark set, you are supposed to read it first and then store the updated version, not send incremental changes.
That said, I read the spec several times (XEP-0048 Bookmarks and XEP-0163 PEP). I do not see example or reference regarding the number of items on a PEP node. All the examples show only one item. The goal of PEP being to broadcast updates of a state. The assumption in most of the specification is that there is only one item involved (One avatar, one geoloc, etc). However, we would be happy to revise our assumption if we can find explicit element in the specification about the number of items that can be used.

Add user defined fields in the FIX dictionary

I need to add/modify fields in the FIX4.4 dictionary. I haven't found any helpful documentation or tutorials on this.
I'm guessing I have to modify the FIX44.xml file, but I'm not sure how exactly to do that.
In the <message></message> tags I don't see any attributes that define the number or the type(format) of that field. I see just the name and required attributes.
I think I found attributes I', looking for in the <fields></fields> tags.
I'm not sure if I'm looking in the right place or if I'm doing the right thing, but according to this I should modify the dictionary if it is necessary.
Please help.
A link to a tutorial for beginners that can help me would also be greatly appreciated.
The FIX Data Dictionary in QuickFIX contains Messages and Fields (among other things).
To add Messages you must add the message between the <messages></messages> tags like this:
<message name="CoolMessage" msgcat="app" msgtype="xCM">
<field name="Currency" required="N"/>
<field name="Text" required="N"/>
<field name="Account" required="Y"/>
</message>
And then add the new msgtype to the MsgType field in the <fields></fields> section like this:
<field number='35' name='MsgType' type='STRING'>
...
<value enum='xCM' description='COOLMESSAGE'/>
</field>
If you want to add new fields, just add them between the <fields></fields> tags like this:
<fields>
<field number="1" name="Account" type="STRING"/>
<field number="2" name="AdvId" type="STRING"/>
<field number="3" name="AdvRefID" type="STRING"/>
...
<field number="9006" name="AwesomeField" type="STRING"/>
</fields>
This and more information can be found in this tutorial.