-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge 4.9.0 into master
- Loading branch information
Showing
285 changed files
with
7,804 additions
and
13,620 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
## Mount application | ||
|
||
The application mounts a ReactJS application into the HTML element provided by the parameters received on the `mount` method of the Wazuh dashboard application. The application could be wrapped in the root level with some contexts as `I18nProvider` and Redux provider to these are accessibles from any component in the tree: | ||
|
||
```ts | ||
// plugin.ts | ||
{ | ||
mount: async (params: AppMountParameters) => { | ||
try { | ||
// Load application bundle | ||
const { renderApp } = await import('./application'); | ||
const unmount = await renderApp(params); | ||
return () => { | ||
unmount(); | ||
}; | ||
} catch (error) { | ||
console.debug(error); | ||
} | ||
}, | ||
} | ||
|
||
``` | ||
|
||
```tsx | ||
// application.ts | ||
export async function renderApp(params) { | ||
/* Load or initiate the dependencies, async styles, etc... */ | ||
|
||
const deps = {}; // dependencies | ||
ReactDOM.render( | ||
<I18nProvider> | ||
<Provider store={store}> | ||
<Application {...deps} /> | ||
</Provider> | ||
</I18nProvider>, | ||
params.element, | ||
); | ||
return () => ReactDOM.unmountComponentAtNode(params.element); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
## Navigation | ||
|
||
Due we need to do some redirections to routes that are defined in services that are decoupled of the navigation, we need to use some service that has the context of the navigation. This is done though the `NavigationService`. | ||
|
||
The `NavigationService` is responsible to manage the navigation of the same application and navigate to others applications and is created with a reference to a new history we create before mount the application. This services is using for navigating instead of using the interfaces provided by the `react-router-dom` | ||
|
||
```ts | ||
NavigationService.getInstance(history); | ||
``` | ||
|
||
## Routing | ||
|
||
The `Application` component defines the layout of the application under the router provided by `react-router-dom`. | ||
|
||
The routing of the application is based on path names and search parameters. This architecture is inherited from the old routing based on AngularJS that was using the application. | ||
|
||
```tsx | ||
// app-router | ||
import { Router, Switch, Route } from 'react-router-dom'; | ||
|
||
const Application = () => { | ||
// general states or effects | ||
|
||
return ( | ||
<Router history={history}> | ||
{/* General components that could be always displayed in all views or conditionally */} | ||
<Switch> | ||
<Route path={'/health-check'} exact render={HealthCheck}></Route> | ||
{/* Rest of routes */} | ||
<Switch> | ||
<Router> | ||
) | ||
} | ||
``` | ||
|
||
### Routing based on search parameters | ||
|
||
Some views are managed depending on the search parameters ( `tab=syscollector` ), and the current version of `react-router-dom` that is `v5` is unable to re-render components when the search parameters change. To cover this requirement, we use a custom routing components/hooks/HOCs that have a similar interface to the provided by the `react-router-dom`. | ||
|
||
- Components with similar interface that provided by `react-router-dom` | ||
- Switch: find the first Route that matches the search paramerts or render the Redirect if this is included | ||
- Route: define the route match parameters to render the component | ||
- Redirect: redirect to another "route" based on search parameters | ||
|
||
```tsx | ||
import { Switch, Route, Redict } from '../router-search'; | ||
|
||
const Security = () => { | ||
return ( | ||
<Switch> | ||
<Route path='?tab=users'> | ||
<Users></Users> | ||
</Route> | ||
<Route path='?tab=roles'> | ||
<Roles></Roles> | ||
</Route> | ||
<Route path='?tab=policies'> | ||
<Policies></Policies> | ||
</Route> | ||
<Route path='?tab=roleMapping'> | ||
<> | ||
{allowRunAs !== undefined && | ||
allowRunAs !== | ||
getWazuhCorePlugin().API_USER_STATUS_RUN_AS.ENABLED && | ||
isNotRunAs(allowRunAs)} | ||
<RolesMapping></RolesMapping> | ||
</> | ||
</Route> | ||
<Redirect to='?tab=users'></Redirect> | ||
</Switch> | ||
); | ||
}; | ||
``` | ||
|
||
The `path` property of the `Route` component allows to define a variable value for a search parameter, using the `:` at the beggining of the search parameter definition using the syntax: `?<parameter_name>=:value`. The `:value` defines the value for `<parameter_name>` search parameter is variable. The name of the `value` is unused. To access to the value of the `<parameter_name>` search parameter, use the `render` property of the `Route` component.Example: | ||
|
||
```tsx | ||
class RegistryTable extends Coomponent { | ||
render() { | ||
return ( | ||
<div> | ||
{registryTable} | ||
<Switch> | ||
<Route | ||
path='?file=:file' | ||
render={({ search: { file } }) => ( | ||
<FlyoutDetail | ||
fileName={file} | ||
agentId={this.props.agent.id} | ||
closeFlyout={() => this.closeFlyout()} | ||
view='inventory' | ||
{...this.props} | ||
/> | ||
)} | ||
></Route> | ||
</Switch> | ||
</div> | ||
); | ||
} | ||
} | ||
``` | ||
|
||
- hooks: | ||
- useRouterSearch: returns the search parameters | ||
|
||
```tsx | ||
import { useRouterSearch } from '../use-router-search'; | ||
export const Component = () => { | ||
// Get the tab search parameter | ||
const { tab } = useRouterSearch(); | ||
return <></>; | ||
}; | ||
``` | ||
|
||
```tsx | ||
import { useRouterSearch } from '../use-router-search'; | ||
export const Component = () => { | ||
// Get the tab search parameter and use a value as default if this is undefined | ||
const { tab = 'welcome' } = useRouterSearch(); | ||
return <></>; | ||
}; | ||
``` | ||
|
||
- HOCs: | ||
- withRouterSearch: inject the search parameters through the `search` property | ||
|
||
```tsx | ||
import { withRouterSearch } from '../with-router-search'; | ||
export const Component = withRouterSearch(({ search }) => { | ||
// search property has the searh parameters | ||
|
||
if (search.tab === 'value') { | ||
// any logic | ||
} | ||
return <></>; | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,4 +30,4 @@ | |
], | ||
"server": true, | ||
"ui": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import React, { useEffect } from 'react'; | ||
import { Router, Route, Switch, Redirect } from 'react-router-dom'; | ||
import { ToolsRouter } from './components/tools/tools-router'; | ||
import { getWazuhCorePlugin, getWzMainParams } from './kibana-services'; | ||
import { updateCurrentPlatform } from './redux/actions/appStateActions'; | ||
import { useDispatch } from 'react-redux'; | ||
import { checkPluginVersion } from './utils'; | ||
import { WzAuthentication, loadAppConfig } from './react-services'; | ||
import { WzMenuWrapper } from './components/wz-menu/wz-menu-wrapper'; | ||
import { WzAgentSelectorWrapper } from './components/wz-agent-selector/wz-agent-selector-wrapper'; | ||
import { ToastNotificationsModal } from './components/notifications/modal'; | ||
import { WzUpdatesNotification } from './components/wz-updates-notification'; | ||
import { HealthCheck } from './components/health-check'; | ||
import { WzBlankScreen } from './components/wz-blank-screen/wz-blank-screen'; | ||
import { RegisterAgent } from './components/endpoints-summary/register-agent/containers/register-agent/register-agent'; | ||
import { MainEndpointsSummary } from './components/endpoints-summary'; | ||
import { AgentView } from './components/endpoints-summary/agent'; | ||
import WzManagement from './controllers/management/components/management/management-provider'; | ||
import { Overview } from './components/overview/overview'; | ||
import { Settings } from './components/settings'; | ||
import { WzSecurity } from './components/security'; | ||
import $ from 'jquery'; | ||
import NavigationService from './react-services/navigation-service'; | ||
|
||
export function Application(props) { | ||
const dispatch = useDispatch(); | ||
const navigationService = NavigationService.getInstance(); | ||
const history = navigationService.getHistory(); | ||
|
||
useEffect(() => { | ||
// Get the dashboard security | ||
getWazuhCorePlugin() | ||
.dashboardSecurity.fetchCurrentPlatform() | ||
.then(item => { | ||
dispatch(updateCurrentPlatform(item)); | ||
}) | ||
.catch(() => {}); | ||
|
||
// Init the process of refreshing the user's token when app starts. | ||
checkPluginVersion().finally(() => { | ||
WzAuthentication.refresh(); | ||
}); | ||
|
||
// Load the app state | ||
loadAppConfig(); | ||
|
||
// TODO: Replace this with document insteat | ||
// Bind deleteExistentToken on Log out component. | ||
$('.euiHeaderSectionItem__button, .euiHeaderSectionItemButton').on( | ||
'mouseleave', | ||
function () { | ||
// opendistro | ||
$('button:contains(Log out)').on('click', function () { | ||
WzAuthentication.deleteExistentToken(); | ||
}); | ||
}, | ||
); | ||
}, []); | ||
|
||
return ( | ||
<Router history={history}> | ||
<div className='wazuhNotReadyYet'></div> | ||
{/* TODO: The plugins/main/public/components/wz-menu/wz-menu.js defines a portal to mount here. We could avoid the usage of the React portal and render the component instead*/} | ||
<WzMenuWrapper /> | ||
<ToastNotificationsModal /> {/* TODO: check if this is being used */} | ||
<WzAgentSelectorWrapper /> | ||
<WzUpdatesNotification /> | ||
<Switch> | ||
<Route path={'/health-check'} exact render={HealthCheck}></Route> | ||
<Route | ||
path={'/agents-preview/deploy'} | ||
exact | ||
render={RegisterAgent} | ||
></Route> | ||
<Route path={'/agents'} exact render={AgentView}></Route> | ||
<Route | ||
path={'/agents-preview/'} | ||
exact | ||
render={MainEndpointsSummary} | ||
></Route> | ||
<Route path={'/manager'} exact render={WzManagement}></Route> | ||
<Route | ||
path={'/overview'} | ||
exact | ||
render={props => <Overview {...props} />} | ||
></Route> | ||
<Route path={'/settings'} exact render={Settings}></Route> | ||
<Route path={'/security'} exact render={WzSecurity}></Route> | ||
<Route | ||
path={'/wazuh-dev'} | ||
exact | ||
render={props => <ToolsRouter {...props} />} | ||
></Route> | ||
<Route | ||
path={'/blank-screen'} | ||
exact | ||
render={props => <WzBlankScreen {...props} />} | ||
></Route> | ||
<Redirect from='/' to={getWzMainParams()} /> | ||
</Switch> | ||
</Router> | ||
); | ||
} |
Oops, something went wrong.