XMPP / Ejabberd: Why does the roster item is always ask='subscribe'? - xmpp

The roster of user "john#localhost" is
<iq xmlns="jabber:client" xml:lang="en" to="john#localhost/2182919552157840751291" from="john#localhost" type="result" id="56c73b295y">
<query xmlns="jabber:iq:roster">
<item subscription="both" jid="johnna#localhost"/>
</query>
</iq>
But the roster of user "johnna#localhost" is
<iq xmlns="jabber:client" xml:lang="en" to="johnna#localhost/15960489746475669037996" from="johnna#localhost" type="result" id="56c73b295y">
<query xmlns="jabber:iq:roster">
<item ask="subscribe" jid="john#localhost"/>
</query>
</iq>
How it's possible ?
Why item is ask="subscribe" when john has both subscription ?
Step to reproduce
eJabberd version: ejabberd/ecs:20.01
john#localhost send stanza:
<presence type="subscribe" to="johnna#localhost" id="test1" />
johnna#localhost reply with:
<presence type="subscribed" to="john#localhost" id="test1" />
Then send:
<presence type="subscribe" to="john#localhost" id="test2" />
Finally, john#localhost reply:
<presence type="subscribed" to="johnna#localhost" id="test2" />
Roster iq received by john is
<iq xmlns="jabber:client" xml:lang="en" to="johnna#localhost/15960489746475669037996" from="johnna#localhost" type="set" id="56c73b295y">
<query xmlns="jabber:iq:roster">
<item subscription="both" jid="johnna#localhost"/>
</query>
</iq>
But johnna received:
<iq xmlns="jabber:client" xml:lang="en" to="johnna#localhost/15960489746475669037996" from="johnna#localhost" type="set" id="56c73b295y">
<query xmlns="jabber:iq:roster">
<item ask="subscribe" jid="john#localhost"/>
</query>
</iq>
modules enabled
modules:
mod_admin_extra: {}
mod_block_strangers: {}
mod_blocking: {}
mod_client_state: {}
mod_http_api: {}
mod_last: {}
mod_mam:
default: always
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_privacy: {}
mod_roster: {}

Related

How to configure a xmpp pubsub leafnode so that anyone can publish or update item there?

The user romeo#host creates a LeafNode 0c55624367fc10d2548c569782f569dc:downline by this configuration:
("pubsub#deliver_payloads", "true")
("pubsub#notify_config", "false")
("pubsub#notify_delete", "false")
("pubsub#notify_retract", "false")
("pubsub#purge_offline", "false")
("pubsub#persist_items", "true")
("pubsub#publish_model", "open")
("pubsub#max_items", "50")
("pubsub#subscribe", "false")
("pubsub#access_model", "open")
("pubsub#send_last_published_item", "never")
("pubsub#deliver_notifications", "false")
Creates an item like this:
<item id='downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
<downline>
{"users":[{"username":"do hdhddkd","userphone":"+8801111111147"}]}
</downline>
</downline>
</item>
User juliet#host tries to update/publish in the same node in this way:
<iq to='pubsub.192.168.0.100' id='1P42B-58' type='set'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='0c55624367fc10d2548c569782f569dc:downline'>
<item id='downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
{"users":[{"username":"chhy","userphone":"+8801111111147"},{"username":"do hdhddkd","userphone":"+8801111111147"}]}
</downline>
</downline>
</item>
</publish>
</pubsub>
</iq>
But juliet is getting an error like this:
<iq xml:lang='en-US' to='+8801111111153#192.168.0.100/12934698245865334251579' from='pubsub.192.168.0.100' type='error' id='1P42B-58'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='0c55624367fc10d2548c569782f569dc:downline'>
<item id='downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
<downline>
{"users":[{"username":"chhy","userphone":"+8801111111147"},{"username":"do hdhddkd","userphone":"+8801111111147"}]}
</downline>
</downline>
</item>
</publish>
</pubsub>
<error type='auth'>
<forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
</error>
</iq>
Am I missing a point, perhaps a configuration?
After research, I find out the problem. The problem was not within the configuration but within the item id.
<item id='downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
<downline>
{"users":[{"username":"do hdhddkd","userphone":"+8801111111147"}]}
</downline>
</downline>
</item>
in Romeo's case the item id was downline and also in Juliet's case the id was downline
<item id='downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
<downline xmlns='pubsub:mecloak:users:downline'>
{"users":[{"username":"chhy","userphone":"+8801111111147"},{"username":"do hdhddkd","userphone":"+8801111111147"}]}
</downline>
</downline>
</item>
juliet has no right to override romeo's item that is why server rejects it.
juliet changed the item id and it works fine. :)

