ejabberd pubsub unsubscribe issue - xmpp

I have issues when I try to unsubscribe from a pubsub node.
I am writting a BOSH client in js.
This is how I subscribe (with a full JID) :
<body rid='1023502710' xmlns='http://jabber.org/protocol/httpbind' sid='2ded0255fc6e8bf912a2871d415173faadecfea6'>
<presence xmlns='jabber:client'/>
<presence from='sav1#my.server.com/my_resource' to='amd.my.server.com/sav' xmlns='jabber:client'/>
<iq to='pubsub.my.server.com' type='set' xmlns='jabber:client' id='5007:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscribe node='/home/monitoring/sav' jid='sav1#my.server.com/my_resource'/>
</pubsub>
</iq>
</body>
On my next bind request, I receive the following stanza (because I've subscribe with a node attribute) :
http://xmpp.org/extensions/xep-0060.html#example-24 : An entity MAY also request all of its subscriptions at a specific node (e.g., if it has subscriptions with multiple SubIDs) by including a 'node' attribute on the element.
<body xmlns='http://jabber.org/protocol/httpbind'>
<message xmlns='jabber:client' from='pubsub.my.server.com' to='sav1#my.server.com/my_resource'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='/home/monitoring/sav'>
<item id='monitor'>
<!-- some pubsub information -->
</item>
</items>
</event>
<delay xmlns='urn:xmpp:delay' from='amd.my.server.com' stamp='2012-09-14T12:36:28Z'/>
</message>
<iq xmlns='jabber:client' from='pubsub.my.server.com' to='sav1#my.server.com/my_resource' id='5007:sendIQ' type='result'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscription jid='sav1#my.server.com/my_resource' subscription='subscribed' subid='543990DD8E6E6' node='/home/monitoring/sav'/>
</pubsub>
</iq>
<message xmlns='jabber:client' from='pubsub.my.server.com' to='sav1#my.server.com/my_resource' type='headline'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='/home/monitoring/sav'>
<item id='monitor'>
<!-- some pubsub information -->
</item>
</items>
</event>
<headers xmlns='http://jabber.org/protocol/shim'>
<header name='Collection'>/home/monitoring/sav</header>
<header name='SubID'>5435B7F0CA392</header>
<!-- a lot of other SubIDs -->
</headers>
</message>
</body>
In the headers section, I receive a lot of SubID. I suppose the reason for this is bad unsubscribe.
When I end my session, I unsubsribe from every SubID :
<body rid='1023502724' xmlns='http://jabber.org/protocol/httpbind' sid='2ded0255fc6e8bf912a2871d415173faadecfea6'>
<iq to='pubsub.my.server.com' type='set' xmlns='jabber:client' id='5008:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<unsubscribe node='/home/monitoring/sav' jid='sav1#my.server.com' subid='5435B7F0CA392'/>
</pubsub>
</iq>
<!-- a lot of other unsubscribed iqs -->
</body>
The answer is immediate :
<body xmlns='http://jabber.org/protocol/httpbind'>
<iq xmlns='jabber:client' from='pubsub.my.server.com' to='sav1#my.server.com/my_resource' type='error' id='5008:sendIQ'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<unsubscribe node='/home/monitoring/sav' jid='sav1#my.server.com' subid='5435B7F0CA392'/>
</pubsub>
<error code='401' type='cancel'>
<unexpected-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
<not-subscribed xmlns='http://jabber.org/protocol/pubsub#errors'/>
</error>
</iq>
</body>
No other SubID is mentionned except the first I initially received.
What am I doing wrong ?
I am running ejabberd 2.1.10.

I don't think the resource should be passed with the jid on a subscribe. I don't know if that is just something left in the example, but that may be messing things up.

Try doing an unsubscribe with the full JID that is associated with the subscription instead of the base JID you are currently using.
You can get the JID from your response to your request for current subsriptions. The jid attribute contains the full jid the subscription is associated with.
<iq xmlns='jabber:client' from='pubsub.my.server.com' to='sav1#my.server.com/my_resource' id='5007:sendIQ' type='result'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscription jid='sav1#my.server.com/my_resource' subscription='subscribed' subid='543990DD8E6E6' node='/home/monitoring/sav'/>
</pubsub>
</iq>

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

Privacy lists in ejabberd

I would like to block all incoming presence updates from my roster. I have tried using privacy lists by sending the following IQ.
<iq id='oQQwF-18' type='set'>
<query xmlns='jabber:iq:privacy'>
<list name="subscription">
<item action="deny" order="9" type="subscription" value="to">
<presence-in/>
</item>
</list>
</query>
</iq>
I can see that the privacy list is being store in MySQL but i still receive presence updates from roster buddies.
I am aware of mod_client_state, but i would like to give privacy lists a try first.
In XEP-0016, when matching for subscription types, you need to match each subscription type separately. With the stanza above, you are blocking incoming presence stanzas from users whose subscription status is "to", but presumably most of them have subscription status "both" (and some might have "from"). Try this:
<iq id='oQQwF-18' type='set'>
<query xmlns='jabber:iq:privacy'>
<list name="subscription">
<item action="deny" order="9" type="subscription" value="to">
<presence-in/>
</item>
<item action="deny" order="10" type="subscription" value="from">
<presence-in/>
</item>
<item action="deny" order="11" type="subscription" value="both">
<presence-in/>
</item>
</list>
</query>
</iq>
Besides, you may need to set the subscription list to be the active privacy list:
<iq type='set' id='active1'>
<query xmlns='jabber:iq:privacy'>
<active name='subscription'/>
</query>
</iq>

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.

Result Set Management for Last Page (Reversed RSM)

I'm now developing an apps with message history retrieval based on XEP-0136 with Openfire Server.
I've read that message history retrieval can be combined with Result Set Management (RSM)-XEP-0059.
We can delimit the number of message retrieval request by setting max attribute of RSM like this:
<iq type='get' id='juliet1'>
<list xmlns='urn:xmpp:archive'
with='juliet#capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>5</max>
</set>
</list>
</iq>
This should return the first 5 chat list from the top (ordered by chat time ascending).
My question is how to retrieve the last 5 chat list from the bottom, so I can get the latest chat message not the first time chat.
I've seen this Reversed RSM standard suggestion, like this:
<iq type='get' id='juliet1'>
<list xmlns='urn:xmpp:archive'
with='juliet#capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>5</max>
<before />
<reversed />
</set>
</list>
</iq>
But this standard seems not yet implemented.
Thanks in advance
Based on this, the stanza is like this:
<iq type='get' id='juliet1'>
<list xmlns='urn:xmpp:archive'
with='juliet#capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>5</max>
<before />
</set>
</list>
</iq>
You can retrieve the collection from bottom by RSM.
But seems Openfire message archiving plugin had some bugs with this RSM.
Reference: http://community.igniterealtime.org/message/230389#230389
So, the possible solution is getting count of my collection:
<iq type='get' id='juliet1'>
<list xmlns='urn:xmpp:archive'
with='juliet#capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>0</max>
</set>
</list>
</iq>
It will return:
<iq xmlns='jabber:client' type='result' id='juliet1' to='admin#somehost'>
<list xmlns='urn:xmpp:archive'>
<set xmlns='http://jabber.org/protocol/rsm'>
<count>10</count>
</set>
</list>
</iq>
And I select the collection by index:
<iq type='get' id='juliet1'>
<list xmlns='urn:xmpp:archive'
with='juliet#capulet.com'>
<set xmlns='http://jabber.org/protocol/rsm'>
<max>5</max>
<index>4</index>
</set>
</list>
</iq>

Get members nickname of MUC Room

Is there a way to get all nicknames of a MUC Room with an ejabberd server?
I'm trying with:
<iq from='crone1#shakespeare.lit/desktop'
id='member3'
to='coven#chat.shakespeare.lit'
type='get'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='member'/>
</query>
</iq>
but I obtain only jid without nicknames:
<iq from='coven#chat.shakespeare.lit'
id='member3'
to='crone1#shakespeare.lit/desktop'
type='result'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='member'
jid='hag66#shakespeare.lit'
role='participant'/>
</query>
</iq>
On 6.5 Querying for Room Items from XEP 0045 when you send
<iq from='$user-name#$user-server/$user-resorce'
id='someid'
to='$chat-room-to-query#$chatserver'
type='get'>
<query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
You have the following description
An implementation MAY return a list of existing occupants if that information is publicly available, or return no list at all if this information is kept private.(emphasis mine)
if the room is public them you get
<iq from='$chat-room-to-query#$chatserver'
id='someid'
to='$user-name#$user-server/$user-resorce'
type='result'>
<query xmlns='http://jabber.org/protocol/disco#items'>
<item jid='$chat-room-to-query#$chatserver/$firstnick'/>
<item jid='$chat-room-to-query#$chatserver/$secondnick'/>
<...>
</query>
</iq>
From my knowledge ejabberd implements this correctly.