From d66931e1c61843d606e1d6d44ba1eea4b06ece7c Mon Sep 17 00:00:00 2001
From: Dessalines <dessalines@users.noreply.github.com>
Date: Sun, 19 Sep 2021 15:32:51 -0400
Subject: [PATCH] Password strength meter (#427)

* Updating translations.

* Updating translations.

* Add password strength meter. Fixes #388
---
 lemmy-translations                        |  2 +-
 package.json                              |  1 +
 src/shared/components/home/login.tsx      | 54 +++++++++++++++++++++++
 src/shared/components/person/settings.tsx |  6 ---
 yarn.lock                                 |  5 +++
 5 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/lemmy-translations b/lemmy-translations
index a700edf..7dd7b98 160000
--- a/lemmy-translations
+++ b/lemmy-translations
@@ -1 +1 @@
-Subproject commit a700edf2dc9c290050b036b6d33e0ea351c92274
+Subproject commit 7dd7b98da76477222f9fd9720b4b25e14e3ddc97
diff --git a/package.json b/package.json
index c08b1cd..c273861 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
   "dependencies": {
     "@typescript-eslint/parser": "^4.31.1",
     "autosize": "^5.0.1",
+    "check-password-strength": "^2.0.3",
     "choices.js": "^9.0.1",
     "emoji-short-name": "^1.0.0",
     "express": "~4.17.1",
diff --git a/src/shared/components/home/login.tsx b/src/shared/components/home/login.tsx
index 612a6b7..2addcf0 100644
--- a/src/shared/components/home/login.tsx
+++ b/src/shared/components/home/login.tsx
@@ -1,3 +1,5 @@
+import { Options, passwordStrength } from "check-password-strength";
+import { I18nKeys } from "i18next";
 import { Component, linkEvent } from "inferno";
 import { T } from "inferno-i18next-dess";
 import {
@@ -28,6 +30,33 @@ import {
 import { HtmlTags } from "../common/html-tags";
 import { Icon, Spinner } from "../common/icon";
 
+const passwordStrengthOptions: Options<string> = [
+  {
+    id: 0,
+    value: "too_weak",
+    minDiversity: 0,
+    minLength: 0,
+  },
+  {
+    id: 1,
+    value: "weak",
+    minDiversity: 2,
+    minLength: 10,
+  },
+  {
+    id: 2,
+    value: "medium",
+    minDiversity: 3,
+    minLength: 12,
+  },
+  {
+    id: 3,
+    value: "strong",
+    minDiversity: 4,
+    minLength: 14,
+  },
+];
+
 interface State {
   loginForm: LoginForm;
   registerForm: Register;
@@ -227,10 +256,16 @@ export class Login extends Component<any, State> {
               value={this.state.registerForm.password}
               autoComplete="new-password"
               onInput={linkEvent(this, this.handleRegisterPasswordChange)}
+              minLength={10}
               maxLength={60}
               class="form-control"
               required
             />
+            {this.state.registerForm.password && (
+              <div class={this.passwordColorClass}>
+                {i18n.t(this.passwordStrength as I18nKeys)}
+              </div>
+            )}
           </div>
         </div>
 
@@ -349,6 +384,25 @@ export class Login extends Component<any, State> {
     );
   }
 
+  get passwordStrength() {
+    return passwordStrength(
+      this.state.registerForm.password,
+      passwordStrengthOptions
+    ).value;
+  }
+
+  get passwordColorClass(): string {
+    let strength = this.passwordStrength;
+
+    if (["weak", "medium"].includes(strength)) {
+      return "text-warning";
+    } else if (strength == "strong") {
+      return "text-success";
+    } else {
+      return "text-danger";
+    }
+  }
+
   handleLoginSubmit(i: Login, event: any) {
     event.preventDefault();
     i.state.loginLoading = true;
diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx
index 2990fa2..22bcd25 100644
--- a/src/shared/components/person/settings.tsx
+++ b/src/shared/components/person/settings.tsx
@@ -1035,12 +1035,6 @@ export class Settings extends Component<any, SettingsState> {
     i.setState(i.state);
   }
 
-  handleLogoutClick(_i: Settings) {
-    UserService.Instance.logout();
-    window.location.href = "/";
-    location.reload();
-  }
-
   handleDeleteAccount(i: Settings, event: any) {
     event.preventDefault();
     i.state.deleteAccountLoading = true;
diff --git a/yarn.lock b/yarn.lock
index 2250867..284e2c1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2062,6 +2062,11 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1:
     ansi-styles "^4.1.0"
     supports-color "^7.1.0"
 
+check-password-strength@^2.0.3:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/check-password-strength/-/check-password-strength-2.0.3.tgz#fed038b1c457ac11a2999bd96f3185af34e88895"
+  integrity sha512-UW3YgMUne9QuejgnNWjWwYi4QhWArVj+1OXqDR1NkEQcmMKKO74O3P5ZvXr9JZNbTBfcwlK3yurYCMuJsck83A==
+
 choices.js@^9.0.1:
   version "9.0.1"
   resolved "https://registry.yarnpkg.com/choices.js/-/choices.js-9.0.1.tgz#745fb29af8670428fdc0bf1cc9dfaa404e9d0510"
-- 
2.44.1