mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-30 02:25:55 +01:00
Closes #5521
This commit is contained in:
@@ -95,7 +95,8 @@
|
||||
"validator": "^6.1.0",
|
||||
"winston": "^2.1.0",
|
||||
"xml": "^1.0.1",
|
||||
"xregexp": "~3.1.0"
|
||||
"xregexp": "~3.1.0",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"coveralls": "^2.11.14",
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"min-username-length": "Minimum Username Length",
|
||||
"max-username-length": "Maximum Username Length",
|
||||
"min-password-length": "Minimum Password Length",
|
||||
"min-password-strength": "Minimum Password Strength",
|
||||
"max-about-me-length": "Maximum About Me Length",
|
||||
"terms-of-use": "Forum Terms of Use <small>(Leave blank to disable)</small>",
|
||||
"user-search": "User Search",
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
"username_taken_workaround": "The username you requested was already taken, so we have altered it slightly. You are now known as <strong>%1</strong>",
|
||||
"password_same_as_username": "Your password is the same as your username, please select another password.",
|
||||
"password_same_as_email": "Your password is the same as your email, please select another password.",
|
||||
"weak_password": "Weak password.",
|
||||
|
||||
"upload_picture": "Upload picture",
|
||||
"upload_a_picture": "Upload a picture",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
define('forum/account/edit/password', ['forum/account/header', 'translator'], function (header, translator) {
|
||||
define('forum/account/edit/password', ['forum/account/header', 'translator', 'zxcvbn'], function (header, translator, zxcvbn) {
|
||||
var AccountEditPassword = {};
|
||||
|
||||
AccountEditPassword.init = function () {
|
||||
@@ -20,6 +20,7 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
|
||||
var passwordsmatch = false;
|
||||
|
||||
function onPasswordChanged() {
|
||||
var passwordStrength = zxcvbn(password.val());
|
||||
passwordvalid = false;
|
||||
if (password.val().length < ajaxify.data.minimumPasswordLength) {
|
||||
showError(password_notify, '[[user:change_password_error_length]]');
|
||||
@@ -29,6 +30,8 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
|
||||
showError(password_notify, '[[user:password_same_as_username]]');
|
||||
} else if (password.val() === ajaxify.data.email) {
|
||||
showError(password_notify, '[[user:password_same_as_email]]');
|
||||
} else if (passwordStrength.score < ajaxify.data.minimumPasswordStrength) {
|
||||
showError(password_notify, '[[user:weak_password]]');
|
||||
} else {
|
||||
showSuccess(password_notify);
|
||||
passwordvalid = true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
|
||||
define('forum/register', ['translator'], function (translator) {
|
||||
define('forum/register', ['translator', 'zxcvbn'], function (translator, zxcvbn) {
|
||||
var Register = {};
|
||||
var validationError = false;
|
||||
var successIcon = '';
|
||||
@@ -170,6 +170,7 @@ define('forum/register', ['translator'], function (translator) {
|
||||
function validatePassword(password, password_confirm) {
|
||||
var password_notify = $('#password-notify');
|
||||
var password_confirm_notify = $('#password-confirm-notify');
|
||||
var passwordStrength = zxcvbn(password);
|
||||
|
||||
if (password.length < ajaxify.data.minimumPasswordLength) {
|
||||
showError(password_notify, '[[user:change_password_error_length]]');
|
||||
@@ -181,6 +182,8 @@ define('forum/register', ['translator'], function (translator) {
|
||||
showError(password_notify, '[[user:password_same_as_username]]');
|
||||
} else if (password === $('#email').val()) {
|
||||
showError(password_notify, '[[user:password_same_as_email]]');
|
||||
} else if (passwordStrength.score < ajaxify.data.minimumPasswordStrength) {
|
||||
showError(password_notify, '[[user:weak_password]]');
|
||||
} else {
|
||||
showSuccess(password_notify, successIcon);
|
||||
}
|
||||
|
||||
@@ -36,15 +36,12 @@ editController.get = function (req, res, callback) {
|
||||
});
|
||||
|
||||
userData.title = '[[pages:account/edit, ' + userData.username + ']]';
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
{
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([{
|
||||
text: userData.username,
|
||||
url: '/user/' + userData.userslug,
|
||||
},
|
||||
{
|
||||
}, {
|
||||
text: '[[user:edit]]',
|
||||
},
|
||||
]);
|
||||
}]);
|
||||
userData.editButtons = [];
|
||||
|
||||
plugins.fireHook('filter:user.account.edit', userData, function (err, userData) {
|
||||
@@ -80,22 +77,19 @@ function renderRoute(name, req, res, next) {
|
||||
|
||||
if (name === 'password') {
|
||||
userData.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
|
||||
userData.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
|
||||
}
|
||||
|
||||
userData.title = '[[pages:account/edit/' + name + ', ' + userData.username + ']]';
|
||||
userData.breadcrumbs = helpers.buildBreadcrumbs([
|
||||
{
|
||||
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);
|
||||
});
|
||||
|
||||
@@ -48,7 +48,11 @@ Controllers.home = function (req, res, next) {
|
||||
var hook = 'action:homepage.get:' + route;
|
||||
|
||||
if (plugins.hasListeners(hook)) {
|
||||
return plugins.fireHook(hook, { req: req, res: res, next: next });
|
||||
return plugins.fireHook(hook, {
|
||||
req: req,
|
||||
res: res,
|
||||
next: next,
|
||||
});
|
||||
}
|
||||
|
||||
if (route === 'categories' || route === '/') {
|
||||
@@ -85,7 +89,12 @@ Controllers.reset = function (req, res, next) {
|
||||
displayExpiryNotice: req.session.passwordExpired,
|
||||
code: req.params.code,
|
||||
minimumPasswordLength: parseInt(meta.config.minimumPasswordLength, 10),
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[reset_password:reset_password]]', url: '/reset' }, { text: '[[reset_password:update_password]]' }]),
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{
|
||||
text: '[[reset_password:reset_password]]',
|
||||
url: '/reset',
|
||||
}, {
|
||||
text: '[[reset_password:update_password]]',
|
||||
}]),
|
||||
title: '[[pages:reset]]',
|
||||
});
|
||||
|
||||
@@ -94,7 +103,9 @@ Controllers.reset = function (req, res, next) {
|
||||
} else {
|
||||
res.render('reset', {
|
||||
code: null,
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[reset_password:reset_password]]' }]),
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{
|
||||
text: '[[reset_password:reset_password]]',
|
||||
}]),
|
||||
title: '[[pages:reset]]',
|
||||
});
|
||||
}
|
||||
@@ -124,7 +135,9 @@ Controllers.login = function (req, res, next) {
|
||||
data.allowLocalLogin = parseInt(meta.config.allowLocalLogin, 10) === 1 || parseInt(req.query.local, 10) === 1;
|
||||
data.allowRegistration = registrationType === 'normal' || registrationType === 'admin-approval' || registrationType === 'admin-approval-ip';
|
||||
data.allowLoginWith = '[[login:' + allowLoginWith + ']]';
|
||||
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[global:login]]' }]);
|
||||
data.breadcrumbs = helpers.buildBreadcrumbs([{
|
||||
text: '[[global:login]]',
|
||||
}]);
|
||||
data.error = req.flash('error')[0] || errorText;
|
||||
data.title = '[[pages:login]]';
|
||||
|
||||
@@ -171,7 +184,11 @@ Controllers.register = function (req, res, next) {
|
||||
}
|
||||
},
|
||||
function (next) {
|
||||
plugins.fireHook('filter:parse.post', { postData: { content: meta.config.termsOfUse || '' } }, next);
|
||||
plugins.fireHook('filter:parse.post', {
|
||||
postData: {
|
||||
content: meta.config.termsOfUse || '',
|
||||
},
|
||||
}, next);
|
||||
},
|
||||
], function (err, termsOfUse) {
|
||||
if (err) {
|
||||
@@ -188,8 +205,11 @@ Controllers.register = function (req, res, next) {
|
||||
data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10);
|
||||
data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10);
|
||||
data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
|
||||
data.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
|
||||
data.termsOfUse = termsOfUse.postData.content;
|
||||
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[register:register]]' }]);
|
||||
data.breadcrumbs = helpers.buildBreadcrumbs([{
|
||||
text: '[[register:register]]',
|
||||
}]);
|
||||
data.regFormEntry = [];
|
||||
data.error = req.flash('error')[0] || errorText;
|
||||
data.title = '[[pages:register]]';
|
||||
@@ -333,7 +353,9 @@ Controllers.outgoing = function (req, res, next) {
|
||||
res.render('outgoing', {
|
||||
outgoing: validator.escape(String(url)),
|
||||
title: meta.config.title,
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[notifications:outgoing_link]]' }]),
|
||||
breadcrumbs: helpers.buildBreadcrumbs([{
|
||||
text: '[[notifications:outgoing_link]]',
|
||||
}]),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -341,7 +363,9 @@ Controllers.termsOfUse = function (req, res, next) {
|
||||
if (!meta.config.termsOfUse) {
|
||||
return next();
|
||||
}
|
||||
res.render('tos', { termsOfUse: meta.config.termsOfUse });
|
||||
res.render('tos', {
|
||||
termsOfUse: meta.config.termsOfUse,
|
||||
});
|
||||
};
|
||||
|
||||
Controllers.ping = function (req, res) {
|
||||
|
||||
@@ -89,6 +89,7 @@ module.exports = function (Meta) {
|
||||
'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js',
|
||||
'buzz.js': 'public/vendor/buzz/buzz.js',
|
||||
'cropper.js': './node_modules/cropperjs/dist/cropper.min.js',
|
||||
'zxcvbn.js': './node_modules/zxcvbn/dist/zxcvbn.js',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -110,7 +111,9 @@ module.exports = function (Meta) {
|
||||
}
|
||||
|
||||
if (filePath.endsWith('.min.js')) {
|
||||
minified = { code: buffer.toString() };
|
||||
minified = {
|
||||
code: buffer.toString(),
|
||||
};
|
||||
return cb();
|
||||
}
|
||||
|
||||
@@ -345,7 +348,9 @@ module.exports = function (Meta) {
|
||||
/**
|
||||
* otherwise, just clean up --debug/--debug-brk options which are set up by default from the parent one
|
||||
*/
|
||||
forkProcessParams = { execArgv: [] };
|
||||
forkProcessParams = {
|
||||
execArgv: [],
|
||||
};
|
||||
}
|
||||
|
||||
return forkProcessParams;
|
||||
|
||||
@@ -167,6 +167,16 @@
|
||||
<label>[[admin/settings/user:min-password-length]]</label>
|
||||
<input type="text" class="form-control" value="6" data-field="minimumPasswordLength">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>[[admin/settings/user:min-password-strength]]</label>
|
||||
<select class="form-control" data-field="minimumPasswordStrength">
|
||||
<option value="0">0 - too guessable: risky password</option>
|
||||
<option value="1">1 - very guessable</option>
|
||||
<option value="2">2 - somewhat guessable</option>
|
||||
<option value="3">3 - safely unguessable</option>
|
||||
<option value="4">4 - very unguessable</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>[[admin/settings/user:max-about-me-length]]</label>
|
||||
<input type="text" class="form-control" value="500" data-field="maximumAboutMeLength">
|
||||
|
||||
Reference in New Issue
Block a user