Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add frontend state service #7037

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c289b6b
feat(state): create state core service
Desvelao Sep 30, 2024
4328609
chore: remove unused methods and no-effect functions
Desvelao Sep 30, 2024
bf5a9ab
feat(state): add tests
Desvelao Sep 30, 2024
f2e54f6
feat(state): wrap the subscrition handler to allow they can unsubscri…
Desvelao Oct 1, 2024
ffea2e3
Merge branch 'master' of https://github.com/wazuh/wazuh-kibana-app in…
Desvelao Nov 27, 2024
f11467b
fix(state): enhance README.md examples
Desvelao Nov 27, 2024
d5dd4bb
Apply suggestions from code review
Desvelao Nov 27, 2024
05cfa5e
fix(state): typos
Desvelao Nov 27, 2024
722dfef
Merge branch 'enhancement/6959-extract-common-services-frontend-state…
Desvelao Nov 27, 2024
d86df0c
fix(state): minor fixes
Desvelao Nov 27, 2024
b883a65
fix(state): unsubscribe from state container
Desvelao Nov 27, 2024
01fc56f
fix: upgrade react-cookie dependency to remove vulnerability in package
Desvelao Nov 27, 2024
f6e7854
Apply suggestions from code review
Desvelao Nov 27, 2024
65d7a4c
Merge branch 'master' of https://github.com/wazuh/wazuh-kibana-app in…
Desvelao Dec 11, 2024
9a2dafa
fix(state): lint and prettier
Desvelao Dec 12, 2024
d45a4c3
fix(state): lint and prettier
Desvelao Dec 12, 2024
ad1f0d2
fix(core): dependencies
Desvelao Dec 12, 2024
f03fca3
fix(settings): improve types for SettingsComponent props
guidomodarelli Dec 12, 2024
56395ee
fix(eslint): disable unicorn/no-static-only-class rule
guidomodarelli Dec 12, 2024
93eedab
fix(types): improve type annotations for decoratorCheckIsEnabled call…
guidomodarelli Dec 12, 2024
cc66b04
fix(eslint): remove redundant eslint directive for unicorn/no-static-…
guidomodarelli Dec 12, 2024
f6c2ff4
fix(types): set default type parameters for State and LifecycleServic…
guidomodarelli Dec 12, 2024
3fde6b8
fix(eslint): remove unnecessary eslint directive for unicorn/no-stati…
guidomodarelli Dec 12, 2024
254fcdd
fix(eslint): add consistent-function-scoping rule to enforce function…
guidomodarelli Dec 12, 2024
c8bc275
fix(eslint): replace Promise.reject with throw for error handling in …
guidomodarelli Dec 12, 2024
ee2a167
fix(eslint): update type definition for WrappedComponent in createHOC…
guidomodarelli Dec 12, 2024
1f1caa9
fix(types): update remove method type in StateContainer for improved …
guidomodarelli Dec 12, 2024
7a2c1f2
fix(types): update createHooks to handle optional updater$ for better…
guidomodarelli Dec 12, 2024
5a9c0de
fix(logging): improve error handling by explicitly casting error to E…
guidomodarelli Dec 12, 2024
ecd91a9
fix(logging): enhance error logging by explicitly casting to Error fo…
guidomodarelli Dec 12, 2024
e29fb5b
fix(types): improve typing for set method and enhance error logging c…
guidomodarelli Dec 12, 2024
9da059b
Merge branch 'master' into enhancement/6959-extract-common-services-f…
guidomodarelli Dec 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ jest.mock('../components/check-result', () => ({
}));

