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;