From e60af0fbf8ed09429c371598423870734cc77bb7 Mon Sep 17 00:00:00 2001 From: SleeplessOne1917 Date: Fri, 7 Jul 2023 14:07:54 -0400 Subject: [PATCH] Make working password inputs --- .../components/common/password-input.tsx | 161 ++++++++++++++++++ src/shared/components/home/login.tsx | 32 +--- src/shared/components/home/setup.tsx | 49 ++---- src/shared/components/home/signup.tsx | 112 ++---------- .../components/person/password-change.tsx | 46 ++--- src/shared/components/person/settings.tsx | 94 ++++------ 6 files changed, 254 insertions(+), 240 deletions(-) create mode 100644 src/shared/components/common/password-input.tsx diff --git a/src/shared/components/common/password-input.tsx b/src/shared/components/common/password-input.tsx new file mode 100644 index 00000000..d96f2ff8 --- /dev/null +++ b/src/shared/components/common/password-input.tsx @@ -0,0 +1,161 @@ +import { Options, passwordStrength } from "check-password-strength"; +import classNames from "classnames"; +import { NoOptionI18nKeys } from "i18next"; +import { Component, FormEventHandler, linkEvent } from "inferno"; +import { NavLink } from "inferno-router"; +import { I18NextService } from "../../services"; + +interface PasswordInputProps { + id: string; + value?: string; + onInput: FormEventHandler; + className?: string; + showStrength?: boolean; + cols?: number | null; + label?: string; + showForgotLink?: boolean; +} + +interface PasswordInputState { + show: boolean; +} + +const passwordStrengthOptions: Options = [ + { + id: 0, + value: "very_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, + }, +]; + +function handleToggleShow(i: PasswordInput) { + i.setState(prev => ({ + ...prev, + show: !prev.show, + })); +} + +class PasswordInput extends Component { + state: PasswordInputState = { + show: false, + }; + + constructor(props: PasswordInputProps, context: any) { + super(props, context); + } + + render() { + const { + props: { + id, + value, + onInput, + className, + showStrength, + cols = 10, + label, + showForgotLink, + }, + state: { show }, + } = this; + + return ( + <> +
+ {label && ( + + )} +
+
+ + +
+ {showForgotLink && ( + + {I18NextService.i18n.t("forgot_password")} + + )} +
+
+ {showStrength && value && ( +
+ {I18NextService.i18n.t(this.passwordStrength as NoOptionI18nKeys)} +
+ )} + + ); + } + + get passwordStrength(): string | undefined { + const password = this.props.value; + return password + ? passwordStrength(password, passwordStrengthOptions).value + : undefined; + } + + get passwordColorClass(): string { + const strength = this.passwordStrength; + + if (strength && ["weak", "medium"].includes(strength)) { + return "text-warning"; + } else if (strength == "strong") { + return "text-success"; + } else { + return "text-danger"; + } + } +} + +export default PasswordInput; diff --git a/src/shared/components/home/login.tsx b/src/shared/components/home/login.tsx index e2986b57..f0817ab0 100644 --- a/src/shared/components/home/login.tsx +++ b/src/shared/components/home/login.tsx @@ -1,13 +1,13 @@ import { myAuth, setIsoData } from "@utils/app"; import { isBrowser } from "@utils/browser"; import { Component, linkEvent } from "inferno"; -import { NavLink } from "inferno-router"; import { GetSiteResponse, LoginResponse } from "lemmy-js-client"; import { I18NextService, UserService } from "../../services"; import { HttpService, RequestState } from "../../services/HttpService"; import { toast } from "../../toast"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; +import PasswordInput from "../common/password-input"; interface State { loginRes: RequestState; @@ -90,28 +90,14 @@ export class Login extends Component { /> -
- -
- - - {I18NextService.i18n.t("forgot_password")} - -
+
+
{this.state.showTotp && (
diff --git a/src/shared/components/home/setup.tsx b/src/shared/components/home/setup.tsx index f4bdb555..adf295f3 100644 --- a/src/shared/components/home/setup.tsx +++ b/src/shared/components/home/setup.tsx @@ -10,6 +10,7 @@ import { import { I18NextService, UserService } from "../../services"; import { HttpService, RequestState } from "../../services/HttpService"; import { Spinner } from "../common/icon"; +import PasswordInput from "../common/password-input"; import { SiteForm } from "./site-form"; interface State { @@ -121,41 +122,21 @@ export class Setup extends Component { />
-
- -
- -
+
+
-
- -
- -
+
+
diff --git a/src/shared/components/home/signup.tsx b/src/shared/components/home/signup.tsx index bb1e1f11..0fe3215e 100644 --- a/src/shared/components/home/signup.tsx +++ b/src/shared/components/home/signup.tsx @@ -1,8 +1,6 @@ import { myAuth, setIsoData } from "@utils/app"; import { isBrowser } from "@utils/browser"; import { validEmail } from "@utils/helpers"; -import { Options, passwordStrength } from "check-password-strength"; -import { NoOptionI18nKeys } from "i18next"; import { Component, linkEvent } from "inferno"; import { T } from "inferno-i18next-dess"; import { @@ -20,33 +18,7 @@ import { toast } from "../../toast"; import { HtmlTags } from "../common/html-tags"; import { Icon, Spinner } from "../common/icon"; import { MarkdownTextArea } from "../common/markdown-textarea"; - -const passwordStrengthOptions: Options = [ - { - id: 0, - value: "very_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, - }, -]; +import PasswordInput from "../common/password-input"; interface State { registerRes: RequestState; @@ -210,57 +182,26 @@ export class Signup extends Component {
-
- -
- - {this.state.form.password && ( -
- {I18NextService.i18n.t( - this.passwordStrength as NoOptionI18nKeys - )} -
- )} -
+
+
-
- -
- -
+
+
- {siteView.local_site.registration_mode == "RequireApplication" && ( + {siteView.local_site.registration_mode === "RequireApplication" && ( <>
@@ -411,25 +352,6 @@ export class Signup extends Component { ); } - get passwordStrength(): string | undefined { - const password = this.state.form.password; - return password - ? passwordStrength(password, passwordStrengthOptions).value - : undefined; - } - - get passwordColorClass(): string { - const strength = this.passwordStrength; - - if (strength && ["weak", "medium"].includes(strength)) { - return "text-warning"; - } else if (strength == "strong") { - return "text-success"; - } else { - return "text-danger"; - } - } - async handleRegisterSubmit(i: Signup, event: any) { event.preventDefault(); const { diff --git a/src/shared/components/person/password-change.tsx b/src/shared/components/person/password-change.tsx index 565f55e6..718b8c35 100644 --- a/src/shared/components/person/password-change.tsx +++ b/src/shared/components/person/password-change.tsx @@ -6,6 +6,7 @@ import { HttpService, I18NextService, UserService } from "../../services"; import { RequestState } from "../../services/HttpService"; import { HtmlTags } from "../common/html-tags"; import { Spinner } from "../common/icon"; +import PasswordInput from "../common/password-input"; interface State { passwordChangeRes: RequestState; @@ -60,37 +61,22 @@ export class PasswordChange extends Component { passwordChangeForm() { return (
-
- -
- -
+
+
-
- -
- -
+
+
diff --git a/src/shared/components/person/settings.tsx b/src/shared/components/person/settings.tsx index 4caef458..e7864042 100644 --- a/src/shared/components/person/settings.tsx +++ b/src/shared/components/person/settings.tsx @@ -40,6 +40,7 @@ import { ImageUploadForm } from "../common/image-upload-form"; import { LanguageSelect } from "../common/language-select"; import { ListingTypeSelect } from "../common/listing-type-select"; import { MarkdownTextArea } from "../common/markdown-textarea"; +import PasswordInput from "../common/password-input"; import { SearchableSelect } from "../common/searchable-select"; import { SortSelect } from "../common/sort-select"; import Tabs from "../common/tabs"; @@ -318,59 +319,33 @@ export class Settings extends Component { <>

{I18NextService.i18n.t("change_password")}

-
- -
- -
+
+
-
- -
- -
+
+
-
- -
- -
+
+
{this.state.deleteAccountShowConfirm && ( <> -
+
- +