When I run my vxml application I get this syntax error

I get this error when I run my vxml app;
"ECMAScript runtime error: Compilation produced 1 syntax
errors.\n\nWhile evaluating:\n\"var acc_no = [37492414, 94190610,
23228367, 39574988, 64742440];\n\t\t\t\t\tfunction checkAccount(arr,
val) {\n\t\t\t\t\treturn arr.some(arrVal => val ===
arrVal);\n\t\t\t\t\t\t\t\t\t\t\t} \"";
Here's my vxml script where the error arises:
<?xml version="1.0" encoding="UTF-8"?>
<vxml xmlns:voxeo="http://community.voxeo.com/xmlns/vxml"
version="2.1" xml:lang="en-US"
xml:base="http://webhosting.voxeo.net/201985/www/">
<property name="inputmodes" value="dtmf"/>
<property name="termchar" value="#"/>
<property name="interdigittimeout" value="2s"/>
<property name="bargein" value="false"/>
<var name = "accountNumber"/>
<var name = "pinNumber"/>
<form id="userAuth" scope="document">
<var name="iMaxTries" expr="3"/>
<var name="iTriesAcc" expr="0"/>
<var name="iTriesPin" expr="0"/>
<var name="fatal" expr="'We are having technical difficulties validating your credentials. Try back later.'"/>
<catch event="event.pinNumber.invalid">
<!-- increment the attempt counter; if the count is exceeded, disconnect -->
<assign name="iTriesPin" expr="iTriesPin+1"/>
<if cond="iMaxTries == iTries">
<value expr="fatal"/>
<disconnect/>
<else/>
<!-- clear is unnecessary on a nomatch, but we use the same code to handle a bad filled -->
<clear namelist="pinNumber"/>
<reprompt/>
</if>
</catch>
<catch event="event.accountNumber.invalid">
<!-- increment the attempt counter; if the count is exceeded, disconnect -->
<assign name="iTriesAcc" expr="iTriesAcc+1"/>
<if cond="iMaxTries == iTries">
<value expr="fatal"/>
<disconnect/>
<else/>
<!-- clear is unnecessary on a nomatch, but we use the same code to handle a bad filled -->
<clear namelist="accountNumber"/>
<reprompt/>
</if>
</catch>
<!-- exec this on the first and second noinput/nomatch -->
<!-- each event has its own counter -->
<catch event="noinput">
I'm sorry. I didn't get you.
<reprompt />
</catch>
<!-- exec this on the third nomatch -->
<catch event="nomatch">
<throw event="event.password.invalid"/>
</catch>
<!-- silently disconnect on the third noinput -->
<catch event="noinput" count="3">
<disconnect/>
</catch>
<field name="accountNumber" type="digits?length=8">
<prompt> Please enter your account number followed by the pound key. </prompt>
<grammar mode="dtmf" version="1.0" root="pin"
tag-format="semantics/1.0">
<rule id="digit" scope="public" >
<one-of>
<item> 0 </item>
<item> 1 </item>
<item> 2 </item>
<item> 3 </item>
<item> 4 </item>
<item> 5 </item>
<item> 6 </item>
<item> 7 </item>
<item> 8 </item>
<item> 9 </item>
</one-of>
</rule>
<rule id="pin" scope="public">
<tag>out=""</tag>
<item repeat="8">
<ruleref uri="#digit"/>
<tag>out += rules.latest( );</tag>
</item>
</rule>
</grammar>
<filled>
<script> <![CDATA[
var acc_no = [37492414, 94190610, 23228367, 39574988, 64742440];
function checkAccount(arr, val) {
return arr.some(arrVal => val === arrVal);
}
]]> </script>
<block>
<var name="chk_acc" expr="checkAccount(acc_no, accountNumber);"/>
<if cond="chk_acc =='true'">
<goto next="#pinNumber"/>
<else/>
<prompt>Sorry, Account number not recognised. </prompt>
<throw event="event.accountNumber.invalid"/>
</if>
</block>
</filled>
</field>
<field name="pinNumber" type="digits?length=4">
<prompt> please enter your four digit pin followed by the pound key. </prompt>
<grammar mode="dtmf" version="1.0" root="pin"
tag-format="semantics/1.0">
<rule id="digit" scope="public" >
<one-of>
<item> 0 </item>
<item> 1 </item>
<item> 2 </item>
<item> 3 </item>
<item> 4 </item>
<item> 5 </item>
<item> 6 </item>
<item> 7 </item>
<item> 8 </item>
<item> 9 </item>
</one-of>
</rule>
<rule id="pin" scope="public">
<tag>out=""</tag>
<item repeat="4">
<ruleref uri="#digit"/>
<tag>out += rules.latest( );</tag>
</item>
</rule>
</grammar>
<filled>
<script> <![CDATA[
var pin_no = [2414, 0610,8367, 4988, 2440];
function checkPin(arr, val) {
return arr.some(arrVal => val === arrVal);
}
]]> </script>
<block>
<var name="chk_pin" expr="checkPin(pin_no, pinNumber);"/>
<if cond="chk_pin =='false'">
<prompt>Sorry, you have entered is an invalid pin. Please try again </prompt>
<throw event="event.pinNumber.invalid"/>
</if>
</block>
</filled>
</field>
<filled mode="all" namelist="accountNumber pinNumber">
<script> <![CDATA[
var accDetails = [
{acc_name: 'Lawrence Burkins', account: 37492414, pin: 2414, acc_type: 'checking', acc_bal: 2372351.74 , acc_br:'Montreal'},
{acc_name: 'Ola Macaulay', account: 94190610, pin: 0610, acc_type: 'checking', acc_bal: 908242.49 , acc_br:'Tisdale'},
{acc_name: 'Judy Cefalu', account: 23228367, pin: 8367, acc_type: 'checking', acc_bal: 15700526.57 , acc_br:'Toronto'},
{acc_name: 'Mellisa Garcia', account: 39574988, pin: 4988, acc_type: 'checking', acc_bal: 568201.26 , acc_br:'Prince Albert'},
{acc_name: '', account: 64742440, pin: 2440, acc_type: 'checking', acc_bal: 1952000.00 , acc_br:'Fort McMurray'},
];
function accDetails(details) {
return details.account === accountNumber ;
}
var newDetail = accDetails.find(accDetails);
var myDetail = [newDetail];
var myBal = myDetail.slice(0, 4);
]]> </script>
<var name = "accountBalance" expr = "myBal.toString()"/>
<prompt>
Your Checking account balance is <prosody rate="slow"><say-as type="currency"> $ + <value class="currency" expr="accountBalance"/> </say-as></prosody>
</prompt>
<goto next="after_bal.vxml"/>
</filled>
</form>
</vxml>
I am still new to vxml and ecmascript.
The ECMAScript in question seems to be syntactically correct:
var acc_no = [37492414, 94190610, 23228367, 39574988, 64742440];
function checkAccount(arr, val) {
return arr.some(arrVal => val === arrVal);
}
I would suggest breaking this piecemeal and reduce the complexity of the VXML code to debug it. Use a very basic VXML file with one simple field, put the above ECMAScript in the filled section and then see if you get the same error. If you do, move the script further up in the code (i.e not in the filled section) and again check if you get the same error.
The error statement is a bit confusing because of the linefeeds etc. Does the error message look like that when you see it the first time?

