github.com/minio/console@v1.4.1/web-app/src/screens/LoginPage/LoginCallback.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2021 MinIO, Inc.
     3  //
     4  // This program is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Affero General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // This program is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12  // GNU Affero General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Affero General Public License
    15  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16  
    17  import React, { Fragment, useEffect, useState } from "react";
    18  import styled from "styled-components";
    19  import { useNavigate } from "react-router-dom";
    20  import api from "../../common/api";
    21  import { baseUrl } from "../../history";
    22  import { Box, Button, LoginWrapper, WarnIcon } from "mds";
    23  import { getLogoVar } from "../../config";
    24  import get from "lodash/get";
    25  
    26  const CallBackContainer = styled.div(({ theme }) => ({
    27    "& .errorDescription": {
    28      fontStyle: "italic",
    29      transition: "all .2s ease-in-out",
    30      padding: "0 15px",
    31      marginTop: 5,
    32      overflow: "auto",
    33    },
    34    "& .errorLabel": {
    35      color: get(theme, "fontColor", "#000"),
    36      fontSize: 18,
    37      fontWeight: "bold",
    38      marginLeft: 5,
    39    },
    40    "& .simpleError": {
    41      marginTop: 5,
    42      padding: "2px 5px",
    43      fontSize: 16,
    44      color: get(theme, "fontColor", "#000"),
    45    },
    46    "& .messageIcon": {
    47      color: get(theme, "signalColors.danger", "#C72C48"),
    48      display: "flex",
    49      "& svg": {
    50        width: 32,
    51        height: 32,
    52      },
    53    },
    54    "& .errorTitle": {
    55      display: "flex",
    56      alignItems: "center",
    57      borderBottom: 15,
    58    },
    59  }));
    60  
    61  const LoginCallback = () => {
    62    const navigate = useNavigate();
    63  
    64    const [error, setError] = useState<string>("");
    65    const [errorDescription, setErrorDescription] = useState<string>("");
    66    const [loading, setLoading] = useState<boolean>(true);
    67  
    68    useEffect(() => {
    69      if (loading) {
    70        const queryString = window.location.search;
    71        const urlParams = new URLSearchParams(queryString);
    72        const code = urlParams.get("code");
    73        const state = urlParams.get("state");
    74        const error = urlParams.get("error");
    75        const errorDescription = urlParams.get("errorDescription");
    76        if (error || errorDescription) {
    77          setError(error || "");
    78          setErrorDescription(errorDescription || "");
    79          setLoading(false);
    80        } else {
    81          api
    82            .invoke("POST", "/api/v1/login/oauth2/auth", { code, state })
    83            .then(() => {
    84              // We push to history the new URL.
    85              let targetPath = "/";
    86              if (
    87                localStorage.getItem("redirect-path") &&
    88                localStorage.getItem("redirect-path") !== ""
    89              ) {
    90                targetPath = `${localStorage.getItem("redirect-path")}`;
    91                localStorage.setItem("redirect-path", "");
    92              }
    93              if (state) {
    94                localStorage.setItem("auth-state", state);
    95              }
    96              setLoading(false);
    97              navigate(targetPath);
    98            })
    99            .catch((error) => {
   100              setError(error.errorMessage);
   101              setErrorDescription(error.detailedError);
   102              setLoading(false);
   103            });
   104        }
   105      }
   106    }, [loading, navigate]);
   107    return error !== "" || errorDescription !== "" ? (
   108      <Fragment>
   109        <LoginWrapper
   110          logoProps={{ applicationName: "console", subVariant: getLogoVar() }}
   111          form={
   112            <CallBackContainer>
   113              <div className={"errorTitle"}>
   114                <span className={"messageIcon"}>
   115                  <WarnIcon />
   116                </span>
   117                <span className={"errorLabel"}>Error from IDP</span>
   118              </div>
   119              <div className={"simpleError"}>{error}</div>
   120              <Box className={"errorDescription"}>{errorDescription}</Box>
   121              <Button
   122                id={"back-to-login"}
   123                onClick={() => {
   124                  window.location.href = `${baseUrl}login`;
   125                }}
   126                type="submit"
   127                variant="callAction"
   128                fullWidth
   129              >
   130                Back to Login
   131              </Button>
   132            </CallBackContainer>
   133          }
   134          promoHeader={
   135            <span style={{ fontSize: 28 }}>High-Performance Object Store</span>
   136          }
   137          promoInfo={
   138            <span style={{ fontSize: 14, lineHeight: 1 }}>
   139              MinIO is a cloud-native object store built to run on any
   140              infrastructure - public, private or edge clouds. Primary use cases
   141              include data lakes, databases, AI/ML, SaaS applications and fast
   142              backup & recovery. MinIO is dual licensed under GNU AGPL v3 and
   143              commercial license. To learn more, visit{" "}
   144              <a href={"https://min.io/?ref=con"} target="_blank" rel="noopener">
   145                www.min.io
   146              </a>
   147              .
   148            </span>
   149          }
   150          backgroundAnimation={false}
   151        />
   152      </Fragment>
   153    ) : null;
   154  };
   155  
   156  export default LoginCallback;