You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
5.7 KiB
JavaScript
220 lines
5.7 KiB
JavaScript
'use strict';
|
|
|
|
var async = require('async');
|
|
|
|
var user = require('../../user');
|
|
var meta = require('../../meta');
|
|
var events = require('../../events');
|
|
var privileges = require('../../privileges');
|
|
|
|
module.exports = function (SocketUser) {
|
|
SocketUser.changeUsernameEmail = function (socket, data, callback) {
|
|
if (!data || !data.uid || !socket.uid) {
|
|
return callback(new Error('[[error:invalid-data]]'));
|
|
}
|
|
|
|
async.waterfall([
|
|
function (next) {
|
|
isPrivilegedOrSelfAndPasswordMatch(socket.uid, data, next);
|
|
},
|
|
function (next) {
|
|
SocketUser.updateProfile(socket, data, next);
|
|
},
|
|
], callback);
|
|
};
|
|
|
|
SocketUser.updateCover = function (socket, data, callback) {
|
|
if (!socket.uid) {
|
|
return callback(new Error('[[error:no-privileges]]'));
|
|
}
|
|
async.waterfall([
|
|
function (next) {
|
|
user.isAdminOrGlobalModOrSelf(socket.uid, data.uid, next);
|
|
},
|
|
function (next) {
|
|
user.checkMinReputation(socket.uid, data.uid, 'min:rep:cover-picture', next);
|
|
},
|
|
function (next) {
|
|
user.updateCoverPicture(data, next);
|
|
},
|
|
], callback);
|
|
};
|
|
|
|
SocketUser.uploadCroppedPicture = function (socket, data, callback) {
|
|
if (!socket.uid) {
|
|
return callback(new Error('[[error:no-privileges]]'));
|
|
}
|
|
async.waterfall([
|
|
function (next) {
|
|
user.isAdminOrGlobalModOrSelf(socket.uid, data.uid, next);
|
|
},
|
|
function (next) {
|
|
user.checkMinReputation(socket.uid, data.uid, 'min:rep:profile-picture', next);
|
|
},
|
|
function (next) {
|
|
user.uploadCroppedPicture(data, next);
|
|
},
|
|
], callback);
|
|
};
|
|
|
|
SocketUser.removeCover = function (socket, data, callback) {
|
|
if (!socket.uid) {
|
|
return callback(new Error('[[error:no-privileges]]'));
|
|
}
|
|
|
|
async.waterfall([
|
|
function (next) {
|
|
user.isAdminOrGlobalModOrSelf(socket.uid, data.uid, next);
|
|
},
|
|
function (next) {
|
|
user.removeCoverPicture(data, next);
|
|
},
|
|
], callback);
|
|
};
|
|
|
|
function isPrivilegedOrSelfAndPasswordMatch(uid, data, callback) {
|
|
async.waterfall([
|
|
function (next) {
|
|
async.parallel({
|
|
isAdmin: async.apply(user.isAdministrator, uid),
|
|
isTargetAdmin: async.apply(user.isAdministrator, data.uid),
|
|
isGlobalMod: async.apply(user.isGlobalModerator, uid),
|
|
hasPassword: async.apply(user.hasPassword, data.uid),
|
|
passwordMatch: function (next) {
|
|
if (data.password) {
|
|
user.isPasswordCorrect(data.uid, data.password, next);
|
|
} else {
|
|
next(null, false);
|
|
}
|
|
},
|
|
}, next);
|
|
},
|
|
function (results, next) {
|
|
var isSelf = parseInt(uid, 10) === parseInt(data.uid, 10);
|
|
|
|
if (results.isTargetAdmin && !results.isAdmin) {
|
|
return next(new Error('[[error:no-privileges]]'));
|
|
}
|
|
|
|
if (!isSelf && !(results.isAdmin || results.isGlobalMod)) {
|
|
return next(new Error('[[error:no-privileges]]'));
|
|
}
|
|
|
|
if (isSelf && results.hasPassword && !results.passwordMatch) {
|
|
return next(new Error('[[error:invalid-password]]'));
|
|
}
|
|
|
|
next();
|
|
},
|
|
], callback);
|
|
}
|
|
|
|
SocketUser.changePassword = function (socket, data, callback) {
|
|
if (!socket.uid) {
|
|
return callback(new Error('[[error:invalid-uid]]'));
|
|
}
|
|
|
|
if (!data || !data.uid) {
|
|
return callback(new Error('[[error:invalid-data]]'));
|
|
}
|
|
async.waterfall([
|
|
function (next) {
|
|
user.changePassword(socket.uid, data, next);
|
|
},
|
|
function (next) {
|
|
events.log({
|
|
type: 'password-change',
|
|
uid: socket.uid,
|
|
targetUid: data.uid,
|
|
ip: socket.ip,
|
|
});
|
|
next();
|
|
},
|
|
], callback);
|
|
};
|
|
|
|
SocketUser.updateProfile = function (socket, data, callback) {
|
|
if (!socket.uid) {
|
|
return callback(new Error('[[error:invalid-uid]]'));
|
|
}
|
|
|
|
if (!data || !data.uid) {
|
|
return callback(new Error('[[error:invalid-data]]'));
|
|
}
|
|
|
|
var oldUserData;
|
|
async.waterfall([
|
|
function (next) {
|
|
user.getUserFields(data.uid, ['email', 'username'], next);
|
|
},
|
|
function (_oldUserData, next) {
|
|
oldUserData = _oldUserData;
|
|
if (!oldUserData || !oldUserData.username) {
|
|
return next(new Error('[[error:invalid-data]]'));
|
|
}
|
|
|
|
async.parallel({
|
|
isAdminOrGlobalMod: function (next) {
|
|
user.isAdminOrGlobalMod(socket.uid, next);
|
|
},
|
|
canEdit: function (next) {
|
|
privileges.users.canEdit(socket.uid, data.uid, next);
|
|
},
|
|
}, next);
|
|
},
|
|
function (results, next) {
|
|
if (!results.canEdit) {
|
|
return next(new Error('[[error:no-privileges]]'));
|
|
}
|
|
|
|
if (!results.isAdminOrGlobalMod && parseInt(meta.config['username:disableEdit'], 10) === 1) {
|
|
data.username = oldUserData.username;
|
|
}
|
|
|
|
if (!results.isAdminOrGlobalMod && parseInt(meta.config['email:disableEdit'], 10) === 1) {
|
|
data.email = oldUserData.email;
|
|
}
|
|
|
|
user.updateProfile(socket.uid, data, next);
|
|
},
|
|
function (userData, next) {
|
|
function log(type, eventData) {
|
|
eventData.type = type;
|
|
eventData.uid = socket.uid;
|
|
eventData.targetUid = data.uid;
|
|
eventData.ip = socket.ip;
|
|
|
|
events.log(eventData);
|
|
}
|
|
|
|
if (userData.email !== oldUserData.email) {
|
|
log('email-change', { oldEmail: oldUserData.email, newEmail: userData.email });
|
|
}
|
|
|
|
if (userData.username !== oldUserData.username) {
|
|
log('username-change', { oldUsername: oldUserData.username, newUsername: userData.username });
|
|
}
|
|
|
|
next(null, userData);
|
|
},
|
|
], callback);
|
|
};
|
|
|
|
SocketUser.toggleBlock = function (socket, data, callback) {
|
|
async.waterfall([
|
|
function (next) {
|
|
user.blocks.can(socket.uid, data.blockerUid, data.blockeeUid, next);
|
|
},
|
|
function (can, next) {
|
|
if (!can) {
|
|
return next(new Error('[[error:cannot-block-privileged]]'));
|
|
}
|
|
user.blocks.is(data.blockeeUid, data.blockerUid, next);
|
|
},
|
|
function (is, next) {
|
|
user.blocks[is ? 'remove' : 'add'](data.blockeeUid, data.blockerUid, next);
|
|
},
|
|
], callback);
|
|
};
|
|
};
|