REST Service returns CORS? error - ColdFusion

I create a REST service in CF11 and up until last night everything was working fine until I started getting CORS errors all over the place.
Long story short this is my code:
<cfcomponent rest="true" restPath="/testimonials">
<cffunction name="getTestimonials" access="remote" returntype="any" httpMethod="GET" restPath="/getTestimonials">
<cfargument name="showRatings" type="numeric" restArgSource="Query" default="0">
<cfargument name="siteID" type="numeric" restArgSource="Query" default="0">
<cfargument name="pageID" type="numeric" restArgSource="Query" default="0">
.....
And I am calling it like this
<cfhttp url="http://dev.example.com/rest/api/testimonials/getTestimonials" method="GET" result="res">
<cfhttpparam type="URL" name="showRatings" value="0">
<cfhttpparam type="URL" name="siteID" value="17">
<cfhttpparam type="URL" name="pageID" value="2">
</cfhttp>
<cfdump var="#res#">
And this is the return struct that I am getting back
struct
Charset [empty string]
ErrorDetail [empty string]
Filecontent [empty string]
Header HTTP/1.1 200 OK Access-Control-Allow-Methods: POST,GET,OPTIONS Date: Wed, 23 Sep 2015 08:14:02 GMT Content-Length: 0 Access-Control-Allow-Headers: Content-Type Access-Control-Allow-Origin: * Server: Microsoft-IIS/8.0 X-Powered-By: ASP.NET server-error: true
Mimetype Unable to determine MIME type of file.
Responseheader
struct
Access-Control-Allow-Headers Content-Type
Access-Control-Allow-Methods POST,GET,OPTIONS
Access-Control-Allow-Origin *
Content-Length 0
Date Wed, 23 Sep 2015 08:14:02 GMT
Explanation OK
Http_Version HTTP/1.1
Server Microsoft-IIS/8.0
Status_Code 200
X-Powered-By ASP.NET
server-error true
Statuscode 200 OK
Text YES
Nothing Changed as far as I know code-wise or on my IIS server to justify this error. I even added the code below in my web.config to try and enable CORS
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*"/>
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
<add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>

