parent
c5c4028fa6
commit
642ebfc4c3
1 changed files with 128 additions and 0 deletions
@ -0,0 +1,128 @@ |
||||
import { FC, useMemo, useRef } from 'react'; |
||||
|
||||
import Divider from '../Divider'; |
||||
import FlexBox from '../FlexBox'; |
||||
import List, { ListForwardedRefContent } from '../List'; |
||||
import MessageBox from '../MessageBox'; |
||||
import { ExpandablePanel } from '../Panels'; |
||||
import { BodyText } from '../Text'; |
||||
import useProtect from '../../hooks/useProtect'; |
||||
import useProtectedState from '../../hooks/useProtectedState'; |
||||
|
||||
type ChangedSSHKeys = { |
||||
[hostUUID: string]: { |
||||
hostName: string; |
||||
hostUUID: string; |
||||
ipAddress: string; |
||||
isChecked?: boolean; |
||||
}; |
||||
}; |
||||
|
||||
const ManageChangedSSHKeysForm: FC = () => { |
||||
const { protect } = useProtect(); |
||||
|
||||
const listRef = useRef<ListForwardedRefContent>({}); |
||||
|
||||
const [changedSSHKeys, setChangedSSHKeys] = useProtectedState<ChangedSSHKeys>( |
||||
{}, |
||||
protect, |
||||
); |
||||
|
||||
const isAllowCheckAll = useMemo( |
||||
() => Object.keys(changedSSHKeys).length > 1, |
||||
[changedSSHKeys], |
||||
); |
||||
|
||||
return ( |
||||
<ExpandablePanel header={<BodyText>Manage changed SSH keys</BodyText>}> |
||||
<FlexBox spacing=".2em"> |
||||
<BodyText> |
||||
The identity of the following targets have unexpectedly changed. |
||||
</BodyText> |
||||
<MessageBox type="warning" isAllowClose> |
||||
If you haven't rebuilt the listed targets, then you could be |
||||
experiencing a "Man In The Middle" attack. Please verify the |
||||
targets have changed for a known reason before proceeding to remove |
||||
the broken keys. |
||||
</MessageBox> |
||||
<List |
||||
header={ |
||||
<FlexBox |
||||
row |
||||
spacing=".3em" |
||||
sx={{ |
||||
width: '100%', |
||||
|
||||
'& > :not(:last-child)': { |
||||
display: { xs: 'none', sm: 'flex' }, |
||||
}, |
||||
|
||||
'& > :last-child': { |
||||
display: { xs: 'initial', sm: 'none' }, |
||||
marginLeft: 0, |
||||
}, |
||||
}} |
||||
> |
||||
<FlexBox row spacing=".3em" sx={{ flexBasis: 'calc(50% + 1em)' }}> |
||||
<BodyText>Host name</BodyText> |
||||
<Divider sx={{ flexGrow: 1 }} /> |
||||
</FlexBox> |
||||
<FlexBox row spacing=".3em" sx={{ flexGrow: 1 }}> |
||||
<BodyText>IP address</BodyText> |
||||
<Divider sx={{ flexGrow: 1 }} /> |
||||
</FlexBox> |
||||
<Divider sx={{ flexGrow: 1 }} /> |
||||
</FlexBox> |
||||
} |
||||
allowCheckAll={isAllowCheckAll} |
||||
allowCheckItem |
||||
allowDelete |
||||
allowEdit={false} |
||||
edit |
||||
listEmpty={ |
||||
<BodyText sx={{ textAlign: 'center' }}> |
||||
No conflicting keys found. |
||||
</BodyText> |
||||
} |
||||
listItems={changedSSHKeys} |
||||
onAllCheckboxChange={(event, isChecked) => { |
||||
Object.keys(changedSSHKeys).forEach((key) => { |
||||
changedSSHKeys[key].isChecked = isChecked; |
||||
}); |
||||
|
||||
setChangedSSHKeys((previous) => ({ ...previous })); |
||||
}} |
||||
onItemCheckboxChange={(key, event, isChecked) => { |
||||
changedSSHKeys[key].isChecked = isChecked; |
||||
|
||||
listRef.current.setCheckAll?.call( |
||||
null, |
||||
Object.values(changedSSHKeys).every( |
||||
({ isChecked: isItemChecked }) => isItemChecked, |
||||
), |
||||
); |
||||
|
||||
setChangedSSHKeys((previous) => ({ ...previous })); |
||||
}} |
||||
renderListItem={(hostUUID, { hostName, ipAddress }) => ( |
||||
<FlexBox |
||||
spacing={0} |
||||
sm="row" |
||||
sx={{ width: '100%', '& > *': { flexBasis: '50%' } }} |
||||
xs="column" |
||||
> |
||||
<BodyText>{hostName}</BodyText> |
||||
<BodyText>{ipAddress}</BodyText> |
||||
</FlexBox> |
||||
)} |
||||
renderListItemCheckboxState={(key, { isChecked }) => |
||||
isChecked === true |
||||
} |
||||
ref={listRef} |
||||
/> |
||||
</FlexBox> |
||||
</ExpandablePanel> |
||||
); |
||||
}; |
||||
|
||||
export default ManageChangedSSHKeysForm; |
Loading…
Reference in new issue