This commit is contained in:
Adri Valle 2019-10-09 12:18:50 +02:00
parent 5f34eff198
commit 7a44233a2c
38 changed files with 717 additions and 484 deletions

View File

@ -15,7 +15,7 @@ import { Initialize } from './server/initialize';
import { WazuhElasticRouter } from './server/routes/wazuh-elastic'; import { WazuhElasticRouter } from './server/routes/wazuh-elastic';
import { Monitoring } from './server/monitoring'; import { Monitoring } from './server/monitoring';
import { WazuhApiRoutes } from './server/routes/wazuh-api'; import { WazuhApiRoutes } from './server/routes/wazuh-api';
import { WazuhHostsRoutes } from './server/routes/wazuh-hosts' import { WazuhHostsRoutes } from './server/routes/wazuh-hosts';
import { WazuhReportingRoutes } from './server/routes/wazuh-reporting'; import { WazuhReportingRoutes } from './server/routes/wazuh-reporting';
import { WazuhUtilsRoutes } from './server/routes/wazuh-utils'; import { WazuhUtilsRoutes } from './server/routes/wazuh-utils';
import { IndexPatternCronJob } from './server/index-pattern-cron-job'; import { IndexPatternCronJob } from './server/index-pattern-cron-job';

View File

@ -93,11 +93,7 @@ app.run(function($rootScope, $route, $location, appState, $window) {
appState.setNavigation({ appState.setNavigation({
reloaded: false, reloaded: false,
discoverPrevious: false, discoverPrevious: false,
discoverSections: [ discoverSections: ['/overview/', '/agents', '/wazuh-dev']
'/overview/',
'/agents',
'/wazuh-dev'
]
}); });
$rootScope.$on('$routeChangeSuccess', () => { $rootScope.$on('$routeChangeSuccess', () => {

View File

@ -45,4 +45,4 @@ app
.value('BasicTable', BasicTable) .value('BasicTable', BasicTable)
.value('Tabs', Tabs) .value('Tabs', Tabs)
.value('EuiSwitch', EuiSwitch) .value('EuiSwitch', EuiSwitch)
.value('EuiSpacer',EuiSpacer); .value('EuiSpacer', EuiSpacer);

View File

@ -297,11 +297,14 @@ export class AgentsPreviewController {
*/ */
async needsPassword() { async needsPassword() {
try { try {
const result = await this.apiReq.request('GET', '/agents/000/config/auth/auth', {}); const result = await this.apiReq.request(
'GET',
'/agents/000/config/auth/auth',
{}
);
const auth = ((result.data || {}).data || {}).auth || {}; const auth = ((result.data || {}).data || {}).auth || {};
const usePassword = auth.use_password === 'yes'; const usePassword = auth.use_password === 'yes';
return usePassword; return usePassword;
} catch (error) { } catch (error) {
return false; return false;
} }
@ -314,7 +317,9 @@ export class AgentsPreviewController {
try { try {
const result = await this.genericReq.request('GET', '/elastic/apis'); const result = await this.genericReq.request('GET', '/elastic/apis');
const entries = result.data || []; const entries = result.data || [];
const host = entries.filter(e => {return e._id == this.api}); const host = entries.filter(e => {
return e._id == this.api;
});
const url = host[0]._source.url; const url = host[0]._source.url;
const numToClean = url.startsWith('https://') ? 8 : 7; const numToClean = url.startsWith('https://') ? 8 : 7;
return url.substr(numToClean); return url.substr(numToClean);

View File

@ -53,11 +53,11 @@ export class RegisterAgent extends Component {
serverAddress: apiAddress, serverAddress: apiAddress,
needsPassword: needsPassword, needsPassword: needsPassword,
wazuhVersion: wazuhVersion wazuhVersion: wazuhVersion
}) });
} catch (error) { } catch (error) {
this.setState({ this.setState({
wazuhVersion: version wazuhVersion: version
}) });
} }
} }
@ -79,11 +79,10 @@ export class RegisterAgent extends Component {
*/ */
cleanSteps(steps) { cleanSteps(steps) {
if (this.state.needsPassword) return steps; if (this.state.needsPassword) return steps;
steps.splice(2,1); steps.splice(2, 1);
return steps; return steps;
} }
render() { render() {
const rpmButton = ( const rpmButton = (
<EuiButtonToggle <EuiButtonToggle
@ -145,10 +144,38 @@ export class RegisterAgent extends Component {
zIndex: '100' zIndex: '100'
}; };
const customTexts = { const customTexts = {
rpmText: `sudo WAZUH_MANAGER_IP='${this.state.serverAddress}'${this.state.needsPassword ? ` WAZUH_PASSWORD='${this.state.wazuhPassword}' ` : ' '}yum install https://packages.wazuh.com/3.x/yum/wazuh-agent-${this.state.wazuhVersion}-1.x86_64.rpm`, rpmText: `sudo WAZUH_MANAGER_IP='${this.state.serverAddress}'${
debText: `curl -so wazuh-agent.deb https://packages.wazuh.com/3.x/apt/pool/main/w/wazuh-agent/wazuh-agent_${this.state.wazuhVersion}-1_amd64.deb && sudo WAZUH_MANAGER_IP='${this.state.serverAddress}'${this.state.needsPassword ? ` WAZUH_PASSWORD='${this.state.wazuhPassword}' ` : ' '} dpkg -i ./wazuh-agent.deb`, this.state.needsPassword
macosText: `curl -so wazuh-agent.pkg https://packages.wazuh.com/3.x/osx/wazuh-agent-${this.state.wazuhVersion}-1.pkg && sudo launchctl setenv WAZUH_MANAGER_IP '${this.state.serverAddress}'${this.state.needsPassword ? ` setenv WAZUH_PASSWORD '${this.state.wazuhPassword}' ` : ' '} && sudo installer -pkg ./wazuh-agent.pkg -target /`, ? ` WAZUH_PASSWORD='${this.state.wazuhPassword}' `
winText: `Invoke-WebRequest -Uri https://packages.wazuh.com/3.x/windows/wazuh-agent-${this.state.wazuhVersion}-1.msi -OutFile wazuh-agent.msi; wazuh-agent.msi /q ADDRESS='${this.state.serverAddress}' AUTHD_SERVER='${this.state.serverAddress}'${this.state.needsPassword ? ` PASSWORD='${this.state.wazuhPassword}' ` : ' '}` : ' '
}yum install https://packages.wazuh.com/3.x/yum/wazuh-agent-${
this.state.wazuhVersion
}-1.x86_64.rpm`,
debText: `curl -so wazuh-agent.deb https://packages.wazuh.com/3.x/apt/pool/main/w/wazuh-agent/wazuh-agent_${
this.state.wazuhVersion
}-1_amd64.deb && sudo WAZUH_MANAGER_IP='${this.state.serverAddress}'${
this.state.needsPassword
? ` WAZUH_PASSWORD='${this.state.wazuhPassword}' `
: ' '
} dpkg -i ./wazuh-agent.deb`,
macosText: `curl -so wazuh-agent.pkg https://packages.wazuh.com/3.x/osx/wazuh-agent-${
this.state.wazuhVersion
}-1.pkg && sudo launchctl setenv WAZUH_MANAGER_IP '${
this.state.serverAddress
}'${
this.state.needsPassword
? ` setenv WAZUH_PASSWORD '${this.state.wazuhPassword}' `
: ' '
} && sudo installer -pkg ./wazuh-agent.pkg -target /`,
winText: `Invoke-WebRequest -Uri https://packages.wazuh.com/3.x/windows/wazuh-agent-${
this.state.wazuhVersion
}-1.msi -OutFile wazuh-agent.msi; wazuh-agent.msi /q ADDRESS='${
this.state.serverAddress
}' AUTHD_SERVER='${this.state.serverAddress}'${
this.state.needsPassword
? ` PASSWORD='${this.state.wazuhPassword}' `
: ' '
}`
}; };
const field = `${this.state.selectedOS}Text`; const field = `${this.state.selectedOS}Text`;
@ -217,7 +244,7 @@ export class RegisterAgent extends Component {
return ( return (
<div> <div>
<EuiPage restrictWidth="1000px" style={{background: "transparent"}} > <EuiPage restrictWidth="1000px" style={{ background: 'transparent' }}>
<EuiPageBody> <EuiPageBody>
<EuiFlexGroup> <EuiFlexGroup>
<EuiFlexItem> <EuiFlexItem>

View File

@ -12,7 +12,15 @@
*/ */
import React, { Component, Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { EuiCodeEditor, EuiCallOut, EuiSpacer, EuiPanel, EuiFlexItem, EuiButton, EuiFlexGroup } from '@elastic/eui'; import {
EuiCodeEditor,
EuiCallOut,
EuiSpacer,
EuiPanel,
EuiFlexItem,
EuiButton,
EuiFlexGroup
} from '@elastic/eui';
import { DynamicHeight } from '../../../utils/dynamic-height'; import { DynamicHeight } from '../../../utils/dynamic-height';
export class TestConfiguration extends Component { export class TestConfiguration extends Component {
@ -27,10 +35,9 @@ export class TestConfiguration extends Component {
} }
onChange = value => { onChange = value => {
this.setState({ configuration : value }); this.setState({ configuration: value });
}; };
validate = async () => { validate = async () => {
this.setState({ this.setState({
validating: true validating: true
@ -43,29 +50,27 @@ export class TestConfiguration extends Component {
}; };
dynamicHeight = () => dynamicHeight = () =>
DynamicHeight.dynamicHeightStatic( DynamicHeight.dynamicHeightStatic(
'.euiCodeEditorWrapper', '.euiCodeEditorWrapper',
this.state.result ? 110 : 110 this.state.result ? 110 : 110
); );
render() { render() {
this.dynamicHeight(); this.dynamicHeight();
return ( return (
<div> <div>
<Fragment> <Fragment>
<EuiSpacer size="m" /> <EuiSpacer size="m" />
<EuiPanel paddingSize="l"> <EuiPanel paddingSize="l">
{this.state.result && ( {this.state.result && (
<div> <div>
<EuiCallOut <EuiCallOut
title="The configuration is valid!" title="The configuration is valid!"
color="success" color="success"
iconType="check" iconType="check"
> ></EuiCallOut>
</EuiCallOut> <EuiSpacer size="m" />
<EuiSpacer size="m" /> </div>
</div>
)} )}
<EuiCodeEditor <EuiCodeEditor
theme="XML" theme="XML"
@ -83,10 +88,9 @@ export class TestConfiguration extends Component {
</EuiPanel> </EuiPanel>
<EuiSpacer size="m" /> <EuiSpacer size="m" />
<EuiFlexGroup justifyContent="spaceBetween"> <EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem grow={false}></EuiFlexItem>
<EuiFlexItem grow={false}> <EuiFlexItem grow={false}>
</EuiFlexItem> <EuiButton
<EuiFlexItem grow={false}>
<EuiButton
isLoading={this.state.validating} isLoading={this.state.validating}
isDisabled={this.state.validating || !this.state.configuration} isDisabled={this.state.validating || !this.state.configuration}
fill fill
@ -98,7 +102,7 @@ export class TestConfiguration extends Component {
</EuiButton> </EuiButton>
</EuiFlexItem> </EuiFlexItem>
</EuiFlexGroup> </EuiFlexGroup>
</Fragment> </Fragment>
</div> </div>
); );
} }

View File

@ -10,7 +10,7 @@
* *
* Find more information about this on the LICENSE file. * Find more information about this on the LICENSE file.
*/ */
import React, { Component,Fragment } from 'react'; import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { import {
EuiCard, EuiCard,

View File

@ -64,7 +64,10 @@ export class CdbListsController {
`${this.currentList.path}/${this.currentList.name}` `${this.currentList.path}/${this.currentList.name}`
); );
let list = stringToObj(data.data.data); let list = stringToObj(data.data.data);
list = Object.keys(list).length === 1 && !Object.keys(list)[0].trim() ? {} : list list =
Object.keys(list).length === 1 && !Object.keys(list)[0].trim()
? {}
: list;
this.currentList.list = list; this.currentList.list = list;
this.viewingDetail = true; this.viewingDetail = true;
this.$scope.$emit('setCurrentList', { currentList: this.currentList }); this.$scope.$emit('setCurrentList', { currentList: this.currentList });
@ -167,7 +170,7 @@ export class CdbListsController {
/** /**
* Refresh the list of cdb lists * Refresh the list of cdb lists
*/ */
refresh(){ refresh() {
this.search(); this.search();
} }

View File

@ -47,7 +47,7 @@ export class UploadFiles extends Component {
onButtonClick() { onButtonClick() {
this.setState({ this.setState({
isPopoverOpen: !this.state.isPopoverOpen, isPopoverOpen: !this.state.isPopoverOpen
}); });
} }
@ -89,7 +89,7 @@ export class UploadFiles extends Component {
} }
}, 100); }, 100);
} }
} catch (error) { } } catch (error) {}
} }
/** /**
@ -103,34 +103,39 @@ export class UploadFiles extends Component {
} }
/** /**
* Renders the result of a file upload * Renders the result of a file upload
*/ */
renderResult(result) { renderResult(result) {
return ( return (
<Fragment> <Fragment>
{!result.uploaded && {(!result.uploaded && (
<EuiCallOut size="s" title={result.file} color="danger" iconType="alert"> <EuiCallOut
<EuiText size="s"
className='list-element-bad' title={result.file}
size='s' color="danger"
>{result.error} iconType="alert"
>
<EuiText className="list-element-bad" size="s">
{result.error}
</EuiText> </EuiText>
</EuiCallOut> </EuiCallOut>
|| )) || (
<EuiCallOut size="s" title={result.file} color="success" iconType="check"> <EuiCallOut
<EuiText size="s"
className='list-element-ok' title={result.file}
size='s' color="success"
> File upload successfully iconType="check"
>
<EuiText className="list-element-ok" size="s">
{' '}
File upload successfully
</EuiText> </EuiText>
</EuiCallOut> </EuiCallOut>
} )}
</Fragment> </Fragment>
); );
} }
/** /**
* Checks the size of the files in order to check if anyone is bigger that the size allowed * Checks the size of the files in order to check if anyone is bigger that the size allowed
*/ */
@ -176,7 +181,6 @@ export class UploadFiles extends Component {
); );
} }
/** /**
* Renders the errors when trying to upload files * Renders the errors when trying to upload files
*/ */
@ -184,32 +188,28 @@ export class UploadFiles extends Component {
return ( return (
<Fragment> <Fragment>
<EuiListGroup flush={true} className="list-of-files-fail"> <EuiListGroup flush={true} className="list-of-files-fail">
{this.state.uploadErrors.map((error, idx) => { // We first show the files that were successfully uploaded {this.state.uploadErrors.map((error, idx) => {
// We first show the files that were successfully uploaded
if (error.uploaded) { if (error.uploaded) {
return ( return (
<EuiFlexItem <EuiFlexItem key={idx} id={error.index}>
key={idx}
id={error.index}>
{this.renderResult(error)} {this.renderResult(error)}
<EuiSpacer size="s" /> <EuiSpacer size="s" />
</EuiFlexItem> </EuiFlexItem>
) );
} }
}) })}
}
{this.state.uploadErrors.map((error, idx) => { {this.state.uploadErrors.map((error, idx) => {
if (!error.uploaded) { // When all successfully uploaded files are shown, then we show the failed files if (!error.uploaded) {
// When all successfully uploaded files are shown, then we show the failed files
return ( return (
<EuiFlexItem <EuiFlexItem key={idx} id={error.index}>
key={idx}
id={error.index}>
{this.renderResult(error)} {this.renderResult(error)}
<EuiSpacer size="s" /> <EuiSpacer size="s" />
</EuiFlexItem> </EuiFlexItem>
) );
} }
}) })}
}
</EuiListGroup> </EuiListGroup>
</Fragment> </Fragment>
); );
@ -237,45 +237,49 @@ export class UploadFiles extends Component {
<EuiTitle size="m"> <EuiTitle size="m">
<h1>{`Upload ${this.props.msg}`}</h1> <h1>{`Upload ${this.props.msg}`}</h1>
</EuiTitle> </EuiTitle>
<EuiFlexItem>{!this.state.uploadErrors && <EuiFlexItem>
<EuiFilePicker {!this.state.uploadErrors && (
id="filePicker" <EuiFilePicker
multiple id="filePicker"
compressed={false} multiple
initialPromptText={`Select or drag and drop your ${this.props.msg} files here`} compressed={false}
className="no-max-width" initialPromptText={`Select or drag and drop your ${this.props.msg} files here`}
onChange={files => { className="no-max-width"
this.onChange(files); onChange={files => {
}} this.onChange(files);
/> }}
}</EuiFlexItem> />
)}
</EuiFlexItem>
{this.state.files.length > 0 && {this.state.files.length > 0 &&
this.state.files.length < 6 && this.state.files.length < 6 &&
!this.checkOverSize() > 0 && !this.checkOverSize() > 0 &&
this.checkValidFileExtensions() > 0 && ( this.checkValidFileExtensions() > 0 && (
<Fragment> <Fragment>
<EuiFlexItem>{!this.state.uploadErrors && <EuiFlexItem>
this.renderFiles() || {(!this.state.uploadErrors && this.renderFiles()) ||
this.renderErrors() this.renderErrors()}
}</EuiFlexItem> </EuiFlexItem>
<EuiFlexItem grow={false}>{!this.state.uploadErrors && <EuiFlexItem grow={false}>
<EuiButton {(!this.state.uploadErrors && (
className="upload-files-button" <EuiButton
fill className="upload-files-button"
iconType="sortUp" fill
onClick={() => this.startUpload()} iconType="sortUp"
> onClick={() => this.startUpload()}
Upload >
</EuiButton> Upload
|| </EuiButton>
<EuiButtonEmpty )) || (
className="upload-files-button" <EuiButtonEmpty
onClick={() => this.closePopover()} className="upload-files-button"
> onClick={() => this.closePopover()}
Close >
</EuiButtonEmpty> Close
}</EuiFlexItem> </EuiButtonEmpty>
)}
</EuiFlexItem>
</Fragment> </Fragment>
)} )}

View File

@ -159,7 +159,7 @@ export function GroupsController(
$scope.groupsSelectedTab = 'agents'; $scope.groupsSelectedTab = 'agents';
$scope.groupsTabsProps.selectedTab = 'agents'; $scope.groupsTabsProps.selectedTab = 'agents';
return $scope.loadGroup(parameters.group); return $scope.loadGroup(parameters.group);
});; });
$scope.$on('wazuhShowGroupFile', (ev, parameters) => { $scope.$on('wazuhShowGroupFile', (ev, parameters) => {
ev.stopPropagation(); ev.stopPropagation();

View File

@ -454,20 +454,30 @@ export class ManagementController {
this.errors = false; this.errors = false;
this.results = []; this.results = [];
if (path === 'etc/rules') { if (path === 'etc/rules') {
this.upload = this.rulesetHandler.sendRuleConfiguration this.upload = this.rulesetHandler.sendRuleConfiguration;
} else if (path === 'etc/decoders') { } else if (path === 'etc/decoders') {
this.upload = this.rulesetHandler.sendDecoderConfiguration this.upload = this.rulesetHandler.sendDecoderConfiguration;
} else { } else {
this.upload = this.rulesetHandler.sendCdbList this.upload = this.rulesetHandler.sendCdbList;
} }
for (let idx in files) { for (let idx in files) {
const { file, content } = files[idx]; const { file, content } = files[idx];
try { try {
await this.upload(file, content, true); // True does not overwrite the file await this.upload(file, content, true); // True does not overwrite the file
this.results.push({index: idx, uploaded: true, file: file, error: 0}); this.results.push({
index: idx,
uploaded: true,
file: file,
error: 0
});
} catch (error) { } catch (error) {
this.errors = true this.errors = true;
this.results.push({index: idx, uploaded: false, file: file, error: error}); this.results.push({
index: idx,
uploaded: false,
file: file,
error: error
});
} }
} }
if (this.errors) throw this.results; if (this.errors) throw this.results;
@ -478,4 +488,4 @@ export class ManagementController {
this.errorHandler.handle('Files cannot be uploaded'); this.errorHandler.handle('Files cannot be uploaded');
} }
} }
} }

View File

@ -140,7 +140,7 @@ export class HealthCheck {
async checkApiConnection() { async checkApiConnection() {
try { try {
const currentApi = JSON.parse(this.appState.getCurrentAPI() || '{}'); const currentApi = JSON.parse(this.appState.getCurrentAPI() || '{}');
if (this.checks.api && currentApi && currentApi.id) { if (this.checks.api && currentApi && currentApi.id) {
const data = await this.testAPI.checkStored(currentApi.id); const data = await this.testAPI.checkStored(currentApi.id);
if (((data || {}).data || {}).idChanged) { if (((data || {}).data || {}).idChanged) {
@ -217,7 +217,7 @@ export class HealthCheck {
async load() { async load() {
try { try {
const configuration = this.wazuhConfig.getConfig(); const configuration = this.wazuhConfig.getConfig();
this.appState.setPatternSelector(configuration['ip.selector']); this.appState.setPatternSelector(configuration['ip.selector']);
this.checks.pattern = configuration['checks.pattern']; this.checks.pattern = configuration['checks.pattern'];

View File

@ -35,9 +35,8 @@ export class AddApi extends Component {
}; };
} }
componentDidMount() { componentDidMount() {
this.setState({enableClose: this.props.enableClose}); this.setState({ enableClose: this.props.enableClose });
this.checkErrorsAtInit(); this.checkErrorsAtInit();
} }
@ -50,7 +49,9 @@ export class AddApi extends Component {
this.setState({ this.setState({
status: error.type || 'danger', status: error.type || 'danger',
blockClose: true, blockClose: true,
message: (error.data || error).message || 'Wazuh API not reachable, please review your configuration', message:
(error.data || error).message ||
'Wazuh API not reachable, please review your configuration',
fetchingData: false fetchingData: false
}); });
} }
@ -65,7 +66,7 @@ export class AddApi extends Component {
this.setState({ this.setState({
status: 'incomplete', status: 'incomplete',
fetchingData: true, fetchingData: true,
blockClose: false, blockClose: false
}); });
await this.props.checkForNewApis(); await this.props.checkForNewApis();
@ -76,13 +77,18 @@ export class AddApi extends Component {
closedEnabled: true closedEnabled: true
}); });
} catch (error) { } catch (error) {
const close = (error.data && error.data.code && error.data.code === 2001) ? false : (error.closedEnabled || false); const close =
error.data && error.data.code && error.data.code === 2001
? false
: error.closedEnabled || false;
this.setState({ this.setState({
status: error.type || 'danger', status: error.type || 'danger',
closedEnabled: close, closedEnabled: close,
blockClose: !close, blockClose: !close,
enableClose: false, enableClose: false,
message: (error.data || error).message || 'Wazuh API not reachable, please review your configuration', message:
(error.data || error).message ||
'Wazuh API not reachable, please review your configuration',
fetchingData: false fetchingData: false
}); });
} }
@ -98,14 +104,16 @@ export class AddApi extends Component {
const checkConnectionChildren = ( const checkConnectionChildren = (
<div> <div>
{(this.state.status === 'warning' || this.state.status === 'danger') && ( {(this.state.status === 'warning' ||
this.state.status === 'danger') && (
<EuiCallOut <EuiCallOut
color={this.state.status} color={this.state.status}
iconType="help" iconType="help"
title={this.state.message} title={this.state.message}
/> />
)} )}
{(this.state.status === 'warning' || this.state.status === 'danger') && <EuiSpacer />} {(this.state.status === 'warning' ||
this.state.status === 'danger') && <EuiSpacer />}
<EuiText> <EuiText>
Check that the Kibana server can reach the configured Wazuh API(s). Check that the Kibana server can reach the configured Wazuh API(s).
</EuiText> </EuiText>
@ -116,13 +124,12 @@ export class AddApi extends Component {
> >
Check connection Check connection
</EuiButton> </EuiButton>
{((this.state.closedEnabled || this.state.enableClose) && !this.state.blockClose) && ( {(this.state.closedEnabled || this.state.enableClose) &&
<EuiButtonEmpty !this.state.blockClose && (
onClick={() => this.props.closeAddApi()} <EuiButtonEmpty onClick={() => this.props.closeAddApi()}>
> Close
Close </EuiButtonEmpty>
</EuiButtonEmpty> )}
)}
</div> </div>
); );
@ -170,7 +177,7 @@ export class AddApi extends Component {
</EuiFlexItem> </EuiFlexItem>
<EuiFlexItem /> <EuiFlexItem />
<EuiFlexItem grow={false}> <EuiFlexItem grow={false}>
{(this.state.enableClose && !this.state.blockClose) && ( {this.state.enableClose && !this.state.blockClose && (
<EuiButtonEmpty <EuiButtonEmpty
size="s" size="s"
onClick={() => this.props.closeAddApi()} onClick={() => this.props.closeAddApi()}

View File

@ -41,7 +41,6 @@ export class ApiIsDown extends Component {
}; };
} }
componentDidMount() { componentDidMount() {
this.setState({ this.setState({
apiEntries: [...this.props.apiEntries] apiEntries: [...this.props.apiEntries]
@ -68,7 +67,7 @@ export class ApiIsDown extends Component {
try { try {
const data = await this.props.testApi(entry); const data = await this.props.testApi(entry);
const clusterInfo = data.data || {}; const clusterInfo = data.data || {};
const id = entries[idx].id;; const id = entries[idx].id;
entries[idx].status = 'online'; entries[idx].status = 'online';
entries[idx].cluster_info = clusterInfo; entries[idx].cluster_info = clusterInfo;
//Updates the cluster info in the registry //Updates the cluster info in the registry
@ -76,7 +75,8 @@ export class ApiIsDown extends Component {
} catch (error) { } catch (error) {
numErr = numErr + 1; numErr = numErr + 1;
const code = ((error || {}).data || {}).code; const code = ((error || {}).data || {}).code;
const downReason = ((error || {}).data || {}).message || 'Wazuh is not reachable'; const downReason =
((error || {}).data || {}).message || 'Wazuh is not reachable';
const status = code === 3099 ? 'down' : 'unknown'; const status = code === 3099 ? 'down' : 'unknown';
entries[idx].status = { status, downReason }; entries[idx].status = { status, downReason };
} }
@ -91,7 +91,12 @@ export class ApiIsDown extends Component {
refreshingEntries: false refreshingEntries: false
}); });
} catch (error) { } catch (error) {
if (error && error.data && error.data.message && error.data.code === 2001) { if (
error &&
error.data &&
error.data.message &&
error.data.code === 2001
) {
this.setState({ error: error.data.message, status: 'danger' }); this.setState({ error: error.data.message, status: 'danger' });
} }
} }
@ -122,16 +127,14 @@ hosts:
</EuiButton> </EuiButton>
{this.state.status !== 'danger' && {this.state.status !== 'danger' &&
this.state.status !== 'incomplete' && ( this.state.status !== 'incomplete' && (
<EuiButtonEmpty <EuiButtonEmpty onClick={() => this.props.closeApiIsDown()}>
onClick={() => this.props.closeApiIsDown()}
>
Close Close
</EuiButtonEmpty> </EuiButtonEmpty>
)} )}
<EuiSpacer /> <EuiSpacer />
<EuiText>Already configured Wazuh API(s)</EuiText> <EuiText>Already configured Wazuh API(s)</EuiText>
<EuiSpacer /> <EuiSpacer />
{!this.state.error && ( {(!this.state.error && (
<EuiBasicTable <EuiBasicTable
loading={this.state.refreshingEntries} loading={this.state.refreshingEntries}
items={this.state.apiEntries} items={this.state.apiEntries}
@ -150,33 +153,50 @@ hosts:
<span> <span>
<EuiHealth color="warning">Warning</EuiHealth> <EuiHealth color="warning">Warning</EuiHealth>
<EuiToolTip position="top" content={item.downReason}> <EuiToolTip position="top" content={item.downReason}>
<EuiButtonIcon color="primary" style={{ marginTop: '-12px' }} iconType="questionInCircle" onClick={() => this.props.copyToClipBoard(item.downReason)}/> <EuiButtonIcon
color="primary"
style={{ marginTop: '-12px' }}
iconType="questionInCircle"
onClick={() =>
this.props.copyToClipBoard(item.downReason)
}
/>
</EuiToolTip> </EuiToolTip>
</span> </span>
) : ( ) : (
<span> <span>
<EuiHealth color="danger">Offline</EuiHealth> <EuiHealth color="danger">Offline</EuiHealth>
<EuiToolTip position="top" content={item.downReason}> <EuiToolTip position="top" content={item.downReason}>
<EuiButtonIcon color="primary" style={{ marginTop: '-12px' }} iconType="questionInCircle" onClick={() => this.props.copyToClipBoard(item.downReason)}/> <EuiButtonIcon
</EuiToolTip> color="primary"
</span > style={{ marginTop: '-12px' }}
); iconType="questionInCircle"
onClick={() =>
this.props.copyToClipBoard(item.downReason)
}
/>
</EuiToolTip>
</span>
);
} else { } else {
return (<span><EuiLoadingSpinner size="s" /><span>&nbsp;&nbsp;Checking</span></span>); return (
<span>
<EuiLoadingSpinner size="s" />
<span>&nbsp;&nbsp;Checking</span>
</span>
);
} }
} }
} }
]} ]}
/> />
) || ( )) || (
<EuiCallOut <EuiCallOut
color='danger' color="danger"
iconType="cross" iconType="cross"
title={this.state.error} title={this.state.error}
/> />
)} )}
</div> </div>
); );

View File

@ -42,10 +42,9 @@ export class ApiTable extends Component {
}); });
} }
/** /**
* Refresh the API entries * Refresh the API entries
*/ */
async refresh() { async refresh() {
try { try {
let status = 'complete'; let status = 'complete';
@ -62,7 +61,7 @@ export class ApiTable extends Component {
try { try {
const data = await this.props.testApi(entry); const data = await this.props.testApi(entry);
const clusterInfo = data.data || {}; const clusterInfo = data.data || {};
const id = entries[idx].id;; const id = entries[idx].id;
entries[idx].status = 'online'; entries[idx].status = 'online';
entries[idx].cluster_info = clusterInfo; entries[idx].cluster_info = clusterInfo;
//Updates the cluster info in the registry //Updates the cluster info in the registry
@ -70,7 +69,8 @@ export class ApiTable extends Component {
} catch (error) { } catch (error) {
numErr = numErr + 1; numErr = numErr + 1;
const code = ((error || {}).data || {}).code; const code = ((error || {}).data || {}).code;
const downReason = ((error || {}).data || {}).message || 'Wazuh is not reachable'; const downReason =
((error || {}).data || {}).message || 'Wazuh is not reachable';
const status = code === 3099 ? 'down' : 'unknown'; const status = code === 3099 ? 'down' : 'unknown';
entries[idx].status = { status, downReason }; entries[idx].status = { status, downReason };
} }
@ -84,7 +84,12 @@ export class ApiTable extends Component {
refreshingEntries: false refreshingEntries: false
}); });
} catch (error) { } catch (error) {
if (error && error.data && error.data.message && error.data.code === 2001) { if (
error &&
error.data &&
error.data.message &&
error.data.code === 2001
) {
this.props.showAddApiWithInitialError(error); this.props.showAddApiWithInitialError(error);
} }
} }
@ -92,7 +97,7 @@ export class ApiTable extends Component {
/** /**
* Checks the API connectivity * Checks the API connectivity
* @param {Object} api * @param {Object} api
*/ */
async checkApi(api) { async checkApi(api) {
try { try {
@ -103,7 +108,8 @@ export class ApiTable extends Component {
entries[idx].status = 'online'; entries[idx].status = 'online';
} catch (error) { } catch (error) {
const code = ((error || {}).data || {}).code; const code = ((error || {}).data || {}).code;
const downReason = ((error || {}).data || {}).message || 'Wazuh is not reachable'; const downReason =
((error || {}).data || {}).message || 'Wazuh is not reachable';
const status = code === 3099 ? 'down' : 'unknown'; const status = code === 3099 ? 'down' : 'unknown';
entries[idx].status = { status, downReason }; entries[idx].status = { status, downReason };
} }
@ -122,37 +128,37 @@ export class ApiTable extends Component {
field: 'id', field: 'id',
name: 'ID', name: 'ID',
align: 'left', align: 'left',
sortable: true, sortable: true
}, },
{ {
field: 'cluster_info.cluster', field: 'cluster_info.cluster',
name: 'Cluster', name: 'Cluster',
align: 'left', align: 'left',
sortable: true, sortable: true
}, },
{ {
field: 'cluster_info.manager', field: 'cluster_info.manager',
name: 'Manager', name: 'Manager',
align: 'left', align: 'left',
sortable: true, sortable: true
}, },
{ {
field: 'url', field: 'url',
name: 'Host', name: 'Host',
align: 'left', align: 'left',
sortable: true, sortable: true
}, },
{ {
field: 'port', field: 'port',
name: 'Port', name: 'Port',
align: 'left', align: 'left',
sortable: true, sortable: true
}, },
{ {
field: 'user', field: 'user',
name: 'User', name: 'User',
align: 'left', align: 'left',
sortable: true, sortable: true
}, },
{ {
field: 'status', field: 'status',
@ -167,22 +173,35 @@ export class ApiTable extends Component {
<span> <span>
<EuiHealth color="warning">Warning</EuiHealth> <EuiHealth color="warning">Warning</EuiHealth>
<EuiToolTip position="top" content={item.downReason}> <EuiToolTip position="top" content={item.downReason}>
<EuiButtonIcon color="primary" style={{ marginTop: '-12px' }} iconType="questionInCircle" onClick={() => this.props.copyToClipBoard(item.downReason)}/> <EuiButtonIcon
color="primary"
style={{ marginTop: '-12px' }}
iconType="questionInCircle"
onClick={() => this.props.copyToClipBoard(item.downReason)}
/>
</EuiToolTip> </EuiToolTip>
</span> </span>
) : ( ) : (
<span> <span>
<EuiHealth color="danger">Offline</EuiHealth> <EuiHealth color="danger">Offline</EuiHealth>
<EuiToolTip position="top" content={item.downReason}> <EuiToolTip position="top" content={item.downReason}>
<EuiButtonIcon color="primary" style={{ marginTop: '-12px' }} iconType="questionInCircle" onClick={() => this.props.copyToClipBoard(item.downReason)}/> <EuiButtonIcon
</EuiToolTip> color="primary"
</span > style={{ marginTop: '-12px' }}
); iconType="questionInCircle"
onClick={() => this.props.copyToClipBoard(item.downReason)}
/>
</EuiToolTip>
</span>
);
} else { } else {
return (<span><EuiLoadingSpinner size="s" /><span>&nbsp;&nbsp;Checking</span></span>); return (
<span>
<EuiLoadingSpinner size="s" />
<span>&nbsp;&nbsp;Checking</span>
</span>
);
} }
} }
}, },
{ {
@ -225,7 +244,7 @@ export class ApiTable extends Component {
const search = { const search = {
box: { box: {
incremental: this.state.incremental, incremental: this.state.incremental,
schema: true, schema: true
} }
}; };
@ -247,7 +266,7 @@ export class ApiTable extends Component {
onClick={() => this.props.showAddApi()} onClick={() => this.props.showAddApi()}
> >
Add new Add new
</EuiButtonEmpty> </EuiButtonEmpty>
</EuiFlexItem> </EuiFlexItem>
<EuiFlexItem grow={false}> <EuiFlexItem grow={false}>
<EuiButtonEmpty <EuiButtonEmpty
@ -261,7 +280,8 @@ export class ApiTable extends Component {
<EuiFlexGroup> <EuiFlexGroup>
<EuiFlexItem> <EuiFlexItem>
<EuiText color="subdued" style={{ paddingBottom: '15px' }}> <EuiText color="subdued" style={{ paddingBottom: '15px' }}>
From here you can see how to set up your Wazuh host, establish as default, and check their connection and status. From here you can see how to set up your Wazuh host, establish as
default, and check their connection and status.
</EuiText> </EuiText>
</EuiFlexItem> </EuiFlexItem>
</EuiFlexGroup> </EuiFlexGroup>

View File

@ -83,7 +83,8 @@ export class SettingsController {
await this.getSettings(); await this.getSettings();
const down = await this.checkApisStatus(); const down = await this.checkApisStatus();
//Checks if all the API entries are down //Checks if all the API entries are down
this.apiIsDown = (down >= this.apiEntries.length && this.apiEntries.length > 0); this.apiIsDown =
down >= this.apiEntries.length && this.apiEntries.length > 0;
const location = this.$location.search(); const location = this.$location.search();
if (location && location.tab) { if (location && location.tab) {
@ -93,7 +94,7 @@ export class SettingsController {
await this.getAppInfo(); await this.getAppInfo();
} catch (error) { } catch (error) {
this.errorHandler.handle('Cannot initialize Settings') this.errorHandler.handle('Cannot initialize Settings');
} }
} }
@ -110,8 +111,10 @@ export class SettingsController {
showAddApi: () => this.showAddApi(), showAddApi: () => this.showAddApi(),
getHosts: () => this.getHosts(), getHosts: () => this.getHosts(),
testApi: entry => this.testAPI.check(entry), testApi: entry => this.testAPI.check(entry),
showAddApiWithInitialError: error => this.showAddApiWithInitialError(error), showAddApiWithInitialError: error =>
updateClusterInfoInRegistry: (id, clusterInfo) => this.updateClusterInfoInRegistry(id, clusterInfo), this.showAddApiWithInitialError(error),
updateClusterInfoInRegistry: (id, clusterInfo) =>
this.updateClusterInfoInRegistry(id, clusterInfo),
showApiIsDown: () => this.showApiIsDown(), showApiIsDown: () => this.showApiIsDown(),
copyToClipBoard: msg => this.copyToClipBoard(msg) copyToClipBoard: msg => this.copyToClipBoard(msg)
}; };
@ -119,16 +122,17 @@ export class SettingsController {
this.addApiProps = { this.addApiProps = {
checkForNewApis: () => this.checkForNewApis(), checkForNewApis: () => this.checkForNewApis(),
closeAddApi: () => this.closeAddApi() closeAddApi: () => this.closeAddApi()
} };
this.apiIsDownProps = { this.apiIsDownProps = {
apiEntries: this.apiEntries, apiEntries: this.apiEntries,
testApi: entry => this.testAPI.check(entry), testApi: entry => this.testAPI.check(entry),
closeApiIsDown: () => this.closeApiIsDown(), closeApiIsDown: () => this.closeApiIsDown(),
getHosts: () => this.getHosts(), getHosts: () => this.getHosts(),
updateClusterInfoInRegistry: (id, clusterInfo) => this.updateClusterInfoInRegistry(id, clusterInfo), updateClusterInfoInRegistry: (id, clusterInfo) =>
this.updateClusterInfoInRegistry(id, clusterInfo),
copyToClipBoard: msg => this.copyToClipBoard(msg) copyToClipBoard: msg => this.copyToClipBoard(msg)
} };
this.settingsTabsProps = { this.settingsTabsProps = {
clickAction: tab => { clickAction: tab => {
@ -144,7 +148,7 @@ export class SettingsController {
{ id: 'logs', name: 'Logs' }, { id: 'logs', name: 'Logs' },
{ id: 'about', name: 'About' } { id: 'about', name: 'About' }
] ]
} };
} }
/** /**
@ -162,17 +166,19 @@ export class SettingsController {
// Get current API index // Get current API index
getCurrentAPIIndex() { getCurrentAPIIndex() {
if (this.apiEntries.length) { if (this.apiEntries.length) {
const idx = this.apiEntries.map(entry => entry.id).indexOf(this.currentDefault); const idx = this.apiEntries
.map(entry => entry.id)
.indexOf(this.currentDefault);
this.currentApiEntryIndex = idx; this.currentApiEntryIndex = idx;
} }
} }
/** /**
* Returns the index of the API in the entries array * Returns the index of the API in the entries array
* @param {Object} api * @param {Object} api
*/ */
getApiIndex(api) { getApiIndex(api) {
return this.apiEntries.map(entry => entry.id).indexOf(api.id) return this.apiEntries.map(entry => entry.id).indexOf(api.id);
} }
/** /**
@ -187,14 +193,15 @@ export class SettingsController {
this.apiEntries[idx].status = 'online'; this.apiEntries[idx].status = 'online';
} catch (error) { } catch (error) {
const code = ((error || {}).data || {}).code; const code = ((error || {}).data || {}).code;
const downReason = ((error || {}).data || {}).message || 'Wazuh is not reachable'; const downReason =
((error || {}).data || {}).message || 'Wazuh is not reachable';
const status = code === 3099 ? 'down' : 'unknown'; const status = code === 3099 ? 'down' : 'unknown';
this.apiEntries[idx].status = { status, downReason }; this.apiEntries[idx].status = { status, downReason };
numError = numError + 1; numError = numError + 1;
} }
}; }
return numError; return numError;
} catch (error) { } } catch (error) {}
} }
// Set default API // Set default API
@ -206,7 +213,7 @@ export class SettingsController {
const { cluster_info, id } = api; const { cluster_info, id } = api;
const { manager, cluster, status } = cluster_info; const { manager, cluster, status } = cluster_info;
// Check the connection before set as default // Check the connection before set as default
this.appState.setClusterInfo(cluster_info); this.appState.setClusterInfo(cluster_info);
const clusterEnabled = status === 'disabled'; const clusterEnabled = status === 'disabled';
this.appState.setCurrentAPI( this.appState.setCurrentAPI(
@ -277,7 +284,7 @@ export class SettingsController {
if (currentApi && !this.appState.getExtensions(this.currentDefault)) { if (currentApi && !this.appState.getExtensions(this.currentDefault)) {
const { id, extensions } = this.apiEntries[this.currentApiEntryIndex]; const { id, extensions } = this.apiEntries[this.currentApiEntryIndex];
const apiExtensions = extensions || {} const apiExtensions = extensions || {};
this.appState.setExtensions(id, apiExtensions); this.appState.setExtensions(id, apiExtensions);
} }
@ -286,13 +293,15 @@ export class SettingsController {
this.errorHandler.handle('Error getting API entries', 'Settings'); this.errorHandler.handle('Error getting API entries', 'Settings');
} }
// Every time that the API entries are required in the settings the registry will be checked in order to remove orphan host entries // Every time that the API entries are required in the settings the registry will be checked in order to remove orphan host entries
await this.genericReq.request('POST', '/hosts/remove-orphan-entries', { entries: this.apiEntries }); await this.genericReq.request('POST', '/hosts/remove-orphan-entries', {
entries: this.apiEntries
});
return; return;
} }
/** /**
* @param {String} id * @param {String} id
* @param {Object} clusterInfo * @param {Object} clusterInfo
*/ */
async updateClusterInfoInRegistry(id, clusterInfo) { async updateClusterInfoInRegistry(id, clusterInfo) {
try { try {
@ -309,9 +318,7 @@ export class SettingsController {
async checkManager(item, isIndex, silent = false) { async checkManager(item, isIndex, silent = false) {
try { try {
// Get the index of the API in the entries // Get the index of the API in the entries
const index = isIndex const index = isIndex ? item : this.getApiIndex(item);
? item
: this.getApiIndex(item);
// Get the Api information // Get the Api information
const api = this.apiEntries[index]; const api = this.apiEntries[index];
@ -329,7 +336,7 @@ export class SettingsController {
const data = await this.testAPI.check(tmpData); const data = await this.testAPI.check(tmpData);
tmpData.cluster_info = data.data; tmpData.cluster_info = data.data;
const { cluster_info } = tmpData; const { cluster_info } = tmpData;
// Updates the cluster-information in the registry // Updates the cluster-information in the registry
await this.updateClusterInfoInRegistry(id, cluster_info); await this.updateClusterInfoInRegistry(id, cluster_info);
this.$scope.$emit('updateAPI', { cluster_info }); this.$scope.$emit('updateAPI', { cluster_info });
this.apiEntries[index].cluster_info = cluster_info; this.apiEntries[index].cluster_info = cluster_info;
@ -403,7 +410,10 @@ export class SettingsController {
} }
this.getCurrentAPIIndex(); this.getCurrentAPIIndex();
if ((this.currentApiEntryIndex || this.currentApiEntryIndex === 0) && this.currentApiEntryIndex >= 0) { if (
(this.currentApiEntryIndex || this.currentApiEntryIndex === 0) &&
this.currentApiEntryIndex >= 0
) {
await this.checkManager(this.currentApiEntryIndex, true, true); await this.checkManager(this.currentApiEntryIndex, true, true);
} }
this.$scope.$applyAsync(); this.$scope.$applyAsync();
@ -499,14 +509,28 @@ export class SettingsController {
this.addApiProps.errorsAtInit = false; this.addApiProps.errorsAtInit = false;
const hosts = await this.getHosts(); const hosts = await this.getHosts();
//Tries to check if there are new APIs entries in the wazuh.yml also, checks if some of them have connection //Tries to check if there are new APIs entries in the wazuh.yml also, checks if some of them have connection
if (!hosts.length) throw { message: 'There were not found any API entry in the wazuh.yml', type: 'warning', closedEnabled: false }; if (!hosts.length)
throw {
message: 'There were not found any API entry in the wazuh.yml',
type: 'warning',
closedEnabled: false
};
const notRecheable = await this.checkApisStatus(); const notRecheable = await this.checkApisStatus();
if (notRecheable) { if (notRecheable) {
if (notRecheable >= hosts.length) { if (notRecheable >= hosts.length) {
this.apiIsDown = true; this.apiIsDown = true;
throw { message: 'Wazuh API not recheable, please review your configuration', type: 'danger', closedEnabled: true }; throw {
message:
'Wazuh API not recheable, please review your configuration',
type: 'danger',
closedEnabled: true
};
} }
throw { message: 'Some API entries are not reachable', type: 'warning', closedEnabled: true }; throw {
message: 'Some API entries are not reachable',
type: 'warning',
closedEnabled: true
};
} }
return; return;
} catch (error) { } catch (error) {
@ -551,8 +575,8 @@ export class SettingsController {
} }
/** /**
* Shows the add API component * Shows the add API component
*/ */
showApiIsDown() { showApiIsDown() {
this.apiIsDown = true; this.apiIsDown = true;
this.$scope.$applyAsync(); this.$scope.$applyAsync();
@ -584,7 +608,8 @@ export class SettingsController {
this.apiEntries = await this.getHosts(); this.apiEntries = await this.getHosts();
const down = await this.checkApisStatus(); const down = await this.checkApisStatus();
//Checks if all the API entries are down //Checks if all the API entries are down
this.apiIsDown = (down >= this.apiEntries.length && this.apiEntries.length > 0); this.apiIsDown =
down >= this.apiEntries.length && this.apiEntries.length > 0;
this.$scope.$applyAsync(); this.$scope.$applyAsync();
return this.apiEntries; return this.apiEntries;
} catch (error) { } catch (error) {
@ -595,7 +620,7 @@ export class SettingsController {
/** /**
* Copy to the clickboard the string passed * Copy to the clickboard the string passed
* @param {String} msg * @param {String} msg
*/ */
copyToClipBoard(msg) { copyToClipBoard(msg) {
const el = document.createElement('textarea'); const el = document.createElement('textarea');

View File

@ -814,7 +814,7 @@ function discoverController(
const isClusterMonitoring = $scope.tabView === 'cluster-monitoring'; const isClusterMonitoring = $scope.tabView === 'cluster-monitoring';
// Wazuh. Should we fetch "_source" and "hits" ? // Wazuh. Should we fetch "_source" and "hits" ?
const noHits = (isPanels || isClusterMonitoring); const noHits = isPanels || isClusterMonitoring;
// Wazuh. The very first time, the copies are null, just create them // Wazuh. The very first time, the copies are null, just create them
if (!defaultSearchSource || !noHitsSearchSource) { if (!defaultSearchSource || !noHitsSearchSource) {

View File

@ -34,7 +34,7 @@ export class ApiTester {
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
timeout: timeout || 20000 timeout: timeout || 20000
}; };
const payload = {id: data}; const payload = { id: data };
const result = await this.$http.post( const result = await this.$http.post(
chrome.addBasePath('/api/check-stored-api'), chrome.addBasePath('/api/check-stored-api'),
payload, payload,

View File

@ -23,7 +23,8 @@ export function apiCount($q, genericReq, $location, appState) {
genericReq genericReq
.request('GET', '/hosts/apis') .request('GET', '/hosts/apis')
.then(async data => { .then(async data => {
if (!data || !data.data || !data.data.length) throw new Error('No API entries found'); if (!data || !data.data || !data.data.length)
throw new Error('No API entries found');
if (!appState.getCurrentAPI()) { if (!appState.getCurrentAPI()) {
await tryToSetDefault(data.data, appState); await tryToSetDefault(data.data, appState);
} }
@ -58,4 +59,4 @@ function tryToSetDefault(apis, appState) {
} catch (error) { } catch (error) {
return Promise.reject(error); return Promise.reject(error);
} }
} }

View File

@ -29,7 +29,7 @@ export function settingsWizard(
const checkResponse = data => { const checkResponse = data => {
let fromWazuhHosts = false; let fromWazuhHosts = false;
if (parseInt(data.data.error) === 2) { if (parseInt(data.data.error) === 2) {
console.log('default akaaakaa') console.log('default akaaakaa');
!disableErrors && !disableErrors &&
errorHandler.handle( errorHandler.handle(
'Please set up Wazuh API credentials.', 'Please set up Wazuh API credentials.',
@ -105,7 +105,10 @@ export function settingsWizard(
try { try {
currentApi = JSON.parse(appState.getCurrentAPI()).id; currentApi = JSON.parse(appState.getCurrentAPI()).id;
} catch (error) { } catch (error) {
console.log('Error parsing JSON (settingsWizards.callCheckStored 1)', error); console.log(
'Error parsing JSON (settingsWizards.callCheckStored 1)',
error
);
} }
if (currentApi && !appState.getExtensions(currentApi)) { if (currentApi && !appState.getExtensions(currentApi)) {
const extensions = { const extensions = {
@ -152,7 +155,7 @@ export function settingsWizard(
} }
} }
}) })
.catch((error) => { .catch(error => {
appState.removeCurrentAPI(); appState.removeCurrentAPI();
setUpCredentials( setUpCredentials(
'Wazuh App: Please set up Wazuh API credentials.', 'Wazuh App: Please set up Wazuh API credentials.',
@ -190,9 +193,7 @@ export function settingsWizard(
name: api.cluster_info.manager, name: api.cluster_info.manager,
id: id id: id
}); });
appState.setCurrentAPI( appState.setCurrentAPI(defaultApi);
defaultApi
);
callCheckStored(); callCheckStored();
return defaultApi; return defaultApi;
} }
@ -207,7 +208,7 @@ export function settingsWizard(
} catch (error) { } catch (error) {
return Promise.reject(error); return Promise.reject(error);
} }
} };
const currentParams = $location.search(); const currentParams = $location.search();
const targetedAgent = const targetedAgent =
@ -282,7 +283,7 @@ export function settingsWizard(
} }
} }
}) })
.catch((error) => { .catch(error => {
setUpCredentials('Wazuh App: Please set up Wazuh API credentials.'); setUpCredentials('Wazuh App: Please set up Wazuh API credentials.');
}); });
} }

View File

@ -73,7 +73,8 @@ export class RulesetHandler {
try { try {
const result = await this.apiReq.request( const result = await this.apiReq.request(
'POST', 'POST',
`/manager/files?path=etc/rules/${rule.file || rule}&overwrite=${!overwrite}`, `/manager/files?path=etc/rules/${rule.file ||
rule}&overwrite=${!overwrite}`,
{ content, origin: 'xmleditor' } { content, origin: 'xmleditor' }
); );
return result; return result;
@ -85,9 +86,8 @@ export class RulesetHandler {
try { try {
const result = await this.apiReq.request( const result = await this.apiReq.request(
'POST', 'POST',
`/manager/files?path=etc/decoders/${ `/manager/files?path=etc/decoders/${decoder.file ||
decoder.file || decoder decoder}&overwrite=${!overwrite}`,
}&overwrite=${!overwrite}`,
{ content, origin: 'xmleditor' } { content, origin: 'xmleditor' }
); );
return result; return result;

View File

@ -11,33 +11,31 @@
*/ */
export class StringsTools { export class StringsTools {
constructor () {} constructor() {}
/** /**
* Set the first letter to upper case * Set the first letter to upper case
* *
* @param {*} str * @param {*} str
* @returns capitalized str * @returns capitalized str
* @memberof StringsTools * @memberof StringsTools
*/ */
capitalize (str) { capitalize(str) {
return str[0].toUpperCase() + str.slice(1); return str[0].toUpperCase() + str.slice(1);
} }
/**
/** * Remove all white spaces from str
* Remove all white spaces from str *
* * @param {*} str
* @param {*} str * @returns striped str
* @returns striped str * @memberof StringsTools
* @memberof StringsTools */
*/ strip(str) {
strip (str) { return str.replace(/\s+/g, '');
return str.replace(/\s+/g, ''); }
}
toUpperCamelCase(str) {
toUpperCamelCase (str) { const capitalizeStrs = str.split(' ').map(s => this.capitalize(s));
const capitalizeStrs = str.split(' ').map((s) => this.capitalize(s)); return capitalizeStrs.join('');
return capitalizeStrs.join(''); }
} }
}

View File

@ -44,9 +44,11 @@ export function ErrorResponse(
message.includes('EAI_AGAIN')) && message.includes('EAI_AGAIN')) &&
code === 3005 code === 3005
) { ) {
filteredMessage = 'Wazuh API is not reachable. Please check your url and port.'; filteredMessage =
'Wazuh API is not reachable. Please check your url and port.';
} else if (isString && message.includes('ECONNREFUSED') && code === 3005) { } else if (isString && message.includes('ECONNREFUSED') && code === 3005) {
filteredMessage = 'Wazuh API is not reachable. Please check your url and port.'; filteredMessage =
'Wazuh API is not reachable. Please check your url and port.';
} else if ( } else if (
isString && isString &&
message.toLowerCase().includes('not found') && message.toLowerCase().includes('not found') &&

View File

@ -14,9 +14,4 @@ import { WazuhApiCtrl } from './wazuh-api';
import { WazuhReportingCtrl } from './wazuh-reporting'; import { WazuhReportingCtrl } from './wazuh-reporting';
import { WazuhUtilsCtrl } from './wazuh-utils'; import { WazuhUtilsCtrl } from './wazuh-utils';
export { export { WazuhElasticCtrl, WazuhApiCtrl, WazuhReportingCtrl, WazuhUtilsCtrl };
WazuhElasticCtrl,
WazuhApiCtrl,
WazuhReportingCtrl,
WazuhUtilsCtrl
};

View File

@ -54,9 +54,9 @@ export class WazuhApiCtrl {
async checkStoredAPI(req, reply) { async checkStoredAPI(req, reply) {
try { try {
// Get config from wazuh.yml // Get config from wazuh.yml
const id = req.payload.id || req.payload const id = req.payload.id || req.payload;
const api = await this.manageHosts.getHostById(id); const api = await this.manageHosts.getHostById(id);
// Check Manage Hosts // Check Manage Hosts
if (!Object.keys(api).length) { if (!Object.keys(api).length) {
throw new Error('Could not find Wazuh API entry on wazuh.yml'); throw new Error('Could not find Wazuh API entry on wazuh.yml');
@ -77,7 +77,12 @@ export class WazuhApiCtrl {
// Look for socket-related errors // Look for socket-related errors
if (this.checkResponseIsDown(response)) { if (this.checkResponseIsDown(response)) {
return ErrorResponse(`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`, 3099, 500, reply); return ErrorResponse(
`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`,
3099,
500,
reply
);
} }
// Store error and data fields from the Wazuh API into different variables // Store error and data fields from the Wazuh API into different variables
@ -142,7 +147,7 @@ export class WazuhApiCtrl {
try { try {
const id = Object.keys(api)[0]; const id = Object.keys(api)[0];
const host = api[id]; const host = api[id];
const options = ApiHelper.buildOptionsObject(host); const options = ApiHelper.buildOptionsObject(host);
const response = await needle( const response = await needle(
'get', 'get',
`${host.url}:${host.port}/version`, `${host.url}:${host.port}/version`,
@ -151,7 +156,13 @@ export class WazuhApiCtrl {
); );
if (this.checkResponseIsDown(response)) { if (this.checkResponseIsDown(response)) {
return ErrorResponse(`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`, 3099, 500, reply); return ErrorResponse(
`ERROR3099 - ${response.body.message ||
'Wazuh not ready yet'}`,
3099,
500,
reply
);
} }
if ( if (
@ -245,7 +256,12 @@ export class WazuhApiCtrl {
const responseIsDown = this.checkResponseIsDown(response); const responseIsDown = this.checkResponseIsDown(response);
if (responseIsDown) { if (responseIsDown) {
return ErrorResponse(`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`, 3099, 500, reply); return ErrorResponse(
`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`,
3099,
500,
reply
);
} }
// Check wrong credentials // Check wrong credentials
@ -344,7 +360,7 @@ export class WazuhApiCtrl {
if (!req.headers.id) { if (!req.headers.id) {
return pciRequirementsFile; return pciRequirementsFile;
} }
const apiId = req.headers.id; const apiId = req.headers.id;
const api = await this.manageHosts.getHostById(apiId); const api = await this.manageHosts.getHostById(apiId);
@ -360,7 +376,7 @@ export class WazuhApiCtrl {
400, 400,
reply reply
); );
} }
const response = await needle( const response = await needle(
'get', 'get',
@ -465,7 +481,7 @@ export class WazuhApiCtrl {
400, 400,
reply reply
); );
} }
const response = await needle( const response = await needle(
'get', 'get',
@ -561,7 +577,7 @@ export class WazuhApiCtrl {
400, 400,
reply reply
); );
} }
const response = await needle( const response = await needle(
'get', 'get',
@ -623,7 +639,7 @@ export class WazuhApiCtrl {
if (!req.headers.id) { if (!req.headers.id) {
return nistRequirementsFile; return nistRequirementsFile;
} }
const apiId = req.headers.id; const apiId = req.headers.id;
const api = await this.manageHosts.getHostById(apiId); const api = await this.manageHosts.getHostById(apiId);
@ -639,7 +655,7 @@ export class WazuhApiCtrl {
400, 400,
reply reply
); );
} }
const response = await needle( const response = await needle(
'get', 'get',
@ -787,7 +803,7 @@ export class WazuhApiCtrl {
404, 404,
reply reply
); );
} }
if (!data) { if (!data) {
data = {}; data = {};
@ -845,7 +861,12 @@ export class WazuhApiCtrl {
'wazuh-api:makeRequest', 'wazuh-api:makeRequest',
'Wazuh API is online but Wazuh is not ready yet' 'Wazuh API is online but Wazuh is not ready yet'
); );
return ErrorResponse(`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`, 3099, 500, reply); return ErrorResponse(
`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`,
3099,
500,
reply
);
} }
} }
} }
@ -877,14 +898,24 @@ export class WazuhApiCtrl {
const responseIsDown = this.checkResponseIsDown(response); const responseIsDown = this.checkResponseIsDown(response);
if (responseIsDown) { if (responseIsDown) {
return ErrorResponse(`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`, 3099, 500, reply); return ErrorResponse(
`ERROR3099 - ${response.body.message || 'Wazuh not ready yet'}`,
3099,
500,
reply
);
} }
const responseBody = (response || {}).body || {}; const responseBody = (response || {}).body || {};
let responseData = responseBody.data; let responseData = responseBody.data;
if (!responseData) { if (!responseData) {
responseData = typeof responseData === 'string' && path.includes('/files') && method === 'GET' ? ' ' : false responseData =
response.body.data = responseData typeof responseData === 'string' &&
path.includes('/files') &&
method === 'GET'
? ' '
: false;
response.body.data = responseData;
} }
const responseError = responseBody.error || false; const responseError = responseBody.error || false;
@ -931,7 +962,7 @@ export class WazuhApiCtrl {
if (!Object.keys(api).length) { if (!Object.keys(api).length) {
//Can not get credentials from wazuh-hosts //Can not get credentials from wazuh-hosts
throw new Error('Could not get host credentials'); throw new Error('Could not get host credentials');
} }
if (!method.match(/^(?:GET|PUT|POST|DELETE)$/)) { if (!method.match(/^(?:GET|PUT|POST|DELETE)$/)) {
log('wazuh-api:makeRequest', 'Request method is not valid.'); log('wazuh-api:makeRequest', 'Request method is not valid.');
@ -996,9 +1027,9 @@ export class WazuhApiCtrl {
log('wazuh-api:makeRequest', 'Request method is not valid.'); log('wazuh-api:makeRequest', 'Request method is not valid.');
//Method is not a valid HTTP request method //Method is not a valid HTTP request method
return ErrorResponse('Request method is not valid.', 3015, 400, reply); return ErrorResponse('Request method is not valid.', 3015, 400, reply);
}else if (!req.payload.path) { } else if (!req.payload.path) {
return ErrorResponse('Missing param: path', 3016, 400, reply); return ErrorResponse('Missing param: path', 3016, 400, reply);
}else if (!req.payload.path.match(/^\/.+/)) { } else if (!req.payload.path.match(/^\/.+/)) {
log('wazuh-api:makeRequest', 'Request path is not valid.'); log('wazuh-api:makeRequest', 'Request path is not valid.');
//Path doesn't start with '/' //Path doesn't start with '/'
return ErrorResponse('Request path is not valid.', 3015, 400, reply); return ErrorResponse('Request path is not valid.', 3015, 400, reply);
@ -1078,9 +1109,7 @@ export class WazuhApiCtrl {
? req.payload.filters ? req.payload.filters
: []; : [];
const config = await this.manageHosts.getHostById( const config = await this.manageHosts.getHostById(req.payload.id);
req.payload.id
);
let tmpPath = req.payload.path; let tmpPath = req.payload.path;
@ -1140,10 +1169,7 @@ export class WazuhApiCtrl {
if (isAgents || isAgentsOfGroup) { if (isAgents || isAgentsOfGroup) {
if (isFiles) { if (isFiles) {
fields = [ fields = ['filename', 'hash'];
'filename',
'hash'
];
} else { } else {
fields = [ fields = [
'id', 'id',
@ -1227,9 +1253,7 @@ export class WazuhApiCtrl {
if (!req.params || !req.params.api) if (!req.params || !req.params.api)
throw new Error('Field api is required'); throw new Error('Field api is required');
const config = await this.manageHosts.getHostById( const config = await this.manageHosts.getHostById(req.params.api);
req.params.api
);
const headers = ApiHelper.buildOptionsObject(config); const headers = ApiHelper.buildOptionsObject(config);
@ -1323,7 +1347,9 @@ export class WazuhApiCtrl {
*/ */
getTimeStamp(req, reply) { getTimeStamp(req, reply) {
try { try {
const source = JSON.parse(fs.readFileSync(this.updateRegistry.file, 'utf8')); const source = JSON.parse(
fs.readFileSync(this.updateRegistry.file, 'utf8')
);
if (source.installationDate && source.lastRestart) { if (source.installationDate && source.lastRestart) {
log( log(
'wazuh-api:getTimeStamp', 'wazuh-api:getTimeStamp',
@ -1356,7 +1382,9 @@ export class WazuhApiCtrl {
*/ */
async getSetupInfo(req, reply) { async getSetupInfo(req, reply) {
try { try {
const source = JSON.parse(fs.readFileSync(this.updateRegistry.file, 'utf8')); const source = JSON.parse(
fs.readFileSync(this.updateRegistry.file, 'utf8')
);
return !Object.values(source).length return !Object.values(source).length
? { statusCode: 200, data: '' } ? { statusCode: 200, data: '' }
: { statusCode: 200, data: source }; : { statusCode: 200, data: source };

View File

@ -35,22 +35,24 @@ export class WazuhHostsCtrl {
return result; return result;
} catch (error) { } catch (error) {
log('wazuh-hosts:getHostsEntries', error.message || error); log('wazuh-hosts:getHostsEntries', error.message || error);
const errorResponse = reply ? ErrorResponse(error.message || error, 2001, 500, reply) : error; const errorResponse = reply
? ErrorResponse(error.message || error, 2001, 500, reply)
: error;
return errorResponse; return errorResponse;
} }
} }
/** /**
* Joins the hosts with the related information in the registry * Joins the hosts with the related information in the registry
* @param {Object} hosts * @param {Object} hosts
* @param {Object} registry * @param {Object} registry
*/ */
joinHostRegistry(hosts, registry, removePassword = true) { joinHostRegistry(hosts, registry, removePassword = true) {
try { try {
const joined = []; const joined = [];
hosts.forEach(h => { hosts.forEach(h => {
const id = Object.keys(h)[0]; const id = Object.keys(h)[0];
const api = Object.assign(h[id], {id: id}); const api = Object.assign(h[id], { id: id });
const host = Object.assign(api, registry[id]); const host = Object.assign(api, registry[id]);
if (removePassword) delete host.password; if (removePassword) delete host.password;
joined.push(host); joined.push(host);
@ -61,11 +63,11 @@ export class WazuhHostsCtrl {
} }
} }
/** /**
* This update an API hostname * This update an API hostname
* @param {Object} req * @param {Object} req
* @param {Object} reply * @param {Object} reply
* Status response or ErrorResponse * Status response or ErrorResponse
*/ */
async updateClusterInfo(req, reply) { async updateClusterInfo(req, reply) {
try { try {
const id = req.params.id; const id = req.params.id;
@ -79,7 +81,8 @@ export class WazuhHostsCtrl {
} catch (error) { } catch (error) {
log('wazuh-hosts:updateClusterInfo', error.message || error); log('wazuh-hosts:updateClusterInfo', error.message || error);
return ErrorResponse( return ErrorResponse(
`Could not update data in wazuh-registry.json due to ${error.message || error}`, `Could not update data in wazuh-registry.json due to ${error.message ||
error}`,
2012, 2012,
500, 500,
reply reply
@ -95,13 +98,15 @@ export class WazuhHostsCtrl {
async removeOrphanEntries(req, reply) { async removeOrphanEntries(req, reply) {
try { try {
log('wazuh-hosts:cleanRegistry', 'Cleaning registry', 'debug'); log('wazuh-hosts:cleanRegistry', 'Cleaning registry', 'debug');
if (!req.payload && !req.payload.entries) throw new Error('No entries given to check'); if (!req.payload && !req.payload.entries)
await this.updateRegistry.removeOrphanEntries(req.payload.entries) throw new Error('No entries given to check');
await this.updateRegistry.removeOrphanEntries(req.payload.entries);
return { statusCode: 200, message: 'ok' }; return { statusCode: 200, message: 'ok' };
} catch (error) { } catch (error) {
log('wazuh-hosts:cleanRegistry', error.message || error); log('wazuh-hosts:cleanRegistry', error.message || error);
return ErrorResponse( return ErrorResponse(
`Could not clean entries in the wazuh-registry.json due to ${error.message || error}`, `Could not clean entries in the wazuh-registry.json due to ${error.message ||
error}`,
2013, 2013,
500, 500,
reply reply

View File

@ -43,7 +43,7 @@ export function Initialize(server) {
: 'wazuh-alerts-3.x-*'; : 'wazuh-alerts-3.x-*';
global.XPACK_RBAC_ENABLED = global.XPACK_RBAC_ENABLED =
configurationFile && configurationFile &&
typeof configurationFile['xpack.rbac.enabled'] !== 'undefined' typeof configurationFile['xpack.rbac.enabled'] !== 'undefined'
? configurationFile['xpack.rbac.enabled'] ? configurationFile['xpack.rbac.enabled']
: true; : true;
} catch (e) { } catch (e) {
@ -110,7 +110,6 @@ export function Initialize(server) {
} }
}; };
/** /**
* Checks if the .wazuh index exist in order to migrate to wazuh.yml * Checks if the .wazuh index exist in order to migrate to wazuh.yml
*/ */
@ -123,11 +122,15 @@ export function Initialize(server) {
if (result) { if (result) {
try { try {
const data = await wzWrapper.getWazuhAPIEntries(); const data = await wzWrapper.getWazuhAPIEntries();
const apiEntries = (((data || {}).hits || {}).hits || []); const apiEntries = ((data || {}).hits || {}).hits || [];
await manageHosts.migrateFromIndex(apiEntries) await manageHosts.migrateFromIndex(apiEntries);
log('initialize:checkWazuhIndex', 'Index .wazuh will be removed and its content will be migrated to wazuh.yml', 'debug'); log(
'initialize:checkWazuhIndex',
'Index .wazuh will be removed and its content will be migrated to wazuh.yml',
'debug'
);
// Check if all APIs entries were migrated properly and delete it from the .wazuh index // Check if all APIs entries were migrated properly and delete it from the .wazuh index
await checkProperlyMigrate(); await checkProperlyMigrate();
await wzWrapper.deleteIndexByName('.wazuh'); await wzWrapper.deleteIndexByName('.wazuh');
} catch (error) { } catch (error) {
throw new Error(error); throw new Error(error);
@ -147,7 +150,7 @@ export function Initialize(server) {
let apisIndex = await wzWrapper.getWazuhAPIEntries(); let apisIndex = await wzWrapper.getWazuhAPIEntries();
const hosts = await manageHosts.getHosts(); const hosts = await manageHosts.getHosts();
apisIndex = (apisIndex.hits || {}).hits || []; apisIndex = (apisIndex.hits || {}).hits || [];
const apisIndexKeys = apisIndex.map(api => { const apisIndexKeys = apisIndex.map(api => {
return api._id; return api._id;
}); });
@ -157,19 +160,24 @@ export function Initialize(server) {
// Get into an array the API entries that were not migrated, if the length is 0 then all the API entries were properly migrated. // Get into an array the API entries that were not migrated, if the length is 0 then all the API entries were properly migrated.
const rest = apisIndexKeys.filter(k => { const rest = apisIndexKeys.filter(k => {
return !hostsKeys.includes(k) return !hostsKeys.includes(k);
}); });
if (rest.length) { if (rest.length) {
throw new Error(`Cannot migrate all API entries, missed entries: (${rest.toString()})`) throw new Error(
`Cannot migrate all API entries, missed entries: (${rest.toString()})`
);
} }
log('initialize:checkProperlyMigrate', 'The API entries migration was successful', 'debug'); log(
'initialize:checkProperlyMigrate',
'The API entries migration was successful',
'debug'
);
} catch (error) { } catch (error) {
log('initialize:checkProperlyMigrate', `${error}`, 'error'); log('initialize:checkProperlyMigrate', `${error}`, 'error');
return Promise.reject(error); return Promise.reject(error);
} }
} };
/** /**
* Checks if the .wazuh-version exists, in this case it will be deleted and the wazuh-registry.json will be created * Checks if the .wazuh-version exists, in this case it will be deleted and the wazuh-registry.json will be created
@ -289,7 +297,7 @@ export function Initialize(server) {
return Promise.reject( return Promise.reject(
new Error( new Error(
`Error creating ${ `Error creating ${
wzWrapper.WZ_KIBANA_INDEX wzWrapper.WZ_KIBANA_INDEX
} index due to ${error.message || error}` } index due to ${error.message || error}`
) )
); );
@ -310,7 +318,7 @@ export function Initialize(server) {
return Promise.reject( return Promise.reject(
new Error( new Error(
`Error creating template for ${ `Error creating template for ${
wzWrapper.WZ_KIBANA_INDEX wzWrapper.WZ_KIBANA_INDEX
} due to ${error.message || error}` } due to ${error.message || error}`
) )
); );

View File

@ -22,11 +22,10 @@ export class ManageHosts {
this.updateRegistry = new UpdateRegistry(); this.updateRegistry = new UpdateRegistry();
} }
/** /**
* Composes the host structure * Composes the host structure
* @param {Object} host * @param {Object} host
* @param {String} id * @param {String} id
*/ */
composeHost(host, id) { composeHost(host, id) {
try { try {
@ -44,12 +43,12 @@ export class ManageHosts {
/** /**
* Regex to build the host * Regex to build the host
* @param {Object} host * @param {Object} host
*/ */
composeRegex(host) { composeRegex(host) {
try { try {
const hostId = Object.keys(host)[0]; const hostId = Object.keys(host)[0];
const reg = `\\s*-\\s*${hostId}\\s*:\\s*\\n*\\s*url\\s*:\\s*\\S*\\s*\\n*\\s*port\\s*:\\s*\\S*\\s*\\n*\\s*user\\s*:\\s*\\S*\\s*\\n*\\s*password\\s*:\\s*\\S*` const reg = `\\s*-\\s*${hostId}\\s*:\\s*\\n*\\s*url\\s*:\\s*\\S*\\s*\\n*\\s*port\\s*:\\s*\\S*\\s*\\n*\\s*user\\s*:\\s*\\S*\\s*\\n*\\s*password\\s*:\\s*\\S*`;
log('manage-hosts:composeRegex', 'Composing regex', 'debug'); log('manage-hosts:composeRegex', 'Composing regex', 'debug');
return new RegExp(`${reg}`, 'gm'); return new RegExp(`${reg}`, 'gm');
} catch (error) { } catch (error) {
@ -102,7 +101,9 @@ export class ManageHosts {
async getCurrentHostsIds() { async getCurrentHostsIds() {
try { try {
const hosts = await this.getHosts(); const hosts = await this.getHosts();
const ids = hosts.map(h => { return Object.keys(h)[0] }) const ids = hosts.map(h => {
return Object.keys(h)[0];
});
log('manage-hosts:getCurrentHostsIds', 'Getting hosts ids', 'debug'); log('manage-hosts:getCurrentHostsIds', 'Getting hosts ids', 'debug');
return ids; return ids;
} catch (error) { } catch (error) {
@ -113,15 +114,17 @@ export class ManageHosts {
/** /**
* Get host by id * Get host by id
* @param {String} id * @param {String} id
*/ */
async getHostById(id) { async getHostById(id) {
try { try {
log('manage-hosts:getHostById', `Getting host ${id}`, 'debug'); log('manage-hosts:getHostById', `Getting host ${id}`, 'debug');
const hosts = await this.getHosts(); const hosts = await this.getHosts();
const host = hosts.filter(h => { return Object.keys(h)[0] == id }); const host = hosts.filter(h => {
return Object.keys(h)[0] == id;
});
const key = Object.keys(host[0])[0]; const key = Object.keys(host[0])[0];
const result = Object.assign(host[0][key], {id: key}) || {}; const result = Object.assign(host[0][key], { id: key }) || {};
return result; return result;
} catch (error) { } catch (error) {
log('manage-hosts:getHostById', error.message || error); log('manage-hosts:getHostById', error.message || error);
@ -131,18 +134,15 @@ export class ManageHosts {
/** /**
* Decodes the API password * Decodes the API password
* @param {String} password * @param {String} password
*/ */
decodeApiPassword(password) { decodeApiPassword(password) {
return Buffer.from( return Buffer.from(password, 'base64').toString('ascii');
password,
'base64'
).toString('ascii');
} }
/** /**
* Iterate the array with the API entries in given from the .wazuh index in order to create a valid array * Iterate the array with the API entries in given from the .wazuh index in order to create a valid array
* @param {Object} apiEntries * @param {Object} apiEntries
*/ */
transformIndexedApis(apiEntries) { transformIndexedApis(apiEntries) {
const entries = []; const entries = [];
@ -161,7 +161,11 @@ export class ManageHosts {
}; };
entries.push(api); entries.push(api);
}); });
log('manage-hosts:transformIndexedApis', 'Transforming index API schedule to wazuh.yml', 'debug'); log(
'manage-hosts:transformIndexedApis',
'Transforming index API schedule to wazuh.yml',
'debug'
);
} catch (error) { } catch (error) {
log('manage-hosts:transformIndexedApis', error.message || error); log('manage-hosts:transformIndexedApis', error.message || error);
throw error; throw error;
@ -169,11 +173,10 @@ export class ManageHosts {
return entries; return entries;
} }
/** /**
* Calls transformIndexedApis() to get the entries to migrate and after that calls addSeveralHosts() * Calls transformIndexedApis() to get the entries to migrate and after that calls addSeveralHosts()
* @param {Object} apiEntries * @param {Object} apiEntries
*/ */
async migrateFromIndex(apiEntries) { async migrateFromIndex(apiEntries) {
try { try {
const apis = this.transformIndexedApis(apiEntries); const apis = this.transformIndexedApis(apiEntries);
@ -186,13 +189,19 @@ export class ManageHosts {
/** /**
* Receives an array of hosts and checks if any host is already in the wazuh.yml, in this case is removed from the received array and returns the resulting array * Receives an array of hosts and checks if any host is already in the wazuh.yml, in this case is removed from the received array and returns the resulting array
* @param {Array} hosts * @param {Array} hosts
*/ */
async cleanExistingHosts(hosts) { async cleanExistingHosts(hosts) {
try { try {
const currentHosts = await this.getCurrentHostsIds(); const currentHosts = await this.getCurrentHostsIds();
const cleanHosts = hosts.filter(h => { return !currentHosts.includes(h.id) }); const cleanHosts = hosts.filter(h => {
log('manage-hosts:cleanExistingHosts', 'Preventing add existings hosts', 'debug'); return !currentHosts.includes(h.id);
});
log(
'manage-hosts:cleanExistingHosts',
'Preventing add existings hosts',
'debug'
);
return cleanHosts; return cleanHosts;
} catch (error) { } catch (error) {
log('manage-hosts:cleanExistingHosts', error.message || error); log('manage-hosts:cleanExistingHosts', error.message || error);
@ -204,23 +213,24 @@ export class ManageHosts {
* Throws an error is the wazuh.yml is busy * Throws an error is the wazuh.yml is busy
*/ */
checkBusy() { checkBusy() {
if (this.busy) throw new Error('Another process is writting the configuration file'); if (this.busy)
throw new Error('Another process is writting the configuration file');
} }
/** /**
* Recursive function used to add several APIs entries * Recursive function used to add several APIs entries
* @param {Array} hosts * @param {Array} hosts
*/ */
async addSeveralHosts(hosts) { async addSeveralHosts(hosts) {
try { try {
log('manage-hosts:addSeveralHosts', 'Adding several', 'debug'); log('manage-hosts:addSeveralHosts', 'Adding several', 'debug');
const hostsToAdd = await this.cleanExistingHosts(hosts); const hostsToAdd = await this.cleanExistingHosts(hosts);
if (!hostsToAdd.length) return 'There are not APIs entries to migrate' if (!hostsToAdd.length) return 'There are not APIs entries to migrate';
for (let idx in hostsToAdd) { for (let idx in hostsToAdd) {
const entry = hostsToAdd[idx]; const entry = hostsToAdd[idx];
await this.addHost(entry); await this.addHost(entry);
} }
return 'All APIs entries were migrated to the wazuh.yml' return 'All APIs entries were migrated to the wazuh.yml';
} catch (error) { } catch (error) {
log('manage-hosts:addSeveralHosts', error.message || error); log('manage-hosts:addSeveralHosts', error.message || error);
return Promise.reject(error); return Promise.reject(error);
@ -229,7 +239,7 @@ export class ManageHosts {
/** /**
* Add a single host * Add a single host
* @param {Obeject} host * @param {Obeject} host
*/ */
async addHost(host) { async addHost(host) {
const id = host.id || new Date().getTime(); const id = host.id || new Date().getTime();
@ -237,23 +247,35 @@ export class ManageHosts {
let data = await fs.readFileSync(this.file, { encoding: 'utf-8' }); let data = await fs.readFileSync(this.file, { encoding: 'utf-8' });
try { try {
this.checkBusy(); this.checkBusy();
const hosts = await this.getHosts() || []; const hosts = (await this.getHosts()) || [];
this.busy = true; this.busy = true;
if (!hosts.length) { if (!hosts.length) {
const hostsExists = await this.checkIfHostsKeyExists(); const hostsExists = await this.checkIfHostsKeyExists();
const result = !hostsExists ? `${data}\nhosts:\n${compose}\n` : `${data}\n${compose}\n`; const result = !hostsExists
? `${data}\nhosts:\n${compose}\n`
: `${data}\n${compose}\n`;
await fs.writeFileSync(this.file, result, 'utf8'); await fs.writeFileSync(this.file, result, 'utf8');
} else { } else {
const lastHost = (hosts || []).pop(); const lastHost = (hosts || []).pop();
if (lastHost) { if (lastHost) {
const lastHostObject = this.composeHost(lastHost[Object.keys(lastHost)[0]], Object.keys(lastHost)[0]); const lastHostObject = this.composeHost(
lastHost[Object.keys(lastHost)[0]],
Object.keys(lastHost)[0]
);
const regex = this.composeRegex(lastHost); const regex = this.composeRegex(lastHost);
const replace = data.replace(regex, `\n${lastHostObject}\n${compose}\n`) const replace = data.replace(
regex,
`\n${lastHostObject}\n${compose}\n`
);
await fs.writeFileSync(this.file, replace, 'utf8'); await fs.writeFileSync(this.file, replace, 'utf8');
} }
} }
this.busy = false; this.busy = false;
this.updateRegistry.migrateToRegistry(id, host.cluster_info, host.extensions); this.updateRegistry.migrateToRegistry(
id,
host.cluster_info,
host.extensions
);
log('manage-hosts:addHost', `Host ${id} was properly added`, 'debug'); log('manage-hosts:addHost', `Host ${id} was properly added`, 'debug');
return id; return id;
} catch (error) { } catch (error) {
@ -271,29 +293,36 @@ export class ManageHosts {
let data = await fs.readFileSync(this.file, { encoding: 'utf-8' }); let data = await fs.readFileSync(this.file, { encoding: 'utf-8' });
try { try {
this.checkBusy(); this.checkBusy();
const hosts = await this.getHosts() || []; const hosts = (await this.getHosts()) || [];
this.busy = true; this.busy = true;
if (!hosts.length) { if (!hosts.length) {
throw new Error('There are not configured hosts.'); throw new Error('There are not configured hosts.');
} else { } else {
const hostsNumber = hosts.length; const hostsNumber = hosts.length;
const target = (hosts || []).find((element) => { const target = (hosts || []).find(element => {
return Object.keys(element)[0] === req.params.id; return Object.keys(element)[0] === req.params.id;
}); });
if (!target) { if (!target) {
throw new Error(`Host ${req.params.id} not found.`); throw new Error(`Host ${req.params.id} not found.`);
} }
const regex = this.composeRegex(target); const regex = this.composeRegex(target);
const result = data.replace(regex, ``) const result = data.replace(regex, ``);
await fs.writeFileSync(this.file, result, 'utf8'); await fs.writeFileSync(this.file, result, 'utf8');
if (hostsNumber === 1) { if (hostsNumber === 1) {
data = await fs.readFileSync(this.file, { encoding: 'utf-8' }); data = await fs.readFileSync(this.file, { encoding: 'utf-8' });
const clearHosts = data.replace(new RegExp(`hosts:\\s*[\\n\\r]`, 'gm'), '') const clearHosts = data.replace(
new RegExp(`hosts:\\s*[\\n\\r]`, 'gm'),
''
);
await fs.writeFileSync(this.file, clearHosts, 'utf8'); await fs.writeFileSync(this.file, clearHosts, 'utf8');
} }
} }
this.busy = false; this.busy = false;
log('manage-hosts:deleteHost', `Host ${req.params.id} was properly deleted`, 'debug'); log(
'manage-hosts:deleteHost',
`Host ${req.params.id} was properly deleted`,
'debug'
);
return true; return true;
} catch (error) { } catch (error) {
this.busy = false; this.busy = false;
@ -304,19 +333,19 @@ export class ManageHosts {
/** /**
* Updates the hosts information * Updates the hosts information
* @param {String} id * @param {String} id
* @param {Object} host * @param {Object} host
*/ */
async updateHost(id, host) { async updateHost(id, host) {
let data = await fs.readFileSync(this.file, { encoding: 'utf-8' }); let data = await fs.readFileSync(this.file, { encoding: 'utf-8' });
try { try {
this.checkBusy(); this.checkBusy();
const hosts = await this.getHosts() || []; const hosts = (await this.getHosts()) || [];
this.busy = true; this.busy = true;
if (!hosts.length) { if (!hosts.length) {
throw new Error('There are not configured hosts.'); throw new Error('There are not configured hosts.');
} else { } else {
const target = (hosts || []).find((element) => { const target = (hosts || []).find(element => {
return Object.keys(element)[0] === id; return Object.keys(element)[0] === id;
}); });
if (!target) { if (!target) {
@ -327,7 +356,11 @@ export class ManageHosts {
await fs.writeFileSync(this.file, result, 'utf8'); await fs.writeFileSync(this.file, result, 'utf8');
} }
this.busy = false; this.busy = false;
log('manage-hosts:updateHost', `Host ${id} was properly updated`, 'debug'); log(
'manage-hosts:updateHost',
`Host ${id} was properly updated`,
'debug'
);
return true; return true;
} catch (error) { } catch (error) {
this.busy = false; this.busy = false;

View File

@ -71,7 +71,11 @@ export class UpdateConfigurationFile {
const { key, value } = (input || {}).payload || {}; const { key, value } = (input || {}).payload || {};
this.updateLine(key, value, typeof configuration[key] !== 'undefined'); this.updateLine(key, value, typeof configuration[key] !== 'undefined');
this.busy = false; this.busy = false;
log('update-configuration:updateConfiguration', 'Updating configuration', 'debug'); log(
'update-configuration:updateConfiguration',
'Updating configuration',
'debug'
);
return { needRestart: needRestartFields.includes(key) }; return { needRestart: needRestartFields.includes(key) };
} catch (error) { } catch (error) {
log('update-configuration:updateConfiguration', error.message || error); log('update-configuration:updateConfiguration', error.message || error);

View File

@ -19,13 +19,16 @@ export class UpdateRegistry {
this.file = path.join(__dirname, '../../server/wazuh-registry.json'); this.file = path.join(__dirname, '../../server/wazuh-registry.json');
} }
/** /**
* Reads the Wazuh registry content * Reads the Wazuh registry content
*/ */
async readContent() { async readContent() {
try { try {
log('update-registry:readContent', 'Reading wazuh-registry.json content', 'debug'); log(
'update-registry:readContent',
'Reading wazuh-registry.json content',
'debug'
);
const content = await fs.readFileSync(this.file, { encoding: 'utf-8' }); const content = await fs.readFileSync(this.file, { encoding: 'utf-8' });
return JSON.parse(content); return JSON.parse(content);
} catch (error) { } catch (error) {
@ -49,9 +52,9 @@ export class UpdateRegistry {
} }
/** /**
* Returns the cluster information associated to an API id * Returns the cluster information associated to an API id
* @param {String} id * @param {String} id
*/ */
async getHostById(id) { async getHostById(id) {
try { try {
if (!id) throw new Error('API id is missing'); if (!id) throw new Error('API id is missing');
@ -65,11 +68,15 @@ export class UpdateRegistry {
/** /**
* Writes the wazuh-registry.json * Writes the wazuh-registry.json
* @param {Object} content * @param {Object} content
*/ */
async writeContent(content) { async writeContent(content) {
try { try {
log('update-registry:writeContent', 'Writting wazuh-registry.json content', 'debug'); log(
'update-registry:writeContent',
'Writting wazuh-registry.json content',
'debug'
);
if (this.busy) { if (this.busy) {
throw new Error('Another process is updating the registry file'); throw new Error('Another process is updating the registry file');
} }
@ -78,14 +85,14 @@ export class UpdateRegistry {
this.busy = false; this.busy = false;
} catch (error) { } catch (error) {
log('update-registry:writeContent', error.message || error); log('update-registry:writeContent', error.message || error);
return Promise.reject(error) return Promise.reject(error);
} }
} }
/** /**
* Checks if the host exist in order to update the data, otherwise creates it * Checks if the host exist in order to update the data, otherwise creates it
* @param {String} id * @param {String} id
* @param {Object} hosts * @param {Object} hosts
*/ */
checkHost(id, hosts) { checkHost(id, hosts) {
try { try {
@ -98,18 +105,23 @@ export class UpdateRegistry {
/** /**
* Migrates the cluster information and extensions associated to an API id * Migrates the cluster information and extensions associated to an API id
* @param {String} id * @param {String} id
* @param {Object} clusterInfo * @param {Object} clusterInfo
* @param {Object} clusterExtensions * @param {Object} clusterExtensions
*/ */
async migrateToRegistry(id, clusterInfo, clusterExtensions) { async migrateToRegistry(id, clusterInfo, clusterExtensions) {
try { try {
const content = await this.readContent(); const content = await this.readContent();
if (!Object.keys(content).includes('hosts')) Object.assign(content, {hosts: {}}); if (!Object.keys(content).includes('hosts'))
const info = { cluster_info: clusterInfo, extensions: clusterExtensions}; Object.assign(content, { hosts: {} });
const info = { cluster_info: clusterInfo, extensions: clusterExtensions };
content.hosts[id] = info; content.hosts[id] = info;
await this.writeContent(content); await this.writeContent(content);
log('update-registry:migrateToRegistry', `API ${id} was properly migrated`, 'debug'); log(
'update-registry:migrateToRegistry',
`API ${id} was properly migrated`,
'debug'
);
return info; return info;
} catch (error) { } catch (error) {
log('update-registry:migrateToRegistry', error.message || error); log('update-registry:migrateToRegistry', error.message || error);
@ -117,10 +129,10 @@ export class UpdateRegistry {
} }
} }
/** /**
* Updates the cluster-information or manager-information in the registry * Updates the cluster-information or manager-information in the registry
* @param {String} id * @param {String} id
* @param {Object} clusterInfo * @param {Object} clusterInfo
*/ */
async updateClusterInfo(id, clusterInfo) { async updateClusterInfo(id, clusterInfo) {
try { try {
@ -129,7 +141,11 @@ export class UpdateRegistry {
if (!content.hosts[id]) content.hosts[id] = {}; if (!content.hosts[id]) content.hosts[id] = {};
content.hosts[id].cluster_info = clusterInfo; content.hosts[id].cluster_info = clusterInfo;
await this.writeContent(content); await this.writeContent(content);
log('update-registry:updateClusterInfo', `API ${id} information was properly updated`, 'debug'); log(
'update-registry:updateClusterInfo',
`API ${id} information was properly updated`,
'debug'
);
return id; return id;
} catch (error) { } catch (error) {
log('update-registry:updateClusterInfo', error.message || error); log('update-registry:updateClusterInfo', error.message || error);
@ -137,17 +153,21 @@ export class UpdateRegistry {
} }
} }
/** /**
* Updates the cluster-information or manager-information in the registry * Updates the cluster-information or manager-information in the registry
* @param {String} id * @param {String} id
* @param {Object} clusterInfo * @param {Object} clusterInfo
*/ */
async updateAPIExtensions(id, extensions) { async updateAPIExtensions(id, extensions) {
try { try {
const content = await this.readContent(); const content = await this.readContent();
content.hosts[id].extensions = extensions; content.hosts[id].extensions = extensions;
await this.writeContent(content); await this.writeContent(content);
log('update-registry:updateAPIExtensions', `API ${id} extensions were properly updated`, 'debug'); log(
'update-registry:updateAPIExtensions',
`API ${id} extensions were properly updated`,
'debug'
);
return id; return id;
} catch (error) { } catch (error) {
log('update-registry:updateAPIHostname', error.message || error); log('update-registry:updateAPIHostname', error.message || error);
@ -157,7 +177,7 @@ export class UpdateRegistry {
/** /**
* Remove the given ids from the registry host entries * Remove the given ids from the registry host entries
* @param {Array} ids * @param {Array} ids
*/ */
async removeHostEntries(ids) { async removeHostEntries(ids) {
try { try {
@ -177,11 +197,19 @@ export class UpdateRegistry {
*/ */
async removeOrphanEntries(hosts) { async removeOrphanEntries(hosts) {
try { try {
log('update-registry:removeOrphanEntries', 'Checking orphan registry entries', 'debug'); log(
'update-registry:removeOrphanEntries',
'Checking orphan registry entries',
'debug'
);
const entries = await this.getHosts(); const entries = await this.getHosts();
const hostsKeys = hosts.map(h => {return h.id}); const hostsKeys = hosts.map(h => {
return h.id;
});
const entriesKeys = Object.keys(entries); const entriesKeys = Object.keys(entries);
const diff = entriesKeys.filter(e => {return !hostsKeys.includes(e)}); const diff = entriesKeys.filter(e => {
return !hostsKeys.includes(e);
});
await this.removeHostEntries(diff); await this.removeHostEntries(diff);
} catch (error) { } catch (error) {
log('update-registry:removeOrphanEntries', error.message || error); log('update-registry:removeOrphanEntries', error.message || error);
@ -189,4 +217,3 @@ export class UpdateRegistry {
} }
} }
} }

View File

@ -249,7 +249,7 @@ export class Monitoring {
user: element.user, user: element.user,
password: element.password, password: element.password,
url: element.url, url: element.url,
port: element.port, port: element.port
}; };
log( log(
'monitoring:loadCredentials', 'monitoring:loadCredentials',

View File

@ -32,7 +32,6 @@ export function WazuhHostsRoutes(server) {
} }
}); });
// Checks the orphan hosts in the registry in order to delete them // Checks the orphan hosts in the registry in order to delete them
server.route({ server.route({
method: 'POST', method: 'POST',

View File

@ -4,13 +4,13 @@ import { resolveKibanaPath } from '@kbn/plugin-helpers';
import { pageObjects } from './page_objects'; import { pageObjects } from './page_objects';
import { services } from './services'; import { services } from './services';
export default async function ({ readConfigFile }) { export default async function({ readConfigFile }) {
const kibanaConfig = await readConfigFile(resolveKibanaPath('test/functional/config.js')); const kibanaConfig = await readConfigFile(
resolveKibanaPath('test/functional/config.js')
);
return { return {
testFiles: [ testFiles: [require.resolve('./apps/overview')],
require.resolve('./apps/overview'),
],
services: { services: {
...kibanaConfig.get('services'), ...kibanaConfig.get('services'),
@ -19,22 +19,22 @@ export default async function ({ readConfigFile }) {
pageObjects: { pageObjects: {
...kibanaConfig.get('pageObjects'), ...kibanaConfig.get('pageObjects'),
...pageObjects, ...pageObjects
}, },
apps: { apps: {
...kibanaConfig.get('apps'), ...kibanaConfig.get('apps'),
wazuh: { wazuh: {
pathname: '/app/wazuh', pathname: '/app/wazuh'
} }
}, },
esArchiver: { esArchiver: {
directory: resolve(__dirname, './es_archives'), directory: resolve(__dirname, './es_archives')
}, },
screenshots: { screenshots: {
directory: resolve(__dirname, './tmp/screenshots'), directory: resolve(__dirname, './tmp/screenshots')
}, },
servers: kibanaConfig.get('servers'), servers: kibanaConfig.get('servers'),
@ -47,7 +47,7 @@ export default async function ({ readConfigFile }) {
...kibanaConfig.get('kbnTestServer.serverArgs'), ...kibanaConfig.get('kbnTestServer.serverArgs'),
'--oss', '--oss',
`--plugin-path=${resolve(__dirname, '../../')}` `--plugin-path=${resolve(__dirname, '../../')}`
], ]
}, }
}; };
} }

View File

@ -8,26 +8,26 @@ export function ApiProvider({ getService, getPageObjects }) {
const testSubjects = getService('testSubjects'); const testSubjects = getService('testSubjects');
const toasts = getService('toasts'); const toasts = getService('toasts');
/** /**
* The Api Page class provides functions to automate the process * The Api Page class provides functions to automate the process
* of testing the API configuration * of testing the API configuration
* *
* @class ApiPage * @class ApiPage
*/ */
class ApiPage { class ApiPage {
/**
/** * Complete the form to create a new Api connection.
* Complete the form to create a new Api connection. *
* * @param {string} [type='apiConfig'] Set the form type
* @param {string} [type='apiConfig'] Set the form type * - apiConfig: For new API form
* - apiConfig: For new API form * - apiTableEdit: For edit API form
* - apiTableEdit: For edit API form * @memberof ApiPage
* @memberof ApiPage */
*/ async completeApiForm(type = 'apiConfig') {
async completeApiForm (type='apiConfig') { if (!(type == 'apiConfig' || type == 'apiTableEdit')) {
if (!(type == 'apiConfig' || type == 'apiTableEdit')){ throw new Error(
throw new Error(`Invalid type: ${type}; use 'apiConfig' or 'apiTableEdit'`); `Invalid type: ${type}; use 'apiConfig' or 'apiTableEdit'`
);
} }
await testSubjects.setValue(`${type}Username`, 'foo'); await testSubjects.setValue(`${type}Username`, 'foo');
log.debug('insert the user'); log.debug('insert the user');
@ -48,7 +48,7 @@ export function ApiProvider({ getService, getPageObjects }) {
* @param {string} tab testSubjects value * @param {string} tab testSubjects value
* @memberof ApiPage * @memberof ApiPage
*/ */
async checkTabDisabled (tab) { async checkTabDisabled(tab) {
await testSubjects.click(tab); await testSubjects.click(tab);
await PageObjects.common.sleep(1500); await PageObjects.common.sleep(1500);
expect(await browser.getCurrentUrl()).to.contain('tab=api'); expect(await browser.getCurrentUrl()).to.contain('tab=api');
@ -60,7 +60,7 @@ export function ApiProvider({ getService, getPageObjects }) {
* *
* @memberof ApiPage * @memberof ApiPage
*/ */
async checkIfAllTabsAreDisables () { async checkIfAllTabsAreDisables() {
await this.checkTabDisabled('wzMenuOverview'); await this.checkTabDisabled('wzMenuOverview');
await this.checkTabDisabled('wzMenuManagement'); await this.checkTabDisabled('wzMenuManagement');
await this.checkTabDisabled('wzMenuAgents'); await this.checkTabDisabled('wzMenuAgents');
@ -69,13 +69,13 @@ export function ApiProvider({ getService, getPageObjects }) {
} }
/** /**
* Press all refresh buttons of the API list and * Press all refresh buttons of the API list and
* the response in the toasts * the response in the toasts
* *
* @param {array} buttonList list of button WebElementWrapper * @param {array} buttonList list of button WebElementWrapper
* @memberof ApiPage * @memberof ApiPage
*/ */
async pressAllCheckConnectionButtons (buttonList) { async pressAllCheckConnectionButtons(buttonList) {
for (const key in buttonList) { for (const key in buttonList) {
if (buttonList.hasOwnProperty(key)) { if (buttonList.hasOwnProperty(key)) {
const checkButton = buttonList[key]; const checkButton = buttonList[key];
@ -83,7 +83,9 @@ export function ApiProvider({ getService, getPageObjects }) {
await PageObjects.common.sleep(1000); await PageObjects.common.sleep(1000);
await checkButton.click(); await checkButton.click();
await PageObjects.common.sleep(2000); await PageObjects.common.sleep(2000);
expect(await toasts.findMessageInToasts('Settings. Connection success')).to.be.ok(); expect(
await toasts.findMessageInToasts('Settings. Connection success')
).to.be.ok();
await PageObjects.common.clearAllToasts(); await PageObjects.common.clearAllToasts();
} }
} }
@ -95,13 +97,17 @@ export function ApiProvider({ getService, getPageObjects }) {
* @param {array} apiButtonList list of button WebElementWrapper * @param {array} apiButtonList list of button WebElementWrapper
* @memberof ApiPage * @memberof ApiPage
*/ */
async editAllApis (apiButtonList) { async editAllApis(apiButtonList) {
for (const apiButton of apiButtonList) { for (const apiButton of apiButtonList) {
await apiButton.moveMouseTo(); await apiButton.moveMouseTo();
await PageObjects.common.sleep(1000); await PageObjects.common.sleep(1000);
await apiButton.click(); await apiButton.click();
await this.completeApiForm('apiTableEdit'); await this.completeApiForm('apiTableEdit');
expect(await toasts.findMessageInToasts('Settings. The API was updated successfully')).to.be.ok(); expect(
await toasts.findMessageInToasts(
'Settings. The API was updated successfully'
)
).to.be.ok();
await PageObjects.common.clearAllToasts(); await PageObjects.common.clearAllToasts();
} }
} }
@ -111,14 +117,20 @@ export function ApiProvider({ getService, getPageObjects }) {
* *
* @memberof ApiPage * @memberof ApiPage
*/ */
async deleteAllApis () { async deleteAllApis() {
const deleteApiButtonList = await testSubjects.findAll('apiTableTrashButton'); const deleteApiButtonList = await testSubjects.findAll(
'apiTableTrashButton'
);
for (const deleteButton of deleteApiButtonList) { for (const deleteButton of deleteApiButtonList) {
await deleteButton.moveMouseTo(); await deleteButton.moveMouseTo();
await PageObjects.common.sleep(1000); await PageObjects.common.sleep(1000);
await deleteButton.click(); await deleteButton.click();
await PageObjects.common.sleep(1500); await PageObjects.common.sleep(1500);
expect(await toasts.findMessageInToasts('Settings. The API was removed successfully')).to.be.ok(); expect(
await toasts.findMessageInToasts(
'Settings. The API was removed successfully'
)
).to.be.ok();
await PageObjects.common.clearAllToasts(); await PageObjects.common.clearAllToasts();
} }
} }
@ -128,7 +140,7 @@ export function ApiProvider({ getService, getPageObjects }) {
* *
* @memberof ApiPage * @memberof ApiPage
*/ */
async navigateToApiSetting () { async navigateToApiSetting() {
await testSubjects.click('wzMenuSettings'); await testSubjects.click('wzMenuSettings');
await testSubjects.click('settingMenuApi'); await testSubjects.click('settingMenuApi');
} }
@ -138,14 +150,14 @@ export function ApiProvider({ getService, getPageObjects }) {
* *
* @memberof ApiPage * @memberof ApiPage
*/ */
async insertNewApi () { async insertNewApi() {
const fromUrl = await browser.getCurrentUrl(); const fromUrl = await browser.getCurrentUrl();
await this.navigateToApiSetting(); await this.navigateToApiSetting();
await testSubjects.click('apiTableAddButton'); await testSubjects.click('apiTableAddButton');
await this.completeApiForm(); await this.completeApiForm();
await find.clickByCssSelector('[test-api-default="false"]'); await find.clickByCssSelector('[test-api-default="false"]');
await browser.get(fromUrl); await browser.get(fromUrl);
await PageObjects.common.waitUntilUrlIncludes('tab=welcome'); await PageObjects.common.waitUntilUrlIncludes('tab=welcome');
} }
/** /**
@ -153,7 +165,7 @@ export function ApiProvider({ getService, getPageObjects }) {
* *
* @memberof ApiPage * @memberof ApiPage
*/ */
async deleteNewApi () { async deleteNewApi() {
const fromUrl = await browser.getCurrentUrl(); const fromUrl = await browser.getCurrentUrl();
await this.navigateToApiSetting(); await this.navigateToApiSetting();
await PageObjects.common.sleep(500); await PageObjects.common.sleep(500);
@ -163,23 +175,24 @@ export function ApiProvider({ getService, getPageObjects }) {
} }
/** /**
* Remove the API marked as default * Remove the API marked as default
* *
* @returns * @returns
* @memberof ApiPage * @memberof ApiPage
*/ */
async clickTrashDefaultApi () { async clickTrashDefaultApi() {
const rows = await find.allByCssSelector('table>tbody>tr'); const rows = await find.allByCssSelector('table>tbody>tr');
for (const row of rows) { for (const row of rows) {
try { try {
await row.findByCssSelector('[test-api-default="true"]') await row.findByCssSelector('[test-api-default="true"]');
const trashButton = await row.findByCssSelector('[data-test-subj="apiTableTrashButton"]') const trashButton = await row.findByCssSelector(
'[data-test-subj="apiTableTrashButton"]'
);
await trashButton.click(); await trashButton.click();
return; return;
} catch (error) {} } catch (error) {}
} }
} }
} }
return new ApiPage; return new ApiPage();
} }

View File

@ -2,6 +2,6 @@ import { ApiProvider } from './api_page';
import { WazuhCommonProvider } from './wazuh_common_page'; import { WazuhCommonProvider } from './wazuh_common_page';
export const pageObjects = { export const pageObjects = {
api: ApiProvider, api: ApiProvider,
wazuhCommon: WazuhCommonProvider, wazuhCommon: WazuhCommonProvider
} };

View File

@ -22,13 +22,12 @@ export function WazuhCommonProvider({ getService, getPageObjects }) {
* @class WazuhCommonPage * @class WazuhCommonPage
*/ */
class WazuhCommonPage { class WazuhCommonPage {
/** /**
* Navigate to `Security events` without the timestamp parameter in the URL * Navigate to `Security events` without the timestamp parameter in the URL
* *
* @memberof WazuhCommonPage * @memberof WazuhCommonPage
*/ */
async OpenSecurityEvents () { async OpenSecurityEvents() {
log.debug('Open Security events'); log.debug('Open Security events');
await PageObjects.common.navigateToApp('settings'); await PageObjects.common.navigateToApp('settings');
await appsMenu.clickLink('Wazuh'); await appsMenu.clickLink('Wazuh');
@ -41,7 +40,7 @@ export function WazuhCommonProvider({ getService, getPageObjects }) {
* *
* @memberof WazuhCommonPage * @memberof WazuhCommonPage
*/ */
async OpenIntegrityMonitoring () { async OpenIntegrityMonitoring() {
log.debug('Open Security events'); log.debug('Open Security events');
await PageObjects.common.navigateToApp('settings'); await PageObjects.common.navigateToApp('settings');
await appsMenu.clickLink('Wazuh'); await appsMenu.clickLink('Wazuh');
@ -49,19 +48,20 @@ export function WazuhCommonProvider({ getService, getPageObjects }) {
await testSubjects.click('overviewWelcomeFim'); await testSubjects.click('overviewWelcomeFim');
} }
/** /**
* Select `today` in the commonly used times * Select `today` in the commonly used times
* *
* @memberof WazuhCommonPage * @memberof WazuhCommonPage
*/ */
async setTodayRange () { async setTodayRange() {
log.debug('Set today in the time range picker'); log.debug('Set today in the time range picker');
await PageObjects.timePicker.setCommonlyUsedTime('superDatePickerCommonlyUsed_Today'); await PageObjects.timePicker.setCommonlyUsedTime(
'superDatePickerCommonlyUsed_Today'
);
await PageObjects.common.sleep(3000); await PageObjects.common.sleep(3000);
await testSubjects.click('querySubmitButton'); await testSubjects.click('querySubmitButton');
await PageObjects.common.sleep(3000); await PageObjects.common.sleep(3000);
} }
} }
return new WazuhCommonPage; return new WazuhCommonPage();
} }

View File

@ -8,16 +8,15 @@ export function ExtensionPopoverProvider({ getService, getPageObjects }) {
* @class ExtensionPopover * @class ExtensionPopover
*/ */
class ExtensionPopover { class ExtensionPopover {
/** /**
* Check if the view has PopOvers * Check if the view has PopOvers
* *
* @returns {bool} * @returns {bool}
* @memberof ExtensionPopover * @memberof ExtensionPopover
*/ */
async availablePopovers () { async availablePopovers() {
const currentUrl = await browser.getCurrentUrl(); const currentUrl = await browser.getCurrentUrl();
if(currentUrl.includes('tab=welcome')){ if (currentUrl.includes('tab=welcome')) {
return true; return true;
} }
throw new Error('The current view has not popovers'); throw new Error('The current view has not popovers');
@ -31,24 +30,23 @@ export function ExtensionPopoverProvider({ getService, getPageObjects }) {
* @returns {bool} extension status * @returns {bool} extension status
* @memberof ExtensionPopover * @memberof ExtensionPopover
*/ */
async checkedPopover (key, popOver) { async checkedPopover(key, popOver) {
await this.availablePopovers(); await this.availablePopovers();
if (await testSubjects.exists(popOver)){ if (await testSubjects.exists(popOver)) {
await testSubjects.click(popOver); await testSubjects.click(popOver);
} else { } else {
throw new Error(`Error to locate ${popOver}`); throw new Error(`Error to locate ${popOver}`);
} }
if (await testSubjects.exists(key, { allowHidden: true })){ if (await testSubjects.exists(key, { allowHidden: true })) {
await testSubjects.click(key); await testSubjects.click(key);
const result = await testSubjects.getProperty(key, 'checked'); const result = await testSubjects.getProperty(key, 'checked');
return result; return result;
} else { } else {
throw new Error(`Error to locate ${key}`); throw new Error(`Error to locate ${key}`);
} }
} }
} }
return new ExtensionPopover(); return new ExtensionPopover();
} }

View File

@ -15,5 +15,5 @@ export const services = {
esAreaChart: EsAreaChartProvider, esAreaChart: EsAreaChartProvider,
esPieChart: EsPieChartProvider, esPieChart: EsPieChartProvider,
esTableViz: EsTableVizProvider, esTableViz: EsTableVizProvider,
arrayHelper: ArrayHelperProvider, arrayHelper: ArrayHelperProvider
} };