Web: Client: add password strength setting

This commit is contained in:
Viktor Fomin 2022-04-01 15:01:09 +03:00
parent 78b154416f
commit f362605d56
3 changed files with 232 additions and 0 deletions

View File

@ -15,6 +15,12 @@ StyledArrowRightIcon.defaultProps = { theme: Base };
export const MainContainer = styled.div`
width: 100%;
hr {
margin: 24px 0;
border: none;
border-top: 1px solid #eceef1;
}
.subtitle {
margin-bottom: 20px;
}
@ -71,3 +77,26 @@ export const StyledCategoryWrapper = styled.div`
margin-bottom: 16px;
align-items: center;
`;
export const ButtonsWrapper = styled.div`
display: flex;
flex-direction: row;
gap: 8px;
align-items: center;
@media (max-width: 375px) {
position: absolute;
bottom: 16px;
width: calc(100vw - 32px);
.button {
height: 40px;
width: 100%;
}
.reminder {
position: absolute;
bottom: 48px;
}
}
`;

View File

@ -5,6 +5,7 @@ import Text from "@appserver/components/text";
import { setDocumentTitle } from "../../../../../../helpers/utils";
import { MainContainer } from "../StyledSecurity";
import TfaSection from "./tfa";
import PasswordStrengthSection from "./passwordStrength";
import MobileView from "./mobileView";
import { isMobile } from "react-device-detect";
import CategoryWrapper from "../sub-components/category-wrapper";
@ -20,6 +21,12 @@ const AccessPortal = (props) => {
return (
<MainContainer className="desktop-view">
<Text className="subtitle">{t("PortalAccessSubTitle")}</Text>
<CategoryWrapper
title={t("SettingPasswordStrength")}
tooltipContent={t("SettingPasswordStrengthDescription")}
/>
<PasswordStrengthSection />
<hr />
<CategoryWrapper
title={t("TwoFactorAuth")}
tooltipContent={t("TwoFactorAuthDescription")}

View File

@ -0,0 +1,196 @@
import React, { useState, useEffect } from "react";
import styled from "styled-components";
import { withRouter } from "react-router";
import { withTranslation } from "react-i18next";
import { inject, observer } from "mobx-react";
import Box from "@appserver/components/box";
import Button from "@appserver/components/button";
import Text from "@appserver/components/text";
import Link from "@appserver/components/link";
import Slider from "@appserver/components/slider";
import Checkbox from "@appserver/components/checkbox";
import SectionLoader from "../sub-components/section-loader";
import { getLanguage } from "@appserver/common/utils";
import { isMobile } from "react-device-detect";
import { ButtonsWrapper } from "../StyledSecurity";
const MainContainer = styled.div`
width: 100%;
.page-subtitle {
margin-bottom: 10px;
}
.password-slider {
width: 160px;
height: 8px;
margin: 24px 16px 24px 0px;
}
.checkboxes {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 18px;
margin-bottom: 24px;
}
`;
const PasswordStrength = (props) => {
const { t } = props;
const [passwordLen, setPasswordLen] = useState(8);
const [useUpperCase, setUseUpperCase] = useState(false);
const [useDigits, setUseDigits] = useState(false);
const [useSpecialSymbols, setUseSpecialSymbols] = useState(false);
const [currentState, setCurrentState] = useState([8, false, false, false]);
const [showReminder, setShowReminder] = useState(false);
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
setIsLoading(true);
}, []);
const onSliderChange = (e) => {
setPasswordLen(Number(e.target.value));
if (
Number(e.target.value) === currentState[0] &&
useUpperCase === currentState[1] &&
useDigits === currentState[2] &&
useSpecialSymbols === currentState[3]
)
setShowReminder(false);
else setShowReminder(true);
};
const onClickCheckbox = (e) => {
setShowReminder(true);
switch (e.target.value) {
case "upperCase":
setUseUpperCase(e.target.checked);
e.target.checked === currentState[1] &&
passwordLen === currentState[0] &&
setShowReminder(false);
break;
case "digits":
setUseDigits(e.target.checked);
e.target.checked === currentState[2] &&
passwordLen === currentState[0] &&
setShowReminder(false);
break;
case "special":
setUseSpecialSymbols(e.target.checked);
e.target.checked === currentState[3] &&
passwordLen === currentState[0] &&
setShowReminder(false);
break;
}
};
const onSaveClick = () => {};
const onCancelClick = () => {
setShowReminder(false);
};
const lng = getLanguage(localStorage.getItem("language") || "en");
if (!isLoading) return <SectionLoader />;
return (
<MainContainer>
{isMobile && (
<>
<Text className="page-subtitle">
{t("SettingPasswordStrengthHelper")}
</Text>
<Link
className="learn-more"
target="_blank"
href={`https://helpcenter.onlyoffice.com/${lng}/administration/configuration.aspx#ChangingSecuritySettings_block`}
>
{t("Common:LearnMore")}
</Link>
</>
)}
<Text fontSize="14px" fontWeight="600">
{t("PasswordMinLenght")}
</Text>
<Box displayProp="flex" flexDirection="row" alignItems="center">
<Slider
className="password-slider"
min="8"
max="30"
step="1"
value={passwordLen}
onChange={onSliderChange}
/>
<Text>
{passwordLen} {t("Characters")}
</Text>
</Box>
<Box className="checkboxes">
<Checkbox
onChange={onClickCheckbox}
label={`${t("Use")} ${t("Common:PasswordLimitUpperCase")}`}
isChecked={useUpperCase}
value="upperCase"
/>
<Checkbox
onChange={onClickCheckbox}
label={`${t("Use")} ${t("Common:PasswordLimitDigits")}`}
isChecked={useDigits}
value="digits"
/>
<Checkbox
onChange={onClickCheckbox}
label={`${t("Use")} ${t("Common:PasswordLimitSpecialSymbols")}`}
isChecked={useSpecialSymbols}
value="special"
/>
</Box>
<ButtonsWrapper>
<Button
label={t("Common:SaveButton")}
size="small"
primary={true}
className="button"
onClick={onSaveClick}
isDisabled={!showReminder}
/>
<Button
label={t("Common:CancelButton")}
size="small"
className="button"
onClick={onCancelClick}
isDisabled={!showReminder}
/>
{showReminder && (
<Text
color="#A3A9AE"
fontSize="12px"
fontWeight="600"
className="reminder"
>
{t("YouHaveUnsavedChanges")}
</Text>
)}
</ButtonsWrapper>
</MainContainer>
);
};
export default inject(({ auth }) => {
const { organizationName } = auth.settingsStore;
return {
organizationName,
};
})(
withTranslation(["Settings", "Common"])(
withRouter(observer(PasswordStrength))
)
);