Skip to content
This repository has been archived by the owner on Oct 20, 2023. It is now read-only.

Commit

Permalink
Add a checkbox to disable confirmation dialog & disable hiding final …
Browse files Browse the repository at this point in the history
…item (#84)

* disable hiding last and checkbox WIP

* move last check into Host/Beacon from Dialog/setLast

* check ifLast in server/host/beacon meta to disable hiding last

* refactor to use hooks to check last and move useToggleHidden hooks

* refactor tab-hosts/beacons to hooks for toggle check lastTabItem

* refactor ternary operator in useBeacons

* route to allHosts when hiding last tabItem, Dialog txt change

* comment out partial hiding server test since it's the final server in gt

* minor txt change, multServer upload

* attempt to fix resize error

---------

Co-authored-by: Sebastian Ang <dajian.ang@pnnl.gov>
  • Loading branch information
sharplessHQ and sang2925 authored Feb 28, 2023
1 parent d2e0355 commit df5fa37
Show file tree
Hide file tree
Showing 21 changed files with 390 additions and 175 deletions.
2 changes: 1 addition & 1 deletion applications/client/src/components/Forms/SettingsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const SettingsForm = observer<SettingsFormProps>(({ ...props }) => {
clear: true,
});
}}
label="Show Hidden Beacons, Host, and Servers"
label="Show Hidden Beacons, Hosts, and Servers"
/>
<Switch // Uncomment to test light theme
checked={store.settings.theme === 'light'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
RowTime,
RowTitle,
ToggleHiddenDialog,
useCheckLastUnhidden,
useToggleHidden,
} from '@redeye/client/views';
import { FlexSplitter } from '@redeye/ui-styles';
Expand Down Expand Up @@ -39,10 +40,13 @@ export const BeaconRow = observer<BeaconProps>(({ beacon, ...props }) => {
beaconId: beacon?.id!,
})
);

const { last, isDialogDisabled } = useCheckLastUnhidden('beacon', beacon?.hidden || false);

return (
<InfoRow
cy-test="info-row"
onClick={() => beacon.select()}
onClick={() => (!toggleHidden.showHide ? beacon.select() : null)}
onMouseEnter={() =>
beacon.state !== TimeStatus.FUTURE && store.campaign?.interactionState.onHover(beacon?.hierarchy)
}
Expand Down Expand Up @@ -70,20 +74,23 @@ export const BeaconRow = observer<BeaconProps>(({ beacon, ...props }) => {
/>
<QuickMeta
modal={beacon}
mutateToggleHidden={mutateToggleHidden}
disabled={!!store.appMeta.blueTeam}
click={() => toggleHidden.update('showHide', true)}
/>
<ToggleHiddenDialog
isOpen={toggleHidden.showHide}
infoType={InfoType.BEACON}
isHiddenToggled={!!beacon?.hidden}
onClose={(e) => {
e.stopPropagation();
toggleHidden.update('showHide', false);
}}
onHide={() => mutateToggleHidden.mutate()}
click={() => (isDialogDisabled ? mutateToggleHidden.mutate() : toggleHidden.update('showHide', true))}
/>
{!isDialogDisabled && (
<ToggleHiddenDialog
typeName="beacon"
isOpen={toggleHidden.showHide}
infoType={InfoType.BEACON}
isHiddenToggled={!!beacon?.hidden}
onClose={(e) => {
e.stopPropagation();
toggleHidden.update('showHide', false);
}}
onHide={() => mutateToggleHidden.mutate()}
last={last}
/>
)}
</InfoRow>
);
});
Original file line number Diff line number Diff line change
@@ -1,35 +1,13 @@
import { createSorter, VirtualizedList } from '@redeye/client/components';
import type { BeaconModel, SortType } from '@redeye/client/store';
import { SortDirection, useStore } from '@redeye/client/store';
import type { InfoType } from '@redeye/client/types/explore';
import { VirtualizedList } from '@redeye/client/components';
import type { BeaconModel } from '@redeye/client/store';
import { BeaconRow, defaultInfoRowHeight, MessageRow } from '@redeye/client/views';
import type { Ref } from 'mobx-keystone';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';

type BeaconsProps = ComponentProps<'div'> & {
type: InfoType;
sort: SortType;
};
import type { BeaconsProps } from '../hooks/use-beacons';
import { useBeacons } from '../hooks/use-beacons';