jest.mock('../../../react-services', () => ({
AppState: {
setPatternSelector: () => {},
},
AppState: {},
ErrorHandler: {
handle: error => error,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ function HealthCheckComponent() {
useEffect(() => {
if (appConfig.isReady && !checksInitiated.current) {
checksInitiated.current = true;
AppState.setPatternSelector(appConfig.data['ip.selector']);
}
}, [appConfig]);

Expand Down
2 changes: 0 additions & 2 deletions plugins/main/public/components/settings/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,6 @@ class SettingsComponent extends React.Component {
};

this.setState({ load: false });
// TODO: this seems not to be used to display or not the index pattern selector
AppState.setPatternSelector(this.props.configurationIPSelector);
const pattern = AppState.getCurrentPattern();
Desvelao marked this conversation as resolved.
Show resolved Hide resolved

this.getCurrentAPIIndex();
Expand Down
80 changes: 0 additions & 80 deletions plugins/main/public/react-services/app-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,59 +79,6 @@ export class AppState {
}
}

/**
* Set a new value to the 'createdAt' cookie
* @param {*} date
*/
static setCreatedAt(date) {
try {
const createdAt = encodeURI(date);
const exp = new Date();
exp.setDate(exp.getDate() + 365);
getCookies().set('createdAt', createdAt, {
expires: exp,
});
} catch (error) {
const options = {
context: `${AppState.name}.setCreatedAt`,
level: UI_LOGGER_LEVELS.ERROR,
severity: UI_ERROR_SEVERITIES.UI,
error: {
error: error,
message: error.message || error,
title: `${error.name}: Error set createdAt date`,
},
};
getErrorOrchestrator().handleError(options);
throw error;
}
}

/**
* Get 'createdAt' value
*/
static getCreatedAt() {
try {
const createdAt = getCookies().get('createdAt')
? decodeURI(getCookies().get('createdAt'))
: false;
return createdAt ? createdAt : false;
} catch (error) {
const options = {
context: `${AppState.name}.getCreatedAt`,
level: UI_LOGGER_LEVELS.ERROR,
severity: UI_ERROR_SEVERITIES.UI,
error: {
error: error,
message: error.message || error,
title: `${error.name}: Error get createdAt date`,
},
};
getErrorOrchestrator().handleError(options);
throw error;
}
}

/**
* Get 'API' value
*/
Expand Down Expand Up @@ -190,33 +137,6 @@ export class AppState {
}
}

/**
* Get 'APISelector' value
*/
static getAPISelector() {
return getCookies().get('APISelector')
? decodeURI(getCookies().get('APISelector')) == 'true'
: false;
}

/**
* Get 'patternSelector' value
*/
static getPatternSelector() {
return getCookies().get('patternSelector')
? decodeURI(getCookies().get('patternSelector')) == 'true'
: false;
}

/**
* Set a new value to the 'patternSelector' cookie
* @param {*} value
*/
static setPatternSelector(value) {
const encodedPattern = encodeURI(value);
getCookies().set('patternSelector', encodedPattern, {});
}

/**
* Set a new value to the 'currentPattern' cookie
* @param {*} newPattern
Expand Down
52 changes: 29 additions & 23 deletions plugins/main/public/react-services/wz-api-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,15 @@ export class ApiCheck {
const url = getHttp().basePath.prepend('/api/check-stored-api');
const options = {
method: 'POST',
headers: { ...PLUGIN_PLATFORM_REQUEST_HEADERS, 'content-type': 'application/json' },
headers: {
...PLUGIN_PLATFORM_REQUEST_HEADERS,
'content-type': 'application/json',
},
url: url,
data: payload,
timeout: timeout || 20000
timeout: timeout || 20000,
};

if (Object.keys(configuration).length) {
AppState.setPatternSelector(configuration['ip.selector']);
}

const response = await request(options);

if (response.error) {
Expand All @@ -55,8 +54,10 @@ export class ApiCheck {
return Promise.reject(this.returnErrorInstance(response));
} else {
return (err || {}).message || false
? Promise.reject(this.returnErrorInstance(err,err.message))
: Promise.reject(this.returnErrorInstance(err,err || 'Server did not respond'));
? Promise.reject(this.returnErrorInstance(err, err.message))
: Promise.reject(
this.returnErrorInstance(err, err || 'Server did not respond'),
);
}
}
}
Expand All @@ -65,18 +66,21 @@ export class ApiCheck {
* Check the status of an API entry
* @param {String} apiObject
*/
static async checkApi(apiEntry, forceRefresh=false) {
static async checkApi(apiEntry, forceRefresh = false) {
try {
const wazuhConfig = new WazuhConfig();
const { timeout } = wazuhConfig.getConfig();
const url = getHttp().basePath.prepend('/api/check-api');

const options = {
method: 'POST',
headers: { ...PLUGIN_PLATFORM_REQUEST_HEADERS, 'content-type': 'application/json' },
headers: {
...PLUGIN_PLATFORM_REQUEST_HEADERS,
'content-type': 'application/json',
},
url: url,
data: {...apiEntry, forceRefresh},
timeout: timeout || 20000
data: { ...apiEntry, forceRefresh },
timeout: timeout || 20000,
};

const response = await request(options);
Expand All @@ -92,23 +96,25 @@ export class ApiCheck {
return Promise.reject(this.returnErrorInstance(response));
} else {
return (err || {}).message || false
? Promise.reject(this.returnErrorInstance(err,err.message))
: Promise.reject(this.returnErrorInstance(err,err || 'Server did not respond'));
? Promise.reject(this.returnErrorInstance(err, err.message))
: Promise.reject(
this.returnErrorInstance(err, err || 'Server did not respond'),
);
}
}
}

/**
/**
* Customize message and return an error object
* @param error
* @param message
* @param error
* @param message
* @returns error
*/
static returnErrorInstance(error, message){
if(!error || typeof error === 'string'){
return new Error(message || error);
}
error.message = message
return error
static returnErrorInstance(error, message) {
if (!error || typeof error === 'string') {
return new Error(message || error);
}
error.message = message;
return error;
}
}
3 changes: 2 additions & 1 deletion plugins/wazuh-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
"json2csv": "^4.1.2",
"jwt-decode": "^3.1.2",
"md5": "^2.3.0",
"node-cron": "^3.0.2"
"node-cron": "^3.0.2",
"react-cookie": "^7.2.2"
},
"devDependencies": {
"@testing-library/user-event": "^14.5.0",
Expand Down
48 changes: 45 additions & 3 deletions plugins/wazuh-core/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,24 @@ import {
} from '../common/constants';
import { DashboardSecurity } from './utils/dashboard-security';
import * as hooks from './hooks';
import { CoreState, State } from './services/state';
import { ServerHostClusterInfoStateContainer } from './services/state/containers/server-host-cluster-info';
import { Cookies } from 'react-cookie';
import { ServerHostStateContainer } from './services/state/containers/server-host';
import { DataSourceAlertsStateContainer } from './services/state/containers/data-source-alerts';

export class WazuhCorePlugin
implements Plugin<WazuhCorePluginSetup, WazuhCorePluginStart>
{
runtime: { [key: string]: any } = {
Desvelao marked this conversation as resolved.
Show resolved Hide resolved
state: {},
};
_internal: { [key: string]: any } = {};
Desvelao marked this conversation as resolved.
Show resolved Hide resolved
services: { [key: string]: any } = {};
services: {
[key: string]: any;
dashboardSecurity?: DashboardSecurity;
state?: State;
} = {};
public async setup(core: CoreSetup): Promise<WazuhCorePluginSetup> {
const noop = () => {};
const logger = {
Expand Down Expand Up @@ -46,12 +58,35 @@ export class WazuhCorePlugin

this.services.dashboardSecurity = new DashboardSecurity(logger, core.http);

this.services.state = new CoreState(logger);

this.runtime.state.setup = this.services.state.setup();
const cookiesStore = new Cookies();
this.services.state.register(
'server_host_cluster_info',
new ServerHostClusterInfoStateContainer(logger, { store: cookiesStore }),
);
this.services.state.register(
'server_host',
new ServerHostStateContainer(logger, { store: cookiesStore }),
);
this.services.state.subscribe('server_host', value => {
// TODO: refresh the auth when the server_host data changed and there is value
});
this.services.state.register(
'data_source_alerts',
new DataSourceAlertsStateContainer(logger, { store: cookiesStore }),
);

await this.services.dashboardSecurity.setup();

return {
...this.services,
utils,
API_USER_STATUS_RUN_AS,
hooks: {
...this.runtime.state.setup.hooks,
},
};
}

Expand All @@ -61,14 +96,21 @@ export class WazuhCorePlugin
setUiSettings(core.uiSettings);

await this.services.configuration.start({ http: core.http });
this.services.state.start();

return {
...this.services,
utils,
API_USER_STATUS_RUN_AS,
hooks,
// hooks,
Desvelao marked this conversation as resolved.
Show resolved Hide resolved
hooks: {
...hooks,
...this.runtime.state.setup.hooks,
},
};
}

public stop() {}
public stop() {
this.services.state.stop();
}
}
Loading
Loading