|
342 | 342 | /* Register a handler for roster IQ "set" stanzas, which update
|
343 | 343 | * roster contacts.
|
344 | 344 | */
|
345 |
| - _converse.connection.addHandler( |
346 |
| - _converse.roster.onRosterPush.bind(_converse.roster), |
347 |
| - Strophe.NS.ROSTER, 'iq', "set" |
348 |
| - ); |
| 345 | + _converse.connection.addHandler((iq) => { |
| 346 | + _converse.roster.onRosterPush(iq); |
| 347 | + return true; |
| 348 | + }, Strophe.NS.ROSTER, 'iq', "set"); |
349 | 349 | },
|
350 | 350 |
|
351 | 351 | registerRosterXHandler () {
|
|
506 | 506 |
|
507 | 507 | onRosterPush (iq) {
|
508 | 508 | /* Handle roster updates from the XMPP server.
|
509 |
| - * See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push |
510 |
| - * |
511 |
| - * Parameters: |
512 |
| - * (XMLElement) IQ - The IQ stanza received from the XMPP server. |
513 |
| - */ |
| 509 | + * See: https://xmpp.org/rfcs/rfc6121.html#roster-syntax-actions-push |
| 510 | + * |
| 511 | + * Parameters: |
| 512 | + * (XMLElement) IQ - The IQ stanza received from the XMPP server. |
| 513 | + */ |
514 | 514 | const id = iq.getAttribute('id');
|
515 | 515 | const from = iq.getAttribute('from');
|
516 |
| - if (from && from !== "" && Strophe.getBareJidFromJid(from) !== _converse.bare_jid) { |
517 |
| - // Receiving client MUST ignore stanza unless it has no from or from = user's bare JID. |
518 |
| - // XXX: Some naughty servers apparently send from a full |
519 |
| - // JID so we need to explicitly compare bare jids here. |
520 |
| - // https://github.com/jcbrand/converse.js/issues/493 |
521 |
| - _converse.connection.send( |
522 |
| - $iq({type: 'error', id, from: _converse.connection.jid}) |
523 |
| - .c('error', {'type': 'cancel'}) |
524 |
| - .c('service-unavailable', {'xmlns': Strophe.NS.ROSTER }) |
525 |
| - ); |
526 |
| - return true; |
| 516 | + if (from && from !== _converse.connection.jid) { |
| 517 | + // https://tools.ietf.org/html/rfc6121#page-15 |
| 518 | + // |
| 519 | + // A receiving client MUST ignore the stanza unless it has no 'from' |
| 520 | + // attribute (i.e., implicitly from the bare JID of the user's |
| 521 | + // account) or it has a 'from' attribute whose value matches the |
| 522 | + // user's bare JID <user@domainpart>. |
| 523 | + return; |
527 | 524 | }
|
528 | 525 | _converse.connection.send($iq({type: 'result', id, from: _converse.connection.jid}));
|
529 | 526 | const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
|
530 |
| - _.each(items, this.updateContact.bind(this)); |
| 527 | + if (items.length > 1) { |
| 528 | + _converse.log(iq, Strophe.LogLevel.ERROR); |
| 529 | + throw new Error('Roster push query may not contain more than one "item" element.'); |
| 530 | + } |
| 531 | + if (items.length === 0) { |
| 532 | + _converse.log(iq, Strophe.LogLevel.WARN); |
| 533 | + _converse.log('Received a roster push stanza without an "item" element.', Strophe.LogLevel.WARN); |
| 534 | + return; |
| 535 | + } |
| 536 | + this.updateContact(items.pop()); |
531 | 537 | _converse.emit('rosterPush', iq);
|
532 |
| - return true; |
| 538 | + return; |
533 | 539 | },
|
534 | 540 |
|
535 | 541 | fetchFromServer () {
|
|
552 | 558 |
|
553 | 559 | onReceivedFromServer (iq) {
|
554 | 560 | /* An IQ stanza containing the roster has been received from
|
555 |
| - * the XMPP server. |
556 |
| - */ |
| 561 | + * the XMPP server. |
| 562 | + */ |
557 | 563 | const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
|
558 | 564 | _.each(items, this.updateContact.bind(this));
|
559 | 565 | _converse.emit('roster', iq);
|
560 | 566 | },
|
561 | 567 |
|
562 | 568 | updateContact (item) {
|
563 | 569 | /* Update or create RosterContact models based on items
|
564 |
| - * received in the IQ from the server. |
565 |
| - */ |
| 570 | + * received in the IQ from the server. |
| 571 | + */ |
566 | 572 | const jid = item.getAttribute('jid');
|
567 | 573 | if (this.isSelf(jid)) { return; }
|
568 | 574 |
|
|
0 commit comments