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

Update Comment Manual Link UI // Commented Out #91

Merged
merged 24 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2ca7eef
??? schema.graphql indentation whitespace ???
Mar 8, 2023
5c5bda0
BeaconSuggest: basic layout and simplification
Mar 8, 2023
6ac0059
rename BeaconSuggest
Mar 8, 2023
7f426d0
update CommentBox form link elements
Mar 8, 2023
55ac430
simplify BeaconSuggest components before rebuild
Mar 8, 2023
84054a5
Merge branch 'develop' into UI-Tweaks-2
Mar 8, 2023
0275fab
cleanout BeaconSuggest, add hostname to search query matches
Mar 8, 2023
df7d98a
refactored CommentBox linked beacon state
Mar 8, 2023
7d09278
update hiding, showing and resetting BeaconSuggest
Mar 9, 2023
765339e
promote highlightPattern to its own file, use it in BeaconSuggest
Mar 9, 2023
42890a9
Comment out the annotation link title
Mar 9, 2023
d108233
lint
Mar 9, 2023
c05e8c1
updating .gitignore to exclude server campaign data
Mar 9, 2023
4dc767c
minor comment form UI updates
Mar 10, 2023
4107fd0
icon updates
Mar 10, 2023
8854dd0
remove the command string from beacon sugggest. it was the wrong data
Mar 10, 2023
da245ce
Merge branch 'develop' into develop-annotation-updates
Mar 10, 2023
72fe426
Merge branch 'develop' into develop-annotation-updates
Mar 17, 2023
c3c3c0b
Merge branch 'develop' into develop-annotation-updates
Mar 27, 2023
ef8793a
Merge branch 'develop' into develop-annotation-updates
May 8, 2023
f7fcd42
Merge branch 'develop' into develop-annotation-updates
May 11, 2023
1f536ff
auto-update graphql schema?
May 12, 2023
7d4a1b7
comment out the UI for manual links, restore later in BLDSTRIKE-591
May 12, 2023
368664b
Minor update to multi-command comment test to address failure.
ccarpenter28 May 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ node_modules
dist
build
@redeye/darwin-x64
dev-databases
applications/server/dev-databases
applications/server/campaign
.eslintcache

