Web: Login: Added error handler.

This commit is contained in:
Tatiana Lopaeva 2023-09-01 10:28:52 +03:00
parent a85a721a3b
commit c4d2048e3a
6 changed files with 87 additions and 26 deletions

View File

@ -53,6 +53,8 @@ const {
strongBlue,
lightGrayishStrongBlue,
darkRed,
lightErrorStatus,
} = globalColors;
const Base = {
@ -2785,6 +2787,11 @@ const Base = {
container: {
backgroundColor: grayLightMid,
},
captcha: {
border: `1px solid ${lightErrorStatus}`,
color: lightErrorStatus,
},
},
facebookButton: {

View File

@ -47,6 +47,8 @@ const {
strongBlue,
lightGrayishStrongBlue,
darkRed,
darkErrorStatus,
} = globalColors;
const Dark = {
@ -2791,6 +2793,11 @@ const Dark = {
container: {
backgroundColor: "#474747",
},
captcha: {
border: `1px solid ${darkErrorStatus}`,
color: darkErrorStatus,
},
},
facebookButton: {

View File

@ -56,6 +56,9 @@ const globalColors = {
hoverError: "#F7CDBE",
hoverInfo: "#F8F7BF",
hoverWarning: "#F7E6BE",
lightErrorStatus: "#F24724",
darkErrorStatus: "#E06451",
};
export default globalColors;

View File

@ -7,6 +7,7 @@
"InvalidUsernameOrPassword": "Invalid username or password",
"LoginWithAccountNotFound": "Can't find associated third-party account. You need to connect your social networking account at the profile editing page first.",
"LoginWithBruteForce": "Authorization temporarily blocked",
"LoginWithBruteForceCaptcha": "Confirm that you are not a robot",
"RecaptchaInvalid": "Invalid Recaptcha",
"SsoAttributesNotFound": "Authentication failed (assertion attributes not found)",
"SsoAuthFailed": "Authentication failed",

View File

@ -22,6 +22,11 @@ interface ILoginContentProps {
enabledJoin?: boolean;
}
interface IStyledCaptchaProps {
isCaptchaError?: boolean;
theme?: IUserTheme;
}
export const LoginFormWrapper = styled.div`
display: grid;
grid-template-rows: ${(props: ILoginFormWrapperProps) =>
@ -38,7 +43,7 @@ export const LoginFormWrapper = styled.div`
}
.bg-cover {
background-image: ${props => props.bgPattern};
background-image: ${(props) => props.bgPattern};
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
@ -52,27 +57,46 @@ export const LoginFormWrapper = styled.div`
background-image: none;
}
}
.captcha-container {
margin: 24px 0;
}
`;
export const LoginContent = styled.div`
min-height: ${(props: ILoginContentProps) => props.enabledJoin ? "calc(100vh - 68px)" : "100vh"};
flex: 1 0 auto;
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
@media ${hugeMobile} {
min-height: 100%;
justify-content: start;
}
min-height: ${(props: ILoginContentProps) =>
props.enabledJoin ? "calc(100vh - 68px)" : "100vh"};
flex: 1 0 auto;
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
@media ${hugeMobile} {
min-height: 100%;
justify-content: start;
}
`;
export const StyledCaptcha = styled.div`
margin: 24px 0;
width: fit-content;
.captcha-wrapper {
${(props: IStyledCaptchaProps) =>
props.isCaptchaError &&
css`
border: ${props.theme.login.captcha.border};
padding: 4px 4px 4px 2px;
`};
margin-bottom: 2px;
}
${(props: IStyledCaptchaProps) =>
props.isCaptchaError &&
css`
p {
color: ${props.theme.login.captcha.color};
}
`}
`;

View File

@ -17,6 +17,7 @@ import { thirdPartyLogin } from "@docspace/common/api/user";
import { setWithCredentialsStatus } from "@docspace/common/api/client";
import { isMobileOnly } from "react-device-detect";
import ReCAPTCHA from "react-google-recaptcha";
import { StyledCaptcha } from "../StyledLogin";
interface ILoginFormProps {
isLoading: boolean;
@ -64,6 +65,9 @@ const LoginForm: React.FC<ILoginFormProps> = ({
const [isWithoutPasswordLogin, setIsWithoutPasswordLogin] =
useState(IS_ROOMS_MODE);
const [isCaptchaSuccessful, setIsCaptchaSuccess] = useState(false);
const [isCaptchaError, setIsCaptchaError] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
const { t, ready } = useTranslation(["Login", "Common"]);
@ -152,6 +156,11 @@ const LoginForm: React.FC<ILoginFormProps> = ({
let captchaToken = "";
if (recaptchaPublicKey && isCaptcha) {
if (!isCaptchaSuccessful) {
setIsCaptchaError(true);
return;
}
captchaToken = captchaRef.current.getValue();
}
@ -277,6 +286,10 @@ const LoginForm: React.FC<ILoginFormProps> = ({
setIsLoading(false);
};
const onSuccessfullyComplete = () => {
setIsCaptchaSuccess(true);
};
return (
<form className="auth-form-container">
<FieldContainer
@ -383,13 +396,19 @@ const LoginForm: React.FC<ILoginFormProps> = ({
/>
)}
{recaptchaPublicKey && isCaptcha && (
<div className="captcha-container">
<ReCAPTCHA
sitekey={recaptchaPublicKey}
ref={captchaRef}
theme={isBaseTheme ? "light" : "dark"}
/>
</div>
<StyledCaptcha isCaptchaError={isCaptchaError}>
<div className="captcha-wrapper">
<ReCAPTCHA
sitekey={recaptchaPublicKey}
ref={captchaRef}
theme={isBaseTheme ? "light" : "dark"}
onChange={onSuccessfullyComplete}
/>
</div>
{isCaptchaError && (
<Text>{t("Errors:LoginWithBruteForceCaptcha")}</Text>
)}
</StyledCaptcha>
)}
</>
)}