export const Beacons = observer<BeaconsProps>(({ ...props }) => {
const store = useStore();
const beacons = Array.from<BeaconModel>(
store.campaign?.interactionState[`selected${props.type}`]?.current?.beacons?.values() || []
)
.filter((beacon: BeaconModel | Ref<BeaconModel>) => {
const cBeacon = store.graphqlStore.beacons.get(beacon?.id as string);
return !(!cBeacon || !!cBeacon?.host?.current?.cobaltStrikeServer);
})
.sort((beacon1, beacon2) =>
'current' in beacon1 && 'current' in beacon2
? createSorter(
(beacon: BeaconModel | Ref<BeaconModel>) =>
'current' in beacon ? beacon?.current[props.sort.sortBy || 'id'] : props.sort.sortBy,
props.sort.direction === SortDirection.ASC
)(beacon1, beacon2)
: createSorter(props.sort.sortBy, props.sort.direction === SortDirection.ASC)(beacon1, beacon2)
);
const { beacons } = useBeacons(props);

return (
<VirtualizedList fixedItemHeight={defaultInfoRowHeight}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,11 @@
import { createSorter, VirtualizedList } from '@redeye/client/components';
import type { BeaconModel, SortType } from '@redeye/client/store';
import { SortDirection, useStore } from '@redeye/client/store';
import type { InfoType } from '@redeye/client/types/explore';
import { VirtualizedList } from '@redeye/client/components';
import { BeaconRow, defaultInfoRowHeight, MessageRow } from '@redeye/client/views';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';

type BeaconsProps = ComponentProps<'div'> & {
type: InfoType;
sort: SortType;
};
import type { BeaconsProps } from '../hooks/use-beacons';
import { useBeacons } from '../hooks/use-beacons';

export const HostBeacons = observer<BeaconsProps>(({ ...props }) => {
const store = useStore();
const beacons = (store.campaign?.interactionState.selectedHost?.current?.beaconIds
?.map((beaconId: string | number | symbol) => store.graphqlStore.beacons.get(beaconId as string))
.filter(
(beacon: BeaconModel | undefined) => beacon != null && !(!beacon || !!beacon?.host?.current?.cobaltStrikeServer)
)
.sort(createSorter(props.sort.sortBy, props.sort.direction === SortDirection.ASC)) || []) as BeaconModel[];
const { beacons } = useBeacons(props);

return (
<VirtualizedList fixedItemHeight={defaultInfoRowHeight}>
Expand Down
44 changes: 30 additions & 14 deletions applications/client/src/views/Campaign/Explore/Panels/Host/Host.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { CarbonIcon, dateShortFormat, dateShortPlaceholder, semanticIcons } from
import type { HostModel } from '@redeye/client/store';
import { useStore } from '@redeye/client/store';
import { InfoType, TimeStatus } from '@redeye/client/types';
import { IconLabel, InfoRow, RowTime, RowTitle, ToggleHiddenDialog, useToggleHidden } from '@redeye/client/views';
import {
IconLabel,
InfoRow,
RowTime,
RowTitle,
ToggleHiddenDialog,
useCheckLastUnhidden,
useToggleHidden,
} from '@redeye/client/views';
import { FlexSplitter, Txt } from '@redeye/ui-styles';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';
Expand All @@ -18,6 +26,11 @@ export const HostRow = observer<HostRowProps>(({ host, ...props }) => {

if (!host) return null;

const { last, isDialogDisabled } = useCheckLastUnhidden(
host.cobaltStrikeServer ? 'server' : 'host',
host?.hidden || false
);

const [toggleHidden, mutateToggleHidden] = useToggleHidden(async () =>
host.cobaltStrikeServer
? await store.graphqlStore.mutateToggleServerHidden({
Expand All @@ -29,7 +42,7 @@ export const HostRow = observer<HostRowProps>(({ host, ...props }) => {

return (
<InfoRow
onClick={() => host.select()}
onClick={() => (!toggleHidden.showHide ? host.select() : null)}
onMouseEnter={() => store.campaign?.interactionState.onHover(host.hierarchy)}
{...props}
>
Expand Down Expand Up @@ -58,20 +71,23 @@ export const HostRow = observer<HostRowProps>(({ host, ...props }) => {
)}
<QuickMeta
modal={host}
mutateToggleHidden={mutateToggleHidden}
disabled={!!store.appMeta.blueTeam}
click={() => toggleHidden.update('showHide', true)}
/>
<ToggleHiddenDialog
isOpen={toggleHidden.showHide}
infoType={host.cobaltStrikeServer ? InfoType.SERVER : InfoType.HOST}
isHiddenToggled={!!host?.hidden}
onClose={(e) => {
e.stopPropagation();
toggleHidden.update('showHide', false);
}}
onHide={() => mutateToggleHidden.mutate()}
click={() => (isDialogDisabled ? mutateToggleHidden.mutate() : toggleHidden.update('showHide', true))}
/>
{!isDialogDisabled && (
<ToggleHiddenDialog
typeName={host.cobaltStrikeServer ? 'server' : 'host'}
isOpen={toggleHidden.showHide}
infoType={host.cobaltStrikeServer ? InfoType.SERVER : InfoType.HOST}
isHiddenToggled={!!host?.hidden}
onClose={(e) => {
e.stopPropagation();
toggleHidden.update('showHide', false);
}}
onHide={() => mutateToggleHidden.mutate()}
last={last}
/>
)}
</InfoRow>
);
});
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import { createSorter, VirtualizedList } from '@redeye/client/components';
import type { HostModel, SortType } from '@redeye/client/store';
import { useStore, SortDirection } from '@redeye/client/store';
import type { InfoType } from '@redeye/client/types/explore';
import { VirtualizedList } from '@redeye/client/components';
import { defaultInfoRowHeight, HostRow, MessageRow } from '@redeye/client/views';
import type { Ref } from 'mobx-keystone';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';

type HostsProps = ComponentProps<'div'> & {
type: InfoType;
sort: SortType;
};
import type { HostsProps } from '../hooks/use-hosts';
import { current, useHosts } from '../hooks/use-hosts';

export const Hosts = observer<HostsProps>(({ ...props }) => {
const store = useStore();
const hosts = Array.from<HostModel | Ref<HostModel>>(
store.campaign?.interactionState[`selected${props.type}`]?.current?.hosts?.values() || []
)
.filter((host) => !current(host).cobaltStrikeServer) // remove servers from 'Hosts' list
.sort(
createSorter(
(host: HostModel | Ref<HostModel>) => ('current' in host ? host?.current[props.sort.sortBy || 'id'] : host.id),
props.sort.direction === SortDirection.ASC
)
);
const { hosts } = useHosts(props);

return (
<VirtualizedList fixedItemHeight={defaultInfoRowHeight}>
Expand All @@ -35,5 +17,3 @@ export const Hosts = observer<HostsProps>(({ ...props }) => {
</VirtualizedList>
);
});

const current = (host: HostModel | Ref<HostModel>) => ('current' in host ? host?.current : host);
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ import type { Ref } from 'mobx-keystone';
import { observer } from 'mobx-react-lite';
import moment from 'moment-timezone';
import { useEffect } from 'react';
import { useCheckLastUnhidden } from '../hooks/use-check-last-unhidden';
import { BeaconLinkRow } from './BeaconLinkRow';
import { ToggleHiddenDialog } from './HideDialog';
import { MetaGridLayout, MetaHeader, SaveInputButton, ToggleHiddenButton } from './Meta.styles';
import { useToggleHidden } from './use-toggle-hidden';
import { useToggleHidden } from '../hooks/use-toggle-hidden';

const useGetLastBeaconCommand = (
store: AppStore,
Expand Down Expand Up @@ -80,6 +81,8 @@ export const BeaconMeta = observer(() => {
displayDeathNeedsSaving: false,
});

const { last, isDialogDisabled } = useCheckLastUnhidden('beacon', beacon?.hidden || false);

useEffect(() => {
state.update('displayDeath', beacon?.meta?.[0]?.maybeCurrent?.endTime);
}, [beacon?.meta?.[0]?.maybeCurrent?.endTime, store.campaign.timeline.maxRange]);
Expand Down Expand Up @@ -222,16 +225,18 @@ export const BeaconMeta = observer(() => {
<ToggleHiddenButton
cy-test="show-hide-this-beacon"
disabled={!!store.appMeta.blueTeam}
onClick={() => toggleHidden.update('showHide', true)}
onClick={() => (isDialogDisabled ? mutateToggleHidden.mutate() : toggleHidden.update('showHide', true))}
isHiddenToggled={!!beacon?.hidden}
typeName="beacon"
/>
<ToggleHiddenDialog
typeName="beacon"
isOpen={toggleHidden.showHide}
infoType={InfoType.BEACON}
isHiddenToggled={!!beacon?.hidden}
onClose={() => toggleHidden.update('showHide', false)}
onHide={() => mutateToggleHidden.mutate()}
last={last}
/>
</MetaGridLayout>
);
Expand Down
Loading

0 comments on commit df5fa37

Please sign in to comment.