github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/webui/src/lib/components/auth/credentials.jsx (about) 1 import React, {useState} from "react"; 2 3 import Modal from "react-bootstrap/Modal"; 4 import Table from "react-bootstrap/Table"; 5 import Alert from "react-bootstrap/Alert"; 6 7 import {auth} from "../../api"; 8 import {useAPIWithPagination} from "../../hooks/api"; 9 import {ClipboardButton, DataTable, AlertError, FormattedDate, Loading} from "../controls"; 10 import {ConfirmationButton} from "../modals"; 11 import {Paginator} from "../pagination"; 12 13 14 export const CredentialsTable = ({userId, currentAccessKey, refresh, after, onPaginate}) => { 15 const [internalRefresh, setInternalRefresh] = useState(false); 16 const [revokeError, setRevokeError] = useState(null); 17 18 const {results, error, loading, nextPage} = useAPIWithPagination(() => { 19 return auth.listCredentials(userId, after); 20 }, [refresh, internalRefresh, userId, after]); 21 22 if (error) return <AlertError error={error}/>; 23 if (revokeError) return <AlertError error={revokeError}/>; 24 if (loading) return <Loading/>; 25 26 return ( 27 <> 28 <DataTable 29 keyFn={row => row.access_key_id} 30 emptyState={'No credentials found'} 31 results={results} 32 headers={['Access Key ID', 'Creation Date', '']} 33 rowFn={row => [ 34 <> 35 <code>{row.access_key_id}</code> 36 {(currentAccessKey === row.access_key_id) && <strong>{' '}(current)</strong>} 37 </>, 38 <FormattedDate dateValue={row.creation_date}/>, 39 <span className="row-hover"> 40 {(currentAccessKey !== row.access_key_id) && 41 <ConfirmationButton 42 variant="outline-danger" 43 size="sm" 44 msg={<span>Are you sure you{'\''}d like to delete access key <code>{row.access_key_id}</code>?</span>} 45 onConfirm={() => { 46 auth.deleteCredentials(userId, row.access_key_id) 47 .catch(err => setRevokeError(err)) 48 .then(() => setInternalRefresh(!internalRefresh)) 49 }}> 50 Revoke 51 </ConfirmationButton> 52 } 53 </span> 54 ]} 55 /> 56 <Paginator onPaginate={onPaginate} after={after} nextPage={nextPage}/> 57 </> 58 ); 59 }; 60 61 62 export const CredentialsShowModal = ({ credentials, show, onHide }) => { 63 if (!credentials) return <></>; 64 65 return ( 66 <Modal show={show} onHide={onHide} size="lg"> 67 <Modal.Header closeButton> 68 <Modal.Title>Create Access Key</Modal.Title> 69 </Modal.Header> 70 71 <Modal.Body> 72 <Table> 73 <tbody> 74 <tr> 75 <td><strong>Access Key ID</strong></td> 76 <td><code>{credentials.access_key_id}</code></td> 77 <td> 78 <ClipboardButton variant="outline-dark" tooltip="Copy to clipboard" text={credentials.access_key_id}/> 79 </td> 80 </tr> 81 <tr> 82 <td><strong>Secret Access Key</strong></td> 83 <td><code>{credentials.secret_access_key}</code></td> 84 <td> 85 <ClipboardButton variant="outline-dark" tooltip="Copy to clipboard" text={credentials.secret_access_key}/> 86 </td> 87 </tr> 88 </tbody> 89 </Table> 90 91 <Alert variant="warning" className="mt-3">Copy the Secret Access Key and store it somewhere safe. You will not be able to access it again.</Alert> 92 </Modal.Body> 93 </Modal> 94 ); 95 };