diff --git a/package-lock.json b/package-lock.json
index 08eda3c2f1..6996a2be09 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -43,7 +43,8 @@
"react-modal": "^3.15.1",
"sanitize-html": "^2.7.1",
"tippy.js": "^6.3.7",
- "twemoji": "^14.0.2"
+ "twemoji": "^14.0.2",
+ "zxcvbn": "^4.4.2"
},
"devDependencies": {
"@babel/core": "^7.18.10",
@@ -14304,6 +14305,11 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zxcvbn": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
+ "integrity": "sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ=="
}
},
"dependencies": {
@@ -25024,6 +25030,11 @@
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
"dev": true
+ },
+ "zxcvbn": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
+ "integrity": "sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ=="
}
}
}
diff --git a/package.json b/package.json
index b9d9cd70c8..bd7258638b 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,8 @@
"react-modal": "^3.15.1",
"sanitize-html": "^2.7.1",
"tippy.js": "^6.3.7",
- "twemoji": "^14.0.2"
+ "twemoji": "^14.0.2",
+ "zxcvbn": "^4.4.2"
},
"devDependencies": {
"@babel/core": "^7.18.10",
diff --git a/src/app/pages/App.jsx b/src/app/pages/App.jsx
index af7cc29b00..ad404843b1 100644
--- a/src/app/pages/App.jsx
+++ b/src/app/pages/App.jsx
@@ -1,12 +1,16 @@
-import React from 'react';
+import React, { lazy, Suspense } from 'react';
import { isAuthenticated } from '../../client/state/auth';
-import Auth from '../templates/auth/Auth';
-import Client from '../templates/client/Client';
+const Auth = lazy(() => import('../templates/auth/Auth'));
+const Client = lazy(() => import('../templates/client/Client'));
function App() {
- return isAuthenticated() ? : ;
+ return (
+ }>
+ { isAuthenticated() ? : }
+
+ );
}
export default App;
diff --git a/src/app/templates/auth/Auth.jsx b/src/app/templates/auth/Auth.jsx
index 7c21173605..a1bbb5a4e5 100644
--- a/src/app/templates/auth/Auth.jsx
+++ b/src/app/templates/auth/Auth.jsx
@@ -5,6 +5,7 @@ import './Auth.scss';
import ReCAPTCHA from 'react-google-recaptcha';
import { Formik } from 'formik';
+import zxcvbn from 'zxcvbn';
import * as auth from '../../../client/action/auth';
import cons from '../../../client/state/cons';
import { Debounce, getUrlPrams } from '../../../util/common';
@@ -30,8 +31,6 @@ const LOCALPART_SIGNUP_REGEX = /^[a-z0-9_\-.=/]+$/;
const BAD_LOCALPART_ERROR = 'Username can only contain characters a-z, 0-9, or \'=_-./\'';
const USER_ID_TOO_LONG_ERROR = 'Your user ID, including the hostname, can\'t be more than 255 characters long.';
-const PASSWORD_STRENGHT_REGEX = /^(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d\s:])([^\s]){8,127}$/;
-const BAD_PASSWORD_ERROR = 'Password must contain at least 1 lowercase, 1 uppercase, 1 number, 1 non-alphanumeric character, 8-127 characters with no space.';
const CONFIRM_PASSWORD_ERROR = 'Passwords don\'t match.';
const EMAIL_REGEX = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i;
@@ -317,8 +316,11 @@ function Register({ registerInfo, loginFlow, baseUrl }) {
if (values.username.length > 0 && !isValidInput(values.username, LOCALPART_SIGNUP_REGEX)) {
errors.username = BAD_LOCALPART_ERROR;
}
- if (values.password.length > 0 && !isValidInput(values.password, PASSWORD_STRENGHT_REGEX)) {
- errors.password = BAD_PASSWORD_ERROR;
+ if (values.password.length > 0) {
+ const result = zxcvbn(values.password);
+ if (result.feedback) {
+ errors.password = result.feedback.warning;
+ }
}
if (values.confirmPassword.length > 0
&& !isValidInput(values.confirmPassword, values.password)) {