Jabber Search for advanced user search

I'm trying to search user by username in my xmpp server, but the result always contains no items...
for getting the form format I send:
<iq type='get' to='search.MY_SERVER' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'/>
</iq>
and received:
<iq xmlns="jabber:client" type="result" id="3:sendIQ" from="search.MY_SERVER" to="ID#MY_SERVER/7acf23bb">
<query xmlns="jabber:iq:search">
<instructions>The following fields are available for searching. Wildcard (*) characters are allowed as part of the query.</instructions>
<first/><last/><nick/><email/>
<x xmlns="jabber:x:data" type="form">
<title>Advanced User Search</title>
<instructions>The following fields are available for searching. Wildcard (*) characters are allowed as part of the query.</instructions>
<field var="FORM_TYPE" type="hidden">
<value>jabber:iq:search</value>
</field>
<field var="search" type="text-single" label="Search">
<required/>
</field>
<field var="Username" type="boolean" label="Username">
<value>1</value>
</field>
<field var="Name" type="boolean" label="Name">
<value>1</value>
</field>
<field var="Email" type="boolean" label="Email">
<value>1</value>
</field>
</x>
</query>
</iq>
and then I send:
<iq type='set' to='search.MY_SERVER' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x xmlns='jabber:x:data' type='submit'>
<field type='hidden' var='FORM_TYPE'>
<value>jabber:iq:search</value>
</field>
<field var='search'>
<value>*</value>
</field>
</x>
</query>
</iq>
but received no items:
<iq xmlns="jabber:client" type="result" id="4:sendIQ" from="search.MY_SERVER" to="ID#MY_SERVER/7acf23bb">
<query xmlns="jabber:iq:search">
<x xmlns="jabber:x:data" type="result">
<field var="FORM_TYPE" type="hidden"/>
<reported>
<field var="jid" type="jid-single" label="JID"/>
<field var="Username" type="text-single" label="Username"/>
<field var="Name" type="text-single" label="Name"/>
<field var="Email" type="text-single" label="Email"/>
</reported>
</x>
</query>
</iq>
Does someone know what went wrong?
I have found the answer,send following request will do the trick:
<iq type='set' to='search.MY_SERVER' xmlns='jabber:client'>
<query xmlns='jabber:iq:search'>
<x xmlns='jabber:x:data' type='submit'>
<field var='search'>
<value>SEARCH_CRITERIA</value>
</field>
<field var='Username'>
<value>1</value>
</field>
</x>
</query>
</iq>

How to create conference rooms in Openfire with XMPPHP?

