mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-02 12:05:57 +01:00
closes #1637
This commit is contained in:
@@ -29,6 +29,9 @@
|
||||
"chat": "Chatting with %1",
|
||||
|
||||
"account/edit": "Editing \"%1\"",
|
||||
"account/edit/password": "Editing password of \"%1\"",
|
||||
"account/edit/username": "Editing username of \"%1\"",
|
||||
"account/edit/email": "Editing email of \"%1\"",
|
||||
"account/following": "People %1 follows",
|
||||
"account/followers": "People who follow %1",
|
||||
"account/posts": "Posts made by %1",
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
|
||||
"profile_update_success": "Profile has been updated successfully!",
|
||||
"change_picture": "Change Picture",
|
||||
"change_username": "Change Username",
|
||||
"change_email": "Change Email",
|
||||
"edit": "Edit",
|
||||
"uploaded_picture": "Uploaded Picture",
|
||||
"upload_new_picture": "Upload New Picture",
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define, ajaxify, socket, app, config, utils, bootbox */
|
||||
/* globals define, ajaxify, socket, app, config, templates, bootbox */
|
||||
|
||||
define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'], function(header, uploader, translator) {
|
||||
var AccountEdit = {},
|
||||
gravatarPicture = '',
|
||||
uploadedPicture = '',
|
||||
selectedImageType = '',
|
||||
currentEmail;
|
||||
selectedImageType = '';
|
||||
|
||||
AccountEdit.init = function() {
|
||||
gravatarPicture = ajaxify.data.gravatarpicture;
|
||||
@@ -25,12 +24,9 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
|
||||
});
|
||||
});
|
||||
|
||||
currentEmail = $('#inputEmail').val();
|
||||
|
||||
handleImageChange();
|
||||
handleAccountDelete();
|
||||
handleEmailConfirm();
|
||||
handlePasswordChange();
|
||||
updateSignature();
|
||||
updateAboutMe();
|
||||
};
|
||||
@@ -38,8 +34,6 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
|
||||
function updateProfile() {
|
||||
var userData = {
|
||||
uid: $('#inputUID').val(),
|
||||
username: $('#inputUsername').val(),
|
||||
email: $('#inputEmail').val(),
|
||||
fullname: $('#inputFullname').val(),
|
||||
website: $('#inputWebsite').val(),
|
||||
birthday: $('#inputBirthday').val(),
|
||||
@@ -64,27 +58,13 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
|
||||
gravatarPicture = data.gravatarpicture;
|
||||
}
|
||||
|
||||
if (data.userslug) {
|
||||
var oldslug = $('.account-username-box').attr('data-userslug');
|
||||
$('.account-username-box a').each(function() {
|
||||
$(this).attr('href', $(this).attr('href').replace(oldslug, data.userslug));
|
||||
});
|
||||
|
||||
$('.account-username-box').attr('data-userslug', data.userslug);
|
||||
}
|
||||
|
||||
if (currentEmail !== data.email) {
|
||||
currentEmail = data.email;
|
||||
$('#confirm-email').removeClass('hide');
|
||||
}
|
||||
|
||||
updateHeader(data.picture, userData.username, data.userslug);
|
||||
updateHeader(data.picture);
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function updateHeader(picture, username, userslug) {
|
||||
function updateHeader(picture) {
|
||||
require(['components'], function(components) {
|
||||
if (parseInt(ajaxify.data.theirid, 10) !== parseInt(ajaxify.data.yourid, 10)) {
|
||||
return;
|
||||
@@ -93,11 +73,6 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
|
||||
if (picture) {
|
||||
components.get('header/userpicture').attr('src', picture);
|
||||
}
|
||||
|
||||
if (username && userslug) {
|
||||
components.get('header/profilelink').attr('href', config.relative_path + '/user/' + userslug);
|
||||
components.get('header/username').text(username);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -282,88 +257,6 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
|
||||
});
|
||||
}
|
||||
|
||||
function handlePasswordChange() {
|
||||
var currentPassword = $('#inputCurrentPassword');
|
||||
var password_notify = $('#password-notify');
|
||||
var password_confirm_notify = $('#password-confirm-notify');
|
||||
var password = $('#inputNewPassword');
|
||||
var password_confirm = $('#inputNewPasswordAgain');
|
||||
var passwordvalid = false;
|
||||
var passwordsmatch = false;
|
||||
|
||||
function onPasswordChanged() {
|
||||
if (password.val().length < config.minimumPasswordLength) {
|
||||
showError(password_notify, '[[user:change_password_error_length]]');
|
||||
passwordvalid = false;
|
||||
} else if (!utils.isPasswordValid(password.val())) {
|
||||
showError(password_notify, '[[user:change_password_error]]');
|
||||
passwordvalid = false;
|
||||
} else {
|
||||
showSuccess(password_notify);
|
||||
passwordvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
function onPasswordConfirmChanged() {
|
||||
if (password.val() !== password_confirm.val()) {
|
||||
showError(password_confirm_notify, '[[user:change_password_error_match]]');
|
||||
passwordsmatch = false;
|
||||
} else {
|
||||
if (password.val()) {
|
||||
showSuccess(password_confirm_notify);
|
||||
} else {
|
||||
password_confirm_notify.parent().removeClass('alert-success alert-danger');
|
||||
password_confirm_notify.children().show();
|
||||
password_confirm_notify.find('.msg').html('');
|
||||
}
|
||||
|
||||
passwordsmatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
password.on('blur', onPasswordChanged);
|
||||
password_confirm.on('blur', onPasswordConfirmChanged);
|
||||
|
||||
$('#changePasswordBtn').on('click', function() {
|
||||
onPasswordChanged();
|
||||
onPasswordConfirmChanged();
|
||||
|
||||
var btn = $(this);
|
||||
if ((passwordvalid && passwordsmatch) || app.user.isAdmin) {
|
||||
btn.addClass('disabled').find('i').removeClass('hide');
|
||||
socket.emit('user.changePassword', {
|
||||
'currentPassword': currentPassword.val(),
|
||||
'newPassword': password.val(),
|
||||
'uid': ajaxify.data.theirid
|
||||
}, function(err) {
|
||||
btn.removeClass('disabled').find('i').addClass('hide');
|
||||
currentPassword.val('');
|
||||
password.val('');
|
||||
password_confirm.val('');
|
||||
passwordsmatch = false;
|
||||
passwordvalid = false;
|
||||
|
||||
if (err) {
|
||||
onPasswordChanged();
|
||||
onPasswordConfirmChanged();
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
app.alertSuccess('[[user:change_password_success]]');
|
||||
});
|
||||
} else {
|
||||
if (!passwordsmatch) {
|
||||
app.alertError('[[user:change_password_error_match]]');
|
||||
}
|
||||
|
||||
if (!passwordvalid) {
|
||||
app.alertError('[[user:change_password_error]]');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function changeUserPicture(type, callback) {
|
||||
socket.emit('user.changePicture', {
|
||||
type: type,
|
||||
@@ -393,24 +286,6 @@ define('forum/account/edit', ['forum/account/header', 'uploader', 'translator'],
|
||||
});
|
||||
}
|
||||
|
||||
function showError(element, msg) {
|
||||
translator.translate(msg, function(msg) {
|
||||
element.find('.error').html(msg).removeClass('hide').siblings().addClass('hide');
|
||||
|
||||
element.parent()
|
||||
.removeClass('alert-success')
|
||||
.addClass('alert-danger');
|
||||
element.show();
|
||||
});
|
||||
}
|
||||
|
||||
function showSuccess(element) {
|
||||
element.find('.success').removeClass('hide').siblings().addClass('hide');
|
||||
element.parent()
|
||||
.removeClass('alert-danger')
|
||||
.addClass('alert-success');
|
||||
element.show();
|
||||
}
|
||||
|
||||
return AccountEdit;
|
||||
});
|
||||
|
||||
39
public/src/client/account/edit/email.js
Normal file
39
public/src/client/account/edit/email.js
Normal file
@@ -0,0 +1,39 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define, ajaxify, socket, app */
|
||||
|
||||
define('forum/account/edit/email', ['forum/account/header'], function(header) {
|
||||
var AccountEditEmail = {};
|
||||
|
||||
AccountEditEmail.init = function() {
|
||||
header.init();
|
||||
|
||||
$('#submitBtn').on('click', function () {
|
||||
var userData = {
|
||||
uid: $('#inputUID').val(),
|
||||
email: $('#inputNewEmail').val(),
|
||||
password: $('#inputCurrentPassword').val()
|
||||
};
|
||||
|
||||
if (!userData.email) {
|
||||
return;
|
||||
}
|
||||
|
||||
var btn = $(this);
|
||||
btn.addClass('disabled').find('i').removeClass('hide');
|
||||
|
||||
socket.emit('user.changeUsernameEmail', userData, function(err) {
|
||||
btn.removeClass('disabled').find('i').addClass('hide');
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
ajaxify.go('user/' + ajaxify.data.userslug);
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
return AccountEditEmail;
|
||||
});
|
||||
116
public/src/client/account/edit/password.js
Normal file
116
public/src/client/account/edit/password.js
Normal file
@@ -0,0 +1,116 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define, ajaxify, socket, app, config, utils */
|
||||
|
||||
define('forum/account/edit/password', ['forum/account/header', 'translator'], function(header, translator) {
|
||||
var AccountEditPassword = {};
|
||||
|
||||
AccountEditPassword.init = function() {
|
||||
header.init();
|
||||
|
||||
handlePasswordChange();
|
||||
};
|
||||
|
||||
function handlePasswordChange() {
|
||||
var currentPassword = $('#inputCurrentPassword');
|
||||
var password_notify = $('#password-notify');
|
||||
var password_confirm_notify = $('#password-confirm-notify');
|
||||
var password = $('#inputNewPassword');
|
||||
var password_confirm = $('#inputNewPasswordAgain');
|
||||
var passwordvalid = false;
|
||||
var passwordsmatch = false;
|
||||
|
||||
function onPasswordChanged() {
|
||||
if (password.val().length < config.minimumPasswordLength) {
|
||||
showError(password_notify, '[[user:change_password_error_length]]');
|
||||
passwordvalid = false;
|
||||
} else if (!utils.isPasswordValid(password.val())) {
|
||||
showError(password_notify, '[[user:change_password_error]]');
|
||||
passwordvalid = false;
|
||||
} else {
|
||||
showSuccess(password_notify);
|
||||
passwordvalid = true;
|
||||
}
|
||||
}
|
||||
|
||||
function onPasswordConfirmChanged() {
|
||||
if (password.val() !== password_confirm.val()) {
|
||||
showError(password_confirm_notify, '[[user:change_password_error_match]]');
|
||||
passwordsmatch = false;
|
||||
} else {
|
||||
if (password.val()) {
|
||||
showSuccess(password_confirm_notify);
|
||||
} else {
|
||||
password_confirm_notify.parent().removeClass('alert-success alert-danger');
|
||||
password_confirm_notify.children().show();
|
||||
password_confirm_notify.find('.msg').html('');
|
||||
}
|
||||
|
||||
passwordsmatch = true;
|
||||
}
|
||||
}
|
||||
|
||||
password.on('blur', onPasswordChanged);
|
||||
password_confirm.on('blur', onPasswordConfirmChanged);
|
||||
|
||||
$('#changePasswordBtn').on('click', function() {
|
||||
onPasswordChanged();
|
||||
onPasswordConfirmChanged();
|
||||
|
||||
var btn = $(this);
|
||||
if ((passwordvalid && passwordsmatch) || app.user.isAdmin) {
|
||||
btn.addClass('disabled').find('i').removeClass('hide');
|
||||
socket.emit('user.changePassword', {
|
||||
'currentPassword': currentPassword.val(),
|
||||
'newPassword': password.val(),
|
||||
'uid': ajaxify.data.theirid
|
||||
}, function(err) {
|
||||
btn.removeClass('disabled').find('i').addClass('hide');
|
||||
currentPassword.val('');
|
||||
password.val('');
|
||||
password_confirm.val('');
|
||||
passwordsmatch = false;
|
||||
passwordvalid = false;
|
||||
|
||||
if (err) {
|
||||
onPasswordChanged();
|
||||
onPasswordConfirmChanged();
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
ajaxify.go('user/' + ajaxify.data.userslug);
|
||||
app.alertSuccess('[[user:change_password_success]]');
|
||||
});
|
||||
} else {
|
||||
if (!passwordsmatch) {
|
||||
app.alertError('[[user:change_password_error_match]]');
|
||||
}
|
||||
|
||||
if (!passwordvalid) {
|
||||
app.alertError('[[user:change_password_error]]');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function showError(element, msg) {
|
||||
translator.translate(msg, function(msg) {
|
||||
element.find('.error').html(msg).removeClass('hide').siblings().addClass('hide');
|
||||
|
||||
element.parent()
|
||||
.removeClass('alert-success')
|
||||
.addClass('alert-danger');
|
||||
element.show();
|
||||
});
|
||||
}
|
||||
|
||||
function showSuccess(element) {
|
||||
element.find('.success').removeClass('hide').siblings().addClass('hide');
|
||||
element.parent()
|
||||
.removeClass('alert-danger')
|
||||
.addClass('alert-success');
|
||||
element.show();
|
||||
}
|
||||
|
||||
return AccountEditPassword;
|
||||
});
|
||||
43
public/src/client/account/edit/username.js
Normal file
43
public/src/client/account/edit/username.js
Normal file
@@ -0,0 +1,43 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define, ajaxify, socket, app, utils, config */
|
||||
|
||||
define('forum/account/edit/username', ['forum/account/header'], function(header) {
|
||||
var AccountEditUsername = {};
|
||||
|
||||
AccountEditUsername.init = function() {
|
||||
header.init();
|
||||
|
||||
$('#submitBtn').on('click', function updateUsername() {
|
||||
var userData = {
|
||||
uid: $('#inputUID').val(),
|
||||
username: $('#inputNewUsername').val(),
|
||||
password: $('#inputCurrentPassword').val()
|
||||
};
|
||||
|
||||
if (!userData.username) {
|
||||
return;
|
||||
}
|
||||
var btn = $(this);
|
||||
btn.addClass('disabled').find('i').removeClass('hide');
|
||||
socket.emit('user.changeUsernameEmail', userData, function(err) {
|
||||
btn.removeClass('disabled').find('i').addClass('hide');
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
var userslug = utils.slugify(userData.username);
|
||||
if (userData.username && userslug && parseInt(userData.uid, 10) === parseInt(app.user.uid, 10)) {
|
||||
$('[component="header/profilelink"]').attr('href', config.relative_path + '/user/' + userslug);
|
||||
$('[component="header/username"]').text(userData.username);
|
||||
}
|
||||
|
||||
ajaxify.go('user/' + userslug);
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
return AccountEditUsername;
|
||||
});
|
||||
@@ -14,6 +14,48 @@ var async = require('async'),
|
||||
var editController = {};
|
||||
|
||||
editController.get = function(req, res, callback) {
|
||||
accountHelpers.getUserDataByUserSlug(req.params.userslug, req.uid, function(err, userData) {
|
||||
if (err || !userData) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
userData.title = '[[pages:account/edit, ' + userData.username + ']]';
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([{text: userData.username, url: '/user/' + userData.userslug}, {text: '[[user:edit]]'}]);
|
||||
|
||||
res.render('account/edit', userData);
|
||||
});
|
||||
};
|
||||
|
||||
editController.password = function(req, res, next) {
|
||||
renderRoute('password', req, res, next);
|
||||
};
|
||||
|
||||
editController.username = function(req, res, next) {
|
||||
renderRoute('username', req, res, next);
|
||||
};
|
||||
|
||||
editController.email = function(req, res, next) {
|
||||
renderRoute('email', req, res, next);
|
||||
};
|
||||
|
||||
function renderRoute(name, req, res, next) {
|
||||
getUserData(req, next, function(err, userData) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
userData.title = '[[pages:account/edit/' + name + ', ' + userData.username + ']]';
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
{text: userData.username, url: '/user/' + userData.userslug},
|
||||
{text: '[[user:edit]]', url: '/user/' + userData.userslug + '/edit'},
|
||||
{text: '[[user:' + name + ']]'}
|
||||
]);
|
||||
|
||||
res.render('account/edit/' + name, userData);
|
||||
});
|
||||
}
|
||||
|
||||
function getUserData(req, next, callback) {
|
||||
var userData;
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
@@ -22,7 +64,7 @@ editController.get = function(req, res, callback) {
|
||||
function(data, next) {
|
||||
userData = data;
|
||||
if (!userData) {
|
||||
return callback();
|
||||
return next();
|
||||
}
|
||||
db.getObjectField('user:' + userData.uid, 'password', next);
|
||||
}
|
||||
@@ -33,13 +75,9 @@ editController.get = function(req, res, callback) {
|
||||
|
||||
userData['username:disableEdit'] = parseInt(meta.config['username:disableEdit'], 10) === 1;
|
||||
userData.hasPassword = !!password;
|
||||
userData.title = '[[pages:account/edit, ' + userData.username + ']]';
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([{text: userData.username, url: '/user/' + userData.userslug}, {text: '[[user:edit]]'}]);
|
||||
|
||||
res.render('account/edit', userData);
|
||||
callback(null, userData);
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
editController.uploadPicture = function (req, res, next) {
|
||||
var userPhoto = req.files.files[0];
|
||||
|
||||
@@ -17,6 +17,9 @@ module.exports = function (app, middleware, controllers) {
|
||||
setupPageRoute(app, '/user/:userslug/favourites', middleware, accountMiddlewares, controllers.accounts.posts.getFavourites);
|
||||
setupPageRoute(app, '/user/:userslug/watched', middleware, accountMiddlewares, controllers.accounts.posts.getWatchedTopics);
|
||||
setupPageRoute(app, '/user/:userslug/edit', middleware, accountMiddlewares, controllers.accounts.edit.get);
|
||||
setupPageRoute(app, '/user/:userslug/edit/username', middleware, accountMiddlewares, controllers.accounts.edit.username);
|
||||
setupPageRoute(app, '/user/:userslug/edit/email', middleware, accountMiddlewares, controllers.accounts.edit.email);
|
||||
setupPageRoute(app, '/user/:userslug/edit/password', middleware, accountMiddlewares, controllers.accounts.edit.password);
|
||||
setupPageRoute(app, '/user/:userslug/settings', middleware, accountMiddlewares, controllers.accounts.settings.get);
|
||||
|
||||
setupPageRoute(app, '/notifications', middleware, [middleware.authenticate], controllers.accounts.notifications.get);
|
||||
|
||||
@@ -116,19 +116,6 @@ SocketUser.reset.commit = function(socket, data, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
SocketUser.isAdminOrSelf = function(socket, uid, callback) {
|
||||
if (socket.uid === parseInt(uid, 10)) {
|
||||
return callback();
|
||||
}
|
||||
user.isAdministrator(socket.uid, function(err, isAdmin) {
|
||||
if (err || !isAdmin) {
|
||||
return callback(err || new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
SocketUser.follow = function(socket, data, callback) {
|
||||
if (!socket.uid || !data) {
|
||||
return;
|
||||
@@ -182,7 +169,7 @@ SocketUser.saveSettings = function(socket, data, callback) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
SocketUser.isAdminOrSelf(socket, data.uid, function(err) {
|
||||
user.isAdminOrSelf(socket.uid, data.uid, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ module.exports = function(SocketUser) {
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
SocketUser.isAdminOrSelf(socket, data.uid, next);
|
||||
user.isAdminOrSelf(socket.uid, data.uid, next);
|
||||
},
|
||||
function (next) {
|
||||
user.getUserField(data.uid, type, next);
|
||||
@@ -44,7 +44,7 @@ module.exports = function(SocketUser) {
|
||||
return;
|
||||
}
|
||||
|
||||
SocketUser.isAdminOrSelf(socket, data.uid, function(err) {
|
||||
user.isAdminOrSelf(socket.uid, data.uid, function(err) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
@@ -61,7 +61,7 @@ module.exports = function(SocketUser) {
|
||||
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
SocketUser.isAdminOrSelf(socket, data.uid, next);
|
||||
user.isAdminOrSelf(socket.uid, data.uid, next);
|
||||
},
|
||||
function (next) {
|
||||
user.getUserField(data.uid, 'uploadedpicture', next);
|
||||
|
||||
@@ -8,6 +8,47 @@ var events = require('../../events');
|
||||
|
||||
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) {
|
||||
isAdminOrSelfAndPasswordMatch(socket.uid, data, next);
|
||||
},
|
||||
function (next) {
|
||||
SocketUser.updateProfile(socket, data, next);
|
||||
}
|
||||
], callback);
|
||||
};
|
||||
|
||||
function isAdminOrSelfAndPasswordMatch(uid, data, callback) {
|
||||
async.parallel({
|
||||
isAdmin: function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
},
|
||||
passwordMatch: function(next) {
|
||||
user.isPasswordCorrect(data.uid, data.password, next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
var self = parseInt(uid, 10) === parseInt(data.uid, 10);
|
||||
|
||||
if (!results.isAdmin && !self) {
|
||||
return callback(new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
|
||||
if (self && !results.passwordMatch) {
|
||||
return callback(new Error('[[error:invalid-password]]'));
|
||||
}
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
SocketUser.changePassword = function(socket, data, callback) {
|
||||
if (!data || !data.uid || data.newPassword.length < meta.config.minimumPasswordLength) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
@@ -31,7 +72,6 @@ module.exports = function(SocketUser) {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
SocketUser.updateProfile = function(socket, data, callback) {
|
||||
if (!socket.uid) {
|
||||
return callback('[[error:invalid-uid]]');
|
||||
@@ -55,9 +95,10 @@ module.exports = function(SocketUser) {
|
||||
if (parseInt(meta.config['username:disableEdit'], 10) === 1) {
|
||||
data.username = oldUserData.username;
|
||||
}
|
||||
SocketUser.isAdminOrSelf(socket, data.uid, next);
|
||||
user.isAdminOrSelf(socket.uid, data.uid, next);
|
||||
},
|
||||
function (next) {
|
||||
console.log('updating profile', data)
|
||||
user.updateProfile(data.uid, data, next);
|
||||
},
|
||||
function (userData, next) {
|
||||
|
||||
26
src/user.js
26
src/user.js
@@ -3,14 +3,11 @@
|
||||
var async = require('async'),
|
||||
nconf = require('nconf'),
|
||||
gravatar = require('gravatar'),
|
||||
validator = require('validator'),
|
||||
|
||||
plugins = require('./plugins'),
|
||||
db = require('./database'),
|
||||
meta = require('./meta'),
|
||||
topics = require('./topics'),
|
||||
groups = require('./groups'),
|
||||
Password = require('./password'),
|
||||
privileges = require('./privileges'),
|
||||
utils = require('../public/src/utils');
|
||||
|
||||
@@ -36,6 +33,7 @@ var async = require('async'),
|
||||
require('./user/picture')(User);
|
||||
require('./user/approval')(User);
|
||||
require('./user/invite')(User);
|
||||
require('./user/password')(User);
|
||||
|
||||
User.updateLastOnlineTime = function(uid, callback) {
|
||||
callback = callback || function() {};
|
||||
@@ -160,14 +158,6 @@ var async = require('async'),
|
||||
return gravatar.url(email, options, true);
|
||||
};
|
||||
|
||||
User.hashPassword = function(password, callback) {
|
||||
if (!password) {
|
||||
return callback(null, password);
|
||||
}
|
||||
|
||||
Password.hash(nconf.get('bcrypt_rounds') || 12, password, callback);
|
||||
};
|
||||
|
||||
User.exists = function(uid, callback) {
|
||||
db.isSortedSetMember('users:joindate', uid, callback);
|
||||
};
|
||||
@@ -176,7 +166,7 @@ var async = require('async'),
|
||||
User.getUidByUserslug(userslug, function(err, exists) {
|
||||
callback(err, !! exists);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
User.getUidByUsername = function(username, callback) {
|
||||
if (!username) {
|
||||
@@ -242,6 +232,18 @@ var async = require('async'),
|
||||
privileges.users.isAdministrator(uid, callback);
|
||||
};
|
||||
|
||||
User.isAdminOrSelf = function(callerUid, uid, callback) {
|
||||
if (parseInt(callerUid, 10) === parseInt(uid, 10)) {
|
||||
return callback();
|
||||
}
|
||||
User.isAdministrator(callerUid, function(err, isAdmin) {
|
||||
if (err || !isAdmin) {
|
||||
return callback(err || new Error('[[error:no-privileges]]'));
|
||||
}
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
}(exports));
|
||||
|
||||
|
||||
28
src/user/password.js
Normal file
28
src/user/password.js
Normal file
@@ -0,0 +1,28 @@
|
||||
'use strict';
|
||||
|
||||
var nconf = require('nconf');
|
||||
|
||||
var db = require('../database');
|
||||
var Password = require('../password');
|
||||
|
||||
module.exports = function(User) {
|
||||
|
||||
User.hashPassword = function(password, callback) {
|
||||
if (!password) {
|
||||
return callback(null, password);
|
||||
}
|
||||
|
||||
Password.hash(nconf.get('bcrypt_rounds') || 12, password, callback);
|
||||
};
|
||||
|
||||
User.isPasswordCorrect = function(uid, password, callback) {
|
||||
db.getObjectField('user:' + uid, 'password', function(err, hashedPassword) {
|
||||
if (err || !hashedPassword) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
Password.compare(password || '', hashedPassword, callback);
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
@@ -273,30 +273,21 @@ module.exports = function(User) {
|
||||
return callback(new Error('[[user:change_password_error]]'));
|
||||
}
|
||||
|
||||
if(parseInt(uid, 10) !== parseInt(data.uid, 10)) {
|
||||
if (parseInt(uid, 10) !== parseInt(data.uid, 10)) {
|
||||
User.isAdministrator(uid, function(err, isAdmin) {
|
||||
if(err || !isAdmin) {
|
||||
if (err || !isAdmin) {
|
||||
return callback(err || new Error('[[user:change_password_error_privileges'));
|
||||
}
|
||||
|
||||
hashAndSetPassword(callback);
|
||||
});
|
||||
} else {
|
||||
db.getObjectField('user:' + uid, 'password', function(err, currentPassword) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
User.isPasswordCorrect(uid, data.currentPassword, function(err, correct) {
|
||||
if (err || !correct) {
|
||||
return callback(err || new Error('[[user:change_password_error_wrong_current]]'));
|
||||
}
|
||||
|
||||
if (!currentPassword) {
|
||||
return hashAndSetPassword(callback);
|
||||
}
|
||||
|
||||
Password.compare(data.currentPassword, currentPassword, function(err, res) {
|
||||
if (err || !res) {
|
||||
return callback(err || new Error('[[user:change_password_error_wrong_current]]'));
|
||||
}
|
||||
hashAndSetPassword(callback);
|
||||
});
|
||||
hashAndSetPassword(callback);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user