diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 24501b7e..5cc4738a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,10 +1,9 @@ - name: Build Check -concurrency: +concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - + on: push: branches: @@ -23,20 +22,16 @@ jobs: steps: - uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v3 with: node-version: 16.19.0 cache: 'yarn' - - run: | - git fetch - git config pull.rebase true - git pull origin $GITHUB_HEAD_REF - run: CYPRESS_INSTALL_BINARY=0 yarn install --immutable --inline-builds - run: CYPRESS_INSTALL_BINARY=0 yarn moon ci - uses: 'moonrepo/run-report-action@v1' if: success() || failure() with: access-token: ${{ secrets.GITHUB_TOKEN }} - - diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6baa8063..9e9c57aa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,11 +5,10 @@ name: Release on: push: - branches: [ "main" ] + branches: ['main'] jobs: build: - runs-on: ubuntu-latest strategy: @@ -18,37 +17,36 @@ jobs: # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: 16.19.0 - cache: 'yarn' - - run: | - npm install -g pkg-fetch - pkg-fetch --platform linux --node-range node16 - pkg-fetch --platform mac --node-range node16 - pkg-fetch --platform win --node-range node16 - - run: | - git fetch - git config pull.rebase true - git pull origin $GITHUB_HEAD_REF - yarn install --immutable --inline-builds - yarn run release:all - chmod +x release/mac/RedEye - chmod +x release/linux/RedEye - - name: Archive mac production artifacts - uses: actions/upload-artifact@v3 - with: - name: mac - path: release/mac - - name: Archive linux production artifacts - uses: actions/upload-artifact@v3 - with: - name: linux - path: release/linux - - name: Archive windows production artifacts - uses: actions/upload-artifact@v3 - with: - name: windows - path: release/windows + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: 16.19.0 + cache: 'yarn' + - run: | + npm install -g pkg-fetch + pkg-fetch --platform linux --node-range node16 + pkg-fetch --platform mac --node-range node16 + pkg-fetch --platform win --node-range node16 + - run: | + yarn install --immutable --inline-builds + yarn run release:all + chmod +x release/mac/RedEye + chmod +x release/linux/RedEye + - name: Archive mac production artifacts + uses: actions/upload-artifact@v3 + with: + name: mac + path: release/mac + - name: Archive linux production artifacts + uses: actions/upload-artifact@v3 + with: + name: linux + path: release/linux + - name: Archive windows production artifacts + uses: actions/upload-artifact@v3 + with: + name: windows + path: release/windows diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2ee16ec0..9f4aab09 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,6 +34,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Cache uses: actions/setup-node@v3 @@ -41,10 +43,6 @@ jobs: node-version: 16.19.0 cache: 'yarn' - - run: | - git fetch - git config pull.rebase true - git pull origin $GITHUB_HEAD_REF - run: yarn install --immutable --inline-builds - run: yarn moon run server:build client:build @@ -67,6 +65,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 + with: + fetch-depth: 0 - name: Cache uses: actions/setup-node@v3 @@ -80,10 +80,6 @@ jobs: name: moon-cache path: .moon/cache - - run: | - git fetch - git config pull.rebase true - git pull origin $GITHUB_HEAD_REF - run: yarn install --immutable --inline-builds - name: Red Team Tests - Chrome v${{ matrix.node }} uses: cypress-io/github-action@v5.2.0 diff --git a/.gitignore b/.gitignore index cf9985f8..1a6bd0f9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,8 @@ node_modules dist build @redeye/darwin-x64 -dev-databases +applications/server/dev-databases +applications/server/campaign .eslintcache .yarn/* @@ -25,7 +26,6 @@ junit.xml .vim .nova -server/.env [diff] tool = vscode [difftool "vscode"] diff --git a/.moon/workspace.yml b/.moon/workspace.yml index 72d7571e..55ed209c 100644 --- a/.moon/workspace.yml +++ b/.moon/workspace.yml @@ -17,7 +17,6 @@ projects: - 'applications/*' - 'packages/*' - # Configures the version control system to utilize within the workspace. A VCS # is required for determining touched (added, modified, etc) files, calculating file hashes, # computing affected files, and much more. diff --git a/.prettierrc.yaml b/.prettierrc.yaml index 51494c7e..86191533 100644 --- a/.prettierrc.yaml +++ b/.prettierrc.yaml @@ -1,7 +1,7 @@ printWidth: 120 semi: true singleQuote: true -trailingComma: "es5" -endOfLine: "lf" +trailingComma: 'es5' +endOfLine: 'lf' tabWidth: 2 useTabs: true diff --git a/applications/client/src/components/AuthCheck.tsx b/applications/client/src/components/AuthCheck.tsx index 8bc24988..55f66758 100644 --- a/applications/client/src/components/AuthCheck.tsx +++ b/applications/client/src/components/AuthCheck.tsx @@ -1,66 +1,54 @@ import type { DialogProps } from '@blueprintjs/core'; -import { Button, Classes, Dialog, Intent } from '@blueprintjs/core'; +import { Button, Intent } from '@blueprintjs/core'; import { WarningAlt16 } from '@carbon/icons-react'; -import { css } from '@emotion/react'; -import { CarbonIcon } from '@redeye/client/components'; +import { CarbonIcon, DialogEx } from '@redeye/client/components'; import { RedEyeRoutes, useStore } from '@redeye/client/store'; import { observer } from 'mobx-react-lite'; import { useEffect } from 'react'; +import { DialogBodyEx } from './Dialogs/DialogBodyEx'; +import { DialogFooterEx } from './Dialogs/DialogFooterEx'; type AuthCheckProps = Partial & {}; export const AuthCheck = observer(({ ...props }) => { const store = useStore(); + // Redirect to login if the app loads with no session/connection to the server useEffect(() => { setTimeout(() => { if (!store.appMeta.blueTeam) store.auth.checkServerConnection(); }, 1000); }, []); - const close = () => { + + const onClose = () => { store.auth.setPromptAuth(false); store.auth.setHasClickedAuthDialog(true); }; + const onLogin = () => { + onClose(); + store.router.updateRoute({ path: RedEyeRoutes.LOGIN }); + }; + return ( - } title="Unable to authenticate" - onClose={close} + onClose={onClose} {...props} > -
+ The application was unable to authenticate with the server. Click "Login" to re-authenticate. -
-
- - -
-
+ + + ))} {/* Secondary dialog (if multiple images are found) */} - state.openModal()} @@ -143,7 +143,7 @@ export const ScreenShotCommand = observer(({ command }) alt="Command Screenshot" /> )} - + ) : ( data?.images?.[0]?.url && ( @@ -155,7 +155,7 @@ export const ScreenShotCommand = observer(({ command }) /> ) )} - + ); }); diff --git a/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx b/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx index 6dc66dc7..37fe1326 100644 --- a/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx +++ b/applications/client/src/views/Campaign/Explore/Panels/Comment/CommentGroup.tsx @@ -1,14 +1,13 @@ import { css } from '@emotion/react'; -import { Flex } from '@redeye/client/components'; -import { createState } from '@redeye/client/components/mobx-create-state'; -import type { AnnotationModel, CommandGroupModel, CommandModel } from '@redeye/client/store'; +import type { AnnotationModel, CommandGroupModel } from '@redeye/client/store'; import { useStore } from '@redeye/client/store'; import type { UUID } from '@redeye/client/types/uuid'; import { CommandContainer, CommentBox, NavBreadcrumbs } from '@redeye/client/views'; -import { CoreTokens } from '@redeye/ui-styles'; +import { CoreTokens, ThemeClasses, Flex } from '@redeye/ui-styles'; import type { Ref } from 'mobx-keystone'; import { observer } from 'mobx-react-lite'; import type { ComponentProps } from 'react'; +import { useEffect, useState } from 'react'; export type CommentGroupProps = ComponentProps<'div'> & { commandGroup?: CommandGroupModel; @@ -34,17 +33,22 @@ export const CommentGroup = observer( ...props }) => { const store = useStore(); - const state = createState({ - localCommand: undefined as undefined | CommandModel, - get commandGroupId(): UUID | undefined { - return (commandGroup?.id ?? commandGroupId!) as UUID; - }, - get commandGroup(): CommandGroupModel | undefined { - return state.commandGroupId ? store.graphqlStore.commandGroups.get(state.commandGroupId!) : undefined; - }, - }); - const firstCommandId = state.commandGroup?.commandIds?.[0]; + const [commandGroupId1, setCommandGroupId1] = useState(commandGroupId); + const [commandGroup1, setCommandGroup1] = useState(commandGroup); + const firstCommandId = commandGroup1?.commandIds?.[0]; const firstCommand = firstCommandId && store.graphqlStore.commands.get(firstCommandId); + useEffect(() => { + if (commandGroupId) { + // For Comments Tab + setCommandGroupId1(commandGroupId as UUID); + setCommandGroup1(store.graphqlStore.commandGroups.get(commandGroupId)); + } + if (commandGroup) { + // For Presentation Tab + setCommandGroupId1(commandGroup?.id as UUID); + setCommandGroup1(commandGroup); + } + }, [commandGroupId, commandGroup]); return (
( border-bottom: 1px solid ${CoreTokens.BorderMuted}; //ask ryan how to remove this `, ]} - // id={commandGroupId} // @SEBASTIAN: is this a testing hook? {...props} > - - {state.commandGroup?.annotations?.map((annotation: Ref) => ( + + {commandGroup1?.annotations?.map((annotation: Ref) => ( toggleNewComment(state.commandGroup?.id)} + reply={() => toggleNewComment(commandGroup1?.id)} annotation={annotation?.maybeCurrent} - commandGroup={state.commandGroup} + commandGroup={commandGroup1} isFullList /> ))} - {newComment === state.commandGroup?.id && ( - + {newComment === commandGroup1?.id && ( + )} @@ -99,14 +92,14 @@ export const CommentGroup = observer( /> )} {!hideCommands && - state.commandGroup?.commandIds?.map((commandId) => ( + commandGroup1?.commandIds?.map((commandId) => ( ( const commentBoxStyle = css` border-bottom: none !important; - background: ${CoreTokens.Background1}; + .${ThemeClasses.DARK} & { + background: ${CoreTokens.transparentWhite(0.05)}; + } + .${ThemeClasses.LIGHT} & { + background: ${CoreTokens.transparentBlack(0.04)}; + } margin-bottom: 1px; `; diff --git a/applications/client/src/views/Campaign/Explore/Panels/Host/Host.tsx b/applications/client/src/views/Campaign/Explore/Panels/Host/Host.tsx index 487b0fa1..5c86a530 100644 --- a/applications/client/src/views/Campaign/Explore/Panels/Host/Host.tsx +++ b/applications/client/src/views/Campaign/Explore/Panels/Host/Host.tsx @@ -1,3 +1,4 @@ +import { Menu } from '@blueprintjs/core'; import { ViewOff16 } from '@carbon/icons-react'; import { CarbonIcon, dateShortFormat, dateShortPlaceholder, semanticIcons } from '@redeye/client/components'; import type { HostModel } from '@redeye/client/store'; @@ -15,7 +16,7 @@ import { import { FlexSplitter, Txt } from '@redeye/ui-styles'; import { observer } from 'mobx-react-lite'; import type { ComponentProps } from 'react'; -import { QuickMeta } from '../QuickMeta'; +import { QuickMetaPopoverButton, ShowHideMenuItem } from '../QuickMeta'; type HostRowProps = ComponentProps<'div'> & { host: HostModel; @@ -74,11 +75,19 @@ export const HostRow = observer(({ host, ...props }) => { )} - (isDialogDisabled ? mutateToggleHidden.mutate() : toggleHidden.update('showHide', true))} - /> + {host != null && ( + + (isDialogDisabled ? mutateToggleHidden.mutate() : toggleHidden.update('showHide', true))} + /> + + } + /> + )} {!isDialogDisabled && ( ( window.localStorage.setItem('disableDialog', e.target.checked.toString()); }, []); + const confirmShowHide = + last && !isHiddenToggled + ? onClose + : (e: React.SyntheticEvent) => { + e.stopPropagation(); + setLoading(true); + onHide(); + }; + + const dialogTitle = + last && !isHiddenToggled + ? `Cannot hide final ${infoType.toLowerCase()}` + : `${verb} this ${infoType.toLowerCase()}?`; + return ( - -
+ + {last && !isHiddenToggled ? ( <> @@ -72,37 +79,24 @@ export const ToggleHiddenDialog = observer( )} -
-
-
- - -
-
-
+ + +
+ +
Add Command to Existing Comment
+ } + placeholder="Search comments" + large + /> +
} + {...props} > - } - placeholder="Search comments" - large - /> {isSuccess && ( @@ -126,7 +115,7 @@ export const AddToCommandGroupDialog = observer(({ {/* {isLoading && } */} {isError && } />} - - - - + - - + + +