diff --git a/src/groups/cover.js b/src/groups/cover.js index a18062f307..c4b4024486 100644 --- a/src/groups/cover.js +++ b/src/groups/cover.js @@ -1,80 +1,60 @@ 'use strict'; -var async = require('async'); -var path = require('path'); +const path = require('path'); -var db = require('../database'); -var image = require('../image'); -var file = require('../file'); +const db = require('../database'); +const image = require('../image'); +const file = require('../file'); module.exports = function (Groups) { - Groups.updateCoverPosition = function (groupName, position, callback) { + Groups.updateCoverPosition = async function (groupName, position) { if (!groupName) { - return callback(new Error('[[error:invalid-data]]')); + throw new Error('[[error:invalid-data]]'); } - Groups.setGroupField(groupName, 'cover:position', position, callback); + await Groups.setGroupField(groupName, 'cover:position', position); }; - Groups.updateCover = function (uid, data, callback) { - // Position only? That's fine - if (!data.imageData && !data.file && data.position) { - return Groups.updateCoverPosition(data.groupName, data.position, callback); - } + Groups.updateCover = async function (uid, data) { + let tempPath = data.file ? data.file : ''; + try { + // Position only? That's fine + if (!data.imageData && !data.file && data.position) { + return await Groups.updateCoverPosition(data.groupName, data.position); + } + if (!tempPath) { + tempPath = await image.writeImageDataToTempFile(data.imageData); + } + const filename = 'groupCover-' + data.groupName + path.extname(tempPath); + const uploadData = await image.uploadImage(filename, 'files', { + path: tempPath, + uid: uid, + name: 'groupCover', + }); + const url = uploadData.url; + await Groups.setGroupField(data.groupName, 'cover:url', url); - var tempPath = data.file ? data.file : ''; - var url; + await image.resizeImage({ + path: tempPath, + width: 358, + }); + const thumbUploadData = await image.uploadImage('groupCoverThumb-' + data.groupName + path.extname(tempPath), 'files', { + path: tempPath, + uid: uid, + name: 'groupCover', + }); + await Groups.setGroupField(data.groupName, 'cover:thumb:url', thumbUploadData.url); - async.waterfall([ - function (next) { - if (tempPath) { - return next(null, tempPath); - } - image.writeImageDataToTempFile(data.imageData, next); - }, - function (_tempPath, next) { - tempPath = _tempPath; + if (data.position) { + await Groups.updateCoverPosition(data.groupName, data.position); + } - const filename = 'groupCover-' + data.groupName + path.extname(tempPath); - image.uploadImage(filename, 'files', { - path: tempPath, - uid: uid, - name: 'groupCover', - }, next); - }, - function (uploadData, next) { - url = uploadData.url; - Groups.setGroupField(data.groupName, 'cover:url', url, next); - }, - function (next) { - image.resizeImage({ - path: tempPath, - width: 358, - }, next); - }, - function (next) { - image.uploadImage('groupCoverThumb-' + data.groupName + path.extname(tempPath), 'files', { - path: tempPath, - uid: uid, - name: 'groupCover', - }, next); - }, - function (uploadData, next) { - Groups.setGroupField(data.groupName, 'cover:thumb:url', uploadData.url, next); - }, - function (next) { - if (data.position) { - Groups.updateCoverPosition(data.groupName, data.position, next); - } else { - next(null); - } - }, - ], function (err) { + return { url: url }; + } finally { file.delete(tempPath); - callback(err, { url: url }); - }); + } }; - Groups.removeCover = function (data, callback) { - db.deleteObjectFields('group:' + data.groupName, ['cover:url', 'cover:thumb:url', 'cover:position'], callback); + Groups.removeCover = async function (data) { + await db.deleteObjectFields('group:' + data.groupName, ['cover:url', 'cover:thumb:url', 'cover:position']); }; }; diff --git a/src/groups/create.js b/src/groups/create.js index a5b60e68b5..8b8625cf9b 100644 --- a/src/groups/create.js +++ b/src/groups/create.js @@ -1,79 +1,67 @@ 'use strict'; -var async = require('async'); -var meta = require('../meta'); -var plugins = require('../plugins'); -var utils = require('../utils'); -var db = require('../database'); +const meta = require('../meta'); +const plugins = require('../plugins'); +const utils = require('../utils'); +const db = require('../database'); module.exports = function (Groups) { - Groups.create = function (data, callback) { - var isSystem = isSystemGroup(data); - var groupData; - var timestamp = data.timestamp || Date.now(); - var disableJoinRequests = parseInt(data.disableJoinRequests, 10) === 1 ? 1 : 0; + Groups.create = async function (data) { + const isSystem = isSystemGroup(data); + const timestamp = data.timestamp || Date.now(); + let disableJoinRequests = parseInt(data.disableJoinRequests, 10) === 1 ? 1 : 0; if (data.name === 'administrators') { disableJoinRequests = 1; } - var isHidden = parseInt(data.hidden, 10) === 1; - async.waterfall([ - function (next) { - validateGroupName(data.name, next); - }, - function (next) { - meta.userOrGroupExists(data.name, next); - }, - function (exists, next) { - if (exists) { - return next(new Error('[[error:group-already-exists]]')); - } + const isHidden = parseInt(data.hidden, 10) === 1; - var memberCount = data.hasOwnProperty('ownerUid') ? 1 : 0; - var isPrivate = data.hasOwnProperty('private') ? parseInt(data.private, 10) : 1; - var slug = utils.slugify(data.name); - groupData = { - name: data.name, - slug: slug, - createtime: timestamp, - userTitle: data.userTitle || data.name, - userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0, - description: data.description || '', - memberCount: memberCount, - hidden: isHidden ? 1 : 0, - system: isSystem ? 1 : 0, - private: isPrivate, - disableJoinRequests: disableJoinRequests, - }; - plugins.fireHook('filter:group.create', { group: groupData, data: data }, next); - }, - function (results, next) { - var tasks = [ - async.apply(db.sortedSetAdd, 'groups:createtime', groupData.createtime, groupData.name), - async.apply(db.setObject, 'group:' + groupData.name, groupData), - ]; + validateGroupName(data.name); - if (data.hasOwnProperty('ownerUid')) { - tasks.push(async.apply(db.setAdd, 'group:' + groupData.name + ':owners', data.ownerUid)); - tasks.push(async.apply(db.sortedSetAdd, 'group:' + groupData.name + ':members', timestamp, data.ownerUid)); + const exists = await meta.userOrGroupExists(data.name); + if (exists) { + throw new Error('[[error:group-already-exists]]'); + } - groupData.ownerUid = data.ownerUid; - } + const memberCount = data.hasOwnProperty('ownerUid') ? 1 : 0; + const isPrivate = data.hasOwnProperty('private') ? parseInt(data.private, 10) : 1; + const groupData = { + name: data.name, + slug: utils.slugify(data.name), + createtime: timestamp, + userTitle: data.userTitle || data.name, + userTitleEnabled: parseInt(data.userTitleEnabled, 10) === 1 ? 1 : 0, + description: data.description || '', + memberCount: memberCount, + hidden: isHidden ? 1 : 0, + system: isSystem ? 1 : 0, + private: isPrivate, + disableJoinRequests: disableJoinRequests, + }; - if (!isHidden && !isSystem) { - tasks.push(async.apply(db.sortedSetAdd, 'groups:visible:createtime', timestamp, groupData.name)); - tasks.push(async.apply(db.sortedSetAdd, 'groups:visible:memberCount', groupData.memberCount, groupData.name)); - tasks.push(async.apply(db.sortedSetAdd, 'groups:visible:name', 0, groupData.name.toLowerCase() + ':' + groupData.name)); - } + plugins.fireHook('filter:group.create', { group: groupData, data: data }); - tasks.push(async.apply(db.setObjectField, 'groupslug:groupname', groupData.slug, groupData.name)); + await db.sortedSetAdd('groups:createtime', groupData.createtime, groupData.name); + await db.setObject('group:' + groupData.name, groupData); - async.series(tasks, next); - }, - function (results, next) { - plugins.fireHook('action:group.create', { group: groupData }); - next(null, groupData); - }, - ], callback); + if (data.hasOwnProperty('ownerUid')) { + await db.setAdd('group:' + groupData.name + ':owners', data.ownerUid); + await db.sortedSetAdd('group:' + groupData.name + ':members', timestamp, data.ownerUid); + + groupData.ownerUid = data.ownerUid; + } + + if (!isHidden && !isSystem) { + await db.sortedSetAddBulk([ + ['groups:visible:createtime', timestamp, groupData.name], + ['groups:visible:memberCount', groupData.memberCount, groupData.name], + ['groups:visible:name', 0, groupData.name.toLowerCase() + ':' + groupData.name], + ]); + } + + await db.setObjectField('groupslug:groupname', groupData.slug, groupData.name); + + plugins.fireHook('action:group.create', { group: groupData }); + return groupData; }; function isSystemGroup(data) { @@ -82,23 +70,21 @@ module.exports = function (Groups) { Groups.isPrivilegeGroup(data.name); } - function validateGroupName(name, callback) { + function validateGroupName(name) { if (!name) { - return callback(new Error('[[error:group-name-too-short]]')); + throw new Error('[[error:group-name-too-short]]'); } if (!Groups.isPrivilegeGroup(name) && name.length > meta.config.maximumGroupNameLength) { - return callback(new Error('[[error:group-name-too-long]]')); + throw new Error('[[error:group-name-too-long]]'); } if (name === 'guests' || (!Groups.isPrivilegeGroup(name) && name.includes(':'))) { - return callback(new Error('[[error:invalid-group-name]]')); + throw new Error('[[error:invalid-group-name]]'); } if (name.includes('/') || !utils.slugify(name)) { - return callback(new Error('[[error:invalid-group-name]]')); + throw new Error('[[error:invalid-group-name]]'); } - - callback(); } }; diff --git a/src/groups/data.js b/src/groups/data.js index 7d85624f34..c50d3b263b 100644 --- a/src/groups/data.js +++ b/src/groups/data.js @@ -1,12 +1,11 @@ 'use strict'; -var async = require('async'); -var validator = require('validator'); -var nconf = require('nconf'); +const validator = require('validator'); +const nconf = require('nconf'); -var db = require('../database'); -var plugins = require('../plugins'); -var utils = require('../utils'); +const db = require('../database'); +const plugins = require('../plugins'); +const utils = require('../utils'); const intFields = [ 'createtime', 'memberCount', 'hidden', 'system', 'private', @@ -14,70 +13,54 @@ const intFields = [ ]; module.exports = function (Groups) { - Groups.getGroupsFields = function (groupNames, fields, callback) { + Groups.getGroupsFields = async function (groupNames, fields) { if (!Array.isArray(groupNames) || !groupNames.length) { - return callback(null, []); + return []; } - var ephemeralIdx = groupNames.reduce(function (memo, cur, idx) { + const ephemeralIdx = groupNames.reduce(function (memo, cur, idx) { if (Groups.ephemeralGroups.includes(cur)) { memo.push(idx); } return memo; }, []); - async.waterfall([ - function (next) { - const keys = groupNames.map(groupName => 'group:' + groupName); - if (fields.length) { - db.getObjectsFields(keys, fields, next); - } else { - db.getObjects(keys, next); - } - }, - function (groupData, next) { - if (ephemeralIdx.length) { - ephemeralIdx.forEach(function (idx) { - groupData[idx] = Groups.getEphemeralGroup(groupNames[idx]); - }); - } + let groupData; + const keys = groupNames.map(groupName => 'group:' + groupName); + if (fields.length) { + groupData = await db.getObjectsFields(keys, fields); + } else { + groupData = await db.getObjects(keys); + } + if (ephemeralIdx.length) { + ephemeralIdx.forEach(function (idx) { + groupData[idx] = Groups.getEphemeralGroup(groupNames[idx]); + }); + } - groupData.forEach(group => modifyGroup(group, fields)); + groupData.forEach(group => modifyGroup(group, fields)); - plugins.fireHook('filter:groups.get', { groups: groupData }, next); - }, - function (results, next) { - next(null, results.groups); - }, - ], callback); + const results = await plugins.fireHook('filter:groups.get', { groups: groupData }); + return results.groups; }; - Groups.getGroupsData = function (groupNames, callback) { - Groups.getGroupsFields(groupNames, [], callback); + Groups.getGroupsData = async function (groupNames) { + return await Groups.getGroupsFields(groupNames, []); }; - Groups.getGroupData = function (groupName, callback) { - Groups.getGroupsData([groupName], function (err, groupsData) { - callback(err, Array.isArray(groupsData) && groupsData[0] ? groupsData[0] : null); - }); + Groups.getGroupData = async function (groupName) { + const groupsData = await Groups.getGroupsData([groupName]); + return Array.isArray(groupsData) && groupsData[0] ? groupsData[0] : null; }; - Groups.getGroupFields = function (groupName, fields, callback) { - Groups.getGroupsFields([groupName], fields, function (err, groups) { - callback(err, groups ? groups[0] : null); - }); + Groups.getGroupFields = async function (groupName, fields) { + const groups = await Groups.getGroupsFields([groupName], fields); + return groups ? groups[0] : null; }; - Groups.setGroupField = function (groupName, field, value, callback) { - async.waterfall([ - function (next) { - db.setObjectField('group:' + groupName, field, value, next); - }, - function (next) { - plugins.fireHook('action:group.set', { field: field, value: value, type: 'set' }); - next(); - }, - ], callback); + Groups.setGroupField = async function (groupName, field, value) { + await db.setObjectField('group:' + groupName, field, value); + plugins.fireHook('action:group.set', { field: field, value: value, type: 'set' }); }; };