github.com/minio/console@v1.4.1/web-app/src/screens/Console/Buckets/ListBuckets/Objects/ListObjects/InspectObject.tsx (about)

     1  // This file is part of MinIO Console Server
     2  // Copyright (c) 2022 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, { useState } from "react";
    18  import {
    19    Button,
    20    InspectMenuIcon,
    21    PasswordKeyIcon,
    22    Switch,
    23    Grid,
    24    Box,
    25  } from "mds";
    26  import {
    27    decodeURLString,
    28    deleteCookie,
    29    encodeURLString,
    30    getCookieValue,
    31    performDownload,
    32  } from "../../../../../../common/utils";
    33  import ModalWrapper from "../../../../Common/ModalWrapper/ModalWrapper";
    34  import { modalStyleUtils } from "../../../../Common/FormComponents/common/styleLibrary";
    35  import KeyRevealer from "../../../../Tools/KeyRevealer";
    36  import { setErrorSnackMessage } from "../../../../../../systemSlice";
    37  import { useAppDispatch } from "../../../../../../store";
    38  
    39  interface IInspectObjectProps {
    40    closeInspectModalAndRefresh: (refresh: boolean) => void;
    41    inspectOpen: boolean;
    42    inspectPath: string;
    43    volumeName: string;
    44  }
    45  
    46  const InspectObject = ({
    47    closeInspectModalAndRefresh,
    48    inspectOpen,
    49    inspectPath,
    50    volumeName,
    51  }: IInspectObjectProps) => {
    52    const dispatch = useAppDispatch();
    53    const onClose = () => closeInspectModalAndRefresh(false);
    54    const [isEncrypt, setIsEncrypt] = useState<boolean>(true);
    55    const [decryptionKey, setDecryptionKey] = useState<string>("");
    56    const [insFileName, setInsFileName] = useState<string>("");
    57  
    58    if (!inspectPath) {
    59      return null;
    60    }
    61    const makeRequest = async (url: string) => {
    62      return await fetch(url, { method: "GET" });
    63    };
    64  
    65    const performInspect = async () => {
    66      const file = encodeURLString(inspectPath + "/xl.meta");
    67      const volume = encodeURLString(volumeName);
    68  
    69      let basename = document.baseURI.replace(window.location.origin, "");
    70      const urlOfInspectApi = `${window.location.origin}${basename}/api/v1/admin/inspect?volume=${volume}&file=${file}&encrypt=${isEncrypt}`;
    71  
    72      makeRequest(urlOfInspectApi)
    73        .then(async (res) => {
    74          if (!res.ok) {
    75            const resErr: any = await res.json();
    76  
    77            dispatch(
    78              setErrorSnackMessage({
    79                errorMessage: resErr.message,
    80                detailedError: resErr.code,
    81              }),
    82            );
    83          }
    84          const blob: Blob = await res.blob();
    85  
    86          //@ts-ignore
    87          const filename = res.headers.get("content-disposition").split('"')[1];
    88          const decryptKey = getCookieValue(filename) || "";
    89  
    90          performDownload(blob, filename);
    91          setInsFileName(filename);
    92          if (decryptKey === "") {
    93            onClose();
    94            return;
    95          }
    96          setDecryptionKey(decryptKey);
    97        })
    98        .catch((err) => {
    99          dispatch(setErrorSnackMessage(err));
   100        });
   101    };
   102  
   103    const onCloseDecKeyModal = () => {
   104      deleteCookie(insFileName);
   105      onClose();
   106      setDecryptionKey("");
   107    };
   108  
   109    const onSubmit = (e: React.FormEvent) => {
   110      e.preventDefault();
   111    };
   112  
   113    return (
   114      <React.Fragment>
   115        {!decryptionKey && (
   116          <ModalWrapper
   117            modalOpen={inspectOpen}
   118            titleIcon={<InspectMenuIcon />}
   119            title={`Inspect Object`}
   120            onClose={onClose}
   121          >
   122            <form
   123              noValidate
   124              autoComplete="off"
   125              onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
   126                onSubmit(e);
   127              }}
   128            >
   129              Would you like to encrypt <b>{decodeURLString(inspectPath)}</b>?{" "}
   130              <br />
   131              <Switch
   132                label={"Encrypt"}
   133                indicatorLabels={["Yes", "No"]}
   134                checked={isEncrypt}
   135                value={"encrypt"}
   136                id="encrypt"
   137                name="encrypt"
   138                onChange={(e) => {
   139                  setIsEncrypt(!isEncrypt);
   140                }}
   141                description=""
   142              />
   143              <Grid item xs={12} sx={modalStyleUtils.modalButtonBar}>
   144                <Button
   145                  id={"inspect"}
   146                  type="submit"
   147                  variant="callAction"
   148                  color="primary"
   149                  onClick={performInspect}
   150                  label={"Inspect"}
   151                />
   152              </Grid>
   153            </form>
   154          </ModalWrapper>
   155        )}
   156        {decryptionKey ? (
   157          <ModalWrapper
   158            modalOpen={inspectOpen}
   159            title="Inspect Decryption Key"
   160            onClose={onCloseDecKeyModal}
   161            titleIcon={<PasswordKeyIcon />}
   162          >
   163            <Box>
   164              This will be displayed only once. It cannot be recovered.
   165              <br />
   166              Use secure medium to share this key.
   167            </Box>
   168            <Box>
   169              <KeyRevealer value={decryptionKey} />
   170            </Box>
   171          </ModalWrapper>
   172        ) : null}
   173      </React.Fragment>
   174    );
   175  };
   176  
   177  export default InspectObject;