.yarn/*
Expand All @@ -25,7 +26,6 @@ junit.xml
.vim
.nova

server/.env
[diff]
tool = vscode
[difftool "vscode"]
Expand Down
42 changes: 42 additions & 0 deletions applications/client/src/components/highlightPattern.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { UtilityStyles } from '@redeye/ui-styles';
import type { ReactNode } from 'react';

// Sanitize input for use in regex
function sanitizeRegex(text: string): string {
return (text ?? '').replace(/[#-.]|[[-^]|[?|{}]/g, '\\$&');
}

function tokenize(str) {
return str.split(/\s/gi);
}

function createRegex(pattern: string) {
return `(?:${tokenize(sanitizeRegex(pattern)).join('|')})`;
}

export const highlightPattern = (text?: string, pattern?: string): ReactNode => {
if (!text) return null;
if (!pattern) return text;

const regEx = new RegExp(createRegex(pattern), 'ig');
const splitText = text?.split?.(regEx) || '';
if (splitText.length <= 1) return text;

const matches = text.match(regEx);
if (!matches) return text;

return splitText.reduce<ReactNode[]>(
(arr, element, index) =>
matches[index]
? [
...arr,
element,
// eslint-disable-next-line react/no-array-index-key
<span key={`${element}-${index}`} css={UtilityStyles.textHighlight}>
{matches[index]}
</span>,
]
: [...arr, element],
[]
);
};
1 change: 1 addition & 0 deletions applications/client/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export * from './ScrollBox';
export * from './VirtualizedList';
export * from './create-sorter';
export * from './is-defined-guard';
export * from './highlightPattern';
export * from './mobx-create-state';
export * from './utils-time';
export * from './utils';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Classes } from '@blueprintjs/core';
import { css } from '@emotion/react';
import { createState } from '@redeye/client/components/mobx-create-state';
import type { CommandModel } from '@redeye/client/store';
import type { CommandModel, LinkModel } from '@redeye/client/store';
import { useStore } from '@redeye/client/store';
import type { UUID } from '@redeye/client/types/uuid';
import { Command, CommandOutput, CommentCount, InfoRow } from '@redeye/client/views';
Expand All @@ -10,8 +10,9 @@ import { reaction } from 'mobx';
import { observer } from 'mobx-react-lite';
import type { ComponentProps } from 'react';
import { Suspense, useEffect } from 'react';
import { CarbonIcon, semanticIcons } from '@redeye/client/components';
import { MitreTechniqueIcons } from '../../components/MitreTechniqueIcons';
import { CheckForAddedLink } from '../../components/Comment/CheckForAddedLink';
import { getManualCommandLinks } from '../../components/Comment/CheckForAddedLink';

type CommandContainerProps = ComponentProps<'div'> & {
command?: CommandModel;
Expand Down Expand Up @@ -41,6 +42,9 @@ export const CommandContainer = observer<CommandContainerProps>(
}) => {
const store = useStore();
const state = createState({
manualLink: getManualCommandLinks(commandId, Array.from(store?.graphqlStore.links.values()))[0] as
| LinkModel
| undefined,
get active() {
return store.router.params.activeItem === 'command' && store.router.params.activeItemId === state.commandId;
},
Expand Down Expand Up @@ -97,6 +101,7 @@ export const CommandContainer = observer<CommandContainerProps>(
),
[]
);

return (
<div cy-test="command-info" css={wrapperStyle} {...props}>
<div css={[UtilityStyles.hoverRevealChildrenVisibility, gridWrapperStyle]}>
Expand All @@ -120,10 +125,9 @@ export const CommandContainer = observer<CommandContainerProps>(
showPath={showPath}
/>
</Suspense>
{/* add icon for added beacon link */}
<MitreTechniqueIcons mitreAttackIds={state.command?.mitreTechniques} />
{store.router.params.currentItem === 'beacon' && (
<CheckForAddedLink commandID={commandId} containerOrBox="container" toggleLinkedFlag={() => {}} />
{store.router.params.currentItem === 'beacon' && state.manualLink != null && (
<CarbonIcon icon={semanticIcons.link} />
)}
</InfoRow>
{!hideCommentButton && (
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { ItemPredicate, ItemRenderer, Suggest2Props } from '@blueprintjs/select';
import { Suggest2 } from '@blueprintjs/select';
import type { BeaconModel } from '@redeye/client/store';
import { useStore } from '@redeye/client/store';
import { MenuItem2 } from '@blueprintjs/popover2';
import { observer } from 'mobx-react-lite';
import { Txt } from '@redeye/ui-styles';
import { BeaconSuggestedRow } from './BeaconSuggestedRow';

export type BeaconSuggestProps = Partial<Suggest2Props<BeaconModel>> & {
commandString: string;
};

export const BeaconSuggest = observer<BeaconSuggestProps>(
({ commandString, onItemSelect: _onItemSelect, popoverProps, ...suggestProps }: BeaconSuggestProps) => {
const store = useStore();
const beacons = Array.from(store.graphqlStore.beacons.values() || []);

const onItemSelect: BeaconSuggestProps['onItemSelect'] = (item) => {
_onItemSelect?.(item);
};

const findBeacon: ItemPredicate<BeaconModel> = (query, beaconModel) => {
const { displayName = '', beaconName = '', host } = beaconModel;
const { hostName = '' } = host?.current || {};
const beaconContext = beaconModel.meta[0]?.current.username || '';
// add serverName too?
return [hostName, displayName, beaconName, beaconContext].join(' ').toLowerCase().includes(query.toLowerCase());
};

const renderMenuItem: ItemRenderer<BeaconModel> = (beaconModel, { handleClick, modifiers, query }) => {
if (!modifiers.matchesPredicate) {
return null;
}
return (
<MenuItem2
key={beaconModel.id}
onClick={handleClick}
labelElement={commandString}
shouldDismissPopover={false}
text={<BeaconSuggestedRow beaconModel={beaconModel} query={query} />}
{...modifiers}
/>
);
};

const inputValueRenderer: BeaconSuggestProps['inputValueRenderer'] = (item) =>
`${item.host?.current.displayName} / ${item.displayName}`;

return (
<Suggest2
items={beacons}
itemPredicate={findBeacon}
itemRenderer={renderMenuItem}
inputValueRenderer={inputValueRenderer}
popoverProps={{
minimal: true,
hasBackdrop: true,
...popoverProps,
}}
onItemSelect={onItemSelect}
noResults={noResults}
resetOnQuery
fill
{...suggestProps}
/>
);
}
);

const noResults = (
<MenuItem2
disabled
text={
<Txt disabled italic>
No Results
</Txt>
}
/>
);
Loading