From 5ab2f3db204fa025a8739ae30609fbcec23044cb Mon Sep 17 00:00:00 2001
From: Andrei Cioromila <andrei.cioromila@thinslices.com>
Date: Thu, 29 Nov 2018 10:50:48 +0200
Subject: [PATCH] feat(user-manager): add password strength validation for each
 applicable route

---
 .../src/routes/users/changePassword.js                 |  9 +++++----
 .../component-user-manager/src/routes/users/post.js    |  5 +++++
 .../src/routes/users/resetPassword.js                  | 10 ++++++----
 packages/xpub-faraday/config/default.js                |  3 +++
 4 files changed, 19 insertions(+), 8 deletions(-)

diff --git a/packages/component-user-manager/src/routes/users/changePassword.js b/packages/component-user-manager/src/routes/users/changePassword.js
index 30073accc..040fd8729 100644
--- a/packages/component-user-manager/src/routes/users/changePassword.js
+++ b/packages/component-user-manager/src/routes/users/changePassword.js
@@ -1,15 +1,16 @@
 const { services } = require('pubsweet-component-helper-service')
 const { token } = require('pubsweet-server/src/authentication')
+const { passwordStrengthRegex } = require('config')
 
 module.exports = models => async (req, res) => {
   const { password, newPassword } = req.body
   if (!services.checkForUndefinedParams(password, newPassword))
     return res.status(400).json({ error: 'Missing required params.' })
 
-  if (newPassword.length < 7)
-    return res
-      .status(400)
-      .json({ error: 'Password needs to be at least 7 characters long.' })
+  if (!passwordStrengthRegex.test(newPassword))
+    return res.status(400).json({
+      error: 'Password is too weak. Please check password requirements.',
+    })
 
   let user
   try {
diff --git a/packages/component-user-manager/src/routes/users/post.js b/packages/component-user-manager/src/routes/users/post.js
index 8150e2ca7..44595c0ae 100644
--- a/packages/component-user-manager/src/routes/users/post.js
+++ b/packages/component-user-manager/src/routes/users/post.js
@@ -1,5 +1,6 @@
 const { pick } = require('lodash')
 const Chance = require('chance')
+const { passwordStrengthRegex } = require('config')
 
 const chance = new Chance()
 
@@ -15,6 +16,10 @@ module.exports = models => async (req, res) => {
         error: 'Terms & Conditions must be read and approved.',
       })
     }
+    if (!passwordStrengthRegex.test(req.body.password))
+      return res.status(400).json({
+        error: 'Password is too weak. Please check password requirements.',
+      })
     req.body = pick(req.body, [
       'email',
       'title',
diff --git a/packages/component-user-manager/src/routes/users/resetPassword.js b/packages/component-user-manager/src/routes/users/resetPassword.js
index b46c9cafd..c42dd4cc1 100644
--- a/packages/component-user-manager/src/routes/users/resetPassword.js
+++ b/packages/component-user-manager/src/routes/users/resetPassword.js
@@ -1,14 +1,16 @@
 const { services } = require('pubsweet-component-helper-service')
 
+const { passwordStrengthRegex } = require('config')
+
 module.exports = models => async (req, res) => {
   const { email, password, token } = req.body
   if (!services.checkForUndefinedParams(email, password, token))
     return res.status(400).json({ error: 'missing required params' })
 
-  if (password.length < 7)
-    return res
-      .status(400)
-      .json({ error: 'password needs to be at least 7 characters long' })
+  if (!passwordStrengthRegex.test(req.body.password))
+    return res.status(400).json({
+      error: 'Password is too weak. Please check password requirements.',
+    })
 
   const validateResponse = await services.validateEmailAndToken({
     email,
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
index 4ac021c51..016905070 100644
--- a/packages/xpub-faraday/config/default.js
+++ b/packages/xpub-faraday/config/default.js
@@ -142,4 +142,7 @@ module.exports = {
       editor: 'editorRecommendation',
     },
   },
+  passwordStrengthRegex: new RegExp(
+    '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{6,128})',
+  ),
 }
-- 
GitLab