v1.18.x
pichalite 8 years ago
parent 07b9bb6fb8
commit 4c89497cc4

@ -95,7 +95,8 @@
"validator": "^6.1.0", "validator": "^6.1.0",
"winston": "^2.1.0", "winston": "^2.1.0",
"xml": "^1.0.1", "xml": "^1.0.1",
"xregexp": "~3.1.0" "xregexp": "~3.1.0",
"zxcvbn": "^4.4.2"
}, },
"devDependencies": { "devDependencies": {
"coveralls": "^2.11.14", "coveralls": "^2.11.14",

@ -37,6 +37,7 @@
"min-username-length": "Minimum Username Length", "min-username-length": "Minimum Username Length",
"max-username-length": "Maximum Username Length", "max-username-length": "Maximum Username Length",
"min-password-length": "Minimum Password Length", "min-password-length": "Minimum Password Length",
"min-password-strength": "Minimum Password Strength",
"max-about-me-length": "Maximum About Me Length", "max-about-me-length": "Maximum About Me Length",
"terms-of-use": "Forum Terms of Use <small>(Leave blank to disable)</small>", "terms-of-use": "Forum Terms of Use <small>(Leave blank to disable)</small>",
"user-search": "User Search", "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>", "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_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.", "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_picture": "Upload picture",
"upload_a_picture": "Upload a picture", "upload_a_picture": "Upload a picture",

@ -1,7 +1,7 @@
'use strict'; '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 = {}; var AccountEditPassword = {};
AccountEditPassword.init = function () { AccountEditPassword.init = function () {
@ -20,6 +20,7 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
var passwordsmatch = false; var passwordsmatch = false;
function onPasswordChanged() { function onPasswordChanged() {
var passwordStrength = zxcvbn(password.val());
passwordvalid = false; passwordvalid = false;
if (password.val().length < ajaxify.data.minimumPasswordLength) { if (password.val().length < ajaxify.data.minimumPasswordLength) {
showError(password_notify, '[[user:change_password_error_length]]'); 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]]'); showError(password_notify, '[[user:password_same_as_username]]');
} else if (password.val() === ajaxify.data.email) { } else if (password.val() === ajaxify.data.email) {
showError(password_notify, '[[user:password_same_as_email]]'); showError(password_notify, '[[user:password_same_as_email]]');
} else if (passwordStrength.score < ajaxify.data.minimumPasswordStrength) {
showError(password_notify, '[[user:weak_password]]');
} else { } else {
showSuccess(password_notify); showSuccess(password_notify);
passwordvalid = true; passwordvalid = true;

@ -1,7 +1,7 @@
'use strict'; 'use strict';
define('forum/register', ['translator'], function (translator) { define('forum/register', ['translator', 'zxcvbn'], function (translator, zxcvbn) {
var Register = {}; var Register = {};
var validationError = false; var validationError = false;
var successIcon = ''; var successIcon = '';
@ -170,6 +170,7 @@ define('forum/register', ['translator'], function (translator) {
function validatePassword(password, password_confirm) { function validatePassword(password, password_confirm) {
var password_notify = $('#password-notify'); var password_notify = $('#password-notify');
var password_confirm_notify = $('#password-confirm-notify'); var password_confirm_notify = $('#password-confirm-notify');
var passwordStrength = zxcvbn(password);
if (password.length < ajaxify.data.minimumPasswordLength) { if (password.length < ajaxify.data.minimumPasswordLength) {
showError(password_notify, '[[user:change_password_error_length]]'); 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]]'); showError(password_notify, '[[user:password_same_as_username]]');
} else if (password === $('#email').val()) { } else if (password === $('#email').val()) {
showError(password_notify, '[[user:password_same_as_email]]'); showError(password_notify, '[[user:password_same_as_email]]');
} else if (passwordStrength.score < ajaxify.data.minimumPasswordStrength) {
showError(password_notify, '[[user:weak_password]]');
} else { } else {
showSuccess(password_notify, successIcon); showSuccess(password_notify, successIcon);
} }

@ -36,15 +36,12 @@ editController.get = function (req, res, callback) {
}); });
userData.title = '[[pages:account/edit, ' + userData.username + ']]'; userData.title = '[[pages:account/edit, ' + userData.username + ']]';
userData.breadcrumbs = helpers.buildBreadcrumbs([ userData.breadcrumbs = helpers.buildBreadcrumbs([{
{
text: userData.username, text: userData.username,
url: '/user/' + userData.userslug, url: '/user/' + userData.userslug,
}, }, {
{
text: '[[user:edit]]', text: '[[user:edit]]',
}, }]);
]);
userData.editButtons = []; userData.editButtons = [];
plugins.fireHook('filter:user.account.edit', userData, function (err, userData) { plugins.fireHook('filter:user.account.edit', userData, function (err, userData) {
@ -80,22 +77,19 @@ function renderRoute(name, req, res, next) {
if (name === 'password') { if (name === 'password') {
userData.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10); userData.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
userData.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
} }
userData.title = '[[pages:account/edit/' + name + ', ' + userData.username + ']]'; userData.title = '[[pages:account/edit/' + name + ', ' + userData.username + ']]';
userData.breadcrumbs = helpers.buildBreadcrumbs([ userData.breadcrumbs = helpers.buildBreadcrumbs([{
{
text: userData.username, text: userData.username,
url: '/user/' + userData.userslug, url: '/user/' + userData.userslug,
}, }, {
{
text: '[[user:edit]]', text: '[[user:edit]]',
url: '/user/' + userData.userslug + '/edit', url: '/user/' + userData.userslug + '/edit',
}, }, {
{
text: '[[user:' + name + ']]', text: '[[user:' + name + ']]',
}, }]);
]);
res.render('account/edit/' + name, userData); res.render('account/edit/' + name, userData);
}); });

@ -48,7 +48,11 @@ Controllers.home = function (req, res, next) {
var hook = 'action:homepage.get:' + route; var hook = 'action:homepage.get:' + route;
if (plugins.hasListeners(hook)) { 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 === '/') { if (route === 'categories' || route === '/') {
@ -85,7 +89,12 @@ Controllers.reset = function (req, res, next) {
displayExpiryNotice: req.session.passwordExpired, displayExpiryNotice: req.session.passwordExpired,
code: req.params.code, code: req.params.code,
minimumPasswordLength: parseInt(meta.config.minimumPasswordLength, 10), 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]]', title: '[[pages:reset]]',
}); });
@ -94,7 +103,9 @@ Controllers.reset = function (req, res, next) {
} else { } else {
res.render('reset', { res.render('reset', {
code: null, code: null,
breadcrumbs: helpers.buildBreadcrumbs([{ text: '[[reset_password:reset_password]]' }]), breadcrumbs: helpers.buildBreadcrumbs([{
text: '[[reset_password:reset_password]]',
}]),
title: '[[pages:reset]]', 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.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.allowRegistration = registrationType === 'normal' || registrationType === 'admin-approval' || registrationType === 'admin-approval-ip';
data.allowLoginWith = '[[login:' + allowLoginWith + ']]'; 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.error = req.flash('error')[0] || errorText;
data.title = '[[pages:login]]'; data.title = '[[pages:login]]';
@ -171,7 +184,11 @@ Controllers.register = function (req, res, next) {
} }
}, },
function (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) { ], function (err, termsOfUse) {
if (err) { if (err) {
@ -188,8 +205,11 @@ Controllers.register = function (req, res, next) {
data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10); data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10);
data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10); data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10);
data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10); data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10);
data.minimumPasswordStrength = parseInt(meta.config.minimumPasswordStrength || 0, 10);
data.termsOfUse = termsOfUse.postData.content; data.termsOfUse = termsOfUse.postData.content;
data.breadcrumbs = helpers.buildBreadcrumbs([{ text: '[[register:register]]' }]); data.breadcrumbs = helpers.buildBreadcrumbs([{
text: '[[register:register]]',
}]);
data.regFormEntry = []; data.regFormEntry = [];
data.error = req.flash('error')[0] || errorText; data.error = req.flash('error')[0] || errorText;
data.title = '[[pages:register]]'; data.title = '[[pages:register]]';
@ -333,7 +353,9 @@ Controllers.outgoing = function (req, res, next) {
res.render('outgoing', { res.render('outgoing', {
outgoing: validator.escape(String(url)), outgoing: validator.escape(String(url)),
title: meta.config.title, 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) { if (!meta.config.termsOfUse) {
return next(); return next();
} }
res.render('tos', { termsOfUse: meta.config.termsOfUse }); res.render('tos', {
termsOfUse: meta.config.termsOfUse,
});
}; };
Controllers.ping = function (req, res) { Controllers.ping = function (req, res) {

@ -89,6 +89,7 @@ module.exports = function (Meta) {
'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js', 'jqueryui.js': 'public/vendor/jquery/js/jquery-ui.js',
'buzz.js': 'public/vendor/buzz/buzz.js', 'buzz.js': 'public/vendor/buzz/buzz.js',
'cropper.js': './node_modules/cropperjs/dist/cropper.min.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')) { if (filePath.endsWith('.min.js')) {
minified = { code: buffer.toString() }; minified = {
code: buffer.toString(),
};
return cb(); 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 * otherwise, just clean up --debug/--debug-brk options which are set up by default from the parent one
*/ */
forkProcessParams = { execArgv: [] }; forkProcessParams = {
execArgv: [],
};
} }
return forkProcessParams; return forkProcessParams;

@ -167,6 +167,16 @@
<label>[[admin/settings/user:min-password-length]]</label> <label>[[admin/settings/user:min-password-length]]</label>
<input type="text" class="form-control" value="6" data-field="minimumPasswordLength"> <input type="text" class="form-control" value="6" data-field="minimumPasswordLength">
</div> </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"> <div class="form-group">
<label>[[admin/settings/user:max-about-me-length]]</label> <label>[[admin/settings/user:max-about-me-length]]</label>
<input type="text" class="form-control" value="500" data-field="maximumAboutMeLength"> <input type="text" class="form-control" value="500" data-field="maximumAboutMeLength">

Loading…
Cancel
Save