From 137ff41be229459b4109691a7c2bb4070746945f Mon Sep 17 00:00:00 2001 From: Lenin Alevski Date: Tue, 21 Sep 2021 20:48:24 -0700 Subject: [PATCH] Display detailed errors when login fails (#1069) Signed-off-by: Lenin Alevski Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com> Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> --- .../BucketDetails/AddReplicationModal.tsx | 2 - .../Console/Common/MainError/MainError.tsx | 3 + portal-ui/src/screens/LoginPage/LoginPage.tsx | 60 ++++++++----------- portal-ui/src/theme/main.ts | 4 +- restapi/error.go | 5 +- restapi/user_login.go | 6 +- 6 files changed, 35 insertions(+), 45 deletions(-) diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx index 0558fd376..ac8b65bb2 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/AddReplicationModal.tsx @@ -344,8 +344,6 @@ const AddReplicationModal = ({ name="deleteMarker" label="Delete Marker" onChange={(e) => { - console.log(e); - console.log(e.target.checked); setRepDeleteMarker(e.target.checked); }} value={repDeleteMarker} diff --git a/portal-ui/src/screens/Console/Common/MainError/MainError.tsx b/portal-ui/src/screens/Console/Common/MainError/MainError.tsx index bfb48ddc1..afdce6da3 100644 --- a/portal-ui/src/screens/Console/Common/MainError/MainError.tsx +++ b/portal-ui/src/screens/Console/Common/MainError/MainError.tsx @@ -26,6 +26,7 @@ import { setErrorSnackMessage } from "../../../../actions"; import { snackBarMessage } from "../../../../types"; interface IMainErrorProps { + customStyle?: any; classes: any; snackBar: snackBarMessage; displayErrorMessage: typeof setErrorSnackMessage; @@ -130,6 +131,7 @@ const MainError = ({ classes, snackBar, displayErrorMessage, + customStyle, }: IMainErrorProps) => { const [detailsOpen, setDetailsOpen] = useState(false); const [displayErrorMsg, setDisplayErrorMsg] = useState(false); @@ -171,6 +173,7 @@ const MainError = ({ className={`${classes.mainErrorContainer} ${ displayErrorMsg ? classes.mainErrorShow : "" }`} + style={customStyle} onMouseOver={stopHideTimer} onMouseLeave={() => startHideTimer(closeErrorMessage)} > diff --git a/portal-ui/src/screens/LoginPage/LoginPage.tsx b/portal-ui/src/screens/LoginPage/LoginPage.tsx index f14f1b13b..7c574740d 100644 --- a/portal-ui/src/screens/LoginPage/LoginPage.tsx +++ b/portal-ui/src/screens/LoginPage/LoginPage.tsx @@ -29,19 +29,18 @@ import { Theme, withStyles, } from "@material-ui/core/styles"; -import request from "superagent"; -import ErrorIcon from "@material-ui/icons/Error"; import Button from "@material-ui/core/Button"; import TextField from "@material-ui/core/TextField"; import Grid from "@material-ui/core/Grid"; import Typography from "@material-ui/core/Typography"; import { ILoginDetails, loginStrategyType } from "./types"; import { SystemState } from "../../types"; -import { userLoggedIn } from "../../actions"; +import { setErrorSnackMessage, userLoggedIn } from "../../actions"; import { ErrorResponseHandler } from "../../common/types"; import api from "../../common/api"; import history from "../../history"; import RefreshIcon from "../../icons/RefreshIcon"; +import MainError from "../Console/Common/MainError/MainError"; const styles = (theme: Theme) => createStyles({ @@ -180,13 +179,14 @@ const mapState = (state: SystemState) => ({ loggedIn: state.loggedIn, }); -const connector = connect(mapState, { userLoggedIn }); +const connector = connect(mapState, { userLoggedIn, setErrorSnackMessage }); // The inferred type will look like: // {isOn: boolean, toggleOn: () => void} interface ILoginProps { userLoggedIn: typeof userLoggedIn; + setErrorSnackMessage: typeof setErrorSnackMessage; classes: any; } @@ -198,16 +198,21 @@ interface LoginStrategyPayload { [key: string]: any; } -const Login = ({ classes, userLoggedIn }: ILoginProps) => { +const Login = ({ + classes, + userLoggedIn, + setErrorSnackMessage, +}: ILoginProps) => { const [accessKey, setAccessKey] = useState(""); const [jwt, setJwt] = useState(""); const [secretKey, setSecretKey] = useState(""); - const [error, setError] = useState(null); const [loginStrategy, setLoginStrategy] = useState({ loginStrategy: loginStrategyType.unknown, redirect: "", }); const [loginSending, setLoginSending] = useState(false); + const [loadingFetchConfiguration, setLoadingFetchConfiguration] = + useState(false); const loginStrategyEndpoints: LoginStrategyRoutes = { form: "/api/v1/login", @@ -219,51 +224,39 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => { }; const fetchConfiguration = () => { + setLoadingFetchConfiguration(true); api .invoke("GET", "/api/v1/login") .then((loginDetails: ILoginDetails) => { setLoginStrategy(loginDetails); - setError(null); - if ( - loginDetails.loginStrategy === "redirect" && - loginDetails.redirect !== "" - ) { - //location.href = loginDetails.redirect; - } + setLoadingFetchConfiguration(false); }) .catch((err: ErrorResponseHandler) => { - setError(err); + setErrorSnackMessage(err); + setLoadingFetchConfiguration(false); }); }; const formSubmit = (e: React.FormEvent) => { e.preventDefault(); setLoginSending(true); - request - .post( - loginStrategyEndpoints[loginStrategy.loginStrategy] || "/api/v1/login" + api + .invoke( + "POST", + loginStrategyEndpoints[loginStrategy.loginStrategy] || "/api/v1/login", + loginStrategyPayload[loginStrategy.loginStrategy] ) - .send(loginStrategyPayload[loginStrategy.loginStrategy]) - .then((res: any) => { - const bodyResponse = res.body; - if (bodyResponse.error) { - setLoginSending(false); - // throw will be moved to catch block once bad login returns 403 - throw bodyResponse.error; - } - }) .then(() => { // We set the state in redux userLoggedIn(true); if (loginStrategy.loginStrategy === loginStrategyType.form) { localStorage.setItem("userLoggedIn", btoa(accessKey)); } - history.push("/"); }) .catch((err) => { setLoginSending(false); - setError({ detailedError: "", errorMessage: err.message }); + setErrorSnackMessage(err); }); }; @@ -409,12 +402,12 @@ const Login = ({ classes, userLoggedIn }: ILoginProps) => { default: loginComponent = (
- {error === null ? ( + {loadingFetchConfiguration ? ( ) : (
-

An error has ocurred, the backend cannot be reached.

+

An error has occurred, the backend cannot be reached.