sstrigler/JSJaC

In firefox doesn`t work adding users to roster.

Closed this issue · 11 comments

client - firefox-41.0.2
server - prosody-0.9.4-4
jsjac - latest
Firefox generates request

iq xmlns="jabber:client" type="set" from="rfsdsdf@example.com/oSDK-client2ce76228700" id="JSJaCID_0"><query xmlns="jabber:iq:roster"><item xmlns="" jid="rfdsffdsfsdf@example.com" subscription="none"/></query></iq>

and gets response

<iq type='error' to='rfsdsdf@example.com/oSDK-client2ce76228700' id='JSJaCID_0'><error type='modify'><bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>

In chromium it works correctly:

<iq xmlns="jabber:client" type="set" from="rfsdsdf@example.com/oSDK-client2ce76228700" id="JSJaCID_0"><query xmlns="jabber:iq:roster"><item jid="rfdsffdsfsdf@example.com" subscription="none"/></query></iq>
<iq type='result' to='rfsdsdf@example.com/oSDK-client2ce76228700' id='JSJaCID_0'/><iq type='set' id='lx14'><query xmlns='jabber:iq:roster' ver='673'><item subscription='none' jid='rfdsffdsfsdf@example.com'/></query></iq>

difference that firefox adds xmlns="" to <item>

And the source code that generates those packets?

That code:

    var iq = new JSJaCIQ();
    iq.setType('set');
    iq.setFrom(this.storage.client.jid || this.storage.client.id);
    var query = iq.setQuery(NS_ROSTER);
    var item = iq.buildNode('item', {
      jid: id,
      name: (params.nickname || id.split('@')[0]),
      subscription: 'none'
    });

    item.appendChild(iq.buildNode('group', (params.group || 'general')));
    query.appendChild(item);

    this.connection.sendIQ(iq, {...

And that additiion of xmlns to item fixes problem:

    var iq = new JSJaCIQ();
    iq.setType('set');
    iq.setFrom(this.storage.client.jid || this.storage.client.id);
    var query = iq.setQuery(NS_ROSTER);
    var item = iq.buildNode('item', {
      xmlns: NS_ROSTER,
      jid: id,
      name: (params.nickname || id.split('@')[0]),
      subscription: 'none'
    });

    item.appendChild(iq.buildNode('group', (params.group || 'general')));
    query.appendChild(item);

    this.connection.sendIQ(iq, {....

It seems that if I omit setting of xmlns to item FF appends empty xmlns to it and server answers with error. Chrome don`t append empty xmlns

Second example fixes FF and works fine in Chrome too

I think the reason is that you are building the item element based on the iq element which is of different namespace. What you could try is:

var item = JSJaCBuilder.buildNode(query, 'item', {
      jid: id,
      name: (params.nickname || id.split('@')[0]),
      subscription: 'none'
    });
query.appendChild(item);

This don`t work. Error occurs:

Uncaught TypeError: doc.createElement is not a function

query === doc seems query don`t have createElement method. May be createElementNS?

Sorry, my bad. And sorry for the late reply. Please try

var item = JSJaCBuilder.buildNode(
    query.ownerDocument,
    'item', 
    { jid: id,
      name: (params.nickname || id.split('@')[0]),
      subscription: 'none'
    });
query.appendChild(item);

And sorry again, it's untested.

Anyway, the approach with setting the namespace manually should be good enough too.

Hi, this varian don't work in FireFox (i'm talking about query.ownerDocument) , same error - FF add empty "xmlns" attribute.

My old variant:

var item = iq.buildNode('item', {
    xmlns: NS_ROSTER,
    jid: id,
    name: (params.nickname || id.split('@')[0]),
    subscription: 'none'
});

... is normal crack for FF? :)

Well, apparently? I'm not that deep into web development anymore. But I can understand why they might have implemented this way. Not implying that's my preferred way.

Ok to close this issue?