diff --git a/package.json b/package.json index 0ab698c631..34bbfc76cd 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "nodebb-plugin-spam-be-gone": "0.4.6", "nodebb-rewards-essentials": "0.0.8", "nodebb-theme-lavender": "3.0.10", - "nodebb-theme-persona": "4.0.131", + "nodebb-theme-persona": "4.0.132", "nodebb-theme-vanilla": "5.0.71", "nodebb-widget-essentials": "2.0.9", "nodemailer": "2.0.0", diff --git a/public/language/en_GB/error.json b/public/language/en_GB/error.json index a77cf6cb06..a159a0e42c 100644 --- a/public/language/en_GB/error.json +++ b/public/language/en_GB/error.json @@ -17,6 +17,7 @@ "invalid-password": "Invalid Password", "invalid-username-or-password": "Please specify both a username and password", "invalid-search-term": "Invalid search term", + "csrf-invalid": "We were unable to log you in, likely due to an expired session. Please try again", "invalid-pagination-value": "Invalid pagination value, must be at least %1 and at most %2", diff --git a/public/language/en_GB/login.json b/public/language/en_GB/login.json index 02abac6371..e76658fe3d 100644 --- a/public/language/en_GB/login.json +++ b/public/language/en_GB/login.json @@ -5,7 +5,7 @@ "remember_me": "Remember Me?", "forgot_password": "Forgot Password?", "alternative_logins": "Alternative Logins", - "failed_login_attempt": "Failed login attempt, please try again.", + "failed_login_attempt": "Login Unsuccessful", "login_successful": "You have successfully logged in!", "dont_have_account": "Don't have an account?" } diff --git a/public/src/client/login.js b/public/src/client/login.js index 85aeb68be5..eda34c8add 100644 --- a/public/src/client/login.js +++ b/public/src/client/login.js @@ -31,9 +31,13 @@ define('forum/login', ['csrf', 'translator'], function(csrf, translator) { window.location.href = data + '?loggedin'; }, error: function(data, status) { - errorEl.find('p').translateText(data.responseText); - errorEl.show(); - submitEl.removeClass('disabled'); + if (data.status === 403 && data.statusText === 'Forbidden') { + window.location.href = config.relative_path + '/login?error=csrf-invalid'; + } else { + errorEl.find('p').translateText(data.responseText); + errorEl.show(); + submitEl.removeClass('disabled'); + } } }); } diff --git a/public/src/client/register.js b/public/src/client/register.js index da86c0231d..fdf4b3ab7e 100644 --- a/public/src/client/register.js +++ b/public/src/client/register.js @@ -99,9 +99,13 @@ define('forum/register', ['csrf', 'translator'], function(csrf, translator) { }, error: function(data) { translator.translate(data.responseText, config.defaultLang, function(translated) { - errorEl.find('p').text(translated); - errorEl.removeClass('hidden'); - registerBtn.removeClass('disabled'); + if (data.status === 403 && data.statusText === 'Forbidden') { + window.location.href = config.relative_path + '/register?error=csrf-invalid'; + } else { + errorEl.find('p').text(translated); + errorEl.removeClass('hidden'); + registerBtn.removeClass('disabled'); + } }); } }); diff --git a/src/controllers/index.js b/src/controllers/index.js index 76d86cee31..f0a6e8d023 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -102,13 +102,18 @@ Controllers.login = function(req, res, next) { var allowLoginWith = (meta.config.allowLoginWith || 'username-email'); + var errorText; + if (req.query.error === 'csrf-invalid') { + errorText = '[[error:csrf-invalid]]'; + } + data.alternate_logins = loginStrategies.length > 0; data.authentication = loginStrategies; data.allowLocalLogin = parseInt(meta.config.allowLocalLogin, 10) === 1 || parseInt(req.query.local, 10) === 1; data.allowRegistration = registrationType === 'normal' || registrationType === 'admin-approval'; data.allowLoginWith = '[[login:' + allowLoginWith + ']]'; data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[global:login]]'}]); - data.error = req.flash('error')[0]; + data.error = req.flash('error')[0] || errorText; data.title = '[[pages:login]]'; if (!data.allowLocalLogin && !data.allowRegistration && data.alternate_logins && data.authentication.length === 1) { @@ -137,6 +142,11 @@ Controllers.register = function(req, res, next) { return next(); } + var errorText; + if (req.query.error === 'csrf-invalid') { + errorText = '[[error:csrf-invalid]]'; + } + async.waterfall([ function(next) { if (registrationType === 'invite-only' || registrationType === 'admin-invite-only') { @@ -166,7 +176,7 @@ Controllers.register = function(req, res, next) { data.termsOfUse = termsOfUse.postData.content; data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[register:register]]'}]); data.regFormEntry = []; - data.error = req.flash('error')[0]; + data.error = req.flash('error')[0] || errorText; data.title = '[[pages:register]]'; res.render('register', data);