소스 검색

Work around a Prosody bug.

Prosody doesn't handle it if we set the affiliation for multiple JIDs in one
stanza, so we need to send a stanza for each JID.

Refs https://prosody.im/issues/issue/795
JC Brand 8 년 전
부모
커밋
0bcf61389f
1개의 변경된 파일27개의 추가작업 그리고 20개의 파일을 삭제
  1. 27 20
      src/converse-muc.js

+ 27 - 20
src/converse-muc.js

@@ -587,11 +587,16 @@
                 },
 
                 setAffiliation: function (affiliation, members) {
-                    /* Send an IQ stanzas to the server to modify one particular
-                     * affiliation for certain members
+                    /* Send IQ stanzas to the server to set an affiliation for
+                     * the provided JIDs.
                      *
                      * See: http://xmpp.org/extensions/xep-0045.html#modifymember
                      *
+                     * XXX: Prosody doesn't accept multiple JIDs' affiliations
+                     * being set in one IQ stanza, so as a workaround we send
+                     * a separate stanza for each JID.
+                     * Related ticket: https://prosody.im/issues/issue/795
+                     *
                      * Parameters:
                      *  (Object) members: A map of jids, affiliations and
                      *      optionally reasons. Only those entries with the
@@ -602,26 +607,28 @@
                      *  A promise which resolves and fails depending on the
                      *  XMPP server response.
                      */
-                    var deferred = new $.Deferred();
-                    var iq = $iq({to: this.model.get('jid'), type: "set"})
-                        .c("query", {xmlns: Strophe.NS.MUC_ADMIN});
-
-                    _.each(members, function (member) {
-                        if (!_.isUndefined(member.affiliation) &&
-                                member.affiliation !== affiliation) {
-                            return;
-                        }
-                        iq.c("item", {
-                            'affiliation': member.affiliation || affiliation,
-                            'jid': member.jid
-                        });
+                    members = _.filter(members, function (member) {
+                        // We only want those members who have the right
+                        // affiliation (or none, which implies the provided
+                        // one).
+                        return _.isUndefined(member.affiliation) ||
+                                member.affiliation === affiliation;
+                    });
+                    var promises = _.map(members, function (member) {
+                        var deferred = new $.Deferred();
+                        var iq = $iq({to: this.model.get('jid'), type: "set"})
+                            .c("query", {xmlns: Strophe.NS.MUC_ADMIN})
+                            .c("item", {
+                                'affiliation': member.affiliation || affiliation,
+                                'jid': member.jid
+                            });
                         if (!_.isUndefined(member.reason)) {
-                            iq.c("reason", member.reason).up();
+                            iq.c("reason", member.reason);
                         }
-                        iq.up();
-                    });
-                    converse.connection.sendIQ(iq, deferred.resolve, deferred.reject);
-                    return deferred;
+                        converse.connection.sendIQ(iq, deferred.resolve, deferred.reject);
+                        return deferred;
+                    }, this);
+                    return $.when.apply($, promises);
                 },
 
                 setAffiliations: function (members, onSuccess, onError) {