From 7fdbe565763f1498488eec8d5a1cde29a74fb4ec Mon Sep 17 00:00:00 2001
From: Maximiliano Ibarra
Date: Mon, 7 Jun 2021 16:23:52 -0300
Subject: [PATCH 01/24] Feature/3316 error handler orchestrator (#3327)
* feat(errorBoundary): Added ErrorBoundary HOC and component and added loglevel dependency
* feature(errorBoundary): Moved with the others HOCs.
* feature(errorBoundary): Typo refactor.
* First attempt LoggerService
* Merged error boundary, integrated loggerService.
* changed logger name, create logger-service test file
* Updated CHANGELOG
* Moved to react-services, changed name, traslates comments
* feat(errorBoundary): Removed old integration
* refactor(loggerService): Changed class for function methods.
* test(logger-service): Added basic unit test to logger-service
* refactor(logger-service): Applied new implementation of error-orchestrator service.
* feature(logger-service): PR comments and some refactors.
Co-authored-by: gabiwassan
Co-authored-by: Ibarra Maximiliano
---
CHANGELOG.md | 3 +
common/constants.ts | 33 ++++++++++
package.json | 3 +-
public/kibana-services.ts | 10 ++-
.../error-orchestrator-base.ts | 65 +++++++++++++++++++
.../error-orchestrator-business.ts | 20 ++++++
.../error-orchestrator-critical.ts | 20 ++++++
.../error-orchestrator-ui.ts | 24 +++++++
.../error-orchestrator.factory.ts | 29 +++++++++
.../error-orchestrator.service.ts | 23 +++++++
.../error-orchestrator/types.ts | 46 +++++++++++++
public/react-services/index.ts | 3 +-
12 files changed, 275 insertions(+), 4 deletions(-)
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-base.ts
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-business.ts
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-critical.ts
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-ui.ts
create mode 100644 public/react-services/error-orchestrator/error-orchestrator.factory.ts
create mode 100644 public/react-services/error-orchestrator/error-orchestrator.service.ts
create mode 100644 public/react-services/error-orchestrator/types.ts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ca9f0e2c74..d0d01a477d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@ All notable changes to the Wazuh app project will be documented in this file.
- Changed ossec to wazuh in sample-data [#3121](https://github.com/wazuh/wazuh-kibana-app/pull/3121)
- Changed empty fields in FIM tables and `syscheck.value_name` in discovery now show an empty tag for visual clarity [#3279](https://github.com/wazuh/wazuh-kibana-app/pull/3279)
+### Added
+- Added new error handler to be responsible for the error orchestration [#3327](https://github.com/wazuh/wazuh-kibana-app/pull/3327)
+
## Wazuh v4.2.0 - Kibana 7.10.2 , 7.11.2 - Revision 4201
### Added
diff --git a/common/constants.ts b/common/constants.ts
index bc7cdcdb62..71b78dd6cb 100644
--- a/common/constants.ts
+++ b/common/constants.ts
@@ -220,3 +220,36 @@ export enum WAZUH_MODULES_ID{
export const AUTHORIZED_AGENTS = 'authorized-agents';
export const HEALTH_CHECK = 'health-check';
+
+// Health check
+export const HEALTH_CHECK_REDIRECTION_TIME = 300; //ms
+
+// Kibana settings
+// Default timeTilter set by the app
+export const WAZUH_KIBANA_SETTING_TIME_FILTER = {
+ from: "now-24h",
+ to: 'now'
+};
+export const KIBANA_SETTING_NAME_TIME_FILTER = 'timepicker:timeDefaults';
+
+// Default maxBuckets set by the app
+export const WAZUH_KIBANA_SETTING_MAX_BUCKETS = 200000;
+export const KIBANA_SETTING_NAME_MAX_BUCKETS = 'timelion:max_buckets';
+
+// Default metaFields Kibana setting set by the app
+export const WAZUH_KIBANA_SETTING_METAFIELDS = ['_source', '_index'];
+export const KIBANA_SETTING_NAME_METAFIELDS = 'metaFields';
+
+
+// Logger
+export const UI_LOGGER_LEVELS = {
+ WARNING: 'WARNING',
+ INFO: 'INFO',
+ ERROR: 'ERROR',
+};
+
+export const UI_TOAST_COLOR = {
+ SUCCESS: 'success',
+ WARNING: 'warning',
+ DANGER: 'danger',
+};
diff --git a/package.json b/package.json
index 197ab09459..1e189b4f85 100644
--- a/package.json
+++ b/package.json
@@ -37,7 +37,7 @@
"test:browser": "plugin-helpers test:browser",
"test:jest": "node scripts/jest",
"generate:api-4.0-info": "cd scripts/generate-api-4.0-info;./generate-api-4.0-info.sh;cd ../..",
- "prebuild": "node scripts/generate-build-version"
+ "prebuild": "node scripts/generate-build-version"
},
"dependencies": {
"angular-animate": "1.7.8",
@@ -48,6 +48,7 @@
"js2xmlparser": "^3.0.0",
"json2csv": "^4.1.2",
"jwt-decode": "^2.2.0",
+ "loglevel": "^1.7.1",
"needle": "^2.0.1",
"node-cron": "^1.1.2",
"pdfmake": "0.1.65",
diff --git a/public/kibana-services.ts b/public/kibana-services.ts
index 33fa421690..c7167d09b4 100644
--- a/public/kibana-services.ts
+++ b/public/kibana-services.ts
@@ -16,6 +16,7 @@ import { DataPublicPluginStart } from '../../../src/plugins/data/public';
import { VisualizationsStart } from '../../../src/plugins/visualizations/public';
import { NavigationPublicPluginStart } from '../../../src/plugins/navigation/public';
import { AppPluginStartDependencies } from './types';
+import { ErrorOrchestrator } from '../common/constants';
export const [getCore, setCore] = createGetterSetter('Core');
export const [getPlugins, setPlugins] = createGetterSetter('Plugins');
@@ -23,7 +24,9 @@ export const [getToasts, setToasts] = createGetterSetter('Toasts');
export const [getHttp, setHttp] = createGetterSetter('Http');
export const [getUiSettings, setUiSettings] = createGetterSetter('UiSettings');
export const [getChrome, setChrome] = createGetterSetter('Chrome');
-export const [getScopedHistory, setScopedHistory] = createGetterSetter('ScopedHistory');
+export const [getScopedHistory, setScopedHistory] = createGetterSetter(
+ 'ScopedHistory'
+);
export const [getOverlays, setOverlays] = createGetterSetter('Overlays');
export const [getSavedObjects, setSavedObjects] = createGetterSetter(
'SavedObjects'
@@ -37,6 +40,9 @@ export const [getVisualizationsPlugin, setVisualizationsPlugin] = createGetterSe
export const [getNavigationPlugin, setNavigationPlugin] = createGetterSetter<
NavigationPublicPluginStart
>('NavigationPlugin');
+export const [getErrorOrchestrator, setErrorOrchestrator] = createGetterSetter(
+ 'ErrorOrchestrator'
+);
/**
* set bootstrapped inner angular module
@@ -66,4 +72,4 @@ export function getDiscoverModule() {
return discoverModule;
}
-export const [getCookies, setCookies] = createGetterSetter('Cookies');
\ No newline at end of file
+export const [getCookies, setCookies] = createGetterSetter('Cookies');
diff --git a/public/react-services/error-orchestrator/error-orchestrator-base.ts b/public/react-services/error-orchestrator/error-orchestrator-base.ts
new file mode 100644
index 0000000000..3a14aaba2c
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-base.ts
@@ -0,0 +1,65 @@
+/*
+ * Wazuh app - Error Orchestrator base
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import { ErrorToastOptions } from 'kibana/public';
+import { UI_LOGGER_LEVELS } from '../../../common/constants';
+import { getToasts } from '../../kibana-services';
+import loglevel from 'loglevel';
+import { GenericRequest } from '../../react-services/generic-request';
+import { ErrorOrchestrator, UIErrorLog } from './types';
+
+export class ErrorOrchestratorBase implements ErrorOrchestrator {
+ public loadErrorLog(errorLog: UIErrorLog) {
+ if (errorLog.display) this.displayError(errorLog);
+ if (errorLog.store) this.storeError(errorLog).then(loglevel.info);
+ }
+
+ public displayError(errorLog: UIErrorLog) {
+ const toast = {
+ title: errorLog.error.title,
+ toastMessage: errorLog.error.message,
+ toastLifeTimeMs: 3000,
+ };
+
+ getToasts().addError(errorLog.error.error, toast as ErrorToastOptions);
+ }
+
+ public loglevelError(errorLog: UIErrorLog) {
+ switch (errorLog.level) {
+ case UI_LOGGER_LEVELS.INFO:
+ loglevel.info(errorLog.error.message, errorLog.error.error);
+ break;
+ case UI_LOGGER_LEVELS.WARNING:
+ loglevel.warn(errorLog.error.message, errorLog.error.error);
+ break;
+ case UI_LOGGER_LEVELS.ERROR:
+ loglevel.error(errorLog.error.message, errorLog.error.error);
+ break;
+ default:
+ console.log('No error level', errorLog.error.message, errorLog.error.error);
+ }
+ }
+
+ private async storeError(errorLog: UIErrorLog) {
+ try {
+ await GenericRequest.request('POST', `/utils/logs/ui`, {
+ body: {
+ message: errorLog.error.message,
+ level: errorLog.level,
+ location: errorLog.location,
+ },
+ });
+ } catch (error) {
+ loglevel.error('Failed on request [POST /utils/logs/ui]', error);
+ }
+ }
+}
diff --git a/public/react-services/error-orchestrator/error-orchestrator-business.ts b/public/react-services/error-orchestrator/error-orchestrator-business.ts
new file mode 100644
index 0000000000..56d365c436
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-business.ts
@@ -0,0 +1,20 @@
+/*
+ * Wazuh app - Error Orchestrator for business implementation
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import { ErrorOrchestratorBase } from './error-orchestrator-base';
+import { UIErrorLog } from './types';
+
+export class ErrorOrchestratorBusiness extends ErrorOrchestratorBase {
+ public displayError(errorLog: UIErrorLog) {
+ super.displayError(errorLog);
+ }
+}
diff --git a/public/react-services/error-orchestrator/error-orchestrator-critical.ts b/public/react-services/error-orchestrator/error-orchestrator-critical.ts
new file mode 100644
index 0000000000..0cdafad8a3
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-critical.ts
@@ -0,0 +1,20 @@
+/*
+ * Wazuh app - Error Orchestrator for critical implementation
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import { ErrorOrchestratorBase } from './error-orchestrator-base';
+import { UIErrorLog } from './types';
+
+export class ErrorOrchestratorCritical extends ErrorOrchestratorBase {
+ public displayError(errorLog: UIErrorLog) {
+ // continue here with the integration with the error-boundary hoc/component
+ }
+}
diff --git a/public/react-services/error-orchestrator/error-orchestrator-ui.ts b/public/react-services/error-orchestrator/error-orchestrator-ui.ts
new file mode 100644
index 0000000000..4277b22ea5
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-ui.ts
@@ -0,0 +1,24 @@
+/*
+ * Wazuh app - Error Orchestrator for UI implementation
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import { ErrorOrchestratorBase } from './error-orchestrator-base';
+import { UIErrorLog } from './types';
+
+export class ErrorOrchestratorUI extends ErrorOrchestratorBase {
+ public displayError(errorLog: UIErrorLog) {
+ super.displayError(errorLog);
+ }
+
+ public loglevelError(errorLog: UIErrorLog) {
+ super.loglevelError(errorLog);
+ }
+}
diff --git a/public/react-services/error-orchestrator/error-orchestrator.factory.ts b/public/react-services/error-orchestrator/error-orchestrator.factory.ts
new file mode 100644
index 0000000000..1d71990a7b
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator.factory.ts
@@ -0,0 +1,29 @@
+/*
+ * Wazuh app - Error Orchestrator factory
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import { ErrorOrchestratorUI } from './error-orchestrator-ui';
+import { ErrorOrchestratorBusiness } from './error-orchestrator-business';
+import { ErrorOrchestratorCritical } from './error-orchestrator-critical';
+import { ErrorOrchestrator, UI_ERROR_SEVERITIES, UIErrorSeverity } from './types';
+
+export const errorOrchestratorFactory = (severity: UIErrorSeverity): ErrorOrchestrator => {
+ switch (severity) {
+ case UI_ERROR_SEVERITIES.UI:
+ return new ErrorOrchestratorUI();
+ case UI_ERROR_SEVERITIES.BUSINESS:
+ return new ErrorOrchestratorBusiness();
+ case UI_ERROR_SEVERITIES.CRITICAL:
+ return new ErrorOrchestratorCritical();
+ default:
+ break;
+ }
+};
diff --git a/public/react-services/error-orchestrator/error-orchestrator.service.ts b/public/react-services/error-orchestrator/error-orchestrator.service.ts
new file mode 100644
index 0000000000..241b0bba43
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator.service.ts
@@ -0,0 +1,23 @@
+/*
+ * Wazuh app - Error Orchestrator service
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import { errorOrchestratorFactory } from './error-orchestrator.factory';
+import { ErrorOrchestrator, UIErrorLog } from './types';
+
+export class ErrorOrchestratorClass {
+ public constructor() {}
+
+ public handleError(uiErrorLog: UIErrorLog) {
+ const errorOrchestrator: ErrorOrchestrator = errorOrchestratorFactory(uiErrorLog.severity);
+ errorOrchestrator.loadErrorLog(uiErrorLog);
+ }
+}
diff --git a/public/react-services/error-orchestrator/types.ts b/public/react-services/error-orchestrator/types.ts
new file mode 100644
index 0000000000..b3d97bcf84
--- /dev/null
+++ b/public/react-services/error-orchestrator/types.ts
@@ -0,0 +1,46 @@
+/*
+ * Wazuh app - Error logger types
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+type WARNING = 'WARNING';
+type INFO = 'INFO';
+type ERROR = 'ERROR';
+export type UILogLevel = WARNING | INFO | ERROR;
+
+type UI = 'UI';
+type BUSINESS = 'BUSINESS';
+type CRITICAL = 'CRITICAL';
+export type UIErrorSeverity = UI | BUSINESS | CRITICAL;
+export const UI_ERROR_SEVERITIES = {
+ UI: 'UI',
+ BUSINESS: 'BUSINESS',
+ CRITICAL: 'CRITICAL',
+};
+
+export type UIError = {
+ message: string;
+ error: any;
+ title?: string;
+};
+
+export type UIErrorLog = {
+ context: string;
+ level: UILogLevel;
+ severity: UIErrorSeverity;
+ display?: boolean;
+ store?: boolean;
+ error: UIError;
+ location: string;
+};
+
+export type ErrorOrchestrator = {
+ loadErrorLog: (uiErrorLog: UIErrorLog) => void;
+};
diff --git a/public/react-services/index.ts b/public/react-services/index.ts
index a10bf3b43d..1d70404858 100644
--- a/public/react-services/index.ts
+++ b/public/react-services/index.ts
@@ -1,4 +1,5 @@
export { GenericRequest } from './generic-request';
export { WzRequest } from './wz-request';
export { ErrorHandler } from './error-handler';
-export { formatUIDate } from './time-service';
\ No newline at end of file
+export { formatUIDate } from './time-service';
+export { ErrorOrchestratorClass } from './error-orchestrator/error-orchestrator.service';
From fcef3c7027ef8f35077f0ebfa8f5aae4ae39fca2 Mon Sep 17 00:00:00 2001
From: Gabriel Wassan
Date: Mon, 7 Jun 2021 16:24:50 -0300
Subject: [PATCH 02/24] Added ErrorBoundary HOC and component. (#3321)
* feat(errorBoundary): Added ErrorBoundary HOC and component and added loglevel dependency
* feature(errorBoundary): Moved with the others HOCs.
* feature(errorBoundary): Typo refactor.
* feature(errorBoundary): Some refactors
* feat(errorBoundary): PR comments and rollback agent-preview
* doc(changelog): Update changelog
* feat(errorBoundary): Rollback
* feat(errorBoundary): Rollback
* feat(errorBoundary): Rollback
* feat(errorBoundary): Rollback
* feat(errorBoundary): Refactor props, pr comments.
* feat(errorBoundary): Added unit test for error boundary.
* feat(errorBoundary): Separated error boundary component of hoc
* doc(error-boundary): Fixed and added licenses blocks.
---
CHANGELOG.md | 1 +
.../error-boundary.test.tsx.snap | 145 ++++++++++++++++
.../error-boundary/error-boundary.test.tsx | 31 ++++
.../common/error-boundary/error-boundary.tsx | 78 +++++++++
.../with-error-boundary.test.tsx.snap | 155 ++++++++++++++++++
.../with-error-boundary.test.tsx | 26 +++
.../error-boundary/with-error-boundary.tsx | 20 +++
public/components/common/hocs/index.ts | 2 +
.../agent/components/agents-preview.js | 16 +-
9 files changed, 466 insertions(+), 8 deletions(-)
create mode 100644 public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
create mode 100644 public/components/common/error-boundary/error-boundary.test.tsx
create mode 100644 public/components/common/error-boundary/error-boundary.tsx
create mode 100644 public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
create mode 100644 public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
create mode 100644 public/components/common/hocs/error-boundary/with-error-boundary.tsx
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d0d01a477d..cd3d7a548c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ All notable changes to the Wazuh app project will be documented in this file.
### Added
- Added new error handler to be responsible for the error orchestration [#3327](https://github.com/wazuh/wazuh-kibana-app/pull/3327)
+- Added `Error Boundary` HOC and Component to handle render errors. [#3321](https://github.com/wazuh/wazuh-kibana-app/pull/3321)
## Wazuh v4.2.0 - Kibana 7.10.2 , 7.11.2 - Revision 4201
diff --git a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
new file mode 100644
index 0000000000..36bcd994ea
--- /dev/null
+++ b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
@@ -0,0 +1,145 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ErrorBoundary component renders correctly and check snapshot 1`] = `
+
+
+
+ }
+ iconType="faceSad"
+ title={
+
+ Something went wrong.
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Something went wrong.
+
+
+
+
+
+
+
+
+
+
+ Error: I crashed!
+
+
+ in ComponentWithError
+ in ErrorBoundary (created by WrapperComponent)
+ in WrapperComponent
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/public/components/common/error-boundary/error-boundary.test.tsx b/public/components/common/error-boundary/error-boundary.test.tsx
new file mode 100644
index 0000000000..a96db0b6e5
--- /dev/null
+++ b/public/components/common/error-boundary/error-boundary.test.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import { mount } from 'enzyme';
+import ErrorBoundary from './error-boundary';
+
+jest.mock('loglevel');
+
+describe('ErrorBoundary component', () => {
+ const ComponentWithError = () => {
+ throw new Error('I crashed!');
+ return <>>;
+ };
+
+ it('renders correctly and check snapshot', () => {
+ const wrapper = mount(
+
+
+
+ );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('should display an ErrorMessage if wrapped component throws', () => {
+ const wrapper = mount(
+
+
+
+ );
+ expect(wrapper.find('EuiTitle').find('h2').text().trim()).toBe('Something went wrong.');
+ });
+});
diff --git a/public/components/common/error-boundary/error-boundary.tsx b/public/components/common/error-boundary/error-boundary.tsx
new file mode 100644
index 0000000000..b88c79b85c
--- /dev/null
+++ b/public/components/common/error-boundary/error-boundary.tsx
@@ -0,0 +1,78 @@
+/*
+* Wazuh app - React component for catch and handles rendering errors.
+*
+* Copyright (C) 2015-2021 Wazuh, Inc.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* Find more information about this on the LICENSE file.
+*
+*/
+
+import React, { Component } from 'react';
+import log from 'loglevel';
+import { EuiEmptyPrompt } from '@elastic/eui';
+
+export default class ErrorBoundary extends Component {
+ constructor(props) {
+ super(props);
+ this.state = { errorTitle: null, errorInfo: null, style: null };
+ }
+
+ componentDidCatch = (errorTitle, errorInfo) => catchFunc(errorTitle, errorInfo, this);
+
+ render() {
+ const { errorTitle, style, errorInfo }: Readonly = this.state;
+
+ if (errorInfo) {
+ return ;
+ }
+ return this.props.children;
+ }
+}
+
+const catchFunc = (errorTitle, errorInfo, ctx) => {
+ ctx.setState({
+ errorTitle: errorTitle,
+ errorInfo: errorInfo,
+ });
+
+ log.error({ errorTitle, errorInfo });
+};
+
+const ErrorComponent = (props: { errorTitle: any; errorInfo: any; style: any }) => {
+ const styles = {
+ error: {
+ borderTop: '1px solid #777',
+ borderBottom: '1px solid #777',
+ padding: '12px',
+ },
+ };
+
+ return (
+
+
+ {props.errorTitle && props.errorTitle.toString()}
+
+ {props.errorInfo.componentStack}
+
+
+ );
+};
+
+const HandleError = (props: { errorTitle: any; errorInfo: any; style: any }) => (
+ Something went wrong.}
+ body={
+
+ }
+ />
+);
diff --git a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
new file mode 100644
index 0000000000..a107118897
--- /dev/null
+++ b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
@@ -0,0 +1,155 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`withErrorBoundary hoc implementation renders correctly and check snapshot 1`] = `
+
+
+
+
+ }
+ iconType="faceSad"
+ title={
+
+ Something went wrong.
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Something went wrong.
+
+
+
+
+
+
+
+
+
+
+ Error: I crashed!
+
+
+ in ComponentWithError
+ in Unknown
+ in ErrorBoundary
+ in Unknown (created by WrapperComponent)
+ in WrapperComponent
+
+
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx b/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
new file mode 100644
index 0000000000..abd64b7c07
--- /dev/null
+++ b/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+import { withErrorBoundary } from './with-error-boundary';
+import { mount } from 'enzyme';
+
+jest.mock('loglevel');
+
+describe('withErrorBoundary hoc implementation', () => {
+ const ComponentWithError = () => {
+ throw new Error('I crashed!');
+ return <>>;
+ }
+
+ it('renders correctly and check snapshot', () => {
+ const ErrorComponentWithHoc = withErrorBoundary(() => );
+ const wrapper = mount( );
+
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it('should display an ErrorMessage if wrapped HOC throws', () => {
+ const ErrorComponentWithHoc = withErrorBoundary(() => );
+ const wrapper = mount( );
+
+ expect(wrapper.find('EuiTitle').find('h2').text().trim()).toBe('Something went wrong.');
+ });
+});
diff --git a/public/components/common/hocs/error-boundary/with-error-boundary.tsx b/public/components/common/hocs/error-boundary/with-error-boundary.tsx
new file mode 100644
index 0000000000..5ddab9f13f
--- /dev/null
+++ b/public/components/common/hocs/error-boundary/with-error-boundary.tsx
@@ -0,0 +1,20 @@
+/*
+ * Wazuh app - React HOCs handles rendering errors
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import React from 'react';
+import ErrorBoundary from '../../error-boundary/error-boundary';
+
+export const withErrorBoundary = (WrappedComponent) => (props) => (
+
+
+
+);
diff --git a/public/components/common/hocs/index.ts b/public/components/common/hocs/index.ts
index 55eae872df..81653072c2 100644
--- a/public/components/common/hocs/index.ts
+++ b/public/components/common/hocs/index.ts
@@ -30,3 +30,5 @@ export { withButtonOpenOnClick } from './withButtonOpenOnClick';
export { withAgentSupportModule } from './withAgentSupportModule';
export { withUserLogged } from './withUserLogged';
+
+export { withErrorBoundary } from './error-boundary/with-error-boundary';
diff --git a/public/controllers/agent/components/agents-preview.js b/public/controllers/agent/components/agents-preview.js
index 9cb2c4ff5a..dbc8f9cdbf 100644
--- a/public/controllers/agent/components/agents-preview.js
+++ b/public/controllers/agent/components/agents-preview.js
@@ -120,7 +120,7 @@ export const AgentsPreview = compose(
this.setState({ platforms: platformsModel, loading: false });
} catch (error) {}
}
-
+
removeFilters(){
this._isMount && this.setState({agentTableFilters: []})
}
@@ -164,7 +164,7 @@ export const AgentsPreview = compose(
{this.totalAgents > 0 && (
-
+
{this.summary && (
@@ -236,7 +236,7 @@ export const AgentsPreview = compose(
-
+
this.props.tableProps.showAgent(
this.lastAgent
)}>{this.lastAgent.name}
@@ -271,7 +271,7 @@ export const AgentsPreview = compose(
style={{ whiteSpace: 'nowrap' }}
titleSize="s"
description="Most active agent"
- titleColor="primary"
+ titleColor="primary"
/>
)}
@@ -298,13 +298,13 @@ export const AgentsPreview = compose(
{this.props.resultState === 'loading' &&
(
-
+
) }
-
+
-
+
-
+
)}
From 5feef14e53c3855b9d0458eeca23a6a1b615bfb5 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 09:43:01 -0300
Subject: [PATCH 03/24] feature(logger-service): PR comments
---
.../common/error-boundary/error-boundary.tsx | 63 +++++++++++++------
.../error-orchestrator-critical.ts | 2 +-
.../error-orchestrator/types.ts | 2 +-
3 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/public/components/common/error-boundary/error-boundary.tsx b/public/components/common/error-boundary/error-boundary.tsx
index b88c79b85c..7957a597a9 100644
--- a/public/components/common/error-boundary/error-boundary.tsx
+++ b/public/components/common/error-boundary/error-boundary.tsx
@@ -1,25 +1,34 @@
/*
-* Wazuh app - React component for catch and handles rendering errors.
-*
-* Copyright (C) 2015-2021 Wazuh, Inc.
-*
-* This program is free software; you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
-* (at your option) any later version.
-*
-* Find more information about this on the LICENSE file.
-*
-*/
+ * Wazuh app - React component for catch and handles rendering errors.
+ *
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ *
+ */
import React, { Component } from 'react';
-import log from 'loglevel';
+import loglevel from 'loglevel';
import { EuiEmptyPrompt } from '@elastic/eui';
+import { UI_LOGGER_LEVELS } from '../../../../common/constants';
+import {
+ UI_ERROR_SEVERITIES,
+ UIErrorLog,
+ UIErrorSeverity,
+ UILogLevel,
+} from '../../../react-services/error-orchestrator/types';
+import { ErrorOrchestratorClass } from '../../../react-services';
export default class ErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = { errorTitle: null, errorInfo: null, style: null };
+ this.context = this.constructor.displayName || this.constructor.name || undefined;
}
componentDidCatch = (errorTitle, errorInfo) => catchFunc(errorTitle, errorInfo, this);
@@ -35,12 +44,30 @@ export default class ErrorBoundary extends Component {
}
const catchFunc = (errorTitle, errorInfo, ctx) => {
- ctx.setState({
- errorTitle: errorTitle,
- errorInfo: errorInfo,
- });
+ try {
+ ctx.setState({
+ errorTitle: errorTitle,
+ errorInfo: errorInfo,
+ });
- log.error({ errorTitle, errorInfo });
+ const options: UIErrorLog = {
+ context: ctx.context,
+ level: UI_LOGGER_LEVELS.WARNING as UILogLevel,
+ severity: UI_ERROR_SEVERITIES.UI as UIErrorSeverity,
+ display: true,
+ store: true,
+ error: {
+ error: errorTitle.name,
+ message: errorTitle.message,
+ title: errorTitle.toString(),
+ },
+ };
+
+ const logger = new ErrorOrchestratorClass();
+ logger.handleError(options);
+ } catch (error) {
+ loglevel.error('Logger failed: ', error);
+ }
};
const ErrorComponent = (props: { errorTitle: any; errorInfo: any; style: any }) => {
diff --git a/public/react-services/error-orchestrator/error-orchestrator-critical.ts b/public/react-services/error-orchestrator/error-orchestrator-critical.ts
index 0cdafad8a3..894dfa905a 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-critical.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-critical.ts
@@ -15,6 +15,6 @@ import { UIErrorLog } from './types';
export class ErrorOrchestratorCritical extends ErrorOrchestratorBase {
public displayError(errorLog: UIErrorLog) {
- // continue here with the integration with the error-boundary hoc/component
+ super.displayError(errorLog)
}
}
diff --git a/public/react-services/error-orchestrator/types.ts b/public/react-services/error-orchestrator/types.ts
index b3d97bcf84..cbe593a7de 100644
--- a/public/react-services/error-orchestrator/types.ts
+++ b/public/react-services/error-orchestrator/types.ts
@@ -38,7 +38,7 @@ export type UIErrorLog = {
display?: boolean;
store?: boolean;
error: UIError;
- location: string;
+ location?: string;
};
export type ErrorOrchestrator = {
From 457e0e540e7196efe54b1b58b8fc9d5c8c180f38 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 16:14:23 -0300
Subject: [PATCH 04/24] feature(logger-orchestrator): Refactors on management
of severity.
---
.../error-orchestrator-base.ts | 27 +------------------
.../error-orchestrator-business.ts | 23 +++++++++++++++-
.../error-orchestrator-critical.ts | 5 +++-
.../error-orchestrator-ui.ts | 20 ++++++++++----
4 files changed, 42 insertions(+), 33 deletions(-)
diff --git a/public/react-services/error-orchestrator/error-orchestrator-base.ts b/public/react-services/error-orchestrator/error-orchestrator-base.ts
index 3a14aaba2c..bc798d88e0 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-base.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-base.ts
@@ -10,9 +10,6 @@
* Find more information about this on the LICENSE file.
*/
-import { ErrorToastOptions } from 'kibana/public';
-import { UI_LOGGER_LEVELS } from '../../../common/constants';
-import { getToasts } from '../../kibana-services';
import loglevel from 'loglevel';
import { GenericRequest } from '../../react-services/generic-request';
import { ErrorOrchestrator, UIErrorLog } from './types';
@@ -24,29 +21,7 @@ export class ErrorOrchestratorBase implements ErrorOrchestrator {
}
public displayError(errorLog: UIErrorLog) {
- const toast = {
- title: errorLog.error.title,
- toastMessage: errorLog.error.message,
- toastLifeTimeMs: 3000,
- };
-
- getToasts().addError(errorLog.error.error, toast as ErrorToastOptions);
- }
-
- public loglevelError(errorLog: UIErrorLog) {
- switch (errorLog.level) {
- case UI_LOGGER_LEVELS.INFO:
- loglevel.info(errorLog.error.message, errorLog.error.error);
- break;
- case UI_LOGGER_LEVELS.WARNING:
- loglevel.warn(errorLog.error.message, errorLog.error.error);
- break;
- case UI_LOGGER_LEVELS.ERROR:
- loglevel.error(errorLog.error.message, errorLog.error.error);
- break;
- default:
- console.log('No error level', errorLog.error.message, errorLog.error.error);
- }
+ throw new Error('Should be implemented!');
}
private async storeError(errorLog: UIErrorLog) {
diff --git a/public/react-services/error-orchestrator/error-orchestrator-business.ts b/public/react-services/error-orchestrator/error-orchestrator-business.ts
index 56d365c436..851bb77b96 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-business.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-business.ts
@@ -12,9 +12,30 @@
import { ErrorOrchestratorBase } from './error-orchestrator-base';
import { UIErrorLog } from './types';
+import { UI_LOGGER_LEVELS } from '../../../common/constants';
+import { getToasts } from '../../kibana-services';
+import { ErrorToastOptions } from 'kibana/public';
export class ErrorOrchestratorBusiness extends ErrorOrchestratorBase {
public displayError(errorLog: UIErrorLog) {
- super.displayError(errorLog);
+ const toast = {
+ title: errorLog.error.title,
+ toastMessage: errorLog.error.message,
+ toastLifeTimeMs: 3000,
+ };
+
+ switch (errorLog.level) {
+ case UI_LOGGER_LEVELS.INFO:
+ getToasts().addInfo(errorLog.error.error, toast as ErrorToastOptions);
+ break;
+ case UI_LOGGER_LEVELS.WARNING:
+ getToasts().addWarning(errorLog.error.error, toast as ErrorToastOptions);
+ break;
+ case UI_LOGGER_LEVELS.ERROR:
+ getToasts().addError(errorLog.error.error, toast as ErrorToastOptions);
+ break;
+ default:
+ console.log('No error level', errorLog.error.message, errorLog.error.error);
+ }
}
}
diff --git a/public/react-services/error-orchestrator/error-orchestrator-critical.ts b/public/react-services/error-orchestrator/error-orchestrator-critical.ts
index 894dfa905a..7ca96fbe4a 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-critical.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-critical.ts
@@ -12,9 +12,12 @@
import { ErrorOrchestratorBase } from './error-orchestrator-base';
import { UIErrorLog } from './types';
+import { WzMisc } from '../../factories/misc';
export class ErrorOrchestratorCritical extends ErrorOrchestratorBase {
public displayError(errorLog: UIErrorLog) {
- super.displayError(errorLog)
+ const wzMisc = new WzMisc();
+ wzMisc.setBlankScr(errorLog.error.message);
+ window.location.href = '#/blank-screen';
}
}
diff --git a/public/react-services/error-orchestrator/error-orchestrator-ui.ts b/public/react-services/error-orchestrator/error-orchestrator-ui.ts
index 4277b22ea5..03d992b110 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-ui.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-ui.ts
@@ -12,13 +12,23 @@
import { ErrorOrchestratorBase } from './error-orchestrator-base';
import { UIErrorLog } from './types';
+import { UI_LOGGER_LEVELS } from '../../../common/constants';
+import loglevel from 'loglevel';
export class ErrorOrchestratorUI extends ErrorOrchestratorBase {
public displayError(errorLog: UIErrorLog) {
- super.displayError(errorLog);
- }
-
- public loglevelError(errorLog: UIErrorLog) {
- super.loglevelError(errorLog);
+ switch (errorLog.level) {
+ case UI_LOGGER_LEVELS.INFO:
+ loglevel.info(errorLog.error.message, errorLog.error.error);
+ break;
+ case UI_LOGGER_LEVELS.WARNING:
+ loglevel.warn(errorLog.error.message, errorLog.error.error);
+ break;
+ case UI_LOGGER_LEVELS.ERROR:
+ loglevel.error(errorLog.error.message, errorLog.error.error);
+ break;
+ default:
+ console.log('No error level', errorLog.error.message, errorLog.error.error);
+ }
}
}
From 76b10097211bbcd5b909a40221d98d066110eb9c Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 16:16:38 -0300
Subject: [PATCH 05/24] feature(logger-orchestrator): Refactor on
wz-blank-screen component.
---
.../wz-blank-screen/wz-blank-screen.js | 38 ++++++++-----------
1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/public/components/wz-blank-screen/wz-blank-screen.js b/public/components/wz-blank-screen/wz-blank-screen.js
index b919c68af1..0c00993409 100644
--- a/public/components/wz-blank-screen/wz-blank-screen.js
+++ b/public/components/wz-blank-screen/wz-blank-screen.js
@@ -9,14 +9,9 @@
*
* Find more information about this on the LICENSE file.
*/
-import React, { Component, Fragment } from 'react';
-import {
- EuiPage,
- EuiPageContent,
- EuiEmptyPrompt,
- EuiButton,
- EuiHorizontalRule
-} from '@elastic/eui';
+import React, { Component } from 'react';
+import { EuiButton, EuiHorizontalRule, EuiPage, EuiPageContent } from '@elastic/eui';
+import { ErrorComponentPrompt } from '../common/error-boundary-prompt/error-boundary-prompt';
export class WzBlankScreen extends Component {
constructor(props) {
@@ -28,29 +23,28 @@ export class WzBlankScreen extends Component {
return (
- {this.props.errorToShow || 'Something went wrong'}}
- body={
-
-
+
- https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
+ Elastic Guide
+
- https://documentation.wazuh.com/current/installation-guide/
+ Wazuh installation guide
-
- }
- actions={
-
- Refresh
-
+
+
+ Refresh
+
+ >
}
/>
From f6d115cc6f3152d5f6945913e70b0b2ae201e793 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 16:17:46 -0300
Subject: [PATCH 06/24] feature(logger-orchestrator): Separated prompt
component from error-boundary.
---
.../error-boundary-prompt.tsx | 34 ++++++++++++++++
.../common/error-boundary/error-boundary.tsx | 40 ++-----------------
2 files changed, 37 insertions(+), 37 deletions(-)
create mode 100644 public/components/common/error-boundary-prompt/error-boundary-prompt.tsx
diff --git a/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx b/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx
new file mode 100644
index 0000000000..03276c3c37
--- /dev/null
+++ b/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import { EuiEmptyPrompt } from '@elastic/eui';
+
+export const ErrorComponentPrompt = (props: {
+ errorTitle: any;
+ errorInfo?: any;
+ style?: any;
+ action?: React.ReactNode;
+}) => {
+ const styles = {
+ error: {
+ borderTop: '1px solid #777',
+ borderBottom: '1px solid #777',
+ padding: '12px',
+ },
+ };
+
+ return (
+ Something went wrong.}
+ body={
+
+
+ {props.errorTitle && props.errorTitle.toString()}
+
+ {props.errorInfo?.componentStack || ''}
+
+
+ }
+ actions={props.action || null}
+ />
+ );
+};
diff --git a/public/components/common/error-boundary/error-boundary.tsx b/public/components/common/error-boundary/error-boundary.tsx
index 7957a597a9..e95b0592a2 100644
--- a/public/components/common/error-boundary/error-boundary.tsx
+++ b/public/components/common/error-boundary/error-boundary.tsx
@@ -14,7 +14,6 @@
import React, { Component } from 'react';
import loglevel from 'loglevel';
-import { EuiEmptyPrompt } from '@elastic/eui';
import { UI_LOGGER_LEVELS } from '../../../../common/constants';
import {
UI_ERROR_SEVERITIES,
@@ -23,6 +22,7 @@ import {
UILogLevel,
} from '../../../react-services/error-orchestrator/types';
import { ErrorOrchestratorClass } from '../../../react-services';
+import { ErrorComponentPrompt } from '../error-boundary-prompt/error-boundary-prompt';
export default class ErrorBoundary extends Component {
constructor(props) {
@@ -37,7 +37,7 @@ export default class ErrorBoundary extends Component {
const { errorTitle, style, errorInfo }: Readonly = this.state;
if (errorInfo) {
- return ;
+ return ;
}
return this.props.children;
}
@@ -54,7 +54,7 @@ const catchFunc = (errorTitle, errorInfo, ctx) => {
context: ctx.context,
level: UI_LOGGER_LEVELS.WARNING as UILogLevel,
severity: UI_ERROR_SEVERITIES.UI as UIErrorSeverity,
- display: true,
+ display: false,
store: true,
error: {
error: errorTitle.name,
@@ -69,37 +69,3 @@ const catchFunc = (errorTitle, errorInfo, ctx) => {
loglevel.error('Logger failed: ', error);
}
};
-
-const ErrorComponent = (props: { errorTitle: any; errorInfo: any; style: any }) => {
- const styles = {
- error: {
- borderTop: '1px solid #777',
- borderBottom: '1px solid #777',
- padding: '12px',
- },
- };
-
- return (
-
-
- {props.errorTitle && props.errorTitle.toString()}
-
- {props.errorInfo.componentStack}
-
-
- );
-};
-
-const HandleError = (props: { errorTitle: any; errorInfo: any; style: any }) => (
- Something went wrong.}
- body={
-
- }
- />
-);
From 5b64c9c619d2b075c12dd7ea862ea1886b8c6314 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 16:19:35 -0300
Subject: [PATCH 07/24] feature(logger-orchestrator): Typo.
---
public/components/wz-blank-screen/wz-blank-screen.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/public/components/wz-blank-screen/wz-blank-screen.js b/public/components/wz-blank-screen/wz-blank-screen.js
index 0c00993409..d12e963d88 100644
--- a/public/components/wz-blank-screen/wz-blank-screen.js
+++ b/public/components/wz-blank-screen/wz-blank-screen.js
@@ -30,7 +30,7 @@ export class WzBlankScreen extends Component {
<>
- Elastic Guide
+ Elastic guide
From 123e9503481dde17ebba96ab433d2350681c278d Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 16:22:44 -0300
Subject: [PATCH 08/24] test(error-boundary): Update snapshots.
---
.../error-boundary.test.tsx.snap | 145 ----------------
.../with-error-boundary.test.tsx.snap | 155 ------------------
2 files changed, 300 deletions(-)
delete mode 100644 public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
delete mode 100644 public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
diff --git a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
deleted file mode 100644
index 36bcd994ea..0000000000
--- a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
+++ /dev/null
@@ -1,145 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ErrorBoundary component renders correctly and check snapshot 1`] = `
-
-
-
- }
- iconType="faceSad"
- title={
-
- Something went wrong.
-
- }
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
- Something went wrong.
-
-
-
-
-
-
-
-
-
-
- Error: I crashed!
-
-
- in ComponentWithError
- in ErrorBoundary (created by WrapperComponent)
- in WrapperComponent
-
-
-
-
-
-
-
-
-
-
-
-`;
diff --git a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
deleted file mode 100644
index a107118897..0000000000
--- a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
+++ /dev/null
@@ -1,155 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`withErrorBoundary hoc implementation renders correctly and check snapshot 1`] = `
-
-
-
-
- }
- iconType="faceSad"
- title={
-
- Something went wrong.
-
- }
- >
-
-
-
-
-
-
-
-
-
-
-
-
-
- Something went wrong.
-
-
-
-
-
-
-
-
-
-
- Error: I crashed!
-
-
- in ComponentWithError
- in Unknown
- in ErrorBoundary
- in Unknown (created by WrapperComponent)
- in WrapperComponent
-
-
-
-
-
-
-
-
-
-
-
-
-`;
From bfc6dfa2bc12fcb307add6bdeb9e0ea880595c15 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Tue, 8 Jun 2021 16:23:44 -0300
Subject: [PATCH 09/24] test(error-boundary): Update snapshots
---
.../error-boundary.test.tsx.snap | 145 +++++++++++++++++
.../with-error-boundary.test.tsx.snap | 153 ++++++++++++++++++
2 files changed, 298 insertions(+)
create mode 100644 public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
create mode 100644 public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
diff --git a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
new file mode 100644
index 0000000000..98fbce8e8f
--- /dev/null
+++ b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
@@ -0,0 +1,145 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`ErrorBoundary component renders correctly and check snapshot 1`] = `
+
+
+
+
+ Error: I crashed!
+
+
+ in ComponentWithError
+ in ErrorBoundary (created by WrapperComponent)
+ in WrapperComponent
+
+
+ }
+ iconType="faceSad"
+ title={
+
+ Something went wrong.
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Something went wrong.
+
+
+
+
+
+
+
+
+
+ Error: I crashed!
+
+
+ in ComponentWithError
+ in ErrorBoundary (created by WrapperComponent)
+ in WrapperComponent
+
+
+
+
+
+
+
+
+
+
+`;
diff --git a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
new file mode 100644
index 0000000000..4225368f1c
--- /dev/null
+++ b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
@@ -0,0 +1,153 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`withErrorBoundary hoc implementation renders correctly and check snapshot 1`] = `
+
+
+
+
+
+ Error: I crashed!
+
+
+ in ComponentWithError
+ in Unknown
+ in ErrorBoundary
+ in Unknown (created by WrapperComponent)
+ in WrapperComponent
+
+
+ }
+ iconType="faceSad"
+ title={
+
+ Something went wrong.
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Something went wrong.
+
+
+
+
+
+
+
+
+
+ Error: I crashed!
+
+
+ in ComponentWithError
+ in Unknown
+ in ErrorBoundary
+ in Unknown (created by WrapperComponent)
+ in WrapperComponent
+
+
+
+
+
+
+
+
+
+
+
+`;
From d8c0f96750f6f93cee1ad57dbbdc7e24e881567b Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Wed, 9 Jun 2021 11:37:00 -0300
Subject: [PATCH 10/24] fix(logger-orchestrator): PR comments and refactors,
fix unit tests.
---
.../error-boundary-prompt.tsx | 18 +++++++++++++--
.../error-boundary.test.tsx.snap | 20 ++++++++++++-----
.../error-boundary/error-boundary.test.tsx | 10 +++++++--
.../common/error-boundary/error-boundary.tsx | 22 +++++++++++++++----
.../with-error-boundary.test.tsx.snap | 20 ++++++++++++-----
.../with-error-boundary.test.tsx | 11 +++++++---
.../wz-blank-screen/wz-blank-screen.js | 2 +-
.../error-orchestrator.service.ts | 2 +-
public/react-services/index.ts | 2 +-
9 files changed, 81 insertions(+), 26 deletions(-)
diff --git a/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx b/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx
index 03276c3c37..b4bb7f1ab7 100644
--- a/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx
+++ b/public/components/common/error-boundary-prompt/error-boundary-prompt.tsx
@@ -1,3 +1,17 @@
+/*
+ * Wazuh app - React Prompt handles rendering errors.
+ *
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ *
+ */
+
import React from 'react';
import { EuiEmptyPrompt } from '@elastic/eui';
@@ -22,9 +36,9 @@ export const ErrorComponentPrompt = (props: {
body={
- {props.errorTitle && props.errorTitle.toString()}
+ {props.errorTitle && props.errorTitle.toString()}
- {props.errorInfo?.componentStack || ''}
+ {props.errorInfo?.componentStack || ''}
}
diff --git a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
index 98fbce8e8f..0c0bd88dd0 100644
--- a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
+++ b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`ErrorBoundary component renders correctly and check snapshot 1`] = `
+exports[`ErrorBoundary component renders correctly to match the snapshot 1`] = `
- Error: I crashed!
+
+ Error: I crashed! I crash very hard
+
-
+
+
in ComponentWithError
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent
+
}
@@ -126,12 +130,16 @@ exports[`ErrorBoundary component renders correctly and check snapshot 1`] = `
}
}
>
- Error: I crashed!
+
+ Error: I crashed! I crash very hard
+
-
+
+
in ComponentWithError
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent
+
diff --git a/public/components/common/error-boundary/error-boundary.test.tsx b/public/components/common/error-boundary/error-boundary.test.tsx
index a96db0b6e5..239d9e5e07 100644
--- a/public/components/common/error-boundary/error-boundary.test.tsx
+++ b/public/components/common/error-boundary/error-boundary.test.tsx
@@ -6,11 +6,11 @@ jest.mock('loglevel');
describe('ErrorBoundary component', () => {
const ComponentWithError = () => {
- throw new Error('I crashed!');
+ throw new Error('I crashed! I crash very hard');
return <>>;
};
- it('renders correctly and check snapshot', () => {
+ it('renders correctly to match the snapshot', () => {
const wrapper = mount(
@@ -26,6 +26,12 @@ describe('ErrorBoundary component', () => {
);
+
+ expect(wrapper.find('EuiTitle').exists()).toBeTruthy();
+ expect(wrapper.find('EuiText').exists('details')).toBeTruthy();
expect(wrapper.find('EuiTitle').find('h2').text().trim()).toBe('Something went wrong.');
+ expect(wrapper.find('EuiText').find('details').find('span').at(0).text()).toBe(
+ 'Error: I crashed! I crash very hard'
+ );
});
});
diff --git a/public/components/common/error-boundary/error-boundary.tsx b/public/components/common/error-boundary/error-boundary.tsx
index e95b0592a2..395f9f3152 100644
--- a/public/components/common/error-boundary/error-boundary.tsx
+++ b/public/components/common/error-boundary/error-boundary.tsx
@@ -21,14 +21,16 @@ import {
UIErrorSeverity,
UILogLevel,
} from '../../../react-services/error-orchestrator/types';
-import { ErrorOrchestratorClass } from '../../../react-services';
+import { ErrorOrchestratorService } from '../../../react-services';
import { ErrorComponentPrompt } from '../error-boundary-prompt/error-boundary-prompt';
export default class ErrorBoundary extends Component {
+ private logger: ErrorOrchestratorService;
constructor(props) {
super(props);
this.state = { errorTitle: null, errorInfo: null, style: null };
this.context = this.constructor.displayName || this.constructor.name || undefined;
+ this.logger = new ErrorOrchestratorService();
}
componentDidCatch = (errorTitle, errorInfo) => catchFunc(errorTitle, errorInfo, this);
@@ -63,9 +65,21 @@ const catchFunc = (errorTitle, errorInfo, ctx) => {
},
};
- const logger = new ErrorOrchestratorClass();
- logger.handleError(options);
+ ctx.logger.handleError(options);
} catch (error) {
- loglevel.error('Logger failed: ', error);
+ const optionsCatch: UIErrorLog = {
+ context: ctx.context,
+ level: UI_LOGGER_LEVELS.ERROR as UILogLevel,
+ severity: UI_ERROR_SEVERITIES.UI as UIErrorSeverity,
+ display: false,
+ store: true,
+ error: {
+ error: error,
+ message: error?.message || '',
+ title: '',
+ },
+ };
+
+ ctx.logger.handleError(optionsCatch);
}
};
diff --git a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
index 4225368f1c..24212ec32e 100644
--- a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
+++ b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`withErrorBoundary hoc implementation renders correctly and check snapshot 1`] = `
+exports[`withErrorBoundary hoc implementation renders correctly to match the snapshot 1`] = `
- Error: I crashed!
+
+ Error: I crashed! I crash very hard
+
-
+
+
in ComponentWithError
in Unknown
in ErrorBoundary
in Unknown (created by WrapperComponent)
in WrapperComponent
+
}
@@ -131,14 +135,18 @@ exports[`withErrorBoundary hoc implementation renders correctly and check snapsh
}
}
>
- Error: I crashed!
+
+ Error: I crashed! I crash very hard
+
-
+
+
in ComponentWithError
in Unknown
in ErrorBoundary
in Unknown (created by WrapperComponent)
in WrapperComponent
+
diff --git a/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx b/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
index abd64b7c07..6b6e7c37c6 100644
--- a/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
+++ b/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
@@ -6,11 +6,11 @@ jest.mock('loglevel');
describe('withErrorBoundary hoc implementation', () => {
const ComponentWithError = () => {
- throw new Error('I crashed!');
+ throw new Error('I crashed! I crash very hard');
return <>>;
- }
+ };
- it('renders correctly and check snapshot', () => {
+ it('renders correctly to match the snapshot', () => {
const ErrorComponentWithHoc = withErrorBoundary(() => );
const wrapper = mount( );
@@ -21,6 +21,11 @@ describe('withErrorBoundary hoc implementation', () => {
const ErrorComponentWithHoc = withErrorBoundary(() => );
const wrapper = mount( );
+ expect(wrapper.find('EuiTitle').exists()).toBeTruthy();
+ expect(wrapper.find('EuiText').exists('details')).toBeTruthy();
expect(wrapper.find('EuiTitle').find('h2').text().trim()).toBe('Something went wrong.');
+ expect(wrapper.find('EuiText').find('details').find('span').at(0).text()).toBe(
+ 'Error: I crashed! I crash very hard'
+ );
});
});
diff --git a/public/components/wz-blank-screen/wz-blank-screen.js b/public/components/wz-blank-screen/wz-blank-screen.js
index d12e963d88..919c9b0349 100644
--- a/public/components/wz-blank-screen/wz-blank-screen.js
+++ b/public/components/wz-blank-screen/wz-blank-screen.js
@@ -34,7 +34,7 @@ export class WzBlankScreen extends Component {
-
+
Wazuh installation guide
diff --git a/public/react-services/error-orchestrator/error-orchestrator.service.ts b/public/react-services/error-orchestrator/error-orchestrator.service.ts
index 241b0bba43..5537693d32 100644
--- a/public/react-services/error-orchestrator/error-orchestrator.service.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator.service.ts
@@ -13,7 +13,7 @@
import { errorOrchestratorFactory } from './error-orchestrator.factory';
import { ErrorOrchestrator, UIErrorLog } from './types';
-export class ErrorOrchestratorClass {
+export class ErrorOrchestratorService {
public constructor() {}
public handleError(uiErrorLog: UIErrorLog) {
diff --git a/public/react-services/index.ts b/public/react-services/index.ts
index 1d70404858..0b3f7801c1 100644
--- a/public/react-services/index.ts
+++ b/public/react-services/index.ts
@@ -2,4 +2,4 @@ export { GenericRequest } from './generic-request';
export { WzRequest } from './wz-request';
export { ErrorHandler } from './error-handler';
export { formatUIDate } from './time-service';
-export { ErrorOrchestratorClass } from './error-orchestrator/error-orchestrator.service';
+export { ErrorOrchestratorService } from './error-orchestrator/error-orchestrator.service';
From 05a95a48c529c479a5a70417ec10bf396fb609c9 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Wed, 9 Jun 2021 15:20:28 -0300
Subject: [PATCH 11/24] test(error-orchestrator-base): Added simple unit test.
Fixed licence block.
---
.../error-boundary/error-boundary.test.tsx | 14 ++++++
.../error-orchestrator-base.test.ts | 44 +++++++++++++++++++
.../error-orchestrator-base.ts | 2 +-
.../wz-user-permissions.test.ts | 2 +-
4 files changed, 60 insertions(+), 2 deletions(-)
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-base.test.ts
diff --git a/public/components/common/error-boundary/error-boundary.test.tsx b/public/components/common/error-boundary/error-boundary.test.tsx
index 239d9e5e07..cd5ca53a33 100644
--- a/public/components/common/error-boundary/error-boundary.test.tsx
+++ b/public/components/common/error-boundary/error-boundary.test.tsx
@@ -1,3 +1,17 @@
+/*
+ * Wazuh app - React test for ErrorBoundary component.
+ *
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ *
+ */
+
import React from 'react';
import { mount } from 'enzyme';
import ErrorBoundary from './error-boundary';
diff --git a/public/react-services/error-orchestrator/error-orchestrator-base.test.ts b/public/react-services/error-orchestrator/error-orchestrator-base.test.ts
new file mode 100644
index 0000000000..9a0d5a7e48
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-base.test.ts
@@ -0,0 +1,44 @@
+/*
+ * Wazuh app - React test for ErrorOrchestratorBase.
+ *
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ *
+ */
+
+import { ErrorOrchestratorBase } from './error-orchestrator-base';
+import { UIErrorLog } from './types';
+
+describe('Wazuh Error Orchestrator Base', () => {
+ describe('Given a valid options params ', () => {
+ it('Should be called displayError and storeError', () => {
+ const options: UIErrorLog = {
+ context: 'unitTest',
+ level: 'ERROR',
+ severity: 'UI',
+ display: true,
+ store: true,
+ error: {
+ error: 'error name test1',
+ message: 'message test1',
+ title: 'title jest testing1',
+ },
+ };
+ const errorOrchestratorBase = new ErrorOrchestratorBase();
+ const myDisplayError = (ErrorOrchestratorBase.prototype.displayError = jest.fn());
+ const myStoreError = jest.spyOn(ErrorOrchestratorBase.prototype as any, 'storeError');
+ myStoreError.mockImplementation(() => {})
+
+ errorOrchestratorBase.loadErrorLog(options);
+
+ expect(myDisplayError).toBeCalledTimes(1);
+ expect(myStoreError).toBeCalledTimes(1);
+ });
+ });
+});
diff --git a/public/react-services/error-orchestrator/error-orchestrator-base.ts b/public/react-services/error-orchestrator/error-orchestrator-base.ts
index bc798d88e0..61592d8ba9 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-base.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-base.ts
@@ -17,7 +17,7 @@ import { ErrorOrchestrator, UIErrorLog } from './types';
export class ErrorOrchestratorBase implements ErrorOrchestrator {
public loadErrorLog(errorLog: UIErrorLog) {
if (errorLog.display) this.displayError(errorLog);
- if (errorLog.store) this.storeError(errorLog).then(loglevel.info);
+ if (errorLog.store) this.storeError(errorLog);
}
public displayError(errorLog: UIErrorLog) {
diff --git a/public/react-services/wz-user-permissions.test.ts b/public/react-services/wz-user-permissions.test.ts
index fe2cb6f8a5..b204c83b39 100644
--- a/public/react-services/wz-user-permissions.test.ts
+++ b/public/react-services/wz-user-permissions.test.ts
@@ -1,5 +1,5 @@
/*
- * Wazuh app - React hook for get query of Kibana searchBar
+ * Wazuh app - React test for wz-user-permissions
* Copyright (C) 2015-2021 Wazuh, Inc.
*
* This program is free software; you can redistribute it and/or modify
From e481167204365d8d94457d05189f51a143bf8eb3 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Wed, 9 Jun 2021 15:47:29 -0300
Subject: [PATCH 12/24] test(error-orchestrator-base): Added simple unit test
to ErrorOrchestratorCritical
---
.../error-orchestrator-base.test.ts | 16 +++----
.../error-orchestrator-critical.test.ts | 44 +++++++++++++++++++
2 files changed, 52 insertions(+), 8 deletions(-)
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-critical.test.ts
diff --git a/public/react-services/error-orchestrator/error-orchestrator-base.test.ts b/public/react-services/error-orchestrator/error-orchestrator-base.test.ts
index 9a0d5a7e48..b90361c916 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-base.test.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-base.test.ts
@@ -1,5 +1,5 @@
/*
- * Wazuh app - React test for ErrorOrchestratorBase.
+ * Wazuh app - Unit test for ErrorOrchestratorBase.
*
* Copyright (C) 2015-2021 Wazuh, Inc.
*
@@ -13,7 +13,7 @@
*/
import { ErrorOrchestratorBase } from './error-orchestrator-base';
-import { UIErrorLog } from './types';
+import { ErrorOrchestrator, UIErrorLog } from './types';
describe('Wazuh Error Orchestrator Base', () => {
describe('Given a valid options params ', () => {
@@ -30,15 +30,15 @@ describe('Wazuh Error Orchestrator Base', () => {
title: 'title jest testing1',
},
};
- const errorOrchestratorBase = new ErrorOrchestratorBase();
- const myDisplayError = (ErrorOrchestratorBase.prototype.displayError = jest.fn());
- const myStoreError = jest.spyOn(ErrorOrchestratorBase.prototype as any, 'storeError');
- myStoreError.mockImplementation(() => {})
+ const errorOrchestratorBase: ErrorOrchestrator = new ErrorOrchestratorBase();
+ const mockDisplayError = (ErrorOrchestratorBase.prototype.displayError = jest.fn());
+ const mockStoreError = jest.spyOn(ErrorOrchestratorBase.prototype as any, 'storeError');
+ mockStoreError.mockImplementation(() => {})
errorOrchestratorBase.loadErrorLog(options);
- expect(myDisplayError).toBeCalledTimes(1);
- expect(myStoreError).toBeCalledTimes(1);
+ expect(mockDisplayError).toBeCalledTimes(1);
+ expect(mockStoreError).toBeCalledTimes(1);
});
});
});
diff --git a/public/react-services/error-orchestrator/error-orchestrator-critical.test.ts b/public/react-services/error-orchestrator/error-orchestrator-critical.test.ts
new file mode 100644
index 0000000000..87531d7aae
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-critical.test.ts
@@ -0,0 +1,44 @@
+/*
+ * Wazuh app - Unit test for ErrorOrchestratorCritical.
+ *
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ *
+ */
+
+import { ErrorOrchestrator, UIErrorLog } from './types';
+import { ErrorOrchestratorCritical } from './error-orchestrator-critical';
+import { WzMisc } from '../../factories/misc';
+
+describe('Wazuh Error Orchestrator Critical', () => {
+ describe('Given a valid options params ', () => {
+ it('Should be called mockSetBlankScr and redirect to BlankScreen', () => {
+ const options: UIErrorLog = {
+ context: 'unitTest',
+ level: 'ERROR',
+ severity: 'UI',
+ display: true,
+ store: false,
+ error: {
+ error: 'error name test1',
+ message: 'message test1',
+ title: 'title jest testing1',
+ },
+ };
+
+ const mockSetBlankScr = (WzMisc.prototype.setBlankScr = jest.fn());
+
+ const errorOrchestratorCritical: ErrorOrchestrator = new ErrorOrchestratorCritical();
+ errorOrchestratorCritical.loadErrorLog(options);
+
+ expect(mockSetBlankScr).toBeCalledTimes(1);
+ expect(window.location.href).toEqual('http://localhost/#/blank-screen');
+ });
+ });
+});
From dd5ba352365de7d15dfc1a954cfe4a641c0bdd38 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Wed, 9 Jun 2021 16:25:23 -0300
Subject: [PATCH 13/24] test(error-orchestrator-ui): Added simple unit test to
ErrorOrchestratorUi
---
.../error-orchestrator-ui.test.ts | 87 +++++++++++++++++++
1 file changed, 87 insertions(+)
create mode 100644 public/react-services/error-orchestrator/error-orchestrator-ui.test.ts
diff --git a/public/react-services/error-orchestrator/error-orchestrator-ui.test.ts b/public/react-services/error-orchestrator/error-orchestrator-ui.test.ts
new file mode 100644
index 0000000000..5a795a60f2
--- /dev/null
+++ b/public/react-services/error-orchestrator/error-orchestrator-ui.test.ts
@@ -0,0 +1,87 @@
+/*
+ * Wazuh app - Unit test for ErrorOrchestratorUI.
+ *
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ *
+ */
+
+import { ErrorOrchestrator, UIErrorLog } from './types';
+import { ErrorOrchestratorUI } from './error-orchestrator-ui';
+import loglevel from 'loglevel';
+
+const options: UIErrorLog = {
+ context: 'unitTest',
+ level: 'INFO',
+ severity: 'UI',
+ display: true,
+ store: false,
+ error: {
+ error: 'Testing loglevel INFO',
+ message: 'Message loglevel INFO',
+ title: 'title jest testing1',
+ },
+};
+
+describe('Wazuh Error Orchestrator UI', () => {
+ describe('Given a valid options params for log INFO', () => {
+ it('Should be called loglevelInfo', () => {
+ const mockLoglevelInfo = loglevel.info = jest.fn();
+ const mockError = 'Testing loglevel INFO';
+ const mockMessage = 'Message loglevel INFO';
+
+ const errorOrchestratorUI: ErrorOrchestrator = new ErrorOrchestratorUI();
+ errorOrchestratorUI.loadErrorLog(options);
+
+ expect(mockLoglevelInfo).toBeCalled();
+ expect(mockLoglevelInfo).toBeCalledWith(mockMessage, mockError);
+ expect(mockLoglevelInfo).toBeCalledTimes(1);
+ });
+ });
+
+ describe('Given a valid options params for log WARNING', () => {
+ it('Should be called loglevelWarning', () => {
+ options.level = 'WARNING';
+ options.error.error = 'Testing loglevel WARNING';
+ options.error.message = 'Message loglevel WARNING';
+
+ const mockError = 'Testing loglevel WARNING';
+ const mockMessage = 'Message loglevel WARNING';
+
+ const mockLoglevelWarning = loglevel.warn = jest.fn();
+
+ const errorOrchestratorUI: ErrorOrchestrator = new ErrorOrchestratorUI();
+ errorOrchestratorUI.loadErrorLog(options);
+
+ expect(mockLoglevelWarning).toBeCalled();
+ expect(mockLoglevelWarning).toBeCalledWith(mockMessage, mockError);
+ expect(mockLoglevelWarning).toBeCalledTimes(1);
+ });
+ });
+
+ describe('Given a valid options params for log ERROR', () => {
+ it('Should be called loglevelError', () => {
+ options.level = 'ERROR';
+ options.error.error = 'Testing loglevel ERROR';
+ options.error.message = 'Message loglevel ERROR';
+
+ const mockError = 'Testing loglevel ERROR';
+ const mockMessage = 'Message loglevel ERROR';
+
+ const mockLoglevelError = loglevel.error = jest.fn();
+
+ const errorOrchestratorUI: ErrorOrchestrator = new ErrorOrchestratorUI();
+ errorOrchestratorUI.loadErrorLog(options);
+
+ expect(mockLoglevelError).toBeCalled();
+ expect(mockLoglevelError).toBeCalledWith(mockMessage, mockError);
+ expect(mockLoglevelError).toBeCalledTimes(1);
+ });
+ });
+});
From ba214d50e690b6c72daf172cf70637125130686a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Mart=C3=ADnez?=
Date: Wed, 9 Jun 2021 21:37:37 +0200
Subject: [PATCH 14/24] Create new backend service (#3324)
* Add endpoint
* Create new backend service
* Add changelog
* Renamed constants
* Added interfaces, created new controller and renamed
* Created ui-logged, to prevent logger superclass
* Added types, fixed responses types
* Added new route file to ui-logs, changed method put to post, added in index,ts
* Added test files, we must create all unit tests to those new features
* Fixed if condition
* Rename tests files, created endpoints test
* Changed controller name ui-logs, removed duplicated export
* Fixed file comments
* Applied prettier formater
* Added new base class base-logger
* Remove wrong constants and fix errors
* test(ui-logger-controller): Added simple unit test.
* test(ui-logs-controller): Fix params.
* Added test to ui-logs controller
* Renamed test files
* test(logs-controller): Added mock to function checkFileExist + prettier.
* Solve comments
* Add copyright and remove unused import
Co-authored-by: Ibarra Maximiliano
Co-authored-by: gabiwassan
---
CHANGELOG.md | 4 +
common/constants.ts | 8 +-
server/controllers/index.ts | 2 +-
server/controllers/wazuh-utils/index.ts | 2 +
.../wazuh-utils/ui-logs.controller.test.ts | 64 ++++++
.../wazuh-utils/ui-logs.controller.ts | 96 ++++++++
.../{ => wazuh-utils}/wazuh-utils.ts | 16 +-
server/lib/base-logger.ts | 214 ++++++++++++++++++
server/lib/logger.ts | 169 +-------------
server/lib/ui-logger.ts | 18 ++
server/routes/index.ts | 3 +-
server/routes/wazuh-utils/index.ts | 2 +
server/routes/wazuh-utils/ui-logs.test.ts | 39 ++++
server/routes/wazuh-utils/ui-logs.ts | 39 ++++
.../{ => wazuh-utils}/wazuh-utils.test.ts | 0
.../routes/{ => wazuh-utils}/wazuh-utils.ts | 2 +-
test/jest/config.js | 3 +-
17 files changed, 508 insertions(+), 173 deletions(-)
create mode 100644 server/controllers/wazuh-utils/index.ts
create mode 100644 server/controllers/wazuh-utils/ui-logs.controller.test.ts
create mode 100644 server/controllers/wazuh-utils/ui-logs.controller.ts
rename server/controllers/{ => wazuh-utils}/wazuh-utils.ts (89%)
create mode 100644 server/lib/base-logger.ts
create mode 100644 server/lib/ui-logger.ts
create mode 100644 server/routes/wazuh-utils/index.ts
create mode 100644 server/routes/wazuh-utils/ui-logs.test.ts
create mode 100644 server/routes/wazuh-utils/ui-logs.ts
rename server/routes/{ => wazuh-utils}/wazuh-utils.test.ts (100%)
rename server/routes/{ => wazuh-utils}/wazuh-utils.ts (96%)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cd3d7a548c..37f4d4fd2a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,10 @@ All notable changes to the Wazuh app project will be documented in this file.
## Wazuh v4.3.0 - Kibana 7.10.2 , 7.11.2 - Revision 4301
+### Added
+
+- Added new endpoint service to collect the frontend logs into a file [#3324](https://github.com/wazuh/wazuh-kibana-app/pull/3324)
+
### Changed
- Changed ossec to wazuh in sample-data [#3121](https://github.com/wazuh/wazuh-kibana-app/pull/3121)
diff --git a/common/constants.ts b/common/constants.ts
index 71b78dd6cb..56208aa173 100644
--- a/common/constants.ts
+++ b/common/constants.ts
@@ -125,8 +125,12 @@ export const WAZUH_DATA_CONFIG_REGISTRY_PATH = path.join(WAZUH_DATA_CONFIG_DIREC
// Wazuh data path - logs
export const WAZUH_DATA_LOGS_DIRECTORY_PATH = path.join(WAZUH_DATA_ABSOLUTE_PATH, 'logs');
-export const WAZUH_DATA_LOGS_PLAIN_PATH = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, 'wazuhapp-plain.log');
-export const WAZUH_DATA_LOGS_RAW_PATH = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, 'wazuhapp.log');
+export const WAZUH_DATA_LOGS_PLAIN_FILENAME = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, 'wazuhapp-plain.log');
+export const WAZUH_DATA_LOGS_RAW_FILENAME = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, 'wazuhapp.log');
+
+// Wazuh data path - UI logs
+export const WAZUH_UI_LOGS_PLAIN_FILENAME = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, 'wazuh-ui-plain.log');
+export const WAZUH_UI_LOGS_RAW_FILENAME = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, 'wazuh-ui.log');
// Wazuh data path - downloads
export const WAZUH_DATA_DOWNLOADS_DIRECTORY_PATH = path.join(WAZUH_DATA_ABSOLUTE_PATH, 'downloads');
diff --git a/server/controllers/index.ts b/server/controllers/index.ts
index 591a8f3fe4..c0f2597270 100644
--- a/server/controllers/index.ts
+++ b/server/controllers/index.ts
@@ -11,6 +11,6 @@
*/
export { WazuhElasticCtrl } from './wazuh-elastic';
export { WazuhApiCtrl } from './wazuh-api';
-export { WazuhUtilsCtrl } from './wazuh-utils';
export { WazuhReportingCtrl } from './wazuh-reporting';
export { WazuhHostsCtrl } from './wazuh-hosts'
+export * from './wazuh-utils';
\ No newline at end of file
diff --git a/server/controllers/wazuh-utils/index.ts b/server/controllers/wazuh-utils/index.ts
new file mode 100644
index 0000000000..ecac9686fe
--- /dev/null
+++ b/server/controllers/wazuh-utils/index.ts
@@ -0,0 +1,2 @@
+export * from './wazuh-utils';
+export * from './ui-logs.controller';
diff --git a/server/controllers/wazuh-utils/ui-logs.controller.test.ts b/server/controllers/wazuh-utils/ui-logs.controller.test.ts
new file mode 100644
index 0000000000..15eb657e6b
--- /dev/null
+++ b/server/controllers/wazuh-utils/ui-logs.controller.test.ts
@@ -0,0 +1,64 @@
+import { UiLogsCtrl } from './ui-logs.controller';
+import { WAZUH_UI_LOGS_RAW_FILENAME } from '../../../common/constants';
+import uiLogger from '../../lib/ui-logger';
+
+const readLastLines = require('read-last-lines');
+
+const buildMockResponse = () => {
+ const res = {};
+ res.ok = jest.fn().mockReturnValue(res);
+ return res;
+};
+
+const buildMockRequest = () => {
+ const req = {};
+ req.body = jest.fn().mockReturnValue(req);
+ req.params = jest.fn().mockReturnValue(req);
+ return req;
+};
+
+describe('Spec UiLogsCtrl', function () {
+ describe('Check method getUiLogs ', () => {
+ it('Should 200 and return correct value', async () => {
+ const result = { body: { error: 0, rawLogs: ['my test mocked'] } };
+ const mockResponse = buildMockResponse();
+ jest.spyOn(readLastLines, 'read').mockReturnValue('my test mocked');
+ jest.spyOn(uiLogger, 'checkFileExist').mockReturnValue(true);
+
+ const controller = new UiLogsCtrl();
+ await controller.getUiLogs(mockResponse);
+
+ expect(mockResponse.ok).toHaveBeenCalledTimes(1);
+ expect(mockResponse.ok.mock.calls.length).toBe(1);
+ expect(mockResponse.ok).toHaveBeenCalledWith(result);
+ });
+
+ it('Should 200 and return message Log has been added', async () => {
+ const result = { body: { message: 'Log has been added' } };
+ const mockResponse = buildMockResponse();
+ jest.spyOn(readLastLines, 'read').mockReturnValue('Log has been added');
+ jest.spyOn(uiLogger, 'checkFileExist').mockReturnValue(true);
+
+ const mockRequest = buildMockRequest();
+ mockRequest.body = {
+ level: 'error',
+ message: 'Message example',
+ location: 'Location example',
+ };
+
+ const controller = new UiLogsCtrl();
+ await controller.createUiLogs(mockRequest, mockResponse);
+
+ expect(mockResponse.ok).toHaveBeenCalledTimes(1);
+ expect(mockResponse.ok.mock.calls.length).toBe(1);
+ expect(mockResponse.ok).toHaveBeenCalledWith(result);
+ });
+
+ it('Should return a Array logs', async () => {
+ const controller = new UiLogsCtrl();
+ let res = await controller.getUiFileLogs(WAZUH_UI_LOGS_RAW_FILENAME);
+
+ expect(Array.isArray(res)).toBe(true);
+ });
+ });
+});
diff --git a/server/controllers/wazuh-utils/ui-logs.controller.ts b/server/controllers/wazuh-utils/ui-logs.controller.ts
new file mode 100644
index 0000000000..6080e6672f
--- /dev/null
+++ b/server/controllers/wazuh-utils/ui-logs.controller.ts
@@ -0,0 +1,96 @@
+/*
+ * Wazuh app - Class for UI Logs functions
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+// Require some libraries
+import { ErrorResponse } from '../../lib/error-response';
+import { read } from 'read-last-lines';
+import { WAZUH_UI_LOGS_RAW_FILENAME } from '../../../common/constants';
+import { KibanaRequest, RequestHandlerContext, KibanaResponseFactory } from 'src/core/server';
+import uiLogger from '../../lib/ui-logger';
+
+export class UiLogsCtrl {
+ /**
+ * Constructor
+ * @param {*} server
+ */
+ constructor() {}
+
+ /**
+ * Returns Wazuh ui logs
+ * @param {Object} response
+ * @returns {Array} app logs or ErrorResponse
+ */
+ async getUiLogs(
+ response: KibanaResponseFactory
+ ) {
+ try {
+ return uiLogger.initDirectory().then(async () => {
+ if (!uiLogger.checkFileExist(WAZUH_UI_LOGS_RAW_FILENAME)) {
+ return response.ok({
+ body: {
+ error: 0,
+ rawLogs: [],
+ },
+ });
+ } else {
+ let arrayLog = await this.getUiFileLogs(WAZUH_UI_LOGS_RAW_FILENAME);
+ return response.ok({
+ body: {
+ error: 0,
+ rawLogs: arrayLog.filter((item) => typeof item === 'string' && item.length),
+ },
+ });
+ }
+ });
+ } catch (error) {
+ return ErrorResponse(error.message || error, 3036, 500, response);
+ }
+ }
+
+ /**
+ * Add new UI Log entry in ui logs file
+ * @param context
+ * @param request
+ * @param response
+ * @returns success message or ErrorResponse
+ */
+ async createUiLogs(
+ request: KibanaRequest,
+ response: KibanaResponseFactory
+ ) {
+ try {
+ const { location, message, level } = request.body;
+ await uiLogger.log(location, message, level);
+ return response.ok({
+ body: {
+ message: 'Log has been added',
+ },
+ });
+ } catch (error) {
+ return ErrorResponse(error.message || error, 3021, 500, response);
+ }
+ }
+
+ /**
+ * Get UI logs from specific log file
+ * @param filepath
+ * @returns Array
+ */
+ async getUiFileLogs(filepath) {
+ try {
+ const lastLogs = await read(filepath, 50);
+ return lastLogs.split('\n');
+ } catch (err) {
+ throw err;
+ }
+ }
+}
diff --git a/server/controllers/wazuh-utils.ts b/server/controllers/wazuh-utils/wazuh-utils.ts
similarity index 89%
rename from server/controllers/wazuh-utils.ts
rename to server/controllers/wazuh-utils/wazuh-utils.ts
index 466923d44b..97567ec7ad 100644
--- a/server/controllers/wazuh-utils.ts
+++ b/server/controllers/wazuh-utils/wazuh-utils.ts
@@ -11,15 +11,15 @@
*/
// Require some libraries
-import { ErrorResponse } from '../lib/error-response';
-import { getConfiguration } from '../lib/get-configuration';
+import { ErrorResponse } from '../../lib/error-response';
+import { getConfiguration } from '../../lib/get-configuration';
import { read } from 'read-last-lines';
-import { UpdateConfigurationFile } from '../lib/update-configuration';
+import { UpdateConfigurationFile } from '../../lib/update-configuration';
import jwtDecode from 'jwt-decode';
-import { WAZUH_ROLE_ADMINISTRATOR_ID, WAZUH_DATA_LOGS_RAW_PATH } from '../../common/constants';
-import { ManageHosts } from '../lib/manage-hosts';
+import { WAZUH_ROLE_ADMINISTRATOR_ID, WAZUH_DATA_LOGS_RAW_FILENAME, WAZUH_UI_LOGS_RAW_PATH } from '../../../common/constants';
+import { ManageHosts } from '../../lib/manage-hosts';
import { KibanaRequest, RequestHandlerContext, KibanaResponseFactory } from 'src/core/server';
-import { getCookieValueByName } from '../lib/cookie';
+import { getCookieValueByName } from '../../lib/cookie';
const updateConfigurationFile = new UpdateConfigurationFile();
@@ -108,7 +108,7 @@ export class WazuhUtilsCtrl {
async getAppLogs(context: RequestHandlerContext, request: KibanaRequest, response: KibanaResponseFactory) {
try {
const lastLogs = await read(
- WAZUH_DATA_LOGS_RAW_PATH,
+ WAZUH_DATA_LOGS_RAW_FILENAME,
50
);
const spliterLog = lastLogs.split('\n');
@@ -126,4 +126,6 @@ export class WazuhUtilsCtrl {
return ErrorResponse(error.message || error, 3036, 500, response);
}
}
+
+
}
diff --git a/server/lib/base-logger.ts b/server/lib/base-logger.ts
new file mode 100644
index 0000000000..17b0cf71dd
--- /dev/null
+++ b/server/lib/base-logger.ts
@@ -0,0 +1,214 @@
+/*
+ * Wazuh app - Settings controller
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+
+import winston from 'winston';
+import fs from 'fs';
+import path from 'path';
+import { getConfiguration } from './get-configuration';
+import { createDataDirectoryIfNotExists } from './filesystem';
+
+import { WAZUH_DATA_LOGS_DIRECTORY_PATH } from '../../common/constants';
+
+export interface IUIPlainLoggerSettings {
+ level: string;
+ message: string;
+ }
+
+ export interface IUILoggerSettings extends IUIPlainLoggerSettings {
+ date: Date;
+ location: string;
+ }
+
+export class BaseLogger {
+ allowed: boolean = false;
+ wazuhLogger: winston.Logger | undefined = undefined;
+ wazuhPlainLogger: winston.Logger | undefined = undefined;
+ PLAIN_LOGS_PATH: string = '';
+ RAW_LOGS_PATH: string = '';
+
+ constructor(plainLogsPath: string, rawLogsPath: string) {
+ this.PLAIN_LOGS_PATH = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, plainLogsPath);
+ this.RAW_LOGS_PATH = path.join(WAZUH_DATA_LOGS_DIRECTORY_PATH, rawLogsPath);
+ }
+
+ /**
+ * Initialize loggers, plain and raw logger
+ */
+ private initLogger = () => {
+ const configurationFile = getConfiguration();
+ const level =
+ typeof (configurationFile || {})['logs.level'] !== 'undefined' &&
+ ['info', 'debug'].includes(configurationFile['logs.level'])
+ ? configurationFile['logs.level']
+ : 'info';
+
+ // JSON logger
+ this.wazuhLogger = winston.createLogger({
+ level,
+ format: winston.format.json(),
+ transports: [
+ new winston.transports.File({
+ filename: this.RAW_LOGS_PATH,
+ }),
+ ],
+ });
+
+ // Prevents from exit on error related to the logger.
+ this.wazuhLogger.exitOnError = false;
+
+ // Plain text logger
+ this.wazuhPlainLogger = winston.createLogger({
+ level,
+ format: winston.format.simple(),
+ transports: [
+ new winston.transports.File({
+ filename: this.PLAIN_LOGS_PATH,
+ }),
+ ],
+ });
+
+ // Prevents from exit on error related to the logger.
+ this.wazuhPlainLogger.exitOnError = false;
+ };
+
+ /**
+ * Checks if wazuh/logs exists. If it doesn't exist, it will be created.
+ */
+ initDirectory = async () => {
+ try {
+ createDataDirectoryIfNotExists();
+ createDataDirectoryIfNotExists('logs');
+ if (typeof this.wazuhLogger === 'undefined' || typeof this.wazuhPlainLogger === 'undefined') {
+ this.initLogger();
+ }
+ this.allowed = true;
+ return;
+ } catch (error) {
+ this.allowed = false;
+ return Promise.reject(error);
+ }
+ };
+
+ /**
+ * Returns given file size in MB, if the file doesn't exist returns 0
+ * @param {*} filename Path to the file
+ */
+ getFilesizeInMegaBytes = (filename) => {
+ if (this.allowed) {
+ if (fs.existsSync(filename)) {
+ const stats = fs.statSync(filename);
+ const fileSizeInMegaBytes = stats.size;
+
+ return fileSizeInMegaBytes / 1000000.0;
+ }
+ }
+ return 0;
+ };
+
+ /**
+ * Check if file exist
+ * @param filename
+ * @returns boolean
+ */
+ checkFileExist = (filename) => {
+ return fs.existsSync(filename);
+ };
+
+ /**
+ * Checks if the wazuhapp.log file size is greater than 100MB, if so it rotates the file.
+ */
+ private checkFiles = () => {
+ if (this.allowed) {
+ // check raw log file
+ if (this.getFilesizeInMegaBytes(this.RAW_LOGS_PATH) >= 100) {
+ fs.renameSync(
+ this.RAW_LOGS_PATH,
+ `${WAZUH_DATA_LOGS_DIRECTORY_PATH}/wazuhapp.${new Date().getTime()}.log`
+ );
+ fs.writeFileSync(
+ this.RAW_LOGS_PATH,
+ JSON.stringify({
+ date: new Date(),
+ level: 'info',
+ location: 'logger',
+ message: 'Rotated log file',
+ }) + '\n'
+ );
+ }
+
+ // check log file
+ if (this.getFilesizeInMegaBytes(this.PLAIN_LOGS_PATH) >= 100) {
+ fs.renameSync(
+ this.PLAIN_LOGS_PATH,
+ `${WAZUH_DATA_LOGS_DIRECTORY_PATH}/wazuhapp-plain.${new Date().getTime()}.log`
+ );
+ }
+ }
+ };
+
+
+ /**
+ * Get Current Date
+ * @returns string
+ */
+ private yyyymmdd = () => {
+ const now = new Date();
+ const y = now.getFullYear();
+ const m = now.getMonth() + 1;
+ const d = now.getDate();
+ const seconds = now.getSeconds();
+ const minutes = now.getMinutes();
+ const hour = now.getHours();
+ return `${y}/${m < 10 ? '0' : ''}${m}/${d < 10 ? '0' : ''}${d} ${hour}:${minutes}:${seconds}`;
+ };
+
+
+
+ /**
+ * Main function to add a new log
+ * @param {*} location File where the log is being thrown
+ * @param {*} message Message to show
+ * @param {*} level Optional, default is 'error'
+ */
+
+ async log(location: string, message: string, level: string) {
+ return this.initDirectory()
+ .then(() => {
+ if (this.allowed) {
+ this.checkFiles();
+
+ const plainLogData: IUIPlainLoggerSettings = {
+ level: level || 'error',
+ message: `${this.yyyymmdd()}: ${location || 'Unknown origin'}: ${
+ message || 'An error occurred'
+ }`,
+ };
+
+ this.wazuhPlainLogger.log(plainLogData);
+
+ const logData: IUILoggerSettings = {
+ date: new Date(),
+ level: level || 'error',
+ location: location || 'Unknown origin',
+ message: message || 'An error occurred',
+ };
+
+ this.wazuhLogger.log(logData);
+ }
+ })
+ .catch((error) => {
+ console.error(`Cannot create the logs directory due to:\n${error.message || error}`);
+ throw error;
+ });
+
+ }
+}
diff --git a/server/lib/logger.ts b/server/lib/logger.ts
index 7cb8115d79..435edb5d88 100644
--- a/server/lib/logger.ts
+++ b/server/lib/logger.ts
@@ -9,165 +9,14 @@
*
* Find more information about this on the LICENSE file.
*/
-import winston from 'winston';
-import fs from 'fs';
-import { getConfiguration } from './get-configuration';
-import { WAZUH_DATA_LOGS_DIRECTORY_PATH, WAZUH_DATA_LOGS_PLAIN_PATH, WAZUH_DATA_LOGS_RAW_PATH } from '../../common/constants';
-import { createDataDirectoryIfNotExists } from './filesystem';
+import { BaseLogger } from './base-logger';
+import {
+ WAZUH_DATA_LOGS_PLAIN_FILENAME,
+ WAZUH_DATA_LOGS_RAW_FILENAME
+} from '../../common/constants';
-let allowed = false;
-let wazuhlogger = undefined;
-let wazuhPlainLogger = undefined;
+const logger = new BaseLogger(WAZUH_DATA_LOGS_PLAIN_FILENAME,WAZUH_DATA_LOGS_RAW_FILENAME);
-/**
- * Here we create the loggers
- */
-const initLogger = () => {
- const configurationFile = getConfiguration();
- const level =
- typeof (configurationFile || {})['logs.level'] !== 'undefined' &&
- ['info', 'debug'].includes(configurationFile['logs.level'])
- ? configurationFile['logs.level']
- : 'info';
-
- // JSON logger
- wazuhlogger = winston.createLogger({
- level,
- format: winston.format.json(),
- transports: [
- new winston.transports.File({
- filename: WAZUH_DATA_LOGS_RAW_PATH
- })
- ]
- });
-
- // Prevents from exit on error related to the logger.
- wazuhlogger.exitOnError = false;
-
- // Plain text logger
- wazuhPlainLogger = winston.createLogger({
- level,
- format: winston.format.simple(),
- transports: [
- new winston.transports.File({
- filename: WAZUH_DATA_LOGS_PLAIN_PATH
- })
- ]
- });
-
- // Prevents from exit on error related to the logger.
- wazuhPlainLogger.exitOnError = false;
-};
-
-/**
- * Checks if wazuh/logs exists. If it doesn't exist, it will be created.
- */
-const initDirectory = async () => {
- try {
- createDataDirectoryIfNotExists();
- createDataDirectoryIfNotExists('logs');
- if (
- typeof wazuhlogger === 'undefined' ||
- typeof wazuhPlainLogger === 'undefined'
- ) {
- initLogger();
- }
- allowed = true;
- return;
- } catch (error) {
- allowed = false;
- return Promise.reject(error);
- }
-};
-
-/**
- * Returns given file size in MB, if the file doesn't exist returns 0
- * @param {*} filename Path to the file
- */
-const getFilesizeInMegaBytes = filename => {
- if (allowed) {
- if (fs.existsSync(filename)) {
- const stats = fs.statSync(filename);
- const fileSizeInMegaBytes = stats.size;
-
- return fileSizeInMegaBytes / 1000000.0;
- }
- }
- return 0;
-};
-
-/**
- * Checks if the wazuhapp.log file size is greater than 100MB, if so it rotates the file.
- */
-const checkFiles = () => {
- if (allowed) {
- if (getFilesizeInMegaBytes(WAZUH_DATA_LOGS_RAW_PATH) >= 100) {
- fs.renameSync(
- WAZUH_DATA_LOGS_RAW_PATH,
- `${WAZUH_DATA_LOGS_DIRECTORY_PATH}/wazuhapp.${new Date().getTime()}.log`
- );
- fs.writeFileSync(
- WAZUH_DATA_LOGS_RAW_PATH,
- JSON.stringify({
- date: new Date(),
- level: 'info',
- location: 'logger',
- message: 'Rotated log file'
- }) + '\n'
- );
- }
- if (getFilesizeInMegaBytes(WAZUH_DATA_LOGS_PLAIN_PATH) >= 100) {
- fs.renameSync(
- WAZUH_DATA_LOGS_PLAIN_PATH,
- `${WAZUH_DATA_LOGS_DIRECTORY_PATH}/wazuhapp-plain.${new Date().getTime()}.log`
- );
- }
- }
-};
-
-const yyyymmdd = () => {
- const now = new Date();
- const y = now.getFullYear();
- const m = now.getMonth() + 1;
- const d = now.getDate();
- const seconds = now.getSeconds();
- const minutes = now.getMinutes();
- const hour = now.getHours();
- return `${y}/${m < 10 ? '0' : ''}${m}/${
- d < 10 ? '0' : ''
- }${d} ${hour}:${minutes}:${seconds}`;
-};
-
-/**
- * Main function to add a new log
- * @param {*} location File where the log is being thrown
- * @param {*} message Message to show
- * @param {*} level Optional, default is 'error'
- */
-export function log(location, message, level) {
- initDirectory()
- .then(() => {
- if (allowed) {
- checkFiles();
- wazuhlogger.log({
- date: new Date(),
- level: level || 'error',
- location: location || 'Unknown origin',
- message: message || 'An error occurred'
- });
- try {
- wazuhPlainLogger.log({
- level: level || 'error',
- message: `${yyyymmdd()}: ${location ||
- 'Unknown origin'}: ${message || 'An error occurred'}`
- });
- } catch (error) {} // eslint-disable-line
- }
- })
- .catch(error =>
- // eslint-disable-next-line
- console.error(
- `Cannot create the logs directory due to:\n${error.message || error}`
- )
- );
-}
+export const log = (location, message, level) => {
+ logger.log(location, message, level )
+}
\ No newline at end of file
diff --git a/server/lib/ui-logger.ts b/server/lib/ui-logger.ts
new file mode 100644
index 0000000000..2ac71076e9
--- /dev/null
+++ b/server/lib/ui-logger.ts
@@ -0,0 +1,18 @@
+/*
+ * Wazuh app - Module for ui logging functions
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+import { BaseLogger } from './base-logger';
+import {
+ WAZUH_UI_LOGS_PLAIN_FILENAME,
+ WAZUH_UI_LOGS_RAW_FILENAME
+} from '../../common/constants';
+
+export default new BaseLogger(WAZUH_UI_LOGS_PLAIN_FILENAME,WAZUH_UI_LOGS_RAW_FILENAME);
diff --git a/server/routes/index.ts b/server/routes/index.ts
index 5f9b743be0..8af0e65dc0 100644
--- a/server/routes/index.ts
+++ b/server/routes/index.ts
@@ -2,7 +2,7 @@ import { IRouter } from 'kibana/server';
import { WazuhApiRoutes } from './wazuh-api';
import { WazuhElasticRoutes } from "./wazuh-elastic";
import { WazuhHostsRoutes } from "./wazuh-hosts";
-import { WazuhUtilsRoutes } from "./wazuh-utils";
+import { WazuhUtilsRoutes, UiLogsRoutes } from './wazuh-utils'
import { WazuhReportingRoutes } from "./wazuh-reporting";
export const setupRoutes = (router: IRouter) => {
@@ -11,4 +11,5 @@ export const setupRoutes = (router: IRouter) => {
WazuhHostsRoutes(router);
WazuhUtilsRoutes(router);
WazuhReportingRoutes(router);
+ UiLogsRoutes(router);
};
diff --git a/server/routes/wazuh-utils/index.ts b/server/routes/wazuh-utils/index.ts
new file mode 100644
index 0000000000..f02845ce09
--- /dev/null
+++ b/server/routes/wazuh-utils/index.ts
@@ -0,0 +1,2 @@
+export { WazuhUtilsRoutes } from "./wazuh-utils";
+export { UiLogsRoutes } from './ui-logs';
\ No newline at end of file
diff --git a/server/routes/wazuh-utils/ui-logs.test.ts b/server/routes/wazuh-utils/ui-logs.test.ts
new file mode 100644
index 0000000000..a6fcebc80e
--- /dev/null
+++ b/server/routes/wazuh-utils/ui-logs.test.ts
@@ -0,0 +1,39 @@
+// To launch this file
+// yarn test:jest --testEnvironment node --verbose server/routes/wazuh-utils/ui-logs
+import axios from 'axios';
+
+function buildAxiosOptions(method: string, path: string, data: any = {}, headers: any = {}){
+ return {
+ method: method,
+ headers: { 'Content-Type': 'application/json', 'kbn-xsrf': 'kibana', ...headers },
+ url: `http://localhost:5601${path}`,
+ data: data
+ };
+};
+
+
+describe('Wazuh API - /utils/logs/ui', () => {
+ test('[200] Get UI Logs', () => {
+ const options = buildAxiosOptions('get', '/utils/logs/ui');
+ return axios(options).then(response => {
+ expect(response.status).toBe(200);
+ //expect(typeof response.data.data).toBe('object');
+ //expect(typeof response.data.data.hosts).toBe('object');
+ }).catch(error => {throw error})
+ },6000);
+});
+
+describe('Wazuh API - /utils/logs/ui', () => {
+ let userToken = null;
+
+ test('[200] Create UI Logs', () => {
+ const options = buildAxiosOptions('post', '/utils/logs/ui', {
+ message: 'Message test',
+ level: 'error',
+ location: 'Location'
+ });
+ return axios(options).then(response => {
+ expect(response.status).toBe(200);
+ }).catch(error => {throw error})
+ },6000);
+});
diff --git a/server/routes/wazuh-utils/ui-logs.ts b/server/routes/wazuh-utils/ui-logs.ts
new file mode 100644
index 0000000000..345f16af6f
--- /dev/null
+++ b/server/routes/wazuh-utils/ui-logs.ts
@@ -0,0 +1,39 @@
+/*
+ * Wazuh app - Module for UI Logs routes
+ * Copyright (C) 2015-2021 Wazuh, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Find more information about this on the LICENSE file.
+ */
+import { UiLogsCtrl } from '../../controllers';
+import { IRouter } from 'kibana/server';
+import { schema } from '@kbn/config-schema';
+
+export function UiLogsRoutes(router: IRouter) {
+ const ctrl = new UiLogsCtrl();
+ router.get(
+ {
+ path: '/utils/logs/ui',
+ validate: false,
+ },
+ async (context, request, response) => await ctrl.getUiLogs(context, request, response)
+ );
+
+ router.post(
+ {
+ path: '/utils/logs/ui',
+ validate: {
+ body: schema.object({
+ message: schema.string(),
+ level: schema.string(),
+ location: schema.string(),
+ }),
+ },
+ },
+ async (context, request, response) => await ctrl.createUiLogs(context, request, response)
+ );
+}
diff --git a/server/routes/wazuh-utils.test.ts b/server/routes/wazuh-utils/wazuh-utils.test.ts
similarity index 100%
rename from server/routes/wazuh-utils.test.ts
rename to server/routes/wazuh-utils/wazuh-utils.test.ts
diff --git a/server/routes/wazuh-utils.ts b/server/routes/wazuh-utils/wazuh-utils.ts
similarity index 96%
rename from server/routes/wazuh-utils.ts
rename to server/routes/wazuh-utils/wazuh-utils.ts
index f1d6608f51..52587dd0d3 100644
--- a/server/routes/wazuh-utils.ts
+++ b/server/routes/wazuh-utils/wazuh-utils.ts
@@ -9,7 +9,7 @@
*
* Find more information about this on the LICENSE file.
*/
-import { WazuhUtilsCtrl } from '../controllers';
+import { WazuhUtilsCtrl } from '../../controllers';
import { IRouter } from 'kibana/server';
import { schema } from '@kbn/config-schema';
diff --git a/test/jest/config.js b/test/jest/config.js
index 3e6e911ff9..4a1fe3f72a 100644
--- a/test/jest/config.js
+++ b/test/jest/config.js
@@ -48,7 +48,8 @@ export default {
'target/',
],
testMatch: [
- '**/*.test.{js,ts,tsx}'
+ '**/*.test.{js,ts,tsx}',
+ '**/*{js,ts,tsx}'
],
transform: {
'^.+\\.js$': `${kbnDir}/src/dev/jest/babel_transform.js`,
From dc8a304da7e3d5e591b5086c68ede1db9e2fc5be Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Thu, 10 Jun 2021 17:29:23 -0300
Subject: [PATCH 15/24] bugfix(error-orchestrator): Added some improvements and
fixes.
---
.../error-orchestrator/error-orchestrator-base.ts | 8 +++-----
.../error-orchestrator-business.ts | 2 ++
.../controllers/wazuh-utils/ui-logs.controller.ts | 14 +++++---------
server/routes/wazuh-utils/ui-logs.ts | 4 ++--
4 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/public/react-services/error-orchestrator/error-orchestrator-base.ts b/public/react-services/error-orchestrator/error-orchestrator-base.ts
index 61592d8ba9..dc585ec3ec 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-base.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-base.ts
@@ -27,11 +27,9 @@ export class ErrorOrchestratorBase implements ErrorOrchestrator {
private async storeError(errorLog: UIErrorLog) {
try {
await GenericRequest.request('POST', `/utils/logs/ui`, {
- body: {
- message: errorLog.error.message,
- level: errorLog.level,
- location: errorLog.location,
- },
+ message: errorLog.error.message,
+ level: errorLog.level,
+ location: errorLog.location,
});
} catch (error) {
loglevel.error('Failed on request [POST /utils/logs/ui]', error);
diff --git a/public/react-services/error-orchestrator/error-orchestrator-business.ts b/public/react-services/error-orchestrator/error-orchestrator-business.ts
index 851bb77b96..13ecf0c326 100644
--- a/public/react-services/error-orchestrator/error-orchestrator-business.ts
+++ b/public/react-services/error-orchestrator/error-orchestrator-business.ts
@@ -19,8 +19,10 @@ import { ErrorToastOptions } from 'kibana/public';
export class ErrorOrchestratorBusiness extends ErrorOrchestratorBase {
public displayError(errorLog: UIErrorLog) {
const toast = {
+ error: errorLog.error,
title: errorLog.error.title,
toastMessage: errorLog.error.message,
+ message: errorLog.error.message,
toastLifeTimeMs: 3000,
};
diff --git a/server/controllers/wazuh-utils/ui-logs.controller.ts b/server/controllers/wazuh-utils/ui-logs.controller.ts
index 6080e6672f..f2c7cc184d 100644
--- a/server/controllers/wazuh-utils/ui-logs.controller.ts
+++ b/server/controllers/wazuh-utils/ui-logs.controller.ts
@@ -14,7 +14,7 @@
import { ErrorResponse } from '../../lib/error-response';
import { read } from 'read-last-lines';
import { WAZUH_UI_LOGS_RAW_FILENAME } from '../../../common/constants';
-import { KibanaRequest, RequestHandlerContext, KibanaResponseFactory } from 'src/core/server';
+import { KibanaRequest, KibanaResponseFactory } from 'src/core/server';
import uiLogger from '../../lib/ui-logger';
export class UiLogsCtrl {
@@ -29,9 +29,7 @@ export class UiLogsCtrl {
* @param {Object} response
* @returns {Array} app logs or ErrorResponse
*/
- async getUiLogs(
- response: KibanaResponseFactory
- ) {
+ async getUiLogs(response: KibanaResponseFactory) {
try {
return uiLogger.initDirectory().then(async () => {
if (!uiLogger.checkFileExist(WAZUH_UI_LOGS_RAW_FILENAME)) {
@@ -58,20 +56,18 @@ export class UiLogsCtrl {
/**
* Add new UI Log entry in ui logs file
- * @param context
* @param request
* @param response
* @returns success message or ErrorResponse
*/
- async createUiLogs(
- request: KibanaRequest,
- response: KibanaResponseFactory
- ) {
+ async createUiLogs(request: KibanaRequest, response: KibanaResponseFactory) {
try {
const { location, message, level } = request.body;
await uiLogger.log(location, message, level);
return response.ok({
body: {
+ statusCode: 200,
+ error: 0,
message: 'Log has been added',
},
});
diff --git a/server/routes/wazuh-utils/ui-logs.ts b/server/routes/wazuh-utils/ui-logs.ts
index 345f16af6f..5d4b7a5844 100644
--- a/server/routes/wazuh-utils/ui-logs.ts
+++ b/server/routes/wazuh-utils/ui-logs.ts
@@ -20,7 +20,7 @@ export function UiLogsRoutes(router: IRouter) {
path: '/utils/logs/ui',
validate: false,
},
- async (context, request, response) => await ctrl.getUiLogs(context, request, response)
+ async (context, request, response) => await ctrl.getUiLogs(response)
);
router.post(
@@ -34,6 +34,6 @@ export function UiLogsRoutes(router: IRouter) {
}),
},
},
- async (context, request, response) => await ctrl.createUiLogs(context, request, response)
+ async (context, request, response) => await ctrl.createUiLogs(request, response)
);
}
From 3ba96f4e15b74fa19207e0c817933a09d65179e1 Mon Sep 17 00:00:00 2001
From: gabiwassan
Date: Thu, 10 Jun 2021 17:49:56 -0300
Subject: [PATCH 16/24] test(ui-logs-controller): Updated unit test.
---
server/controllers/wazuh-utils/ui-logs.controller.test.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/server/controllers/wazuh-utils/ui-logs.controller.test.ts b/server/controllers/wazuh-utils/ui-logs.controller.test.ts
index 15eb657e6b..5553f4bef1 100644
--- a/server/controllers/wazuh-utils/ui-logs.controller.test.ts
+++ b/server/controllers/wazuh-utils/ui-logs.controller.test.ts
@@ -34,7 +34,7 @@ describe('Spec UiLogsCtrl', function () {
});
it('Should 200 and return message Log has been added', async () => {
- const result = { body: { message: 'Log has been added' } };
+ const result = { body: { error: 0, message: 'Log has been added', statusCode: 200 } };
const mockResponse = buildMockResponse();
jest.spyOn(readLastLines, 'read').mockReturnValue('Log has been added');
jest.spyOn(uiLogger, 'checkFileExist').mockReturnValue(true);
From ec219f56376d846b7d9615bf6271533748e0abb7 Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Fri, 11 Jun 2021 12:27:43 +0200
Subject: [PATCH 17/24] Settings
---
.../add-modules-data/WzSampleDataWrapper.js | 16 +++++-----
.../cluster/cluster-visualization.js | 31 +++++++------------
public/components/notifications/modal.tsx | 5 +--
public/components/settings/api/add-api.js | 5 +--
public/components/settings/api/api-is-down.js | 5 +--
public/components/settings/api/api-table.js | 10 +++---
.../settings/configuration/configuration.tsx | 17 +++++-----
public/components/settings/modules/modules.js | 16 +++++-----
.../components/settings/settings-logs/logs.js | 7 ++++-
.../agent/components/agents-preview.js | 3 +-
.../agent/components/register-agent.js | 9 ++----
11 files changed, 57 insertions(+), 67 deletions(-)
diff --git a/public/components/add-modules-data/WzSampleDataWrapper.js b/public/components/add-modules-data/WzSampleDataWrapper.js
index 6fd6d81996..d3c6331863 100644
--- a/public/components/add-modules-data/WzSampleDataWrapper.js
+++ b/public/components/add-modules-data/WzSampleDataWrapper.js
@@ -24,8 +24,9 @@ import {
} from '@elastic/eui';
import WzSampleData from './sample-data'
import WzReduxProvider from '../../redux/wz-redux-provider';
-import { withUserAuthorizationPrompt } from '../../components/common/hocs/withUserAuthorization';
+import { withUserAuthorizationPrompt, withErrorBoundary, withReduxProvider } from '../../components/common/hocs';
import store from '../../redux/store';
+import { compose } from 'redux';
import { updateSelectedSettingsSection } from '../../redux/actions/appStateActions';
import { WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../../common/constants';
@@ -73,11 +74,8 @@ export class WzSampleDataProvider extends Component {
}
}
-const WzSampleDataWrapperWithAdministrator = withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])(WzSampleDataProvider);
-export function WzSampleDataWrapper() {
- return (
-
-
-
- )
-}
+export const WzSampleDataWrapper = compose(
+ withErrorBoundary,
+ withReduxProvider,
+ withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])
+)(WzSampleDataProvider);
diff --git a/public/components/management/cluster/cluster-visualization.js b/public/components/management/cluster/cluster-visualization.js
index e80377a1dd..cf698b57cc 100644
--- a/public/components/management/cluster/cluster-visualization.js
+++ b/public/components/management/cluster/cluster-visualization.js
@@ -1,23 +1,14 @@
-import React, { Component } from 'react';
-import WzReduxProvider from '../../../redux/wz-redux-provider';
+import React from 'react';
import KibanaVis from '../../../kibana-integrations/kibana-vis';
+import { withErrorBoundary, withReduxProvider } from '../../../components/common/hocs';
+import {compose} from 'redux'
-export class KibanaVisWrapper extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
-
- render() {
- return (
-
-
-
-
-
- );
- }
+function KibanaVisClass() {
+ return (
+
+
+
+ );
}
+
+export const KibanaVisWrapper = compose(withErrorBoundary, withReduxProvider)(KibanaVisClass);
\ No newline at end of file
diff --git a/public/components/notifications/modal.tsx b/public/components/notifications/modal.tsx
index 2bcaccf172..1680613acb 100644
--- a/public/components/notifications/modal.tsx
+++ b/public/components/notifications/modal.tsx
@@ -27,9 +27,10 @@ import {
import { useSelector, useDispatch } from 'react-redux';
import { updateToastNotificationsModal } from '../../redux/actions/appStateActions';
-import { withReduxProvider } from '../common/hocs'
+import { withReduxProvider, withErrorBoundary } from '../common/hocs';
+import { compose } from 'redux';
-export const ToastNotificationsModal = withReduxProvider(() => {
+export const ToastNotificationsModal = compose (withErrorBoundary, withReduxProvider)(() => {
const [isOpen, setIsOpen] = useState(false);
const toastNotification = useSelector(state => state.appStateReducers.toastNotification);
const dispatch = useDispatch();
diff --git a/public/components/settings/api/add-api.js b/public/components/settings/api/add-api.js
index e7ffe9b70d..e10e8bf5d0 100644
--- a/public/components/settings/api/add-api.js
+++ b/public/components/settings/api/add-api.js
@@ -25,8 +25,9 @@ import {
EuiCallOut,
EuiPanel
} from '@elastic/eui';
+import { withErrorBoundary } from '../../common/hocs';
-export class AddApi extends Component {
+export const AddApi = withErrorBoundary (class AddApi extends Component {
constructor(props) {
super(props);
this.state = {
@@ -203,7 +204,7 @@ export class AddApi extends Component {
return view;
}
-}
+})
AddApi.propTypes = {
checkForNewApis: PropTypes.func,
diff --git a/public/components/settings/api/api-is-down.js b/public/components/settings/api/api-is-down.js
index 16eb39ba3e..c81f9f87e5 100644
--- a/public/components/settings/api/api-is-down.js
+++ b/public/components/settings/api/api-is-down.js
@@ -30,8 +30,9 @@ import {
EuiButtonIcon,
EuiPanel
} from '@elastic/eui';
+import { withErrorBoundary } from '../../common/hocs';
-export class ApiIsDown extends Component {
+export const ApiIsDown = withErrorBoundary (class ApiIsDown extends Component {
constructor(props) {
super(props);
this.state = {
@@ -257,7 +258,7 @@ hosts:
);
}
-}
+});
ApiIsDown.propTypes = {
apiEntries: PropTypes.array,
diff --git a/public/components/settings/api/api-table.js b/public/components/settings/api/api-table.js
index fe3cec4133..3bdab8d65e 100644
--- a/public/components/settings/api/api-table.js
+++ b/public/components/settings/api/api-table.js
@@ -28,13 +28,15 @@ import {
EuiIcon
} from '@elastic/eui';
import { WzButtonPermissions } from '../../common/permissions/button';
-import WzReduxProvider from '../../../redux/wz-redux-provider';
import store from '../../../redux/store';
import { updateSelectedSettingsSection } from '../../../redux/actions/appStateActions';
import { AppState } from '../../../react-services/app-state';
import { API_USER_STATUS_RUN_AS } from '../../../../server/lib/cache-api-user-has-run-as';
+import { withErrorBoundary, withReduxProvider } from '../../common/hocs';
+import { compose } from 'redux'
-export class ApiTable extends Component {
+
+export const ApiTable = compose(withErrorBoundary, withReduxProvider)(class ApiTable extends Component {
constructor(props) {
super(props);
@@ -295,7 +297,6 @@ export class ApiTable extends Component {
return (
-
@@ -344,11 +345,10 @@ export class ApiTable extends Component {
loading={this.state.refreshingEntries}
/>
-
);
}
-}
+});
ApiTable.propTypes = {
apiEntries: PropTypes.array,
diff --git a/public/components/settings/configuration/configuration.tsx b/public/components/settings/configuration/configuration.tsx
index 62e7dc75bb..bc8a712fda 100644
--- a/public/components/settings/configuration/configuration.tsx
+++ b/public/components/settings/configuration/configuration.tsx
@@ -27,11 +27,11 @@ import {
categoriesEquivalence,
formEquivalence
} from '../../../utils/config-equivalences';
-import WzReduxProvider from '../../../redux/wz-redux-provider'
import store from '../../../redux/store'
import { updateSelectedSettingsSection } from '../../../redux/actions/appStateActions';
-import { withUserAuthorizationPrompt } from '../../common/hocs/withUserAuthorization'
+import { withUserAuthorizationPrompt, withErrorBoundary, withReduxProvider } from '../../common/hocs'
import { WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../../../common/constants';
+import { compose } from 'redux';
export type ISetting = {
setting: string
@@ -81,11 +81,8 @@ const WzConfigurationSettingsProvider = (props) => {
);
}
-const WzConfigurationSettingsWrapper = withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])(WzConfigurationSettingsProvider);
-export function WzConfigurationSettings(props) {
- return(
-
-
-
- );
-}
+export const WzConfigurationSettings = compose (
+ withErrorBoundary,
+ withReduxProvider,
+ withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])
+)(WzConfigurationSettingsProvider);
diff --git a/public/components/settings/modules/modules.js b/public/components/settings/modules/modules.js
index 22abc8f78e..c0c07613c1 100644
--- a/public/components/settings/modules/modules.js
+++ b/public/components/settings/modules/modules.js
@@ -16,8 +16,9 @@ import { AppState } from '../../../react-services/app-state';
import WzReduxProvider from '../../../redux/wz-redux-provider';
import store from '../../../redux/store';
import { updateSelectedSettingsSection } from '../../../redux/actions/appStateActions';
-import { withUserAuthorizationPrompt } from '../../common/hocs/withUserAuthorization';
+import { withUserAuthorizationPrompt, withErrorBoundary, withReduxProvider } from '../../common/hocs';
import { WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../../../common/constants';
+import { compose } from 'redux'
export class EnableModulesWrapper extends Component {
constructor(props) {
@@ -165,11 +166,8 @@ export class EnableModulesWrapper extends Component {
}
}
-const WzEnableModulesWithAdministrator = withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])(EnableModulesWrapper);
-export function EnableModules() {
- return(
-
-
-
- );
-}
\ No newline at end of file
+export const EnableModules = compose (
+ withErrorBoundary,
+ withReduxProvider,
+ withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])
+)(EnableModulesWrapper);
\ No newline at end of file
diff --git a/public/components/settings/settings-logs/logs.js b/public/components/settings/settings-logs/logs.js
index b69b4e3206..bdb642d32c 100644
--- a/public/components/settings/settings-logs/logs.js
+++ b/public/components/settings/settings-logs/logs.js
@@ -27,8 +27,9 @@ import {
import { formatUIDate } from '../../../react-services/time-service';
import store from '../../../redux/store';
import { updateSelectedSettingsSection } from '../../../redux/actions/appStateActions';
+import { withErrorBoundary } from '../../common/hocs';
-export default class SettingsLogs extends Component {
+class SettingsLogs extends Component {
constructor(props) {
super(props);
this.offset = 275;
@@ -137,3 +138,7 @@ export default class SettingsLogs extends Component {
);
}
}
+
+export default withErrorBoundary(
+ SettingsLogs
+)
\ No newline at end of file
diff --git a/public/controllers/agent/components/agents-preview.js b/public/controllers/agent/components/agents-preview.js
index dbc8f9cdbf..4f8ad4f9ad 100644
--- a/public/controllers/agent/components/agents-preview.js
+++ b/public/controllers/agent/components/agents-preview.js
@@ -21,7 +21,6 @@ import {
EuiStat,
EuiLoadingChart,
EuiSpacer,
- EuiText,
EuiEmptyPrompt,
EuiToolTip
} from '@elastic/eui';
@@ -40,8 +39,10 @@ import { WzDatePicker } from '../../../components/wz-date-picker/wz-date-picker'
import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt } from '../../../components/common/hocs';
import { formatUIDate } from '../../../../public/react-services/time-service';
import { compose } from 'redux';
+import { withErrorBoundary } from '../../../components/common/hocs'
export const AgentsPreview = compose(
+ withErrorBoundary,
withReduxProvider,
withGlobalBreadcrumb([{ text: '' }, { text: 'Agents' }]),
withUserAuthorizationPrompt([[{action: 'agent:read', resource: 'agent:id:*'},{action: 'agent:read', resource: 'agent:group:*'}]])
diff --git a/public/controllers/agent/components/register-agent.js b/public/controllers/agent/components/register-agent.js
index ca150d594b..085689fb37 100644
--- a/public/controllers/agent/components/register-agent.js
+++ b/public/controllers/agent/components/register-agent.js
@@ -14,14 +14,11 @@ import { version } from '../../../../package.json';
import { WazuhConfig } from '../../../react-services/wazuh-config';
import {
EuiSteps,
- EuiTabs,
EuiTabbedContent,
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
- EuiButtonToggle,
EuiButtonGroup,
- EuiFormRow,
EuiComboBox,
EuiFieldText,
EuiText,
@@ -38,7 +35,7 @@ import {
EuiCode
} from '@elastic/eui';
import { WzRequest } from '../../../react-services/wz-request';
-
+import { withErrorBoundary } from '../../../components/common/hocs'
const architectureButtons = [
{
@@ -114,7 +111,7 @@ const pTextCheckConnectionStyle = {
marginTop: '3em',
};
-export class RegisterAgent extends Component {
+export const RegisterAgent = withErrorBoundary (class RegisterAgent extends Component {
constructor(props) {
super(props);
this.wazuhConfig = new WazuhConfig();
@@ -703,4 +700,4 @@ export class RegisterAgent extends Component {
);
}
-}
+})
From 5ae8a91634f69c9fa67fa406dc24c268b5b97e97 Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Mon, 14 Jun 2021 10:41:34 +0200
Subject: [PATCH 18/24] Added hoc
---
.../components/agents/stats/agent-stats.tsx | 3 +-
.../components/agents/syscollector/main.tsx | 18 +-
public/components/common/modules/main.tsx | 11 +-
.../common/welcome/agents-welcome.js | 10 +-
.../management/cluster/cluster-disabled.js | 6 +-
.../management/cluster/cluster-timelions.js | 161 ++++++++----------
.../cluster/cluster-visualization.js | 4 +-
public/components/overview/mitre/mitre.tsx | 6 +-
public/components/visualize/wz-visualize.js | 5 +-
.../wz-agent-selector-wrapper.js | 21 +--
.../components/wz-filter-bar/wz-filter-bar.js | 5 +-
public/components/wz-menu/wz-menu-wrapper.js | 20 +--
.../agent/components/agents-table.js | 5 +-
.../agent/components/export-configuration.js | 5 +-
14 files changed, 117 insertions(+), 163 deletions(-)
diff --git a/public/components/agents/stats/agent-stats.tsx b/public/components/agents/stats/agent-stats.tsx
index 0bb652062e..3f0f7059f8 100644
--- a/public/components/agents/stats/agent-stats.tsx
+++ b/public/components/agents/stats/agent-stats.tsx
@@ -21,7 +21,7 @@ import {
EuiText
} from '@elastic/eui';
-import { withGlobalBreadcrumb, withReduxProvider, withGuard, withUserAuthorizationPrompt } from '../../common/hocs';
+import { withGlobalBreadcrumb, withReduxProvider, withGuard, withUserAuthorizationPrompt, withErrorBoundary } from '../../common/hocs';
import { compose } from 'redux';
import { WzRequest, formatUIDate } from '../../../react-services';
import { AgentStatTable } from './table';
@@ -80,6 +80,7 @@ const statsAgents: {title: string, field: string, render?: (value) => any}[] = [
];
export const MainAgentStats = compose(
+ withErrorBoundary,
withReduxProvider,
withGlobalBreadcrumb(({agent}) => [
{
diff --git a/public/components/agents/syscollector/main.tsx b/public/components/agents/syscollector/main.tsx
index 0be7dff02e..a4d71095b8 100644
--- a/public/components/agents/syscollector/main.tsx
+++ b/public/components/agents/syscollector/main.tsx
@@ -10,16 +10,12 @@
* Find more information about this on the LICENSE file.
*/
-import React, { Component } from 'react';
-import { SyscollectorInventory } from './inventory'
+import React from 'react';
+import { withErrorBoundary } from '../../common/hocs';
+import { SyscollectorInventory } from './inventory';
-export class MainSyscollector extends Component {
-
- constructor(props) {
- super(props);
- }
-
- render() {
- return ( )
- }
+function MainSyscollectorClass(props) {
+ return ;
}
+
+export const MainSyscollector = withErrorBoundary (MainSyscollectorClass);
diff --git a/public/components/common/modules/main.tsx b/public/components/common/modules/main.tsx
index 22d8e5ff34..b3df090ade 100644
--- a/public/components/common/modules/main.tsx
+++ b/public/components/common/modules/main.tsx
@@ -27,9 +27,10 @@ import { getAngularModule, getDataPlugin, getUiSettings } from '../../../kibana-
import { MainModuleAgent } from './main-agent'
import { MainModuleOverview } from './main-overview';
import store from '../../../redux/store';
-import WzReduxProvider from '../../../redux/wz-redux-provider.js';
+import { compose } from 'redux';
+import { withReduxProvider,withErrorBoundary } from '../hocs';
-export class MainModule extends Component {
+export const MainModule = compose (withErrorBoundary,withReduxProvider) (class MainModule extends Component {
constructor(props) {
super(props);
this.reportingService = new ReportingService();
@@ -211,13 +212,13 @@ export class MainModule extends Component {
onSelectedTabChanged: (id) => this.onSelectedTabChanged(id)
}
return (
-
+ <>
{agent &&
|| ((this.props.section && this.props.section !== 'welcome') &&
)
}
-
+ >
);
}
-}
+})
diff --git a/public/components/common/welcome/agents-welcome.js b/public/components/common/welcome/agents-welcome.js
index 01c4637c27..ac768905dc 100644
--- a/public/components/common/welcome/agents-welcome.js
+++ b/public/components/common/welcome/agents-welcome.js
@@ -23,12 +23,9 @@ import {
EuiFlexGrid,
EuiButtonEmpty,
EuiTitle,
- EuiHealth,
- EuiHorizontalRule,
EuiPage,
EuiButton,
EuiPopover,
- EuiSelect,
EuiLoadingChart,
EuiToolTip,
EuiButtonIcon,
@@ -54,8 +51,9 @@ import { updateCurrentAgentData } from '../../../redux/actions/appStateActions';
import WzTextWithTooltipIfTruncated from '../wz-text-with-tooltip-if-truncated';
import { getAngularModule } from '../../../kibana-services';
import { hasAgentSupportModule } from '../../../react-services/wz-agents';
+import { withErrorBoundary } from '../hocs';
-export class AgentsWelcome extends Component {
+export const AgentsWelcome = withErrorBoundary (class AgentsWelcome extends Component {
_isMount = false;
constructor(props) {
super(props);
@@ -329,7 +327,7 @@ export class AgentsWelcome extends Component {
- );
+ );withErrorBoundary
}
@@ -614,4 +612,4 @@ export class AgentsWelcome extends Component {
);
}
-}
+})
diff --git a/public/components/management/cluster/cluster-disabled.js b/public/components/management/cluster/cluster-disabled.js
index 979bdc0b94..8222d54a99 100644
--- a/public/components/management/cluster/cluster-disabled.js
+++ b/public/components/management/cluster/cluster-disabled.js
@@ -1,7 +1,7 @@
import React, { Component, Fragment } from 'react';
import { EuiPage, EuiPageContent, EuiEmptyPrompt } from '@elastic/eui';
-
-export class ClusterDisabled extends Component {
+import { withErrorBoundary } from '../../common/hocs'
+export const ClusterDisabled = withErrorBoundary (class ClusterDisabled extends Component {
constructor(props) {
super(props);
this.state = {};
@@ -43,4 +43,4 @@ export class ClusterDisabled extends Component {
);
}
-}
+})
diff --git a/public/components/management/cluster/cluster-timelions.js b/public/components/management/cluster/cluster-timelions.js
index 8d0aaeecbf..63f4f33772 100644
--- a/public/components/management/cluster/cluster-timelions.js
+++ b/public/components/management/cluster/cluster-timelions.js
@@ -1,107 +1,86 @@
import React, { Component } from 'react';
-import {
- EuiFlexGroup,
- EuiFlexItem,
- EuiPanel,
- EuiButtonIcon
-} from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiButtonIcon } from '@elastic/eui';
import WzReduxProvider from '../../../redux/wz-redux-provider';
import KibanaVis from '../../../kibana-integrations/kibana-vis';
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../../common/hocs';
-export class ClusterTimelions extends Component {
+export const ClusterTimelions = compose (withErrorBoundary,withReduxProvider) (class ClusterTimelions extends Component {
constructor(props) {
super(props);
this.state = {};
}
- expand = id => {
+ expand = (id) => {
this.setState({ expandedVis: this.state.expandedVis === id ? false : id });
};
render() {
return (
-
-
-
-
-
-
-
- {'Cluster alerts summary'}
-
-
- this.expand(
- 'Wazuh-App-Cluster-monitoring-Overview-Manager'
- )
- }
- iconType="expand"
- aria-label="Expand"
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {'Alerts by node summary'}
-
-
- this.expand('Wazuh-App-Cluster-monitoring-Overview')
- }
- iconType="expand"
- aria-label="Expand"
- />
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+ {'Cluster alerts summary'}
+ this.expand('Wazuh-App-Cluster-monitoring-Overview-Manager')}
+ iconType="expand"
+ aria-label="Expand"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {'Alerts by node summary'}
+ this.expand('Wazuh-App-Cluster-monitoring-Overview')}
+ iconType="expand"
+ aria-label="Expand"
+ />
+
+
+
+
+
+
+
+
+
+
);
}
-}
+})
diff --git a/public/components/management/cluster/cluster-visualization.js b/public/components/management/cluster/cluster-visualization.js
index cf698b57cc..231d77db56 100644
--- a/public/components/management/cluster/cluster-visualization.js
+++ b/public/components/management/cluster/cluster-visualization.js
@@ -3,10 +3,10 @@ import KibanaVis from '../../../kibana-integrations/kibana-vis';
import { withErrorBoundary, withReduxProvider } from '../../../components/common/hocs';
import {compose} from 'redux'
-function KibanaVisClass() {
+function KibanaVisClass(props) {
return (
-
+
);
}
diff --git a/public/components/overview/mitre/mitre.tsx b/public/components/overview/mitre/mitre.tsx
index 71fdbbf884..897e214449 100644
--- a/public/components/overview/mitre/mitre.tsx
+++ b/public/components/overview/mitre/mitre.tsx
@@ -25,14 +25,14 @@ import { KbnSearchBar } from '../../kbn-search-bar';
import { TimeRange, Query } from '../../../../../../src/plugins/data/common';
import { ModulesHelper } from '../../common/modules/modules-helper';
import { getDataPlugin, getToasts } from '../../../kibana-services';
-import { WzEmptyPromptNoPermissions } from "../../common/permissions/prompt";
+import { withErrorBoundary } from "../../common/hocs"
export interface ITactic {
[key:string]: string[]
}
-export class Mitre extends Component {
+export const Mitre = withErrorBoundary (class Mitre extends Component {
_isMount = false;
timefilter: {
getTime(): TimeRange
@@ -190,5 +190,5 @@ export class Mitre extends Component {
);
}
-}
+})
diff --git a/public/components/visualize/wz-visualize.js b/public/components/visualize/wz-visualize.js
index 5cf22181d4..21ffca0f15 100644
--- a/public/components/visualize/wz-visualize.js
+++ b/public/components/visualize/wz-visualize.js
@@ -36,12 +36,13 @@ import { PatternHandler } from '../../react-services/pattern-handler';
import { getToasts } from '../../kibana-services';
import { SecurityAlerts } from './components';
import { toMountPoint } from '../../../../../src/plugins/kibana_react/public';
-import { withReduxProvider } from '../common/hocs';
+import { withReduxProvider,withErrorBoundary } from '../common/hocs';
+import { compose } from 'redux';
const visHandler = new VisHandlers();
-export const WzVisualize = withReduxProvider(class WzVisualize extends Component {
+export const WzVisualize = compose (withErrorBoundary,withReduxProvider) (class WzVisualize extends Component {
_isMount = false;
constructor(props) {
super(props);
diff --git a/public/components/wz-agent-selector/wz-agent-selector-wrapper.js b/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
index f469f8bd8d..fcd52db577 100644
--- a/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
+++ b/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
@@ -11,22 +11,9 @@
* Find more information about this on the LICENSE file.
*
*/
-import React, { Component } from 'react';
+import React from 'react';
import WzAgentSelector from './wz-agent-selector';
-import WzReduxProvider from '../../redux/wz-redux-provider';
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../common/hocs';
-
-export class WzAgentSelectorWrapper extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
+export const WzAgentSelectorWrapper = compose (withErrorBoundary, withReduxProvider)(WzAgentSelector);
\ No newline at end of file
diff --git a/public/components/wz-filter-bar/wz-filter-bar.js b/public/components/wz-filter-bar/wz-filter-bar.js
index 2b0d06332c..ada604ae3c 100644
--- a/public/components/wz-filter-bar/wz-filter-bar.js
+++ b/public/components/wz-filter-bar/wz-filter-bar.js
@@ -13,8 +13,9 @@ import React, { Component } from 'react';
import { EuiComboBox } from '@elastic/eui';
import PropTypes from 'prop-types';
import './wz-filter-bar.scss';
+import { withErrorBoundary } from '../common/hocs';
-export class WzFilterBar extends Component {
+export const WzFilterBar = withErrorBoundary (class WzFilterBar extends Component {
constructor(props) {
super(props);
const { model, selectedOptions } = this.props;
@@ -295,7 +296,7 @@ export class WzFilterBar extends Component {
/>
);
}
-}
+});
WzFilterBar.propTypes = {
clickAction: PropTypes.func,
diff --git a/public/components/wz-menu/wz-menu-wrapper.js b/public/components/wz-menu/wz-menu-wrapper.js
index 92f5ef409d..5d16e61145 100644
--- a/public/components/wz-menu/wz-menu-wrapper.js
+++ b/public/components/wz-menu/wz-menu-wrapper.js
@@ -11,22 +11,10 @@
* Find more information about this on the LICENSE file.
*
*/
-import React, { Component } from 'react';
+import React from 'react';
import WzMenu from './wz-menu';
-import WzReduxProvider from '../../redux/wz-redux-provider';
import './wz-menu.scss';
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../common/hocs';
-export class WzMenuWrapper extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
+export const WzMenuWrapper = compose (withErrorBoundary, withReduxProvider)(WzMenu);
diff --git a/public/controllers/agent/components/agents-table.js b/public/controllers/agent/components/agents-table.js
index 077f4f78e5..1e1432b246 100644
--- a/public/controllers/agent/components/agents-table.js
+++ b/public/controllers/agent/components/agents-table.js
@@ -40,8 +40,9 @@ import { WzSearchBar, filtersToObject } from '../../../components/wz-search-bar'
import { getAgentFilterValues } from '../../../controllers/management/components/management/groups/get-agents-filters-values';
import { WzButtonPermissions } from '../../../components/common/permissions/button';
import { formatUIDate } from '../../../react-services/time-service';
+import { withErrorBoundary } from '../../../components/common/hocs'
-export class AgentsTable extends Component {
+export const AgentsTable = withErrorBoundary (class AgentsTable extends Component {
_isMount = false;
constructor(props) {
super(props);
@@ -1024,7 +1025,7 @@ export class AgentsTable extends Component {
);
}
-}
+});
AgentsTable.propTypes = {
wzReq: PropTypes.func,
diff --git a/public/controllers/agent/components/export-configuration.js b/public/controllers/agent/components/export-configuration.js
index 004b428b6a..40dda2331b 100644
--- a/public/controllers/agent/components/export-configuration.js
+++ b/public/controllers/agent/components/export-configuration.js
@@ -22,8 +22,9 @@ import {
import PropTypes from 'prop-types';
import { UnsupportedComponents } from '../../../utils/components-os-support';
import { WAZUH_AGENTS_OS_TYPE } from '../../../../common/constants';
+import { withErrorBoundary } from '../../../components/common/hocs';
-export class ExportConfiguration extends Component {
+export const ExportConfiguration = withErrorBoundary (class ExportConfiguration extends Component {
constructor(props) {
super(props);
@@ -163,7 +164,7 @@ export class ExportConfiguration extends Component {
);
}
-}
+});
ExportConfiguration.propTypes = {
exportConfiguration: PropTypes.func,
From b0d519c5aec579b04342541e968a17ff92fc0cc5 Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Mon, 14 Jun 2021 15:33:53 +0200
Subject: [PATCH 19/24] Before rebase
---
.../add-modules-data/WzSampleDataWrapper.js | 4 +-
.../common/modules/discover/discover.tsx | 3 +-
.../welcome/management-welcome-wrapper.js | 19 ++-----
.../wz-agent-selector-wrapper.js | 1 -
.../configuration/configuration-main.js | 52 +++++++------------
.../management/management-provider.js | 24 +++------
6 files changed, 31 insertions(+), 72 deletions(-)
diff --git a/public/components/add-modules-data/WzSampleDataWrapper.js b/public/components/add-modules-data/WzSampleDataWrapper.js
index d3c6331863..7f00da1c50 100644
--- a/public/components/add-modules-data/WzSampleDataWrapper.js
+++ b/public/components/add-modules-data/WzSampleDataWrapper.js
@@ -62,9 +62,7 @@ export class WzSampleDataProvider extends Component {
-
-
-
+
diff --git a/public/components/common/modules/discover/discover.tsx b/public/components/common/modules/discover/discover.tsx
index 0d99e5d902..868ccfb3d3 100644
--- a/public/components/common/modules/discover/discover.tsx
+++ b/public/components/common/modules/discover/discover.tsx
@@ -21,7 +21,7 @@ import { WazuhConfig } from '../../../../react-services/wazuh-config';
import { formatUIDate } from '../../../../react-services/time-service';
import { KbnSearchBar } from '../../../kbn-search-bar';
import { FlyoutTechnique } from '../../../../components/overview/mitre/components/techniques/components/flyout-technique';
-import { withReduxProvider } from '../../../common/hocs';
+import { withErrorBoundary, withReduxProvider } from '../../../common/hocs';
import { connect } from 'react-redux';
import { compose } from 'redux';
import _ from 'lodash';
@@ -57,6 +57,7 @@ const mapStateToProps = state => ({
});
export const Discover = compose(
+ withErrorBoundary,
withReduxProvider,
connect(mapStateToProps)
)(class Discover extends Component {
diff --git a/public/components/common/welcome/management-welcome-wrapper.js b/public/components/common/welcome/management-welcome-wrapper.js
index bb2073a578..0652ada40b 100644
--- a/public/components/common/welcome/management-welcome-wrapper.js
+++ b/public/components/common/welcome/management-welcome-wrapper.js
@@ -12,22 +12,9 @@
*
* DELETE THIS WRAPPER WHEN WELCOME SCREEN WAS NOT BE CALLED FROM ANGULARJS
*/
-import React, { Component } from 'react';
import ManagementWelcome from './management-welcome';
-import WzReduxProvider from '../../../redux/wz-redux-provider';
import './welcome.scss';
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../hocs';
-export class ManagementWelcomeWrapper extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
+export const ManagementWelcomeWrapper = compose (withErrorBoundary,withReduxProvider)(ManagementWelcome)
diff --git a/public/components/wz-agent-selector/wz-agent-selector-wrapper.js b/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
index fcd52db577..9bef47cc22 100644
--- a/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
+++ b/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
@@ -11,7 +11,6 @@
* Find more information about this on the LICENSE file.
*
*/
-import React from 'react';
import WzAgentSelector from './wz-agent-selector';
import { compose } from 'redux';
import { withErrorBoundary, withReduxProvider } from '../common/hocs';
diff --git a/public/controllers/management/components/management/configuration/configuration-main.js b/public/controllers/management/components/management/configuration/configuration-main.js
index 6a4980a58c..b5993a92a8 100644
--- a/public/controllers/management/components/management/configuration/configuration-main.js
+++ b/public/controllers/management/components/management/configuration/configuration-main.js
@@ -10,51 +10,37 @@
* Find more information about this on the LICENSE file.
*/
-import React, { Component } from 'react';
-import WzReduxProvider from '../../../../../redux/wz-redux-provider';
import WzConfigurationSwitch from './configuration-switch';
-import { updateGlobalBreadcrumb } from '../../../../../redux/actions/globalBreadcrumbActions';
-import store from '../../../../../redux/store';
+import {
+ withErrorBoundary,
+ withGlobalBreadcrumb,
+ withReduxProvider,
+} from '../../../../../components/common/hocs';
+import { compose } from 'redux'
-class WzConfigurationMain extends Component {
- constructor(props) {
- super(props);
- }
-
- setGlobalBreadcrumb() {
+export default compose(
+ withErrorBoundary,
+ withReduxProvider,
+ withGlobalBreadcrumb((props) => {
let breadcrumb = false;
- if (this.props.agent.id === '000') {
+ if (props.agent.id === '000') {
breadcrumb = [
{ text: '' },
{ text: 'Management', href: '/app/wazuh#/manager' },
- { text: 'Configuration' }
+ { text: 'Configuration' },
];
} else {
breadcrumb = [
{ text: '' },
{
text: 'Agents',
- href: '#/agents-preview'
+ href: '#/agents-preview',
},
- { agent: this.props.agent },
- { text: 'Configuration' }
+ { agent: props.agent },
+ { text: 'Configuration' },
];
}
- store.dispatch(updateGlobalBreadcrumb(breadcrumb));
- $('#breadcrumbNoTitle').attr("title","");
- }
-
- async componentDidMount() {
- this.setGlobalBreadcrumb();
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
-
-export default WzConfigurationMain;
+ $('#breadcrumbNoTitle').attr('title', '');
+ return breadcrumb;
+ })
+)(WzConfigurationSwitch);
diff --git a/public/controllers/management/components/management/management-provider.js b/public/controllers/management/components/management/management-provider.js
index e370f80015..6d2dbcf586 100644
--- a/public/controllers/management/components/management/management-provider.js
+++ b/public/controllers/management/components/management/management-provider.js
@@ -1,21 +1,9 @@
-import React, { Component } from 'react';
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../../../../components/common/hocs';
// Redux
-import store from '../../../../redux/store';
-import WzReduxProvider from '../../../../redux/wz-redux-provider';
import WzManagementMain from '../management/management-main';
-export default class WzManagement extends Component {
- constructor(props) {
- super(props);
- this.state = {};
- this.store = store;
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
+export default compose(
+ withErrorBoundary,
+ withReduxProvider
+)(WzManagementMain);
\ No newline at end of file
From e4e73eeae79ed6b4f6c224d99b657c2d631848a6 Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Mon, 14 Jun 2021 16:30:30 +0200
Subject: [PATCH 20/24] rebase 4.3-7.10
---
.../error-boundary.test.tsx.snap | 82 ++++++-------
.../error-boundary/error-boundary.test.tsx | 24 +---
.../common/error-boundary/error-boundary.tsx | 111 ++++++++----------
.../with-error-boundary.test.tsx.snap | 84 ++++++-------
.../with-error-boundary.test.tsx | 11 +-
5 files changed, 133 insertions(+), 179 deletions(-)
diff --git a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
index 0c0bd88dd0..36bcd994ea 100644
--- a/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
+++ b/public/components/common/error-boundary/__snapshots__/error-boundary.test.tsx.snap
@@ -1,8 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`ErrorBoundary component renders correctly to match the snapshot 1`] = `
+exports[`ErrorBoundary component renders correctly and check snapshot 1`] = `
-
-
-
- Error: I crashed! I crash very hard
-
-
-
-
+ "componentStack": "
in ComponentWithError
in ErrorBoundary (created by WrapperComponent)
- in WrapperComponent
-
-
-
+ in WrapperComponent",
+ }
+ }
+ errorTitle={[Error: I crashed!]}
+ style={null}
+ />
}
iconType="faceSad"
title={
@@ -114,40 +97,49 @@ exports[`ErrorBoundary component renders correctly to match the snapshot 1`] = `
-
-
-
- Error: I crashed! I crash very hard
-
-
-
+
+ Error: I crashed!
+
in ComponentWithError
in ErrorBoundary (created by WrapperComponent)
in WrapperComponent
-
-
-
+
+
+
-
+
`;
diff --git a/public/components/common/error-boundary/error-boundary.test.tsx b/public/components/common/error-boundary/error-boundary.test.tsx
index cd5ca53a33..a96db0b6e5 100644
--- a/public/components/common/error-boundary/error-boundary.test.tsx
+++ b/public/components/common/error-boundary/error-boundary.test.tsx
@@ -1,17 +1,3 @@
-/*
- * Wazuh app - React test for ErrorBoundary component.
- *
- * Copyright (C) 2015-2021 Wazuh, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Find more information about this on the LICENSE file.
- *
- */
-
import React from 'react';
import { mount } from 'enzyme';
import ErrorBoundary from './error-boundary';
@@ -20,11 +6,11 @@ jest.mock('loglevel');
describe('ErrorBoundary component', () => {
const ComponentWithError = () => {
- throw new Error('I crashed! I crash very hard');
+ throw new Error('I crashed!');
return <>>;
};
- it('renders correctly to match the snapshot', () => {
+ it('renders correctly and check snapshot', () => {
const wrapper = mount(
@@ -40,12 +26,6 @@ describe('ErrorBoundary component', () => {
);
-
- expect(wrapper.find('EuiTitle').exists()).toBeTruthy();
- expect(wrapper.find('EuiText').exists('details')).toBeTruthy();
expect(wrapper.find('EuiTitle').find('h2').text().trim()).toBe('Something went wrong.');
- expect(wrapper.find('EuiText').find('details').find('span').at(0).text()).toBe(
- 'Error: I crashed! I crash very hard'
- );
});
});
diff --git a/public/components/common/error-boundary/error-boundary.tsx b/public/components/common/error-boundary/error-boundary.tsx
index 395f9f3152..b88c79b85c 100644
--- a/public/components/common/error-boundary/error-boundary.tsx
+++ b/public/components/common/error-boundary/error-boundary.tsx
@@ -1,36 +1,25 @@
/*
- * Wazuh app - React component for catch and handles rendering errors.
- *
- * Copyright (C) 2015-2021 Wazuh, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Find more information about this on the LICENSE file.
- *
- */
+* Wazuh app - React component for catch and handles rendering errors.
+*
+* Copyright (C) 2015-2021 Wazuh, Inc.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* Find more information about this on the LICENSE file.
+*
+*/
import React, { Component } from 'react';
-import loglevel from 'loglevel';
-import { UI_LOGGER_LEVELS } from '../../../../common/constants';
-import {
- UI_ERROR_SEVERITIES,
- UIErrorLog,
- UIErrorSeverity,
- UILogLevel,
-} from '../../../react-services/error-orchestrator/types';
-import { ErrorOrchestratorService } from '../../../react-services';
-import { ErrorComponentPrompt } from '../error-boundary-prompt/error-boundary-prompt';
+import log from 'loglevel';
+import { EuiEmptyPrompt } from '@elastic/eui';
export default class ErrorBoundary extends Component {
- private logger: ErrorOrchestratorService;
constructor(props) {
super(props);
this.state = { errorTitle: null, errorInfo: null, style: null };
- this.context = this.constructor.displayName || this.constructor.name || undefined;
- this.logger = new ErrorOrchestratorService();
}
componentDidCatch = (errorTitle, errorInfo) => catchFunc(errorTitle, errorInfo, this);
@@ -39,47 +28,51 @@ export default class ErrorBoundary extends Component {
const { errorTitle, style, errorInfo }: Readonly = this.state;
if (errorInfo) {
- return ;
+ return ;
}
return this.props.children;
}
}
const catchFunc = (errorTitle, errorInfo, ctx) => {
- try {
- ctx.setState({
- errorTitle: errorTitle,
- errorInfo: errorInfo,
- });
+ ctx.setState({
+ errorTitle: errorTitle,
+ errorInfo: errorInfo,
+ });
- const options: UIErrorLog = {
- context: ctx.context,
- level: UI_LOGGER_LEVELS.WARNING as UILogLevel,
- severity: UI_ERROR_SEVERITIES.UI as UIErrorSeverity,
- display: false,
- store: true,
- error: {
- error: errorTitle.name,
- message: errorTitle.message,
- title: errorTitle.toString(),
- },
- };
+ log.error({ errorTitle, errorInfo });
+};
- ctx.logger.handleError(options);
- } catch (error) {
- const optionsCatch: UIErrorLog = {
- context: ctx.context,
- level: UI_LOGGER_LEVELS.ERROR as UILogLevel,
- severity: UI_ERROR_SEVERITIES.UI as UIErrorSeverity,
- display: false,
- store: true,
- error: {
- error: error,
- message: error?.message || '',
- title: '',
- },
- };
+const ErrorComponent = (props: { errorTitle: any; errorInfo: any; style: any }) => {
+ const styles = {
+ error: {
+ borderTop: '1px solid #777',
+ borderBottom: '1px solid #777',
+ padding: '12px',
+ },
+ };
- ctx.logger.handleError(optionsCatch);
- }
+ return (
+
+
+ {props.errorTitle && props.errorTitle.toString()}
+
+ {props.errorInfo.componentStack}
+
+
+ );
};
+
+const HandleError = (props: { errorTitle: any; errorInfo: any; style: any }) => (
+ Something went wrong.}
+ body={
+
+ }
+ />
+);
diff --git a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
index 24212ec32e..a107118897 100644
--- a/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
+++ b/public/components/common/hocs/error-boundary/__snapshots__/with-error-boundary.test.tsx.snap
@@ -1,9 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`withErrorBoundary hoc implementation renders correctly to match the snapshot 1`] = `
+exports[`withErrorBoundary hoc implementation renders correctly and check snapshot 1`] = `
-
-
-
- Error: I crashed! I crash very hard
-
-
-
-
+ "componentStack": "
in ComponentWithError
in Unknown
in ErrorBoundary
in Unknown (created by WrapperComponent)
- in WrapperComponent
-
-
-
+ in WrapperComponent",
+ }
+ }
+ errorTitle={[Error: I crashed!]}
+ style={null}
+ />
}
iconType="faceSad"
title={
@@ -119,43 +102,54 @@ exports[`withErrorBoundary hoc implementation renders correctly to match the sna
-
-
-
- Error: I crashed! I crash very hard
-
-
-
+
+ Error: I crashed!
+
in ComponentWithError
in Unknown
in ErrorBoundary
in Unknown (created by WrapperComponent)
in WrapperComponent
-
-
-
+
+
+
-
+
`;
diff --git a/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx b/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
index 6b6e7c37c6..abd64b7c07 100644
--- a/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
+++ b/public/components/common/hocs/error-boundary/with-error-boundary.test.tsx
@@ -6,11 +6,11 @@ jest.mock('loglevel');
describe('withErrorBoundary hoc implementation', () => {
const ComponentWithError = () => {
- throw new Error('I crashed! I crash very hard');
+ throw new Error('I crashed!');
return <>>;
- };
+ }
- it('renders correctly to match the snapshot', () => {
+ it('renders correctly and check snapshot', () => {
const ErrorComponentWithHoc = withErrorBoundary(() => );
const wrapper = mount( );
@@ -21,11 +21,6 @@ describe('withErrorBoundary hoc implementation', () => {
const ErrorComponentWithHoc = withErrorBoundary(() => );
const wrapper = mount( );
- expect(wrapper.find('EuiTitle').exists()).toBeTruthy();
- expect(wrapper.find('EuiText').exists('details')).toBeTruthy();
expect(wrapper.find('EuiTitle').find('h2').text().trim()).toBe('Something went wrong.');
- expect(wrapper.find('EuiText').find('details').find('span').at(0).text()).toBe(
- 'Error: I crashed! I crash very hard'
- );
});
});
From d9697bec29933ea96c2f214d9445f2f10612f2fe Mon Sep 17 00:00:00 2001
From: Maximiliano Ibarra
Date: Mon, 7 Jun 2021 16:23:52 -0300
Subject: [PATCH 21/24] Feature/3316 error handler orchestrator (#3327)
* feat(errorBoundary): Added ErrorBoundary HOC and component and added loglevel dependency
* feature(errorBoundary): Moved with the others HOCs.
* feature(errorBoundary): Typo refactor.
* First attempt LoggerService
* Merged error boundary, integrated loggerService.
* changed logger name, create logger-service test file
* Updated CHANGELOG
* Moved to react-services, changed name, traslates comments
* feat(errorBoundary): Removed old integration
* refactor(loggerService): Changed class for function methods.
* test(logger-service): Added basic unit test to logger-service
* refactor(logger-service): Applied new implementation of error-orchestrator service.
* feature(logger-service): PR comments and some refactors.
Co-authored-by: gabiwassan
Co-authored-by: Ibarra Maximiliano
---
CHANGELOG.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ab711cccf7..4c8bac1daf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,7 +15,6 @@ All notable changes to the Wazuh app project will be documented in this file.
- Changed ossec to wazuh in sample-data [#3121](https://github.com/wazuh/wazuh-kibana-app/pull/3121)
- Changed empty fields in FIM tables and `syscheck.value_name` in discovery now show an empty tag for visual clarity [#3279](https://github.com/wazuh/wazuh-kibana-app/pull/3279)
-
## Wazuh v4.2.0 - Kibana 7.10.2 , 7.11.2 - Revision 4201
### Added
From 1706f5664393cf2672ff32d302d7b815af59550d Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Mon, 14 Jun 2021 17:52:31 +0200
Subject: [PATCH 22/24] Final implementations
---
.../agents-current-section-wrapper.tsx | 20 ++++---------------
.../overview-current-section-wrapper.tsx | 20 ++++---------------
.../components/common/permissions/prompt.tsx | 13 +++++-------
.../common/welcome/overview-welcome.js | 5 +++--
.../components/health-check/health-check.tsx | 5 +++--
.../management/cluster/node-list.tsx | 5 +++--
.../groups/multiple-agent-selector.tsx | 5 +++--
public/components/overview/mitre/mitre.tsx | 1 -
public/components/security/main.tsx | 3 ++-
.../overview/components/requirement-card.js | 5 +++--
.../overview/components/select-agent.js | 5 +++--
.../controllers/overview/components/stats.js | 5 +++--
.../wz-logtest/components/logtest.tsx | 3 ++-
13 files changed, 38 insertions(+), 57 deletions(-)
diff --git a/public/components/common/modules/agents-current-section-wrapper.tsx b/public/components/common/modules/agents-current-section-wrapper.tsx
index cb5f5921c1..1c9b46700d 100644
--- a/public/components/common/modules/agents-current-section-wrapper.tsx
+++ b/public/components/common/modules/agents-current-section-wrapper.tsx
@@ -10,20 +10,8 @@
*
* Find more information about this on the LICENSE file.
*/
-import React, { Component } from 'react';
-import WzReduxProvider from '../../../redux/wz-redux-provider';
-import WzCurrentAgentsSection from './agents-current-section'
+import WzCurrentAgentsSection from './agents-current-section';
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../hocs';
-export class WzCurrentAgentsSectionWrapper extends Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
\ No newline at end of file
+export const WzCurrentAgentsSectionWrapper = compose (withErrorBoundary, withReduxProvider) (WzCurrentAgentsSection);
diff --git a/public/components/common/modules/overview-current-section-wrapper.tsx b/public/components/common/modules/overview-current-section-wrapper.tsx
index e3f09aa96a..103493d686 100644
--- a/public/components/common/modules/overview-current-section-wrapper.tsx
+++ b/public/components/common/modules/overview-current-section-wrapper.tsx
@@ -10,20 +10,8 @@
*
* Find more information about this on the LICENSE file.
*/
-import React, { Component } from 'react';
-import WzReduxProvider from '../../../redux/wz-redux-provider';
-import WzCurrentOverviewSection from './overview-current-section'
+import { compose } from 'redux';
+import { withErrorBoundary, withReduxProvider } from '../hocs';
+import WzCurrentOverviewSection from './overview-current-section';
-export class WzCurrentOverviewSectionWrapper extends Component {
- constructor(props) {
- super(props);
- }
-
- render() {
- return (
-
-
-
- );
- }
-}
\ No newline at end of file
+export const WzCurrentOverviewSectionWrapper = compose (withErrorBoundary, withReduxProvider) (WzCurrentOverviewSection);
diff --git a/public/components/common/permissions/prompt.tsx b/public/components/common/permissions/prompt.tsx
index 4203c90e4c..4ef609b54f 100644
--- a/public/components/common/permissions/prompt.tsx
+++ b/public/components/common/permissions/prompt.tsx
@@ -16,6 +16,7 @@ import { useUserRolesRequirements } from '../hooks/useUserRoles';
import { EuiEmptyPrompt, EuiSpacer, EuiPanel } from '@elastic/eui';
import { TUserPermissions, TUserPermissionsFunction, TUserRoles, TUserRolesFunction } from '../permissions/button';
import { WzPermissionsFormatted } from './format';
+import { withErrorBoundary } from '../hocs';
interface IEmptyPromptNoPermissions{
permissions?: TUserPermissions
@@ -23,8 +24,8 @@ interface IEmptyPromptNoPermissions{
actions?: React.ReactNode
}
-export const WzEmptyPromptNoPermissions = ({permissions, roles, actions}: IEmptyPromptNoPermissions) => {
- const prompt = ( {
+ return You have no permissions}
body={
@@ -44,12 +45,8 @@ export const WzEmptyPromptNoPermissions = ({permissions, roles, actions}: IEmpty
}
actions={actions}
- />)
- return (
- // {prompt}
- prompt
- )
-}
+ />
+});
interface IPromptNoPermissions{
permissions?: TUserPermissions | TUserPermissionsFunction
diff --git a/public/components/common/welcome/overview-welcome.js b/public/components/common/welcome/overview-welcome.js
index 520f888ebe..0f94fd6c4c 100644
--- a/public/components/common/welcome/overview-welcome.js
+++ b/public/components/common/welcome/overview-welcome.js
@@ -31,8 +31,9 @@ import { updateCurrentTab } from '../../../redux/actions/appStateActions';
import store from '../../../redux/store';
import './welcome.scss';
import { WAZUH_MODULES } from '../../../../common/wazuh-modules';
+import { withErrorBoundary } from '../hocs';
-export class OverviewWelcome extends Component {
+export const OverviewWelcome = withErrorBoundary (class OverviewWelcome extends Component {
constructor(props) {
super(props);
this.strtools = new StringsTools();
@@ -186,4 +187,4 @@ export class OverviewWelcome extends Component {
);
}
-}
\ No newline at end of file
+})
\ No newline at end of file
diff --git a/public/components/health-check/health-check.tsx b/public/components/health-check/health-check.tsx
index 53aa528e16..5eae460b61 100644
--- a/public/components/health-check/health-check.tsx
+++ b/public/components/health-check/health-check.tsx
@@ -13,8 +13,9 @@ import { WAZUH_ERROR_DAEMONS_NOT_READY, WAZUH_INDEX_TYPE_STATISTICS, WAZUH_INDEX
import { checkKibanaSettings, checkKibanaSettingsTimeFilter, checkKibanaSettingsMaxBuckets } from './lib';
import store from '../../redux/store';
import { updateWazuhNotReadyYet } from '../../redux/actions/appStateActions.js';
+import { withErrorBoundary } from '../common/hocs';
-export class HealthCheck extends Component {
+export const HealthCheck = withErrorBoundary (class HealthCheck extends Component {
checkPatternCount = 0;
constructor(props) {
super(props);
@@ -502,4 +503,4 @@ export class HealthCheck extends Component {
);
}
-};
+});
diff --git a/public/components/management/cluster/node-list.tsx b/public/components/management/cluster/node-list.tsx
index e57129e691..d383bdf948 100644
--- a/public/components/management/cluster/node-list.tsx
+++ b/public/components/management/cluster/node-list.tsx
@@ -1,8 +1,9 @@
import React, { Component } from 'react';
import { EuiPanel, EuiFlexGroup, EuiFlexItem, EuiToolTip, EuiButtonIcon, EuiTitle, EuiInMemoryTable, EuiFieldSearch } from '@elastic/eui';
import { WzRequest } from '../../../react-services/wz-request';
+import { withErrorBoundary } from '../../common/hocs';
-export class NodeList extends Component {
+export const NodeList = withErrorBoundary (class NodeList extends Component {
constructor(props) {
super(props);
this.state = {
@@ -109,4 +110,4 @@ export class NodeList extends Component {
);
}
-};
+});
diff --git a/public/components/management/groups/multiple-agent-selector.tsx b/public/components/management/groups/multiple-agent-selector.tsx
index 0c73835a04..aab5fde185 100644
--- a/public/components/management/groups/multiple-agent-selector.tsx
+++ b/public/components/management/groups/multiple-agent-selector.tsx
@@ -19,8 +19,9 @@ import { WzRequest } from '../../../react-services/wz-request';
import './multiple-agent-selector.scss'
import $ from 'jquery';
import { WzFieldSearchDelay } from '../../common/search';
+import { withErrorBoundary } from '../../common/hocs';
-export class MultipleAgentSelector extends Component {
+export const MultipleAgentSelector = withErrorBoundary (class MultipleAgentSelector extends Component {
constructor(props) {
super(props);
this.state = {
@@ -672,4 +673,4 @@ export class MultipleAgentSelector extends Component {
);
}
-};
+});
diff --git a/public/components/overview/mitre/mitre.tsx b/public/components/overview/mitre/mitre.tsx
index 897e214449..257955f35f 100644
--- a/public/components/overview/mitre/mitre.tsx
+++ b/public/components/overview/mitre/mitre.tsx
@@ -31,7 +31,6 @@ export interface ITactic {
[key:string]: string[]
}
-
export const Mitre = withErrorBoundary (class Mitre extends Component {
_isMount = false;
timefilter: {
diff --git a/public/components/security/main.tsx b/public/components/security/main.tsx
index 511ac59578..22f6844bb3 100644
--- a/public/components/security/main.tsx
+++ b/public/components/security/main.tsx
@@ -19,7 +19,7 @@ import { API_USER_STATUS_RUN_AS } from '../../../server/lib/cache-api-user-has-r
import { AppState } from '../../react-services/app-state';
import { ErrorHandler } from '../../react-services/error-handler';
import { RolesMapping } from './roles-mapping/roles-mapping';
-import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt } from '../common/hocs';
+import { withReduxProvider, withGlobalBreadcrumb, withUserAuthorizationPrompt, withErrorBoundary } from '../common/hocs';
import { compose } from 'redux';
import { WAZUH_ROLE_ADMINISTRATOR_NAME } from '../../../common/constants';
import { updateSecuritySection } from '../../redux/actions/securityActions';
@@ -48,6 +48,7 @@ const tabs = [
];
export const WzSecurity = compose(
+ withErrorBoundary,
withReduxProvider,
withGlobalBreadcrumb([{ text: '' }, { text: 'Security' }]),
withUserAuthorizationPrompt(null, [WAZUH_ROLE_ADMINISTRATOR_NAME])
diff --git a/public/controllers/overview/components/requirement-card.js b/public/controllers/overview/components/requirement-card.js
index 0c2818872a..883e405c45 100644
--- a/public/controllers/overview/components/requirement-card.js
+++ b/public/controllers/overview/components/requirement-card.js
@@ -19,8 +19,9 @@ import {
EuiFlexItem,
EuiFlexGroup
} from '@elastic/eui';
+import { withErrorBoundary } from '../../../components/common/hocs';
-export class RequirementCard extends Component {
+export const RequirementCard = withErrorBoundary (class RequirementCard extends Component {
constructor(props) {
super(props);
this.state = {
@@ -171,7 +172,7 @@ export class RequirementCard extends Component {
);
}
-}
+});
RequirementCard.propTypes = {
items: PropTypes.array,
diff --git a/public/controllers/overview/components/select-agent.js b/public/controllers/overview/components/select-agent.js
index c5f5b54f6c..3bda19e17d 100644
--- a/public/controllers/overview/components/select-agent.js
+++ b/public/controllers/overview/components/select-agent.js
@@ -26,8 +26,9 @@ import {
// import { WzRequest } from '../../../../react-services/wz-request';
import { WzRequest } from '../../../react-services/wz-request';
+import { withErrorBoundary } from '../../../components/common/hocs';
-export class SelectAgent extends Component {
+export const SelectAgent = withErrorBoundary (class SelectAgent extends Component {
constructor(props) {
super(props);
@@ -274,7 +275,7 @@ export class SelectAgent extends Component {
);
}
-}
+});
SelectAgent.propTypes = {
items: PropTypes.array
diff --git a/public/controllers/overview/components/stats.js b/public/controllers/overview/components/stats.js
index e866c01331..58ce8323d5 100644
--- a/public/controllers/overview/components/stats.js
+++ b/public/controllers/overview/components/stats.js
@@ -13,8 +13,9 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { EuiStat, EuiFlexItem, EuiFlexGroup, EuiPage, EuiToolTip } from '@elastic/eui';
+import { withErrorBoundary } from '../../../components/common/hocs';
-export class Stats extends Component {
+export const Stats = withErrorBoundary (class Stats extends Component {
constructor(props) {
super(props);
@@ -123,7 +124,7 @@ export class Stats extends Component {
);
}
-}
+});
Stats.propTypes = {
total: PropTypes.any,
diff --git a/public/directives/wz-logtest/components/logtest.tsx b/public/directives/wz-logtest/components/logtest.tsx
index c1a7df3676..adf4f91a3a 100644
--- a/public/directives/wz-logtest/components/logtest.tsx
+++ b/public/directives/wz-logtest/components/logtest.tsx
@@ -27,7 +27,7 @@ import {
EuiTitle,
} from '@elastic/eui';
import { WzRequest } from '../../../react-services';
-import { withReduxProvider, withUserAuthorizationPrompt } from '../../../components/common/hocs';
+import { withErrorBoundary, withReduxProvider, withUserAuthorizationPrompt } from '../../../components/common/hocs';
import { compose } from 'redux';
type LogstestProps = {
@@ -38,6 +38,7 @@ type LogstestProps = {
};
export const Logtest = compose(
+ withErrorBoundary,
withReduxProvider,
withUserAuthorizationPrompt([{ action: 'logtest:run', resource: `*:*:*` }])
)((props: LogstestProps) => {
From 0edc654cba4cd6e461d66d988ce9c8217848c1e6 Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Tue, 15 Jun 2021 13:24:05 +0200
Subject: [PATCH 23/24] Fix errors and apply prettier
---
.../components/agents/syscollector/main.tsx | 6 +-
public/components/common/modules/main.tsx | 336 +++++++++---------
.../components/common/permissions/prompt.tsx | 114 +++---
.../common/welcome/agents-welcome.js | 3 +-
.../cluster/cluster-visualization.js | 11 +-
.../wz-agent-selector-wrapper.js | 5 +-
6 files changed, 259 insertions(+), 216 deletions(-)
diff --git a/public/components/agents/syscollector/main.tsx b/public/components/agents/syscollector/main.tsx
index a4d71095b8..958802f450 100644
--- a/public/components/agents/syscollector/main.tsx
+++ b/public/components/agents/syscollector/main.tsx
@@ -14,8 +14,4 @@ import React from 'react';
import { withErrorBoundary } from '../../common/hocs';
import { SyscollectorInventory } from './inventory';
-function MainSyscollectorClass(props) {
- return ;
-}
-
-export const MainSyscollector = withErrorBoundary (MainSyscollectorClass);
+export const MainSyscollector = withErrorBoundary(SyscollectorInventory);
diff --git a/public/components/common/modules/main.tsx b/public/components/common/modules/main.tsx
index b3df090ade..02e7fa9e0d 100644
--- a/public/components/common/modules/main.tsx
+++ b/public/components/common/modules/main.tsx
@@ -30,195 +30,213 @@ import store from '../../../redux/store';
import { compose } from 'redux';
import { withReduxProvider,withErrorBoundary } from '../hocs';
-export const MainModule = compose (withErrorBoundary,withReduxProvider) (class MainModule extends Component {
- constructor(props) {
- super(props);
- this.reportingService = new ReportingService();
- this.state = {
- selectView: false,
- loadingReport: false,
- switchModule: false,
- showAgentInfo: false
- };
- const app = getAngularModule();
- this.$rootScope = app.$injector.get('$rootScope');
- }
-
- async componentDidMount() {
- if (!(ModulesDefaults[this.props.section] || {}).notModule) {
- this.tabs = (ModulesDefaults[this.props.section] || {}).tabs || [{ id: 'dashboard', name: 'Dashboard' }, { id: 'events', name: 'Events' }];
- this.buttons = (ModulesDefaults[this.props.section] || {}).buttons || ['reporting', 'settings'];
+export const MainModule = compose(
+ withErrorBoundary,
+ withReduxProvider
+)(
+ class MainModule extends Component {
+ constructor(props) {
+ super(props);
+ this.reportingService = new ReportingService();
+ this.state = {
+ selectView: false,
+ loadingReport: false,
+ switchModule: false,
+ showAgentInfo: false,
+ };
+ const app = getAngularModule();
+ this.$rootScope = app.$injector.get('$rootScope');
}
- }
- componentWillUnmount() {
- const { filterManager } = getDataPlugin().query;
- if (filterManager.getFilters() && filterManager.getFilters().length) {
- filterManager.removeAll();
+ async componentDidMount() {
+ if (!(ModulesDefaults[this.props.section] || {}).notModule) {
+ this.tabs = (ModulesDefaults[this.props.section] || {}).tabs || [
+ { id: 'dashboard', name: 'Dashboard' },
+ { id: 'events', name: 'Events' },
+ ];
+ this.buttons = (ModulesDefaults[this.props.section] || {}).buttons || [
+ 'reporting',
+ 'settings',
+ ];
+ }
}
- }
- canBeInit(tab) { //checks if the init table can be set
- let canInit = false;
- this.tabs.forEach(element => {
- if (element.id === tab && (!element.onlyAgent || (element.onlyAgent && this.props.agent))) {
- canInit = true;
+ componentWillUnmount() {
+ const { filterManager } = getDataPlugin().query;
+ if (filterManager.getFilters() && filterManager.getFilters().length) {
+ filterManager.removeAll();
}
- });
- return canInit;
- }
-
- renderTabs(agent = false) {
- const { selectView } = this.state;
- if (!agent) {
+ }
+ canBeInit(tab) {
+ //checks if the init table can be set
+ let canInit = false;
+ this.tabs.forEach((element) => {
+ if (element.id === tab && (!element.onlyAgent || (element.onlyAgent && this.props.agent))) {
+ canInit = true;
+ }
+ });
+ return canInit;
}
- return (
-
-
- {this.tabs.map((tab, index) => {
- if (!tab.onlyAgent || (tab.onlyAgent && this.props.agent)) {
- return this.onSelectedTabChanged(tab.id)}
- isSelected={selectView === tab.id}
- key={index}
- >
- {tab.name}
-
- }
- }
- )}
-
-
- );
- }
+ renderTabs(agent = false) {
+ const { selectView } = this.state;
+ if (!agent) {
+ }
+ return (
+
+
+ {this.tabs.map((tab, index) => {
+ if (!tab.onlyAgent || (tab.onlyAgent && this.props.agent)) {
+ return (
+ this.onSelectedTabChanged(tab.id)}
+ isSelected={selectView === tab.id}
+ key={index}
+ >
+ {tab.name}
+
+ );
+ }
+ })}
+
+
+ );
+ }
- startVis2PngByAgent = async () => {
- const agent =
- (this.props.agent || store.getState().appStateReducers.currentAgentData || {}).id || false;
- await this.reportingService.startVis2Png(this.props.section, agent);
- };
+ startVis2PngByAgent = async () => {
+ const agent =
+ (this.props.agent || store.getState().appStateReducers.currentAgentData || {}).id || false;
+ await this.reportingService.startVis2Png(this.props.section, agent);
+ };
- async startReport() {
- try {
- this.setState({ loadingReport: true });
- const isDarkModeTheme = getUiSettings().get('theme:darkMode');
- if (isDarkModeTheme) {
- const defaultTextColor = '#DFE5EF';
- try {
- $('.euiButtonEmpty__text').css('color', 'black');
+ async startReport() {
+ try {
+ this.setState({ loadingReport: true });
+ const isDarkModeTheme = getUiSettings().get('theme:darkMode');
+ if (isDarkModeTheme) {
+ const defaultTextColor = '#DFE5EF';
+ try {
+ $('.euiButtonEmpty__text').css('color', 'black');
+ await this.startVis2PngByAgent();
+ $('.euiButtonEmpty__text').css('color', defaultTextColor);
+ } catch (e) {
+ $('.euiButtonEmpty__text').css('color', defaultTextColor);
+ this.setState({ loadingReport: false });
+ }
+ } else {
await this.startVis2PngByAgent();
- $('.euiButtonEmpty__text').css('color', defaultTextColor);
- } catch (e) {
- $('.euiButtonEmpty__text').css('color', defaultTextColor);
- this.setState({ loadingReport: false });
}
- } else {
- await this.startVis2PngByAgent();
+ } finally {
+ this.setState({ loadingReport: false });
}
- } finally {
- this.setState({ loadingReport: false });
}
- }
- renderReportButton() {
- return (
- (this.props.disabledReport &&
-
-
- this.startReport()}>
- Generate report
+ renderReportButton() {
+ return (
+ (this.props.disabledReport && (
+
+
+ this.startReport()}
+ >
+ Generate report
-
-
-
- || (
+
+
+ )) || (
this.startReport()}>
+ onClick={async () => this.startReport()}
+ >
Generate report
- ))
- );
- }
+
+ )
+ );
+ }
- renderDashboardButton() {
- const href = `#/overview?tab=${this.props.section}&agentId=${this.props.agent.id}`
- return (
-
- this.onSelectedTabChanged('dashboard')}>
- Dashboard
+ renderDashboardButton() {
+ const href = `#/overview?tab=${this.props.section}&agentId=${this.props.agent.id}`;
+ return (
+
+ this.onSelectedTabChanged('dashboard')}
+ >
+ Dashboard
-
- );
- }
+
+ );
+ }
- renderSettingsButton() {
- return (
-
- this.onSelectedTabChanged('settings')}>
- Configuration
+ renderSettingsButton() {
+ return (
+
+ this.onSelectedTabChanged('settings')}
+ >
+ Configuration
-
- );
- }
+
+ );
+ }
- loadSection(id) {
- this.setState({ selectView: id });
- }
+ loadSection(id) {
+ this.setState({ selectView: id });
+ }
- onSelectedTabChanged(id) {
- if (id !== this.state.selectView) {
- if (id === 'events' || id === 'dashboard' || id === 'inventory') {
- this.$rootScope.moduleDiscoverReady = false;
- if (this.props.switchSubTab) this.props.switchSubTab(id === 'events' ? 'discover' : id === 'inventory' ? 'inventory' : 'panels')
- window.location.href = window.location.href.replace(
- new RegExp("tabView=" + "[^\&]*"),
- `tabView=${id === 'events' ? 'discover' : id === 'inventory' ? 'inventory' : 'panels'}`);
- this.afterLoad = id;
- this.loadSection('loader');
- } else {
- this.loadSection(id === 'panels' ? 'dashboard' : id === 'discover' ? 'events' : id);
+ onSelectedTabChanged(id) {
+ if (id !== this.state.selectView) {
+ if (id === 'events' || id === 'dashboard' || id === 'inventory') {
+ this.$rootScope.moduleDiscoverReady = false;
+ if (this.props.switchSubTab)
+ this.props.switchSubTab(
+ id === 'events' ? 'discover' : id === 'inventory' ? 'inventory' : 'panels'
+ );
+ window.location.href = window.location.href.replace(
+ new RegExp('tabView=' + '[^&]*'),
+ `tabView=${id === 'events' ? 'discover' : id === 'inventory' ? 'inventory' : 'panels'}`
+ );
+ this.afterLoad = id;
+ this.loadSection('loader');
+ } else {
+ this.loadSection(id === 'panels' ? 'dashboard' : id === 'discover' ? 'events' : id);
+ }
}
}
- }
- render() {
- const { agent } = this.props;
- const { selectView } = this.state;
- const mainProps = {
- selectView,
- afterLoad: this.afterLoad,
- buttons: this.buttons,
- tabs: this.tabs,
- renderTabs: () => this.renderTabs(),
- renderReportButton: () => this.renderReportButton(),
- renderDashboardButton: () => this.renderDashboardButton(),
- renderSettingsButton: () => this.renderSettingsButton(),
- loadSection: (id) => this.loadSection(id),
- onSelectedTabChanged: (id) => this.onSelectedTabChanged(id)
+ render() {
+ const { agent } = this.props;
+ const { selectView } = this.state;
+ const mainProps = {
+ selectView,
+ afterLoad: this.afterLoad,
+ buttons: this.buttons,
+ tabs: this.tabs,
+ renderTabs: () => this.renderTabs(),
+ renderReportButton: () => this.renderReportButton(),
+ renderDashboardButton: () => this.renderDashboardButton(),
+ renderSettingsButton: () => this.renderSettingsButton(),
+ loadSection: (id) => this.loadSection(id),
+ onSelectedTabChanged: (id) => this.onSelectedTabChanged(id),
+ };
+ return (
+ <>
+ {(agent && ) ||
+ (this.props.section && this.props.section !== 'welcome' && (
+
+ ))}
+ >
+ );
}
- return (
- <>
- {agent &&
-
- || ((this.props.section && this.props.section !== 'welcome') &&
- )
- }
- >
- );
}
-})
+);
diff --git a/public/components/common/permissions/prompt.tsx b/public/components/common/permissions/prompt.tsx
index 4ef609b54f..37e5747059 100644
--- a/public/components/common/permissions/prompt.tsx
+++ b/public/components/common/permissions/prompt.tsx
@@ -11,53 +11,79 @@
*/
import React, { Fragment } from 'react';
-import { useUserPermissionsRequirements } from '../hooks/useUserPermissions';
-import { useUserRolesRequirements } from '../hooks/useUserRoles';
-import { EuiEmptyPrompt, EuiSpacer, EuiPanel } from '@elastic/eui';
-import { TUserPermissions, TUserPermissionsFunction, TUserRoles, TUserRolesFunction } from '../permissions/button';
+import { useUserPermissionsRequirements, useUserRolesRequirements } from '../hooks';
+import { EuiEmptyPrompt, EuiSpacer } from '@elastic/eui';
+import {
+ TUserPermissions,
+ TUserPermissionsFunction,
+ TUserRoles,
+ TUserRolesFunction,
+} from '../permissions/button';
import { WzPermissionsFormatted } from './format';
-import { withErrorBoundary } from '../hocs';
+import { withErrorBoundary } from '../hocs/error-boundary/with-error-boundary';
-interface IEmptyPromptNoPermissions{
- permissions?: TUserPermissions
- roles?: TUserRoles
- actions?: React.ReactNode
+interface IEmptyPromptNoPermissions {
+ permissions?: TUserPermissions;
+ roles?: TUserRoles;
+ actions?: React.ReactNode;
}
-
-export const WzEmptyPromptNoPermissions = withErrorBoundary (({permissions, roles, actions}: IEmptyPromptNoPermissions) => {
- return You have no permissions}
- body={
-
- {permissions && (
-
- This section requires the {permissions.length > 1 ? 'permissions' : 'permission'}:
- {WzPermissionsFormatted(permissions)}
-
- )}
- {permissions && roles && ( )}
- {roles && (
-
- This section requires {roles.map(role => ({role} )).reduce((accum, cur) => [accum, ', ', cur])} {roles.length > 1 ? 'roles' : 'role'}
-
- )}
-
- }
- actions={actions}
- />
-});
-
-interface IPromptNoPermissions{
- permissions?: TUserPermissions | TUserPermissionsFunction
- roles?: TUserRoles | TUserRolesFunction
- children?: React.ReactNode
- rest?: any
+export const WzEmptyPromptNoPermissions = withErrorBoundary(
+ ({ permissions, roles, actions }: IEmptyPromptNoPermissions) => {
+ return (
+ You have no permissions}
+ body={
+
+ {permissions && (
+
+ This section requires the {permissions.length > 1 ? 'permissions' : 'permission'}:
+ {WzPermissionsFormatted(permissions)}
+
+ )}
+ {permissions && roles && }
+ {roles && (
+
+ This section requires{' '}
+ {roles
+ .map((role) => {role} )
+ .reduce((accum, cur) => [accum, ', ', cur])}{' '}
+ {roles.length > 1 ? 'roles' : 'role'}
+
+ )}
+
+ }
+ actions={actions}
+ />
+ );
+ }
+);
+interface IPromptNoPermissions {
+ permissions?: TUserPermissions | TUserPermissionsFunction;
+ roles?: TUserRoles | TUserRolesFunction;
+ children?: React.ReactNode;
+ rest?: any;
}
-export const WzPromptPermissions = ({permissions = null, roles = null, children, ...rest} : IPromptNoPermissions) => {
- const [userPermissionRequirements, userPermissions] = useUserPermissionsRequirements(typeof permissions === 'function' ? permissions(rest) : permissions);
- const [userRolesRequirements, userRoles] = useUserRolesRequirements(typeof roles === 'function' ? roles(rest) : roles);
+export const WzPromptPermissions = ({
+ permissions = null,
+ roles = null,
+ children,
+ ...rest
+}: IPromptNoPermissions) => {
+ const [userPermissionRequirements, userPermissions] = useUserPermissionsRequirements(
+ typeof permissions === 'function' ? permissions(rest) : permissions
+ );
+ const [userRolesRequirements, userRoles] = useUserRolesRequirements(
+ typeof roles === 'function' ? roles(rest) : roles
+ );
- return (userPermissionRequirements || userRolesRequirements) ? : children;
-}
\ No newline at end of file
+ return userPermissionRequirements || userRolesRequirements ? (
+
+ ) : (
+ children
+ );
+};
diff --git a/public/components/common/welcome/agents-welcome.js b/public/components/common/welcome/agents-welcome.js
index ac768905dc..044d83aa45 100644
--- a/public/components/common/welcome/agents-welcome.js
+++ b/public/components/common/welcome/agents-welcome.js
@@ -327,8 +327,7 @@ export const AgentsWelcome = withErrorBoundary (class AgentsWelcome extends Comp
- );withErrorBoundary
-
+ );
}
buildTabCard(tab, icon) {
diff --git a/public/components/management/cluster/cluster-visualization.js b/public/components/management/cluster/cluster-visualization.js
index 231d77db56..7a961cf826 100644
--- a/public/components/management/cluster/cluster-visualization.js
+++ b/public/components/management/cluster/cluster-visualization.js
@@ -1,14 +1,15 @@
import React from 'react';
import KibanaVis from '../../../kibana-integrations/kibana-vis';
import { withErrorBoundary, withReduxProvider } from '../../../components/common/hocs';
-import {compose} from 'redux'
+import { compose } from 'redux';
-function KibanaVisClass(props) {
+export const KibanaVisWrapper = compose(
+ withErrorBoundary,
+ withReduxProvider
+)((props) => {
return (
);
-}
-
-export const KibanaVisWrapper = compose(withErrorBoundary, withReduxProvider)(KibanaVisClass);
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/public/components/wz-agent-selector/wz-agent-selector-wrapper.js b/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
index 9bef47cc22..290e54efdf 100644
--- a/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
+++ b/public/components/wz-agent-selector/wz-agent-selector-wrapper.js
@@ -15,4 +15,7 @@ import WzAgentSelector from './wz-agent-selector';
import { compose } from 'redux';
import { withErrorBoundary, withReduxProvider } from '../common/hocs';
-export const WzAgentSelectorWrapper = compose (withErrorBoundary, withReduxProvider)(WzAgentSelector);
\ No newline at end of file
+export const WzAgentSelectorWrapper = compose(
+ withErrorBoundary,
+ withReduxProvider
+)(WzAgentSelector);
\ No newline at end of file
From f227ee35b9079567ad25eff9a6992ee9d77ea8cc Mon Sep 17 00:00:00 2001
From: pablomarga
Date: Tue, 15 Jun 2021 14:39:56 +0200
Subject: [PATCH 24/24] Added changelog
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c8bac1daf..6dae2bc5b8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,7 @@ All notable changes to the Wazuh app project will be documented in this file.
- Added new endpoint service to collect the frontend logs into a file [#3324](https://github.com/wazuh/wazuh-kibana-app/pull/3324)
- Added new error handler to be responsible for the error orchestration [#3327](https://github.com/wazuh/wazuh-kibana-app/pull/3327)
- Added `Error Boundary` HOC and Component to handle render errors. [#3321](https://github.com/wazuh/wazuh-kibana-app/pull/3321)
+- Implemented `Error Boundary` HOC in each main react-component. [#3367](https://github.com/wazuh/wazuh-kibana-app/pull/3367)
### Changed