Fixes for 3.9.4-6.8.1 release (#1623)

This commit is contained in:
Juanka Rodríguez 2019-07-23 13:34:54 +02:00 committed by Jesús Ángel
parent 5eb20a6dc0
commit 7f49b9ba31
34 changed files with 377 additions and 129 deletions

View File

@ -2,6 +2,27 @@
All notable changes to the Wazuh app project will be documented in this file.
## Wazuh v3.9.4 - Kibana v6.8.1 Revision 451
### Added
- Support for Wazuh v3.9.4
- Allow filtering by clicking a column in rules/decoders tables [262d7f7](https://github.com/wazuh/wazuh-kibana-app/commit/262d7f7a145a18902a6c5d55dab96c07ac66d9bb).
- Allow open file in rules table clicking on the file column [262d7f7](https://github.com/wazuh/wazuh-kibana-app/commit/262d7f7a145a18902a6c5d55dab96c07ac66d9bb).
### Changed
- Remove path filter from custom rules and decoders [262d7f7](https://github.com/wazuh/wazuh-kibana-app/commit/262d7f7a145a18902a6c5d55dab96c07ac66d9bb).
- Show path column in rules and decoders [262d7f7](https://github.com/wazuh/wazuh-kibana-app/commit/262d7f7a145a18902a6c5d55dab96c07ac66d9bb).
- Removed SCA overview dashboard [6946a34](https://github.com/wazuh/wazuh-kibana-app/commit/6946a34b602c6a502219359570653cc38101fd12).
- Disabled last custom column removal [06f3d4b](https://github.com/wazuh/wazuh-kibana-app/commit/06f3d4b70ca3401160b62e5990f14a243807e8d3).
### Fixed
- Improved wz-table performance [262d7f7](https://github.com/wazuh/wazuh-kibana-app/commit/262d7f7a145a18902a6c5d55dab96c07ac66d9bb).
- Timezone applied in cluster status [9a3a582](https://github.com/wazuh/wazuh-kibana-app/commit/9a3a5827365308fb8fb54cd47eb1d8d0ad76b3b5).
- Fixed Overview Security Events report when wazuh.monitoring is disabled [78d6693](https://github.com/wazuh/wazuh-kibana-app/commit/78d669378dd342a9ae735eb9c0fde9b31cc69ac8).
## Wazuh v3.9.3 - Kibana v6.8.1 Revision 450
### Added

View File

@ -1,8 +1,8 @@
{
"name": "wazuh",
"version": "3.9.3",
"revision": "0450",
"code": "0450-0",
"version": "3.9.4",
"revision": "0451",
"code": "0451-0",
"kibana": {
"version": "6.8.1"
},
@ -64,4 +64,4 @@
"typescript": "^3.0.1",
"typescript-eslint-parser": "^18.0.0"
}
}
}

View File

@ -316,7 +316,7 @@ export class AgentsController {
this.$scope.switchConfigurationTab = (configurationTab, navigate) => {
// Check if configuration is synced
this.$scope.isSynchronized = this.checkSync();
this.checkSync();
this.$scope.navigate = navigate;
this.configurationHandler.switchConfigurationTab(
configurationTab,
@ -672,7 +672,9 @@ export class AgentsController {
`/agents/${this.$scope.agent.id}/group/is_sync`,
{}
);
return (((isSync || {}).data || {}).data || {}).synced || false;
this.$scope.isSynchronized =
(((isSync || {}).data || {}).data || {}).synced || false;
this.$scope.$applyAsync();
}
/**
@ -985,7 +987,9 @@ export class AgentsController {
{}
);
this.errorHandler.info(
`Policy monitoring scan launched successfully on agent ${this.$scope.agent.id}`,
`Policy monitoring scan launched successfully on agent ${
this.$scope.agent.id
}`,
''
);
} catch (error) {

View File

@ -83,7 +83,7 @@ export class DevToolsController {
}
);
// Register plugin for code mirror
CodeMirror.commands.autocomplete = function (cm) {
CodeMirror.commands.autocomplete = function(cm) {
CodeMirror.showHint(cm, CodeMirror.hint.dictionaryHint, {
completeSingle: false
});
@ -335,7 +335,7 @@ export class DevToolsController {
this.apiInputBox.setSize('auto', '100%');
this.apiInputBox.model = [];
this.getAvailableMethods();
this.apiInputBox.on('keyup', function (cm, e) {
this.apiInputBox.on('keyup', function(cm, e) {
if (!ExcludedIntelliSenseTriggerKeys[(e.keyCode || e.which).toString()]) {
cm.execCommand('autocomplete', null, {
completeSingle: false
@ -359,22 +359,22 @@ export class DevToolsController {
this.highlightGroup(currentGroup);
// Register our custom Codemirror hint plugin.
CodeMirror.registerHelper('hint', 'dictionaryHint', function (editor) {
CodeMirror.registerHelper('hint', 'dictionaryHint', function(editor) {
const model = editor.model;
function getDictionary(line, word) {
let hints = [];
const exp = line.split(/\s+/g);
if (exp[0] && exp[0].match(/^(?:GET|PUT|POST|DELETE).*$/)) {
let method = model.find(function (item) {
let method = model.find(function(item) {
return item.method === exp[0];
});
const forbidChars = /^[^?{]+$/;
if (method && !exp[2] && forbidChars.test(word)) {
method.endpoints.forEach(function (endpoint) {
method.endpoints.forEach(function(endpoint) {
endpoint.path = endpoint.name;
if (endpoint.args && endpoint.args.length > 0) {
let argSubs = [];
endpoint.args.forEach(function (arg) {
endpoint.args.forEach(function(arg) {
const pathSplitted = endpoint.name.split('/');
const arrayIdx = pathSplitted.indexOf(arg.name);
const wordSplitted = word.split('/');
@ -386,7 +386,7 @@ export class DevToolsController {
}
});
let auxPath = endpoint.name;
argSubs.forEach(function (arg) {
argSubs.forEach(function(arg) {
auxPath = auxPath.replace(arg.id, arg.value);
});
endpoint.path = auxPath;
@ -407,26 +407,26 @@ export class DevToolsController {
const whiteSpace = /\s/;
while (end < curLine.length && !whiteSpace.test(curLine.charAt(end)))
++end;
while (start && !whiteSpace.test(curLine.charAt(start - 1)))--start;
while (start && !whiteSpace.test(curLine.charAt(start - 1))) --start;
const curWord = start !== end && curLine.slice(start, end);
return {
list: (!curWord
? []
: getDictionary(curLine, curWord).filter(function (item) {
return item.toUpperCase().includes(curWord.toUpperCase());
})
: getDictionary(curLine, curWord).filter(function(item) {
return item.toUpperCase().includes(curWord.toUpperCase());
})
).sort(),
from: CodeMirror.Pos(cur.line, start),
to: CodeMirror.Pos(cur.line, end)
};
});
const evtDocument = this.$document[0];
$('.wz-dev-column-separator').mousedown(function (e) {
$('.wz-dev-column-separator').mousedown(function(e) {
e.preventDefault();
$('.wz-dev-column-separator').addClass('active');
const leftOrigWidth = $('#wz-dev-left-column').width();
const rightOrigWidth = $('#wz-dev-right-column').width();
$(evtDocument).mousemove(function (e) {
$(evtDocument).mousemove(function(e) {
const leftWidth = e.pageX - 215 + 14;
let rightWidth = leftOrigWidth - leftWidth;
$('#wz-dev-left-column').css('width', leftWidth);
@ -434,7 +434,7 @@ export class DevToolsController {
});
});
$(evtDocument).mouseup(function () {
$(evtDocument).mouseup(function() {
$('.wz-dev-column-separator').removeClass('active');
$(evtDocument).unbind('mousemove');
});
@ -454,7 +454,7 @@ export class DevToolsController {
const dynamicHeight = () => {
const self = this;
const window = this.$window;
setTimeout(function () {
setTimeout(function() {
const windows = $(window).height();
$('#wz-dev-left-column').height(
windows - (self.getPosition($('#wz-dev-left-column')[0]).y + 20)
@ -467,7 +467,7 @@ export class DevToolsController {
);
$('.wz-dev-column-separator span').height(
windows -
(self.getPosition($('.wz-dev-column-separator span')[0]).y + 20)
(self.getPosition($('.wz-dev-column-separator span')[0]).y + 20)
);
}, 1);
};
@ -483,10 +483,10 @@ export class DevToolsController {
const desiredGroup = firstTime
? this.groups.filter(item => item.requestText)
: this.groups.filter(
item =>
item.requestText &&
(item.end >= selection.line && item.start <= selection.line)
);
item =>
item.requestText &&
(item.end >= selection.line && item.start <= selection.line)
);
// Place play button at first line from the selected group
const cords = this.apiInputBox.cursorCoords({
@ -542,12 +542,12 @@ export class DevToolsController {
const method = desiredGroup.requestText.startsWith('GET')
? 'GET'
: desiredGroup.requestText.startsWith('POST')
? 'POST'
: desiredGroup.requestText.startsWith('PUT')
? 'PUT'
: desiredGroup.requestText.startsWith('DELETE')
? 'DELETE'
: 'GET';
? 'POST'
: desiredGroup.requestText.startsWith('PUT')
? 'PUT'
: desiredGroup.requestText.startsWith('DELETE')
? 'DELETE'
: 'GET';
let requestCopy = desiredGroup.requestText.includes(method)
? desiredGroup.requestText.split(method)[1].trim()
@ -634,8 +634,7 @@ export class DevToolsController {
var yPosition = 0;
while (element) {
xPosition +=
element.offsetLeft - element.scrollLeft + element.clientLeft;
xPosition += element.offsetLeft - element.scrollLeft + element.clientLeft;
yPosition += element.offsetTop - element.scrollTop + element.clientTop;
element = element.offsetParent;
}

View File

@ -92,6 +92,14 @@ export class DecodersController {
this.$scope.restartBtn = true;
this.$scope.$applyAsync();
});
this.$scope.$on('applyFilter', (event, parameters) => {
this.search(parameters.filter);
});
this.$scope.$on('viewFileOnlyTable', (event, parameters) => {
this.$scope.mctrl.switchFilesSubTab('decoders', { parameters });
});
}
/**
@ -293,6 +301,14 @@ export class DecodersController {
this.closeDetailView();
}
openFile(file, path) {
if (file && path) {
this.$scope.mctrl.switchFilesSubTab('rules', {
parameters: { file: { file, path }, path }
});
}
}
/**
* This function changes to the decoders list view
*/

View File

@ -33,6 +33,19 @@ export class FilesController {
$onInit() {
const configuration = this.wazuhConfig.getConfig();
this.adminMode = !!(configuration || {}).admin;
if (this.$scope.mctrl.showFile) {
this.$scope.editorReadOnly = !(
this.$scope.mctrl.showFile.parameters.path === 'etc/rules' ||
this.$scope.mctrl.showFile.parameters.path === 'etc/decoders'
);
this.editFile(
this.$scope.mctrl.showFile.parameters,
this.$scope.editorReadOnly
);
this.$scope.goBack = true;
this.$scope.viewingDetail = this.$scope.mctrl.showFile.parameters.viewingDetail;
}
this.$scope.mctrl.showFile = false;
this.$scope.$on('editFile', (ev, params) => {
this.$scope.editorReadOnly = false;
@ -50,6 +63,16 @@ export class FilesController {
this.$scope.editingFile = false;
this.$scope.editorReadOnly = false;
this.$scope.fetchedXML = null;
if (this.$scope.goBack) {
if (this.$scope.viewingDetail) {
this.$scope.mctrl.setCurrentRule({
currentRule: this.$scope.mctrl.currentRule
});
this.$scope.mctrl.currentRule = null;
}
this.$scope.mctrl.setRulesTab(this.$scope.mctrl.globalRulesetTab);
this.$scope.goBack = false;
}
this.search();
this.$scope.$applyAsync();
};
@ -136,9 +159,9 @@ export class FilesController {
this.$scope.newFile = false;
try {
this.$scope.currentFile = params.file;
this.$scope.currentFile.type = params.path.includes('rules')
? 'rule'
: 'decoder';
this.$scope.currentFile.type = params.path.includes('decoder')
? 'decoder'
: 'rule';
this.$scope.type = `${this.$scope.currentFile.type}s`;
this.$scope.fetchedXML =
this.$scope.type === 'rules'

View File

@ -523,7 +523,7 @@ export function GroupsController(
const deleteResponse = await apiReq.request(
'DELETE',
`/agents/group/${$scope.currentGroup.name}`,
{ ids: itemsToSave.deletedIds }
{ ids: itemsToSave.deletedIds.toString() }
);
if (deleteResponse.data.data.failed_ids) {
failedIds.push(...deleteResponse.data.data.failed_ids);
@ -537,7 +537,9 @@ export function GroupsController(
}));
$scope.failedErrors = groupBy(failedErrors, 'message') || false;
errorHandler.info(
`Group has been updated but an error has occurred with ${failedIds.length} agents`,
`Group has been updated but an error has occurred with ${
failedIds.length
} agents`,
'',
true
);

View File

@ -56,9 +56,7 @@ export class ManagementController {
this.appState.setNavigation({ status: true });
});
this.$scope.$on('setCurrentRule', (ev, params) => {
this.currentRule = (params || {}).currentRule || false;
this.$location.search('currentRule', true);
this.appState.setNavigation({ status: true });
this.setCurrentRule(params);
});
this.$scope.$on('removeCurrentRule', () => {
this.currentRule = false;
@ -92,6 +90,14 @@ export class ManagementController {
this.$scope.$on('removeCurrentConfiguration', () => {
this.currentConfiguration = false;
});
this.$scope.$on('viewFileOnly', (ev, params) => {
$scope.$broadcast('viewFileOnlyTable', {
file: params.item,
path: params.path
});
});
this.$rootScope.$on('setRestarting', () => {
if (this.clusterInfo.status === 'enabled') {
this.blockEditioncounter = 0;
@ -213,6 +219,12 @@ export class ManagementController {
});
}
setCurrentRule(params) {
this.currentRule = (params || {}).currentRule || false;
this.$location.search('currentRule', true);
this.appState.setNavigation({ status: true });
}
/**
* This switch to a selected tab
* @param {String} tab
@ -268,8 +280,11 @@ export class ManagementController {
this.breadCrumbBack();
}
switchFilesSubTab(flag) {
switchFilesSubTab(flag, showFile) {
this.managingFiles = flag || true;
if (showFile) {
this.showFile = showFile;
}
}
breadCrumbBack(goRoot = false) {

View File

@ -232,6 +232,18 @@ export function RulesController(
$scope.closeDetailView();
};
$scope.openFile = (file, path) => {
if (file && path) {
$scope.mctrl.switchFilesSubTab('rules', {
parameters: {
file: { file, path },
path,
viewingDetail: $scope.viewingDetail
}
});
}
};
//listeners
$scope.$on('wazuhShowRule', (event, parameters) => {
$scope.currentRule = parameters.rule;
@ -381,4 +393,13 @@ export function RulesController(
$scope.overwriteError = true;
$scope.$applyAsync();
});
$scope.$on('applyFilter', (event, parameters) => {
$scope.search(parameters.filter);
});
$scope.$on('viewFileOnlyTable', (event, parameters) => {
parameters.viewingDetail = $scope.viewingDetail;
$scope.mctrl.switchFilesSubTab('rules', { parameters });
});
}

View File

@ -10,7 +10,7 @@
* Find more information about this on the LICENSE file.
*/
export class StatusController {
constructor($scope, errorHandler, apiReq, wazuhConfig) {
constructor($scope, errorHandler, apiReq, wazuhConfig, timeService) {
this.$scope = $scope;
this.errorHandler = errorHandler;
this.apiReq = apiReq;
@ -19,6 +19,7 @@ export class StatusController {
this.selectedNode = false;
this.clusterError = false;
this.wazuhConfig = wazuhConfig;
this.timeService = timeService;
}
/**
@ -42,6 +43,14 @@ export class StatusController {
return arr;
}
offsetTimestamp(time) {
try {
return this.timeService.offset(time);
} catch (error) {
return time !== '-' ? `${time} (UTC)` : time;
}
}
/**
* Fetchs all required data
*/

View File

@ -201,7 +201,9 @@ export class SettingsController {
this.currentDefault = JSON.parse(currentApi).id;
this.errorHandler.info(
`API ${this.apiEntries[index]._source.cluster_info.manager} set as default`,
`API ${
this.apiEntries[index]._source.cluster_info.manager
} set as default`,
'Settings'
);

View File

@ -4,7 +4,7 @@
</div>
<div ng-show="showDropdown" class="chips-dropdown">
<ul class="uiSelectChoices--autoWidth ui-select-choices ui-select-choices-content ui-select-dropdown dropdown-menu">
<li class="ui-select-choices-group" ng-repeat="chip in options track by $index">
<li class="ui-select-choices-group" ng-repeat="chip in options track by $index" ng-hide="chip.hide">
<div class="ui-select-choices-row" role="option" ng-click="select(chip)">
<span class="ui-select-choices-row-inner">
{{chip.label}}

View File

@ -111,7 +111,7 @@ class WzConfigViewer {
$scope.$applyAsync();
$scope.isLogs
? dynamicHeight()
: window.dispatchEvent(new Event('resize'));
: window.dispatchEvent(new Event('resize')); // eslint-disable-line
}, 200);
}
};

View File

@ -201,8 +201,8 @@ app.directive('wzListManage', function() {
* Cancel edition of an entry
*/
$scope.cancelEditingKey = () => {
$scope.editingKey = false;
$scope.loadingChange = false;
$scope.editingKey = false;
$scope.loadingChange = false;
$scope.editingNewValue = '';
};

View File

@ -135,7 +135,10 @@ class WzRegisterAgents {
try {
const data = await apiReq.request(
'PUT',
`/agents/${$scope.registerObj.systems[$scope.registerObj.selectedSystem].steps[3].id}/restart`,
`/agents/${
$scope.registerObj.systems[$scope.registerObj.selectedSystem]
.steps[3].id
}/restart`,
{}
);
const result = ((data || {}).data || {}).data || false;
@ -143,7 +146,10 @@ class WzRegisterAgents {
throw new Error('Unexpected error restarting agent');
}
errorHandler.info(
`Success. Agent ${$scope.registerObj.systems[$scope.registerObj.selectedSystem].steps[0].agentName} has been registered.`
`Success. Agent ${
$scope.registerObj.systems[$scope.registerObj.selectedSystem]
.steps[0].agentName
} has been registered.`
);
$scope.nextStep();
} catch (error) {

View File

@ -26,7 +26,7 @@ import { checkGap } from './lib/check-gap';
const app = uiModules.get('app/wazuh', []);
app.directive('wzTable', function () {
app.directive('wzTable', function() {
return {
restrict: 'E',
scope: {
@ -59,26 +59,31 @@ app.directive('wzTable', function () {
$scope.showColumns = false;
$scope.scapepath = $scope.path.split('/').join('');
$scope.originalkeys = $scope.keys.map((key, idx) => ({ key, idx }));
$scope.updateColumns = key => {
const str = key.key.value || key.key;
const cleanArray = $scope.keys.map(item => item.value || item);
if (cleanArray.includes(str)) {
const idx = cleanArray.indexOf(str);
if (idx > -1) {
$scope.keys.splice(idx, 1);
}
} else {
const originalIdx = $scope.originalkeys.findIndex(
item => (item.key.value || item.key) === (key.key.value || key.key)
);
if (originalIdx >= 0) {
$scope.keys.splice(originalIdx, 0, key.key);
if (!$scope.isLastKey(key)) {
const str = key.key.value || key.key;
const cleanArray = $scope.keys.map(item => item.value || item);
if (cleanArray.includes(str)) {
const idx = cleanArray.indexOf(str);
if (idx > -1) {
$scope.keys.splice(idx, 1);
}
} else {
$scope.keys.push(key.key);
const originalIdx = $scope.originalkeys.findIndex(
item =>
(item.key.value || item.key) === (key.key.value || key.key)
);
if (originalIdx >= 0) {
$scope.keys.splice(originalIdx, 0, key.key);
} else {
$scope.keys.push(key.key);
}
}
init(true);
}
init(true);
};
$scope.exists = key => {
const str = key.key.value || key.key;
for (const k of $scope.keys) if ((k.value || k) === str) return true;
@ -168,6 +173,7 @@ app.directive('wzTable', function () {
filters: instance.filters
});
}
filterableColumns();
if ($scope.customColumns) {
setTimeout(() => {
$scope.setColResizable();
@ -300,11 +306,11 @@ app.directive('wzTable', function () {
$scope.prevPage = () => pagination.prevPage($scope);
$scope.nextPage = async (currentPage, last = false) =>
pagination.nextPage(currentPage, $scope, errorHandler, fetch, last);
$scope.firstPage = function () {
$scope.firstPage = function() {
$scope.setPage(1);
$scope.prevPage();
};
$scope.setPage = function (page = false, logs = false, last = false) {
$scope.setPage = function(page = false, logs = false, last = false) {
this.n = page || this.n;
$scope.currentPage = this.n;
$scope.nextPage(this.n, last).then(() => {
@ -505,6 +511,48 @@ app.directive('wzTable', function () {
$c.remove();
};
$scope.parseKey = key => {
return key ? key.value || key : key;
};
const filterableColumns = () => {
$scope.filterableColumns = [];
$scope.keys.forEach(k => {
const key = $scope.parseKey(k);
const canFilterInRules =
$scope.path === '/rules' &&
(key === 'level' || key === 'file' || key === 'path');
const canFilterInDecoders =
$scope.path === '/decoders' && (key === 'path' || key === 'file');
$scope.filterableColumns[key] = !!(
canFilterInRules || canFilterInDecoders
);
});
};
$scope.handleClick = (key, item, ev) => {
const value = $scope.parseValue(key, item);
let keyTmp = $scope.parseKey(key);
const valueTmp = typeof value !== 'string' ? value.toString() : value;
if ($scope.filterableColumns[keyTmp]) {
if (value !== '-' && keyTmp !== 'file') {
const filter = `${keyTmp}:${valueTmp}`;
$scope.$emit('applyFilter', { filter });
} else if (keyTmp === 'file') {
$scope.$emit('viewFileOnlyTable', { file: item, path: item.path });
}
ev.stopPropagation();
}
};
$scope.isLastKey = key => {
const exists = $scope.exists(key);
const keysLength = $scope.keys.length === 1;
const keyValue = key.key.value || key.key;
const lastKeyValue = $scope.keys[0].value || $scope.keys[0];
return exists && keysLength && keyValue && lastKeyValue;
};
$scope.setColResizable = () => {
$(`#table${$scope.scapepath} th`).resizable({
handles: 'e',

View File

@ -4,7 +4,8 @@
<div ng-if="customColumns" layout="row" ng-show="!error && !wazuh_table_loading && items.length" class="columns-bar"
ng-class="{'columns-bar-active': showColumns}" ng-style="!showColumns && {'margin-bottom': '-35px'}">
<div ng-if="showColumns" class="euiCheckbox wz-margin-right-8" ng-repeat="key in originalkeys" ng-click="updateColumns(key)">
<input class="euiCheckbox__input" type="checkbox" aria-label="Select all rows" ng-checked="exists(key)">
<input class="euiCheckbox__input" type="checkbox" aria-label="Select all rows" ng-checked="exists(key)"
ng-disabled="isLastKey(key)">
<div class="euiCheckbox__square"></div>
<span class="euiCheckbox__label">{{ keyEquivalence[key.key.value || key.key] }}</span>
</div>
@ -29,16 +30,19 @@
</th>
<th ng-if="(path === '/agents' || (path === '/agents/groups' && adminMode) || (isLookingGroup() && adminMode)
|| path === '/rules/files' || path === '/decoders/files' || path === '/lists/files')"
class="euiTableHeaderCell wz-text-left">
class="euiTableHeaderCell wz-text-left" ng-style="path !== '/agents' && {'width':'350px'}">
Actions
</th>
</thead>
<tbody>
<tr ng-class="allowClick ? 'cursor-pointer' : ''" class="wz-word-wrap" ng-repeat="item in pagedItems[currentPage] | filter:{item:'!'}"
ng-click="clickAction(item)">
<td ng-repeat="key in keys" id="{{scapepath}}-td-{{$parent.$index}}-{{$index}}" ng-mouseover="showTooltip($parent.$index, $index, item, scapepath)">
<div class="wz-text-truncatable-container">
<span class="wz-text-truncatable">
ng-click="clickAction(item)" ng-mouseover="selectedRow = $index" ng-mouseleave="selectedRow = false">
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}" ng-mouseover="selectedCell = $index; showTooltip($parent.$index, $index, item);"
ng-mouseleave="selectedCell = false" ng-click="handleClick(key,item,$event)">
<div class="wz-text-truncatable-container">
<span class="wzTableCellFilter" ng-show="filterableColumns[parseKey(key)] && selectedRow === $parent.$index && selectedCell == $index">
<span class="fa fa-search-plus"></span> </span>
<span class="wz-text-truncatable" ng-class="parseKey(key) === 'file' && (path === '/rules' || path === '/decoders' )? 'euiLink euiLink--primary' : ''">
{{
parseValue(key,item)
}}

View File

@ -286,7 +286,9 @@ app.directive('wzXmlFileEditor', function() {
} catch (err) {
params.showRestartManager = 'warn';
}
const msg = `Success. Node (${params.node}) configuration has been updated`;
const msg = `Success. Node (${
params.node
}) configuration has been updated`;
params.showRestartManager
? params.showRestartManager !== 'warn'
? showRestartMessage(msg, params.node)

View File

@ -987,3 +987,9 @@ wz-xml-file-editor {
discover-app-w .container-fluid {
background: #fff;
}
.wzTableCellFilter{
text-align: right;
height: 0;
cursor: pointer;
}

View File

@ -20,7 +20,8 @@ export class ReportingService {
rawVisualizations,
visHandlers,
genericReq,
errorHandler
errorHandler,
wazuhConfig
) {
this.$rootScope = $rootScope;
this.vis2png = vis2png;
@ -28,6 +29,20 @@ export class ReportingService {
this.visHandlers = visHandlers;
this.genericReq = genericReq;
this.errorHandler = errorHandler;
this.wazuhConfig = wazuhConfig;
}
removeAgentStatusVis(idArray) {
const monitoringEnabled = this.wazuhConfig.getConfig()[
'wazuh.monitoring.enabled'
];
if (!monitoringEnabled) {
const visArray = idArray.filter(vis => {
return vis !== 'Wazuh-App-Overview-General-Agents-status';
});
return visArray;
}
return idArray;
}
async startVis2Png(tab, isAgents = false, syscollectorFilters = null) {
@ -42,7 +57,14 @@ export class ReportingService {
this.vis2png.clear();
const idArray = this.rawVisualizations.getList().map(item => item.id);
let idArray = [];
if (tab === 'general') {
idArray = this.removeAgentStatusVis(
this.rawVisualizations.getList().map(item => item.id)
);
} else {
idArray = this.rawVisualizations.getList().map(item => item.id);
}
for (const item of idArray) {
const tmpHTMLElement = $(`#${item}`);

View File

@ -26,7 +26,6 @@ export function settingsWizard(
) {
try {
const deferred = $q.defer();
const checkResponse = data => {
let fromElastic = false;
if (parseInt(data.data.error) === 2) {
@ -156,14 +155,27 @@ export function settingsWizard(
})
.catch(() => {
appState.removeCurrentAPI();
$location.search('tab', 'welcome');
$location.path('/overview');
deferred.resolve();
setUpCredentials(
'Wazuh App: Please set up Wazuh API credentials.',
false
);
});
};
const setUpCredentials = (msg, redirect = false) => {
const comeFromWizard = wzMisc.getWizard();
!comeFromWizard && errorHandler.handle(msg, false, true);
wzMisc.setWizard(true);
if (redirect) {
appState.setCurrentAPI(redirect);
} else if (!$location.path().includes('/settings')) {
$location.search('_a', null);
$location.search('tab', 'api');
$location.path('/settings');
}
return deferred.resolve();
};
const currentParams = $location.search();
const targetedAgent =
currentParams && (currentParams.agent || currentParams.agent === '000');
@ -179,7 +191,8 @@ export function settingsWizard(
deferred.resolve();
} else {
// There's no cookie for current API
if (!appState.getCurrentAPI()) {
const currentApi = appState.getCurrentAPI();
if (!currentApi) {
genericReq
.request('GET', '/elastic/apis')
.then(data => {
@ -193,20 +206,9 @@ export function settingsWizard(
);
callCheckStored();
} else {
const comeFromWizard = wzMisc.getWizard();
!comeFromWizard &&
errorHandler.handle(
'Wazuh App: Please set up Wazuh API credentials.',
false,
true
);
wzMisc.setWizard(true);
if (!$location.path().includes('/settings')) {
$location.search('_a', null);
$location.search('tab', 'api');
$location.path('/settings');
}
deferred.resolve();
setUpCredentials(
'Wazuh App: Please set up Wazuh API credentials.'
);
}
})
.catch(error => {
@ -220,7 +222,37 @@ export function settingsWizard(
deferred.resolve();
});
} else {
callCheckStored();
const apiId = (JSON.parse(currentApi) || {}).id;
genericReq
.request('GET', '/elastic/apis')
.then(data => {
if (
data.data.length > 0 &&
data.data.find(x => x['_id'] == apiId)
) {
callCheckStored();
} else {
appState.removeCurrentAPI();
if (data.data.length > 0) {
const defaultApi = JSON.stringify({
name: data.data[0]._source.cluster_info.manager,
id: data.data[0]._id
});
setUpCredentials(
'Wazuh App: Default API has been updated.',
defaultApi
);
} else {
setUpCredentials(
'Wazuh App: Please set up Wazuh API credentials.',
false
);
}
}
})
.catch(() => {
setUpCredentials('Wazuh App: Please set up Wazuh API credentials.');
});
}
}

View File

@ -21,7 +21,7 @@
<span class="wz-text-bold">{{dctrl.currentDecoder.position}}</span></div>
<div flex="40" ng-if="dctrl.currentDecoder.file" class="wz-text-truncatable">File: <span
class="wz-text-bold wz-text-link"
ng-click="dctrl.addDetailFilter('file', dctrl.currentDecoder.file)"
ng-click="dctrl.openFile(dctrl.currentDecoder.file,dctrl.currentDecoder.path)"
tooltip="Filter by this file" tooltip-placement="bottom">{{dctrl.currentDecoder.file}}</span>
</div>
<div flex="40" ng-if="dctrl.currentDecoder.path" class="wz-text-truncatable">Path: <span

View File

@ -6,7 +6,7 @@
class="euiFieldSearch euiFieldSearch--fullWidth euiFlexItem height-35 ng-empty ng-pristine ng-touched ng-valid"
aria-invalid="false" wz-enter="dctrl.search(dctrl.custom_search)" id="search-input-rules">
<wz-add-filter-chip id-input="search-input-rules"
options="[{label: 'File', value: 'file'}, {label: 'Path', value: 'path'}]" />
options="[{label: 'File', value: 'file'}, {label: 'Path', value: 'path', hide: dctrl.showingLocalDecoders}]" />
<div class="euiFormControlLayoutIcons wz-margin-left-16">
<span class="euiFormControlLayoutCustomIcon">
<react-component name="EuiIcon"
@ -48,11 +48,11 @@
<md-card-content class="wz-padding-bottom-0">
<wz-table custom-columns="true" ng-if="!dctrl.showingLocalDecoders"
implicit-filter="dctrl.appliedFilters" flex path="'/decoders'"
keys="['name',{value:'details.program_name',size:2,nosortable:true},{value:'details.order',size:2,nosortable:true},'file']"
keys="['name',{value:'details.program_name',size:2,nosortable:true},{value:'details.order',size:2,nosortable:true},'file','path']"
allow-click="true" row-sizes="[16,13,11]">
</wz-table>
<wz-table custom-columns="true" ng-if="dctrl.showingLocalDecoders" flex path="'/decoders'"
keys="['name',{value:'details.program_name',size:2,nosortable:true},{value:'details.order',size:2,nosortable:true},'file']"
keys="['name',{value:'details.program_name',size:2,nosortable:true},{value:'details.order',size:2,nosortable:true},'file','path']"
implicit-filter="dctrl.appliedFilters" allow-click="true" row-sizes="[16,13,11]">
</wz-table>
</md-card-content>

View File

@ -1,4 +1,4 @@
<div ng-if="!files.viewingDetail" ng-show="!editingFile" layout="column"
<div ng-if="!viewingDetail" ng-show="!editingFile" layout="column"
ng-init="filesctrl.switchFilesSubTab(mctrl.globalRulesetTab)">
<div layout="row">

View File

@ -22,7 +22,7 @@
<span class="wz-text-bold wz-text-link" ng-click="addDetailFilter('level', currentRule.level)"
tooltip="Filter by this level" tooltip-placement="bottom">{{currentRule.level}}</span></div>
<div flex="35" ng-if="currentRule.file" class="wz-text-truncatable">File: <span
class="wz-text-bold wz-text-link" ng-click="addDetailFilter('file', currentRule.file)"
class="wz-text-bold wz-text-link" ng-click="openFile(currentRule.file,currentRule.path)"
tooltip="Filter by this file" tooltip-placement="bottom">{{currentRule.file}}</span></div>
<div flex="35" ng-if="currentRule.path" class="wz-text-truncatable">Path: <span
class="wz-text-bold wz-text-link" ng-click="addDetailFilter('path', currentRule.path)"

View File

@ -6,7 +6,7 @@
<input placeholder="Filter rules..." ng-model="custom_search" type="text"
class="euiFieldSearch euiFieldSearch--fullWidth euiFlexItem height-35 ng-empty ng-pristine ng-touched ng-valid"
aria-invalid="false" wz-enter="search(custom_search)" id="search-input-rules">
<wz-add-filter-chip id-input="search-input-rules" options="[{label: 'File', value: 'file'}, {label: 'Path', value: 'path'}, {label: 'Level', value: 'level'},
<wz-add-filter-chip id-input="search-input-rules" options="[{label: 'File', value: 'file'}, {label: 'Path', value: 'path', hide: mctrl.showingLocalRules}, {label: 'Level', value: 'level'},
{label: 'Group', value: 'group'}, {label: 'PCI control', value: 'pci'}, {label: 'GDPR', value: 'gdpr'}]" />
<div class="euiFormControlLayoutIcons wz-margin-left-16">
<span class="euiFormControlLayoutCustomIcon">
@ -68,12 +68,12 @@
</md-card-actions>
<md-card-content class="wz-padding-bottom-0">
<wz-table custom-columns="true" flex ng-if="mctrl.showingLocalRules" path="'/rules'"
keys="[{value: 'id', width: '85px'},{value:'description', width: 'auto'},{value:'groups',nosortable:true, width: '250px'},{value:'pci',nosortable:true, width: '170px'},{value:'gdpr',nosortable:true,width: '170px'}, {value: 'level', width: '100px'}, {value:'file',width: '200px'}]"
keys="[{value: 'id', width: '85px'},{value:'description', width: 'auto'},{value:'groups',nosortable:true, width: '250px'},{value:'pci',nosortable:true, width: '170px'},{value:'gdpr',nosortable:true,width: '170px'}, {value: 'level', width: '100px'}, {value:'file',width: '200px'}, {value:'path',width: 'auto'}]"
implicit-filter="appliedFilters" allow-click="true" row-sizes="[16,14,12]">
</wz-table>
<wz-table custom-columns="true" ng-if="!mctrl.showingLocalRules" implicit-filter="appliedFilters" flex
path="'/rules'"
keys="[{value: 'id', width: '85px'},{value:'description', width: 'auto'},{value:'groups',nosortable:true, width: '250px'},{value:'pci',nosortable:true, width: '170px'},{value:'gdpr',nosortable:true,width: '170px'}, {value: 'level', width: '100px'}, {value:'file',width: '200px'}]"
keys="[{value: 'id', width: '85px'},{value:'description', width: 'auto'},{value:'groups',nosortable:true, width: '250px'},{value:'pci',nosortable:true, width: '170px'},{value:'gdpr',nosortable:true,width: '170px'}, {value: 'level', width: '100px'}, {value:'file',width: '200px'},{value:'path', width: 'auto'}]"
allow-click="true" row-sizes="[16,14,12]">
</wz-table>
</md-card-content>

View File

@ -168,7 +168,7 @@
<div layout="row" class="wz-padding-top-10">
<span flex="25">Date add</span>
<span
class="wz-text-right color-grey">{{ctrl.agentInfo.dateAdd ? ctrl.agentInfo.dateAdd : '-'}}</span>
class="wz-text-right color-grey">{{ ctrl.offsetTimestamp(ctrl.agentInfo.dateAdd) }}</span>
</div>
<div layout="row" class="wz-padding-top-10">
<span flex="25">Version</span>
@ -177,8 +177,7 @@
</div>
<div layout="row" class="wz-padding-top-10" ng-if="ctrl.agentInfo.id !== '000'">
<span flex="25">Last keep alive</span>
<span class="wz-text-right color-grey">{{ctrl.agentInfo.lastKeepAlive ?
ctrl.agentInfo.lastKeepAlive : '-'}}</span>
<span class="wz-text-right color-grey">{{ ctrl.offsetTimestamp(ctrl.agentInfo.lastKeepAlive) }}</span>
</div>
<div layout="row" class="wz-padding-top-10">
<span flex="25">Operating system</span>

View File

@ -51,9 +51,6 @@
<wz-welcome-card class="euiFlexItem" logo="'icons/app_advanced_settings.svg'"
card-title="'Policy monitoring'" switch-tab="octrl.switchTab('pm')" current-tab="'pm'"
description="octrl.TabDescription.pm.description" />
<wz-welcome-card class="euiFlexItem" logo="'icons/sca.png'"
card-title="'Security configuration assessment'" switch-tab="octrl.switchTab('sca')"
current-tab="'sca'" description="octrl.TabDescription['sca'].description" />
<wz-welcome-card ng-if="octrl.extensions.audit" class="euiFlexItem"
logo="'icons/app_monitoring.svg'" card-title="'System auditing'"
switch-tab="octrl.switchTab('audit')" current-tab="'audit'"

View File

@ -74,8 +74,6 @@
</md-nav-item>
<md-nav-item ng-show="octrl.extensions.audit" class="wz-nav-item" md-nav-click="octrl.switchTab('audit',true)"
name="audit">{{ octrl.tabNames['audit'] }}</md-nav-item>
<md-nav-item class="wz-nav-item" md-nav-click="octrl.switchTab('sca',true)" name="sca">
{{ octrl.tabNames['sca'] }}</md-nav-item>
<md-nav-item ng-show="octrl.extensions.oscap" class="wz-nav-item" md-nav-click="octrl.switchTab('oscap',true)"
name="oscap">{{ octrl.tabNames['oscap'] }}</md-nav-item>
<md-nav-item ng-show="octrl.extensions.ciscat" class="wz-nav-item" md-nav-click="octrl.switchTab('ciscat',true)"

View File

@ -160,7 +160,9 @@ export class WazuhApiElasticCtrl {
);
log(
'wazuh-api-elastic:saveAPI',
`${req.payload.user}:*****@${req.payload.url}:${req.payload.port} entry saved successfully`,
`${req.payload.user}:*****@${req.payload.url}:${
req.payload.port
} entry saved successfully`,
'debug'
);

View File

@ -46,7 +46,9 @@ export class WazuhElasticCtrl {
if (source.installationDate && source.lastRestart) {
log(
'wazuh-elastic:getTimeStamp',
`Installation date: ${data.hits.hits[0]._source.installationDate}. Last restart: ${data.hits.hits[0]._source.lastRestart}`,
`Installation date: ${
data.hits.hits[0]._source.installationDate
}. Last restart: ${data.hits.hits[0]._source.lastRestart}`,
'debug'
);
return {
@ -503,7 +505,9 @@ export class WazuhElasticCtrl {
let query = '';
if (title === 'Wazuh App Cluster Overview') {
for (const node of nodes) {
query += `.es(index=${pattern_name},q="cluster.name: ${name} AND cluster.node: ${node.name}").label("${node.name}"),`;
query += `.es(index=${pattern_name},q="cluster.name: ${name} AND cluster.node: ${
node.name
}").label("${node.name}"),`;
}
query = query.substring(0, query.length - 1);
} else if (title === 'Wazuh App Cluster Overview Manager') {

View File

@ -1041,12 +1041,16 @@ export class WazuhReportingCtrl {
if (lastScan && lastScan.data) {
if (lastScan.data.start && lastScan.data.end) {
this.dd.content.push({
text: `Last policy monitoring scan was executed from ${lastScan.data.start} to ${lastScan.data.end}.`,
text: `Last policy monitoring scan was executed from ${
lastScan.data.start
} to ${lastScan.data.end}.`,
style: 'standard'
});
} else if (lastScan.data.start) {
this.dd.content.push({
text: `Policy monitoring scan is currently in progress for this agent (started on ${lastScan.data.start}).`,
text: `Policy monitoring scan is currently in progress for this agent (started on ${
lastScan.data.start
}).`,
style: 'standard'
});
} else {
@ -1164,11 +1168,15 @@ export class WazuhReportingCtrl {
if (lastScan && lastScan.data) {
if (lastScan.data.start && lastScan.data.end) {
this.dd.content.push({
text: `Last file integrity monitoring scan was executed from ${lastScan.data.start} to ${lastScan.data.end}.`
text: `Last file integrity monitoring scan was executed from ${
lastScan.data.start
} to ${lastScan.data.end}.`
});
} else if (lastScan.data.start) {
this.dd.content.push({
text: `File integrity monitoring scan is currently in progress for this agent (started on ${lastScan.data.start}).`
text: `File integrity monitoring scan is currently in progress for this agent (started on ${
lastScan.data.start
}).`
});
} else {
this.dd.content.push({

View File

@ -345,7 +345,9 @@ export function Initialize(server) {
await wzWrapper.getTemplateByName('wazuh-kibana');
log(
'initialize:checkKibanaStatus',
`No need to create the ${wzWrapper.WZ_KIBANA_INDEX} template, already exists.`,
`No need to create the ${
wzWrapper.WZ_KIBANA_INDEX
} template, already exists.`,
'debug'
);
await createEmptyKibanaIndex();
@ -458,7 +460,9 @@ export function Initialize(server) {
log(
'initialize:updateSingleHostInformation',
`Successfully updated proper single host information for ${config.manager}`,
`Successfully updated proper single host information for ${
config.manager
}`,
'debug'
);
@ -634,7 +638,9 @@ export function Initialize(server) {
// Nothing to be done, cluster_info is present
log(
'initialize:reachAPI',
`Nothing to be done for ${config.manager} as it is already a 3.x version.`,
`Nothing to be done for ${
config.manager
} as it is already a 3.x version.`,
'debug'
);
}

View File

@ -98,7 +98,9 @@ export class Monitoring {
!this.quiet &&
log(
'monitoring:configuration',
`wazuh.monitoring.pattern: ${this.index_pattern} (index prefix: ${this.index_prefix})`,
`wazuh.monitoring.pattern: ${this.index_pattern} (index prefix: ${
this.index_prefix
})`,
'debug'
);
} catch (error) {