I'm developing a system which at some point I'll have to allow users to create their own conference rooms.
I was reading about create rooms and wrote some code with XMPP which results in the verbose log below.
1422017436 [VERBOSE]: Socket is ready; send it.
1422017436 [VERBOSE]: SENT: <presence from='24527#localhost/xmpphp' to='sala3#myconference.localhost/xmpphp'><x xmlns='http://jabber.org/protocol/muc'/></presence>
1422017436 [VERBOSE]: Successfully sent 134 bytes.
1422017436 [VERBOSE]: Socket is ready; send it.
1422017436 [VERBOSE]: SENT: <iq from='24527#localhost/xmpphp' id='create1' to='sala3#myconference.localhost/xmpphp' type='set'><query xmlns='http://jabber.org/protocol/muc#owner'><x xmlns='jabber:x:data' type='submit'/></query></iq>
1422017436 [VERBOSE]: Successfully sent 203 bytes.
1422017436 [VERBOSE]: Disconnecting...
1422017436 [VERBOSE]: Socket is ready; send it.
1422017436 [VERBOSE]: SENT: </stream:stream>
1422017436 [VERBOSE]: Successfully sent 16 bytes.
1422017436 [VERBOSE]: RECV: <presence from="sala3#myconference.localhost/xmpphp" to="24527#localhost/xmpphp"><x xmlns="http://jabber.org/protocol/muc#user"><item jid="24527#localhost/xmpphp" affiliation="owner" role="moderator"/><status code="110"/><status code="100"/><status code="201"/></x></presence>
1422017436 [DEBUG]: Calling presence_handler
1422017436 [DEBUG]: Presence: sala3#myconference.localhost/xmpphp [available]
1422017436 [DEBUG]: EVENT: presence
1422017436 [VERBOSE]: RECV: <iq type="result" id="create1" from="sala3#myconference.localhost/xmpphp" to="24527#localhost/xmpphp"/>
1422017436 [VERBOSE]: RECV: </stream:stream>
1422017436 [DEBUG]: EVENT: end_stream
It seems to be working, as I can read here:
1422017436 [DEBUG]: Calling presence_handler
1422017436 [DEBUG]: Presence: sala3#myconference.localhost/xmpphp [available]
1422017436 [DEBUG]: EVENT: presence
1422017436 [VERBOSE]: RECV: <iq type="result" id="create1" from="sala3#myconference.localhost/xmpphp" to="24527#localhost/xmpphp"/>
1422017436 [VERBOSE]: RECV: </stream:stream>
But I cannot find the sala3 room in Openfire Panel.
Is there anything wrong with my SENT packets?
Thanks.
It is still ugly, but it worked.
I added it to XMPP.php
public function createGroup() {
$out = "<presence from='24527#localhost/xmpphp' to='sala4#myconference.localhost/xmpphp'><x xmlns='http://jabber.org/protocol/muc'/></presence>";
$this->send($out);
}
public function createGroup2() {
$out = "<iq from='24527#localhost/desktop'
id='create1'
to='sala4#myconference.localhost/xmpphp'
type='get'>
<query xmlns='http://jabber.org/protocol/muc#owner'/>
</iq>";
$this->send($out);
}
public function sendConfigRoom() {
$out = "<iq from='24527#localhost/desktop'
id='create2'
to='sala4#myconference.localhost/xmpphp'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#owner'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE'>
<value>http://jabber.org/protocol/muc#roomconfig</value>
</field>
<field var='muc#roomconfig_roomname'>
<value>A Dark Cave</value>
</field>
<field var='muc#roomconfig_roomdesc'>
<value>The place for all good witches!</value>
</field>
<field var='muc#roomconfig_enablelogging'>
<value>0</value>
</field>
<field var='muc#roomconfig_changesubject'>
<value>1</value>
</field>
<field var='muc#roomconfig_allowinvites'>
<value>0</value>
</field>
<field var='muc#roomconfig_allowpm'>
<value>anyone</value>
</field>
<field var='muc#roomconfig_maxusers'>
<value>10</value>
</field>
<field var='muc#roomconfig_publicroom'>
<value>0</value>
</field>
<field var='muc#roomconfig_persistentroom'>
<value>1</value>
</field>
<field var='muc#roomconfig_moderatedroom'>
<value>0</value>
</field>
<field var='muc#roomconfig_membersonly'>
<value>0</value>
</field>
<field var='muc#roomconfig_passwordprotectedroom'>
<value>1</value>
</field>
<field var='muc#roomconfig_roomsecret'>
<value>cauldronburn</value>
</field>
<field var='muc#roomconfig_whois'>
<value>moderators</value>
</field>
<field var='muc#maxhistoryfetch'>
<value>50</value>
</field>
<field var='muc#roomconfig_roomadmins'>
<value>24527#localhost</value>
</field>
</x>
</query>
</iq> ";
$this->send($out);
}
And my createGroup.php:
<?php
// activate full error reporting
//error_reporting(E_ALL & E_STRICT);
error_reporting(E_ALL);
ini_set('display_errors', 'On');
include 'XMPPHP/XMPP.php';
// load the image from filesystem
#Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports
#If this doesn't work, are you running 64-bit PHP with < 5.2.6?
$conn = new XMPPHP_XMPP('myserver', 5222, '24527', 'my pw', 'xmpphp', 'localhost', $printlog=true, $loglevel=XMPPHP_Log::LEVEL_VERBOSE);
$conn->connect();
$conn->processUntil('session_start');
$conn->useEncryption(false);
$conn->createGroup();
$conn->processUntil('presence');
$conn->createGroup2();
$conn->processUntil('result');
$conn->sendConfigsRoom();
#$conn->processUntil(array('result', 'error'));
$conn->disconnect();