diff --git a/public/src/modules/helpers.js b/public/src/modules/helpers.js
index 838ad7a4da..bc40bde658 100644
--- a/public/src/modules/helpers.js
+++ b/public/src/modules/helpers.js
@@ -26,7 +26,7 @@
if (groupObj.isMember) {
return '';
} else {
- if (groupObj.pending) {
+ if (groupObj.isPending) {
return '';
} else {
return '';
diff --git a/src/groups.js b/src/groups.js
index 60019a47b9..eadabda28f 100644
--- a/src/groups.js
+++ b/src/groups.js
@@ -144,6 +144,14 @@ var async = require('async'),
next(null, isMember);
});
},
+ isPending: function(next) {
+ // Retrieve group membership state, if uid is passed in
+ if (!options.uid) {
+ return next();
+ }
+
+ db.isSetMember('group:' + groupName + ':pending', options.uid, next);
+ },
isOwner: function(next) {
// Retrieve group ownership state, if uid is passed in
if (!options.uid) {
@@ -173,12 +181,19 @@ var async = require('async'),
results.base.deletable = !results.base.system;
results.base.truncated = truncated;
results.base.isMember = results.isMember;
+ results.base.isPending = results.isPending;
results.base.isOwner = results.isOwner;
callback(err, results.base);
});
};
+ Groups.isPrivate = function(groupName, callback) {
+ db.getObjectField('group:' + groupName, 'private', function(err, isPrivate) {
+ callback(err, isPrivate || isPrivate === null); // Private, if not set at all
+ });
+ };
+
Groups.getMembers = function(groupName, callback) {
db.getSetMembers('group:' + groupName + ':members', callback);
};
@@ -521,6 +536,20 @@ var async = require('async'),
});
};
+ Groups.requestMembership = function(groupName, uid, callback) {
+ db.setAdd('group:' + groupName + ':pending', uid, callback);
+ plugins.fireHook('action:groups.requestMembership', {
+ groupName: groupName,
+ uid: uid
+ });
+ };
+
+ Groups.approveMembership = function(groupName, uid, callback) {
+ // Note: For simplicity, this method intentially doesn't check the caller uid for ownership!
+ db.setRemove('group:' + groupName + ':pending', uid, callback);
+ Groups.join.apply(Groups, arguments);
+ };
+
Groups.leave = function(groupName, uid, callback) {
callback = callback || function() {};
diff --git a/src/socket.io/groups.js b/src/socket.io/groups.js
index 943b9dc10c..366a12348f 100644
--- a/src/socket.io/groups.js
+++ b/src/socket.io/groups.js
@@ -1,6 +1,7 @@
"use strict";
var groups = require('../groups'),
+ meta = require('../meta'),
SocketGroups = {};
@@ -9,7 +10,17 @@ SocketGroups.join = function(socket, data, callback) {
return callback(new Error('[[error:invalid-data]]'));
}
- groups.join(data.groupName, socket.uid, callback);
+ if (meta.config.allowPrivateGroups) {
+ groups.isPrivate(data.groupName, function(err, isPrivate) {
+ if (isPrivate) {
+ groups.requestMembership(data.groupName, socket.uid, callback);
+ } else {
+ groups.join(data.groupName, socket.uid, callback);
+ }
+ });
+ } else {
+ groups.join(data.groupName, socket.uid, callback);
+ }
};
SocketGroups.leave = function(socket, data, callback) {