Web: Client: add password strength setting
This commit is contained in:
parent
78b154416f
commit
f362605d56
@ -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;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
@ -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")}
|
||||
|
@ -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))
|
||||
)
|
||||
);
|
Loading…
Reference in New Issue
Block a user